enabler.js.uncompressed.js 1.4 MB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498134991350013501135021350313504135051350613507135081350913510135111351213513135141351513516135171351813519135201352113522135231352413525135261352713528135291353013531135321353313534135351353613537135381353913540135411354213543135441354513546135471354813549135501355113552135531355413555135561355713558135591356013561135621356313564135651356613567135681356913570135711357213573135741357513576135771357813579135801358113582135831358413585135861358713588135891359013591135921359313594135951359613597135981359913600136011360213603136041360513606136071360813609136101361113612136131361413615136161361713618136191362013621136221362313624136251362613627136281362913630136311363213633136341363513636136371363813639136401364113642136431364413645136461364713648136491365013651136521365313654136551365613657136581365913660136611366213663136641366513666136671366813669136701367113672136731367413675136761367713678136791368013681136821368313684136851368613687136881368913690136911369213693136941369513696136971369813699137001370113702137031370413705137061370713708137091371013711137121371313714137151371613717137181371913720137211372213723137241372513726137271372813729137301373113732137331373413735137361373713738137391374013741137421374313744137451374613747137481374913750137511375213753137541375513756137571375813759137601376113762137631376413765137661376713768137691377013771137721377313774137751377613777137781377913780137811378213783137841378513786137871378813789137901379113792137931379413795137961379713798137991380013801138021380313804138051380613807138081380913810138111381213813138141381513816138171381813819138201382113822138231382413825138261382713828138291383013831138321383313834138351383613837138381383913840138411384213843138441384513846138471384813849138501385113852138531385413855138561385713858138591386013861138621386313864138651386613867138681386913870138711387213873138741387513876138771387813879138801388113882138831388413885138861388713888138891389013891138921389313894138951389613897138981389913900139011390213903139041390513906139071390813909139101391113912139131391413915139161391713918139191392013921139221392313924139251392613927139281392913930139311393213933139341393513936139371393813939139401394113942139431394413945139461394713948139491395013951139521395313954139551395613957139581395913960139611396213963139641396513966139671396813969139701397113972139731397413975139761397713978139791398013981139821398313984139851398613987139881398913990139911399213993139941399513996139971399813999140001400114002140031400414005140061400714008140091401014011140121401314014140151401614017140181401914020140211402214023140241402514026140271402814029140301403114032140331403414035140361403714038140391404014041140421404314044140451404614047140481404914050140511405214053140541405514056140571405814059140601406114062140631406414065140661406714068140691407014071140721407314074140751407614077140781407914080140811408214083140841408514086140871408814089140901409114092140931409414095140961409714098140991410014101141021410314104141051410614107141081410914110141111411214113141141411514116141171411814119141201412114122141231412414125141261412714128141291413014131141321413314134141351413614137141381413914140141411414214143141441414514146141471414814149141501415114152141531415414155141561415714158141591416014161141621416314164141651416614167141681416914170141711417214173141741417514176141771417814179141801418114182141831418414185141861418714188141891419014191141921419314194141951419614197141981419914200142011420214203142041420514206142071420814209142101421114212142131421414215142161421714218142191422014221142221422314224142251422614227142281422914230142311423214233142341423514236142371423814239142401424114242142431424414245142461424714248142491425014251142521425314254142551425614257142581425914260142611426214263142641426514266142671426814269142701427114272142731427414275142761427714278142791428014281142821428314284142851428614287142881428914290142911429214293142941429514296142971429814299143001430114302143031430414305143061430714308143091431014311143121431314314143151431614317143181431914320143211432214323143241432514326143271432814329143301433114332143331433414335143361433714338143391434014341143421434314344143451434614347143481434914350143511435214353143541435514356143571435814359143601436114362143631436414365143661436714368143691437014371143721437314374143751437614377143781437914380143811438214383143841438514386143871438814389143901439114392143931439414395143961439714398143991440014401144021440314404144051440614407144081440914410144111441214413144141441514416144171441814419144201442114422144231442414425144261442714428144291443014431144321443314434144351443614437144381443914440144411444214443144441444514446144471444814449144501445114452144531445414455144561445714458144591446014461144621446314464144651446614467144681446914470144711447214473144741447514476144771447814479144801448114482144831448414485144861448714488144891449014491144921449314494144951449614497144981449914500145011450214503145041450514506145071450814509145101451114512145131451414515145161451714518145191452014521145221452314524145251452614527145281452914530145311453214533145341453514536145371453814539145401454114542145431454414545145461454714548145491455014551145521455314554145551455614557145581455914560145611456214563145641456514566145671456814569145701457114572145731457414575145761457714578145791458014581145821458314584145851458614587145881458914590145911459214593145941459514596145971459814599146001460114602146031460414605146061460714608146091461014611146121461314614146151461614617146181461914620146211462214623146241462514626146271462814629146301463114632146331463414635146361463714638146391464014641146421464314644146451464614647146481464914650146511465214653146541465514656146571465814659146601466114662146631466414665146661466714668146691467014671146721467314674146751467614677146781467914680146811468214683146841468514686146871468814689146901469114692146931469414695146961469714698146991470014701147021470314704147051470614707147081470914710147111471214713147141471514716147171471814719147201472114722147231472414725147261472714728147291473014731147321473314734147351473614737147381473914740147411474214743147441474514746147471474814749147501475114752147531475414755147561475714758147591476014761147621476314764147651476614767147681476914770147711477214773147741477514776147771477814779147801478114782147831478414785147861478714788147891479014791147921479314794147951479614797147981479914800148011480214803148041480514806148071480814809148101481114812148131481414815148161481714818148191482014821148221482314824148251482614827148281482914830148311483214833148341483514836148371483814839148401484114842148431484414845148461484714848148491485014851148521485314854148551485614857148581485914860148611486214863148641486514866148671486814869148701487114872148731487414875148761487714878148791488014881148821488314884148851488614887148881488914890148911489214893148941489514896148971489814899149001490114902149031490414905149061490714908149091491014911149121491314914149151491614917149181491914920149211492214923149241492514926149271492814929149301493114932149331493414935149361493714938149391494014941149421494314944149451494614947149481494914950149511495214953149541495514956149571495814959149601496114962149631496414965149661496714968149691497014971149721497314974149751497614977149781497914980149811498214983149841498514986149871498814989149901499114992149931499414995149961499714998149991500015001150021500315004150051500615007150081500915010150111501215013150141501515016150171501815019150201502115022150231502415025150261502715028150291503015031150321503315034150351503615037150381503915040150411504215043150441504515046150471504815049150501505115052150531505415055150561505715058150591506015061150621506315064150651506615067150681506915070150711507215073150741507515076150771507815079150801508115082150831508415085150861508715088150891509015091150921509315094150951509615097150981509915100151011510215103151041510515106151071510815109151101511115112151131511415115151161511715118151191512015121151221512315124151251512615127151281512915130151311513215133151341513515136151371513815139151401514115142151431514415145151461514715148151491515015151151521515315154151551515615157151581515915160151611516215163151641516515166151671516815169151701517115172151731517415175151761517715178151791518015181151821518315184151851518615187151881518915190151911519215193151941519515196151971519815199152001520115202152031520415205152061520715208152091521015211152121521315214152151521615217152181521915220152211522215223152241522515226152271522815229152301523115232152331523415235152361523715238152391524015241152421524315244152451524615247152481524915250152511525215253152541525515256152571525815259152601526115262152631526415265152661526715268152691527015271152721527315274152751527615277152781527915280152811528215283152841528515286152871528815289152901529115292152931529415295152961529715298152991530015301153021530315304153051530615307153081530915310153111531215313153141531515316153171531815319153201532115322153231532415325153261532715328153291533015331153321533315334153351533615337153381533915340153411534215343153441534515346153471534815349153501535115352153531535415355153561535715358153591536015361153621536315364153651536615367153681536915370153711537215373153741537515376153771537815379153801538115382153831538415385153861538715388153891539015391153921539315394153951539615397153981539915400154011540215403154041540515406154071540815409154101541115412154131541415415154161541715418154191542015421154221542315424154251542615427154281542915430154311543215433154341543515436154371543815439154401544115442154431544415445154461544715448154491545015451154521545315454154551545615457154581545915460154611546215463154641546515466154671546815469154701547115472154731547415475154761547715478154791548015481154821548315484154851548615487154881548915490154911549215493154941549515496154971549815499155001550115502155031550415505155061550715508155091551015511155121551315514155151551615517155181551915520155211552215523155241552515526155271552815529155301553115532155331553415535155361553715538155391554015541155421554315544155451554615547155481554915550155511555215553155541555515556155571555815559155601556115562155631556415565155661556715568155691557015571155721557315574155751557615577155781557915580155811558215583155841558515586155871558815589155901559115592155931559415595155961559715598155991560015601156021560315604156051560615607156081560915610156111561215613156141561515616156171561815619156201562115622156231562415625156261562715628156291563015631156321563315634156351563615637156381563915640156411564215643156441564515646156471564815649156501565115652156531565415655156561565715658156591566015661156621566315664156651566615667156681566915670156711567215673156741567515676156771567815679156801568115682156831568415685156861568715688156891569015691156921569315694156951569615697156981569915700157011570215703157041570515706157071570815709157101571115712157131571415715157161571715718157191572015721157221572315724157251572615727157281572915730157311573215733157341573515736157371573815739157401574115742157431574415745157461574715748157491575015751157521575315754157551575615757157581575915760157611576215763157641576515766157671576815769157701577115772157731577415775157761577715778157791578015781157821578315784157851578615787157881578915790157911579215793157941579515796157971579815799158001580115802158031580415805158061580715808158091581015811158121581315814158151581615817158181581915820158211582215823158241582515826158271582815829158301583115832158331583415835158361583715838158391584015841158421584315844158451584615847158481584915850158511585215853158541585515856158571585815859158601586115862158631586415865158661586715868158691587015871158721587315874158751587615877158781587915880158811588215883158841588515886158871588815889158901589115892158931589415895158961589715898158991590015901159021590315904159051590615907159081590915910159111591215913159141591515916159171591815919159201592115922159231592415925159261592715928159291593015931159321593315934159351593615937159381593915940159411594215943159441594515946159471594815949159501595115952159531595415955159561595715958159591596015961159621596315964159651596615967159681596915970159711597215973159741597515976159771597815979159801598115982159831598415985159861598715988159891599015991159921599315994159951599615997159981599916000160011600216003160041600516006160071600816009160101601116012160131601416015160161601716018160191602016021160221602316024160251602616027160281602916030160311603216033160341603516036160371603816039160401604116042160431604416045160461604716048160491605016051160521605316054160551605616057160581605916060160611606216063160641606516066160671606816069160701607116072160731607416075160761607716078160791608016081160821608316084160851608616087160881608916090160911609216093160941609516096160971609816099161001610116102161031610416105161061610716108161091611016111161121611316114161151611616117161181611916120161211612216123161241612516126161271612816129161301613116132161331613416135161361613716138161391614016141161421614316144161451614616147161481614916150161511615216153161541615516156161571615816159161601616116162161631616416165161661616716168161691617016171161721617316174161751617616177161781617916180161811618216183161841618516186161871618816189161901619116192161931619416195161961619716198161991620016201162021620316204162051620616207162081620916210162111621216213162141621516216162171621816219162201622116222162231622416225162261622716228162291623016231162321623316234162351623616237162381623916240162411624216243162441624516246162471624816249162501625116252162531625416255162561625716258162591626016261162621626316264162651626616267162681626916270162711627216273162741627516276162771627816279162801628116282162831628416285162861628716288162891629016291162921629316294162951629616297162981629916300163011630216303163041630516306163071630816309163101631116312163131631416315163161631716318163191632016321163221632316324163251632616327163281632916330163311633216333163341633516336163371633816339163401634116342163431634416345163461634716348163491635016351163521635316354163551635616357163581635916360163611636216363163641636516366163671636816369163701637116372163731637416375163761637716378163791638016381163821638316384163851638616387163881638916390163911639216393163941639516396163971639816399164001640116402164031640416405164061640716408164091641016411164121641316414164151641616417164181641916420164211642216423164241642516426164271642816429164301643116432164331643416435164361643716438164391644016441164421644316444164451644616447164481644916450164511645216453164541645516456164571645816459164601646116462164631646416465164661646716468164691647016471164721647316474164751647616477164781647916480164811648216483164841648516486164871648816489164901649116492164931649416495164961649716498164991650016501165021650316504165051650616507165081650916510165111651216513165141651516516165171651816519165201652116522165231652416525165261652716528165291653016531165321653316534165351653616537165381653916540165411654216543165441654516546165471654816549165501655116552165531655416555165561655716558165591656016561165621656316564165651656616567165681656916570165711657216573165741657516576165771657816579165801658116582165831658416585165861658716588165891659016591165921659316594165951659616597165981659916600166011660216603166041660516606166071660816609166101661116612166131661416615166161661716618166191662016621166221662316624166251662616627166281662916630166311663216633166341663516636166371663816639166401664116642166431664416645166461664716648166491665016651166521665316654166551665616657166581665916660166611666216663166641666516666166671666816669166701667116672166731667416675166761667716678166791668016681166821668316684166851668616687166881668916690166911669216693166941669516696166971669816699167001670116702167031670416705167061670716708167091671016711167121671316714167151671616717167181671916720167211672216723167241672516726167271672816729167301673116732167331673416735167361673716738167391674016741167421674316744167451674616747167481674916750167511675216753167541675516756167571675816759167601676116762167631676416765167661676716768167691677016771167721677316774167751677616777167781677916780167811678216783167841678516786167871678816789167901679116792167931679416795167961679716798167991680016801168021680316804168051680616807168081680916810168111681216813168141681516816168171681816819168201682116822168231682416825168261682716828168291683016831168321683316834168351683616837168381683916840168411684216843168441684516846168471684816849168501685116852168531685416855168561685716858168591686016861168621686316864168651686616867168681686916870168711687216873168741687516876168771687816879168801688116882168831688416885168861688716888168891689016891168921689316894168951689616897168981689916900169011690216903169041690516906169071690816909169101691116912169131691416915169161691716918169191692016921169221692316924169251692616927169281692916930169311693216933169341693516936169371693816939169401694116942169431694416945169461694716948169491695016951169521695316954169551695616957169581695916960169611696216963169641696516966169671696816969169701697116972169731697416975169761697716978169791698016981169821698316984169851698616987169881698916990169911699216993169941699516996169971699816999170001700117002170031700417005170061700717008170091701017011170121701317014170151701617017170181701917020170211702217023170241702517026170271702817029170301703117032170331703417035170361703717038170391704017041170421704317044170451704617047170481704917050170511705217053170541705517056170571705817059170601706117062170631706417065170661706717068170691707017071170721707317074170751707617077170781707917080170811708217083170841708517086170871708817089170901709117092170931709417095170961709717098170991710017101171021710317104171051710617107171081710917110171111711217113171141711517116171171711817119171201712117122171231712417125171261712717128171291713017131171321713317134171351713617137171381713917140171411714217143171441714517146171471714817149171501715117152171531715417155171561715717158171591716017161171621716317164171651716617167171681716917170171711717217173171741717517176171771717817179171801718117182171831718417185171861718717188171891719017191171921719317194171951719617197171981719917200172011720217203172041720517206172071720817209172101721117212172131721417215172161721717218172191722017221172221722317224172251722617227172281722917230172311723217233172341723517236172371723817239172401724117242172431724417245172461724717248172491725017251172521725317254172551725617257172581725917260172611726217263172641726517266172671726817269172701727117272172731727417275172761727717278172791728017281172821728317284172851728617287172881728917290172911729217293172941729517296172971729817299173001730117302173031730417305173061730717308173091731017311173121731317314173151731617317173181731917320173211732217323173241732517326173271732817329173301733117332173331733417335173361733717338173391734017341173421734317344173451734617347173481734917350173511735217353173541735517356173571735817359173601736117362173631736417365173661736717368173691737017371173721737317374173751737617377173781737917380173811738217383173841738517386173871738817389173901739117392173931739417395173961739717398173991740017401174021740317404174051740617407174081740917410174111741217413174141741517416174171741817419174201742117422174231742417425174261742717428174291743017431174321743317434174351743617437174381743917440174411744217443174441744517446174471744817449174501745117452174531745417455174561745717458174591746017461174621746317464174651746617467174681746917470174711747217473174741747517476174771747817479174801748117482174831748417485174861748717488174891749017491174921749317494174951749617497174981749917500175011750217503175041750517506175071750817509175101751117512175131751417515175161751717518175191752017521175221752317524175251752617527175281752917530175311753217533175341753517536175371753817539175401754117542175431754417545175461754717548175491755017551175521755317554175551755617557175581755917560175611756217563175641756517566175671756817569175701757117572175731757417575175761757717578175791758017581175821758317584175851758617587175881758917590175911759217593175941759517596175971759817599176001760117602176031760417605176061760717608176091761017611176121761317614176151761617617176181761917620176211762217623176241762517626176271762817629176301763117632176331763417635176361763717638176391764017641176421764317644176451764617647176481764917650176511765217653176541765517656176571765817659176601766117662176631766417665176661766717668176691767017671176721767317674176751767617677176781767917680176811768217683176841768517686176871768817689176901769117692176931769417695176961769717698176991770017701177021770317704177051770617707177081770917710177111771217713177141771517716177171771817719177201772117722177231772417725177261772717728177291773017731177321773317734177351773617737177381773917740177411774217743177441774517746177471774817749177501775117752177531775417755177561775717758177591776017761177621776317764177651776617767177681776917770177711777217773177741777517776177771777817779177801778117782177831778417785177861778717788177891779017791177921779317794177951779617797177981779917800178011780217803178041780517806178071780817809178101781117812178131781417815178161781717818178191782017821178221782317824178251782617827178281782917830178311783217833178341783517836178371783817839178401784117842178431784417845178461784717848178491785017851178521785317854178551785617857178581785917860178611786217863178641786517866178671786817869178701787117872178731787417875178761787717878178791788017881178821788317884178851788617887178881788917890178911789217893178941789517896178971789817899179001790117902179031790417905179061790717908179091791017911179121791317914179151791617917179181791917920179211792217923179241792517926179271792817929179301793117932179331793417935179361793717938179391794017941179421794317944179451794617947179481794917950179511795217953179541795517956179571795817959179601796117962179631796417965179661796717968179691797017971179721797317974179751797617977179781797917980179811798217983179841798517986179871798817989179901799117992179931799417995179961799717998179991800018001180021800318004180051800618007180081800918010180111801218013180141801518016180171801818019180201802118022180231802418025180261802718028180291803018031180321803318034180351803618037180381803918040180411804218043180441804518046180471804818049180501805118052180531805418055180561805718058180591806018061180621806318064180651806618067180681806918070180711807218073180741807518076180771807818079180801808118082180831808418085180861808718088180891809018091180921809318094180951809618097180981809918100181011810218103181041810518106181071810818109181101811118112181131811418115181161811718118181191812018121181221812318124181251812618127181281812918130181311813218133181341813518136181371813818139181401814118142181431814418145181461814718148181491815018151181521815318154181551815618157181581815918160181611816218163181641816518166181671816818169181701817118172181731817418175181761817718178181791818018181181821818318184181851818618187181881818918190181911819218193181941819518196181971819818199182001820118202182031820418205182061820718208182091821018211182121821318214182151821618217182181821918220182211822218223182241822518226182271822818229182301823118232182331823418235182361823718238182391824018241182421824318244182451824618247182481824918250182511825218253182541825518256182571825818259182601826118262182631826418265182661826718268182691827018271182721827318274182751827618277182781827918280182811828218283182841828518286182871828818289182901829118292182931829418295182961829718298182991830018301183021830318304183051830618307183081830918310183111831218313183141831518316183171831818319183201832118322183231832418325183261832718328183291833018331183321833318334183351833618337183381833918340183411834218343183441834518346183471834818349183501835118352183531835418355183561835718358183591836018361183621836318364183651836618367183681836918370183711837218373183741837518376183771837818379183801838118382183831838418385183861838718388183891839018391183921839318394183951839618397183981839918400184011840218403184041840518406184071840818409184101841118412184131841418415184161841718418184191842018421184221842318424184251842618427184281842918430184311843218433184341843518436184371843818439184401844118442184431844418445184461844718448184491845018451184521845318454184551845618457184581845918460184611846218463184641846518466184671846818469184701847118472184731847418475184761847718478184791848018481184821848318484184851848618487184881848918490184911849218493184941849518496184971849818499185001850118502185031850418505185061850718508185091851018511185121851318514185151851618517185181851918520185211852218523185241852518526185271852818529185301853118532185331853418535185361853718538185391854018541185421854318544185451854618547185481854918550185511855218553185541855518556185571855818559185601856118562185631856418565185661856718568185691857018571185721857318574185751857618577185781857918580185811858218583185841858518586185871858818589185901859118592185931859418595185961859718598185991860018601186021860318604186051860618607186081860918610186111861218613186141861518616186171861818619186201862118622186231862418625186261862718628186291863018631186321863318634186351863618637186381863918640186411864218643186441864518646186471864818649186501865118652186531865418655186561865718658186591866018661186621866318664186651866618667186681866918670186711867218673186741867518676186771867818679186801868118682186831868418685186861868718688186891869018691186921869318694186951869618697186981869918700187011870218703187041870518706187071870818709187101871118712187131871418715187161871718718187191872018721187221872318724187251872618727187281872918730187311873218733187341873518736187371873818739187401874118742187431874418745187461874718748187491875018751187521875318754187551875618757187581875918760187611876218763187641876518766187671876818769187701877118772187731877418775187761877718778187791878018781187821878318784187851878618787187881878918790187911879218793187941879518796187971879818799188001880118802188031880418805188061880718808188091881018811188121881318814188151881618817188181881918820188211882218823188241882518826188271882818829188301883118832188331883418835188361883718838188391884018841188421884318844188451884618847188481884918850188511885218853188541885518856188571885818859188601886118862188631886418865188661886718868188691887018871188721887318874188751887618877188781887918880188811888218883188841888518886188871888818889188901889118892188931889418895188961889718898188991890018901189021890318904189051890618907189081890918910189111891218913189141891518916189171891818919189201892118922189231892418925189261892718928189291893018931189321893318934189351893618937189381893918940189411894218943189441894518946189471894818949189501895118952189531895418955189561895718958189591896018961189621896318964189651896618967189681896918970189711897218973189741897518976189771897818979189801898118982189831898418985189861898718988189891899018991189921899318994189951899618997189981899919000190011900219003190041900519006190071900819009190101901119012190131901419015190161901719018190191902019021190221902319024190251902619027190281902919030190311903219033190341903519036190371903819039190401904119042190431904419045190461904719048190491905019051190521905319054190551905619057190581905919060190611906219063190641906519066190671906819069190701907119072190731907419075190761907719078190791908019081190821908319084190851908619087190881908919090190911909219093190941909519096190971909819099191001910119102191031910419105191061910719108191091911019111191121911319114191151911619117191181911919120191211912219123191241912519126191271912819129191301913119132191331913419135191361913719138191391914019141191421914319144191451914619147191481914919150191511915219153191541915519156191571915819159191601916119162191631916419165191661916719168191691917019171191721917319174191751917619177191781917919180191811918219183191841918519186191871918819189191901919119192191931919419195191961919719198191991920019201192021920319204192051920619207192081920919210192111921219213192141921519216192171921819219192201922119222192231922419225192261922719228192291923019231192321923319234192351923619237192381923919240192411924219243192441924519246192471924819249192501925119252192531925419255192561925719258192591926019261192621926319264192651926619267192681926919270192711927219273192741927519276192771927819279192801928119282192831928419285192861928719288192891929019291192921929319294192951929619297192981929919300193011930219303193041930519306193071930819309193101931119312193131931419315193161931719318193191932019321193221932319324193251932619327193281932919330193311933219333193341933519336193371933819339193401934119342193431934419345193461934719348193491935019351193521935319354193551935619357193581935919360193611936219363193641936519366193671936819369193701937119372193731937419375193761937719378193791938019381193821938319384193851938619387193881938919390193911939219393193941939519396193971939819399194001940119402194031940419405194061940719408194091941019411194121941319414194151941619417194181941919420194211942219423194241942519426194271942819429194301943119432194331943419435194361943719438194391944019441194421944319444194451944619447194481944919450194511945219453194541945519456194571945819459194601946119462194631946419465194661946719468194691947019471194721947319474194751947619477194781947919480194811948219483194841948519486194871948819489194901949119492194931949419495194961949719498194991950019501195021950319504195051950619507195081950919510195111951219513195141951519516195171951819519195201952119522195231952419525195261952719528195291953019531195321953319534195351953619537195381953919540195411954219543195441954519546195471954819549195501955119552195531955419555195561955719558195591956019561195621956319564195651956619567195681956919570195711957219573195741957519576195771957819579195801958119582195831958419585195861958719588195891959019591195921959319594195951959619597195981959919600196011960219603196041960519606196071960819609196101961119612196131961419615196161961719618196191962019621196221962319624196251962619627196281962919630196311963219633196341963519636196371963819639196401964119642196431964419645196461964719648196491965019651196521965319654196551965619657196581965919660196611966219663196641966519666196671966819669196701967119672196731967419675196761967719678196791968019681196821968319684196851968619687196881968919690196911969219693196941969519696196971969819699197001970119702197031970419705197061970719708197091971019711197121971319714197151971619717197181971919720197211972219723197241972519726197271972819729197301973119732197331973419735197361973719738197391974019741197421974319744197451974619747197481974919750197511975219753197541975519756197571975819759197601976119762197631976419765197661976719768197691977019771197721977319774197751977619777197781977919780197811978219783197841978519786197871978819789197901979119792197931979419795197961979719798197991980019801198021980319804198051980619807198081980919810198111981219813198141981519816198171981819819198201982119822198231982419825198261982719828198291983019831198321983319834198351983619837198381983919840198411984219843198441984519846198471984819849198501985119852198531985419855198561985719858198591986019861198621986319864198651986619867198681986919870198711987219873198741987519876198771987819879198801988119882198831988419885198861988719888198891989019891198921989319894198951989619897198981989919900199011990219903199041990519906199071990819909199101991119912199131991419915199161991719918199191992019921199221992319924199251992619927199281992919930199311993219933199341993519936199371993819939199401994119942199431994419945199461994719948199491995019951199521995319954199551995619957199581995919960199611996219963199641996519966199671996819969199701997119972199731997419975199761997719978199791998019981199821998319984199851998619987199881998919990199911999219993199941999519996199971999819999200002000120002200032000420005200062000720008200092001020011200122001320014200152001620017200182001920020200212002220023200242002520026200272002820029200302003120032200332003420035200362003720038200392004020041200422004320044200452004620047200482004920050200512005220053200542005520056200572005820059200602006120062200632006420065200662006720068200692007020071200722007320074200752007620077200782007920080200812008220083200842008520086200872008820089200902009120092200932009420095200962009720098200992010020101201022010320104201052010620107201082010920110201112011220113201142011520116201172011820119201202012120122201232012420125201262012720128201292013020131201322013320134201352013620137201382013920140201412014220143201442014520146201472014820149201502015120152201532015420155201562015720158201592016020161201622016320164201652016620167201682016920170201712017220173201742017520176201772017820179201802018120182201832018420185201862018720188201892019020191201922019320194201952019620197201982019920200202012020220203202042020520206202072020820209202102021120212202132021420215202162021720218202192022020221202222022320224202252022620227202282022920230202312023220233202342023520236202372023820239202402024120242202432024420245202462024720248202492025020251202522025320254202552025620257202582025920260202612026220263202642026520266202672026820269202702027120272202732027420275202762027720278202792028020281202822028320284202852028620287202882028920290202912029220293202942029520296202972029820299203002030120302203032030420305203062030720308203092031020311203122031320314203152031620317203182031920320203212032220323203242032520326203272032820329203302033120332203332033420335203362033720338203392034020341203422034320344203452034620347203482034920350203512035220353203542035520356203572035820359203602036120362203632036420365203662036720368203692037020371203722037320374203752037620377203782037920380203812038220383203842038520386203872038820389203902039120392203932039420395203962039720398203992040020401204022040320404204052040620407204082040920410204112041220413204142041520416204172041820419204202042120422204232042420425204262042720428204292043020431204322043320434204352043620437204382043920440204412044220443204442044520446204472044820449204502045120452204532045420455204562045720458204592046020461204622046320464204652046620467204682046920470204712047220473204742047520476204772047820479204802048120482204832048420485204862048720488204892049020491204922049320494204952049620497204982049920500205012050220503205042050520506205072050820509205102051120512205132051420515205162051720518205192052020521205222052320524205252052620527205282052920530205312053220533205342053520536205372053820539205402054120542205432054420545205462054720548205492055020551205522055320554205552055620557205582055920560205612056220563205642056520566205672056820569205702057120572205732057420575205762057720578205792058020581205822058320584205852058620587205882058920590205912059220593205942059520596205972059820599206002060120602206032060420605206062060720608206092061020611206122061320614206152061620617206182061920620206212062220623206242062520626206272062820629206302063120632206332063420635206362063720638206392064020641206422064320644206452064620647206482064920650206512065220653206542065520656206572065820659206602066120662206632066420665206662066720668206692067020671206722067320674206752067620677206782067920680206812068220683206842068520686206872068820689206902069120692206932069420695206962069720698206992070020701207022070320704207052070620707207082070920710207112071220713207142071520716207172071820719207202072120722207232072420725207262072720728207292073020731207322073320734207352073620737207382073920740207412074220743207442074520746207472074820749207502075120752207532075420755207562075720758207592076020761207622076320764207652076620767207682076920770207712077220773207742077520776207772077820779207802078120782207832078420785207862078720788207892079020791207922079320794207952079620797207982079920800208012080220803208042080520806208072080820809208102081120812208132081420815208162081720818208192082020821208222082320824208252082620827208282082920830208312083220833208342083520836208372083820839208402084120842208432084420845208462084720848208492085020851208522085320854208552085620857208582085920860208612086220863208642086520866208672086820869208702087120872208732087420875208762087720878208792088020881208822088320884208852088620887208882088920890208912089220893208942089520896208972089820899209002090120902209032090420905209062090720908209092091020911209122091320914209152091620917209182091920920209212092220923209242092520926209272092820929209302093120932209332093420935209362093720938209392094020941209422094320944209452094620947209482094920950209512095220953209542095520956209572095820959209602096120962209632096420965209662096720968209692097020971209722097320974209752097620977209782097920980209812098220983209842098520986209872098820989209902099120992209932099420995209962099720998209992100021001210022100321004210052100621007210082100921010210112101221013210142101521016210172101821019210202102121022210232102421025210262102721028210292103021031210322103321034210352103621037210382103921040210412104221043210442104521046210472104821049210502105121052210532105421055210562105721058210592106021061210622106321064210652106621067210682106921070210712107221073210742107521076210772107821079210802108121082210832108421085210862108721088210892109021091210922109321094210952109621097210982109921100211012110221103211042110521106211072110821109211102111121112211132111421115211162111721118211192112021121211222112321124211252112621127211282112921130211312113221133211342113521136211372113821139211402114121142211432114421145211462114721148211492115021151211522115321154211552115621157211582115921160211612116221163211642116521166211672116821169211702117121172211732117421175211762117721178211792118021181211822118321184211852118621187211882118921190211912119221193211942119521196211972119821199212002120121202212032120421205212062120721208212092121021211212122121321214212152121621217212182121921220212212122221223212242122521226212272122821229212302123121232212332123421235212362123721238212392124021241212422124321244212452124621247212482124921250212512125221253212542125521256212572125821259212602126121262212632126421265212662126721268212692127021271212722127321274212752127621277212782127921280212812128221283212842128521286212872128821289212902129121292212932129421295212962129721298212992130021301213022130321304213052130621307213082130921310213112131221313213142131521316213172131821319213202132121322213232132421325213262132721328213292133021331213322133321334213352133621337213382133921340213412134221343213442134521346213472134821349213502135121352213532135421355213562135721358213592136021361213622136321364213652136621367213682136921370213712137221373213742137521376213772137821379213802138121382213832138421385213862138721388213892139021391213922139321394213952139621397213982139921400214012140221403214042140521406214072140821409214102141121412214132141421415214162141721418214192142021421214222142321424214252142621427214282142921430214312143221433214342143521436214372143821439214402144121442214432144421445214462144721448214492145021451214522145321454214552145621457214582145921460214612146221463214642146521466214672146821469214702147121472214732147421475214762147721478214792148021481214822148321484214852148621487214882148921490214912149221493214942149521496214972149821499215002150121502215032150421505215062150721508215092151021511215122151321514215152151621517215182151921520215212152221523215242152521526215272152821529215302153121532215332153421535215362153721538215392154021541215422154321544215452154621547215482154921550215512155221553215542155521556215572155821559215602156121562215632156421565215662156721568215692157021571215722157321574215752157621577215782157921580215812158221583215842158521586215872158821589215902159121592215932159421595215962159721598215992160021601216022160321604216052160621607216082160921610216112161221613216142161521616216172161821619216202162121622216232162421625216262162721628216292163021631216322163321634216352163621637216382163921640216412164221643216442164521646216472164821649216502165121652216532165421655216562165721658216592166021661216622166321664216652166621667216682166921670216712167221673216742167521676216772167821679216802168121682216832168421685216862168721688216892169021691216922169321694216952169621697216982169921700217012170221703217042170521706217072170821709217102171121712217132171421715217162171721718217192172021721217222172321724217252172621727217282172921730217312173221733217342173521736217372173821739217402174121742217432174421745217462174721748217492175021751217522175321754217552175621757217582175921760217612176221763217642176521766217672176821769217702177121772217732177421775217762177721778217792178021781217822178321784217852178621787217882178921790217912179221793217942179521796217972179821799218002180121802218032180421805218062180721808218092181021811218122181321814218152181621817218182181921820218212182221823218242182521826218272182821829218302183121832218332183421835218362183721838218392184021841218422184321844218452184621847218482184921850218512185221853218542185521856218572185821859218602186121862218632186421865218662186721868218692187021871218722187321874218752187621877218782187921880218812188221883218842188521886218872188821889218902189121892218932189421895218962189721898218992190021901219022190321904219052190621907219082190921910219112191221913219142191521916219172191821919219202192121922219232192421925219262192721928219292193021931219322193321934219352193621937219382193921940219412194221943219442194521946219472194821949219502195121952219532195421955219562195721958219592196021961219622196321964219652196621967219682196921970219712197221973219742197521976219772197821979219802198121982219832198421985219862198721988219892199021991219922199321994219952199621997219982199922000220012200222003220042200522006220072200822009220102201122012220132201422015220162201722018220192202022021220222202322024220252202622027220282202922030220312203222033220342203522036220372203822039220402204122042220432204422045220462204722048220492205022051220522205322054220552205622057220582205922060220612206222063220642206522066220672206822069220702207122072220732207422075220762207722078220792208022081220822208322084220852208622087220882208922090220912209222093220942209522096220972209822099221002210122102221032210422105221062210722108221092211022111221122211322114221152211622117221182211922120221212212222123221242212522126221272212822129221302213122132221332213422135221362213722138221392214022141221422214322144221452214622147221482214922150221512215222153221542215522156221572215822159221602216122162221632216422165221662216722168221692217022171221722217322174221752217622177221782217922180221812218222183221842218522186221872218822189221902219122192221932219422195221962219722198221992220022201222022220322204222052220622207222082220922210222112221222213222142221522216222172221822219222202222122222222232222422225222262222722228222292223022231222322223322234222352223622237222382223922240222412224222243222442224522246222472224822249222502225122252222532225422255222562225722258222592226022261222622226322264222652226622267222682226922270222712227222273222742227522276222772227822279222802228122282222832228422285222862228722288222892229022291222922229322294222952229622297222982229922300223012230222303223042230522306223072230822309223102231122312223132231422315223162231722318223192232022321223222232322324223252232622327223282232922330223312233222333223342233522336223372233822339223402234122342223432234422345223462234722348223492235022351223522235322354223552235622357223582235922360223612236222363223642236522366223672236822369223702237122372223732237422375223762237722378223792238022381223822238322384223852238622387223882238922390223912239222393223942239522396223972239822399224002240122402224032240422405224062240722408224092241022411224122241322414224152241622417224182241922420224212242222423224242242522426224272242822429224302243122432224332243422435224362243722438224392244022441224422244322444224452244622447224482244922450224512245222453224542245522456224572245822459224602246122462224632246422465224662246722468224692247022471224722247322474224752247622477224782247922480224812248222483224842248522486224872248822489224902249122492224932249422495224962249722498224992250022501225022250322504225052250622507225082250922510225112251222513225142251522516225172251822519225202252122522225232252422525225262252722528225292253022531225322253322534225352253622537225382253922540225412254222543225442254522546225472254822549225502255122552225532255422555225562255722558225592256022561225622256322564225652256622567225682256922570225712257222573225742257522576225772257822579225802258122582225832258422585225862258722588225892259022591225922259322594225952259622597225982259922600226012260222603226042260522606226072260822609226102261122612226132261422615226162261722618226192262022621226222262322624226252262622627226282262922630226312263222633226342263522636226372263822639226402264122642226432264422645226462264722648226492265022651226522265322654226552265622657226582265922660226612266222663226642266522666226672266822669226702267122672226732267422675226762267722678226792268022681226822268322684226852268622687226882268922690226912269222693226942269522696226972269822699227002270122702227032270422705227062270722708227092271022711227122271322714227152271622717227182271922720227212272222723227242272522726227272272822729227302273122732227332273422735227362273722738227392274022741227422274322744227452274622747227482274922750227512275222753227542275522756227572275822759227602276122762227632276422765227662276722768227692277022771227722277322774227752277622777227782277922780227812278222783227842278522786227872278822789227902279122792227932279422795227962279722798227992280022801228022280322804228052280622807228082280922810228112281222813228142281522816228172281822819228202282122822228232282422825228262282722828228292283022831228322283322834228352283622837228382283922840228412284222843228442284522846228472284822849228502285122852228532285422855228562285722858228592286022861228622286322864228652286622867228682286922870228712287222873228742287522876228772287822879228802288122882228832288422885228862288722888228892289022891228922289322894228952289622897228982289922900229012290222903229042290522906229072290822909229102291122912229132291422915229162291722918229192292022921229222292322924229252292622927229282292922930229312293222933229342293522936229372293822939229402294122942229432294422945229462294722948229492295022951229522295322954229552295622957229582295922960229612296222963229642296522966229672296822969229702297122972229732297422975229762297722978229792298022981229822298322984229852298622987229882298922990229912299222993229942299522996229972299822999230002300123002230032300423005230062300723008230092301023011230122301323014230152301623017230182301923020230212302223023230242302523026230272302823029230302303123032230332303423035230362303723038230392304023041230422304323044230452304623047230482304923050230512305223053230542305523056230572305823059230602306123062230632306423065230662306723068230692307023071230722307323074230752307623077230782307923080230812308223083230842308523086230872308823089230902309123092230932309423095230962309723098230992310023101231022310323104231052310623107231082310923110231112311223113231142311523116231172311823119231202312123122231232312423125231262312723128231292313023131231322313323134231352313623137231382313923140231412314223143231442314523146231472314823149231502315123152231532315423155231562315723158231592316023161231622316323164231652316623167231682316923170231712317223173231742317523176231772317823179231802318123182231832318423185231862318723188231892319023191231922319323194231952319623197231982319923200232012320223203232042320523206232072320823209232102321123212232132321423215232162321723218232192322023221232222322323224232252322623227232282322923230232312323223233232342323523236232372323823239232402324123242232432324423245232462324723248232492325023251232522325323254232552325623257232582325923260232612326223263232642326523266232672326823269232702327123272232732327423275232762327723278232792328023281232822328323284232852328623287232882328923290232912329223293232942329523296232972329823299233002330123302233032330423305233062330723308233092331023311233122331323314233152331623317233182331923320233212332223323233242332523326233272332823329233302333123332233332333423335233362333723338233392334023341233422334323344233452334623347233482334923350233512335223353233542335523356233572335823359233602336123362233632336423365233662336723368233692337023371233722337323374233752337623377233782337923380233812338223383233842338523386233872338823389233902339123392233932339423395233962339723398233992340023401234022340323404234052340623407234082340923410234112341223413234142341523416234172341823419234202342123422234232342423425234262342723428234292343023431234322343323434234352343623437234382343923440234412344223443234442344523446234472344823449234502345123452234532345423455234562345723458234592346023461234622346323464234652346623467234682346923470234712347223473234742347523476234772347823479234802348123482234832348423485234862348723488234892349023491234922349323494234952349623497234982349923500235012350223503235042350523506235072350823509235102351123512235132351423515235162351723518235192352023521235222352323524235252352623527235282352923530235312353223533235342353523536235372353823539235402354123542235432354423545235462354723548235492355023551235522355323554235552355623557235582355923560235612356223563235642356523566235672356823569235702357123572235732357423575235762357723578235792358023581235822358323584235852358623587235882358923590235912359223593235942359523596235972359823599236002360123602236032360423605236062360723608236092361023611236122361323614236152361623617236182361923620236212362223623236242362523626236272362823629236302363123632236332363423635236362363723638236392364023641236422364323644236452364623647236482364923650236512365223653236542365523656236572365823659236602366123662236632366423665236662366723668236692367023671236722367323674236752367623677236782367923680236812368223683236842368523686236872368823689236902369123692236932369423695236962369723698236992370023701237022370323704237052370623707237082370923710237112371223713237142371523716237172371823719237202372123722237232372423725237262372723728237292373023731237322373323734237352373623737237382373923740237412374223743237442374523746237472374823749237502375123752237532375423755237562375723758237592376023761237622376323764237652376623767237682376923770237712377223773237742377523776237772377823779237802378123782237832378423785237862378723788237892379023791237922379323794237952379623797237982379923800238012380223803238042380523806238072380823809238102381123812238132381423815238162381723818238192382023821238222382323824238252382623827238282382923830238312383223833238342383523836238372383823839238402384123842238432384423845238462384723848238492385023851238522385323854238552385623857238582385923860238612386223863238642386523866238672386823869238702387123872238732387423875238762387723878238792388023881238822388323884238852388623887238882388923890238912389223893238942389523896238972389823899239002390123902239032390423905239062390723908239092391023911239122391323914239152391623917239182391923920239212392223923239242392523926239272392823929239302393123932239332393423935239362393723938239392394023941239422394323944239452394623947239482394923950239512395223953239542395523956239572395823959239602396123962239632396423965239662396723968239692397023971239722397323974239752397623977239782397923980239812398223983239842398523986239872398823989239902399123992239932399423995239962399723998239992400024001240022400324004240052400624007240082400924010240112401224013240142401524016240172401824019240202402124022240232402424025240262402724028240292403024031240322403324034240352403624037240382403924040240412404224043240442404524046240472404824049240502405124052240532405424055240562405724058240592406024061240622406324064240652406624067240682406924070240712407224073240742407524076240772407824079240802408124082240832408424085240862408724088240892409024091240922409324094240952409624097240982409924100241012410224103241042410524106241072410824109241102411124112241132411424115241162411724118241192412024121241222412324124241252412624127241282412924130241312413224133241342413524136241372413824139241402414124142241432414424145241462414724148241492415024151241522415324154241552415624157241582415924160241612416224163241642416524166241672416824169241702417124172241732417424175241762417724178241792418024181241822418324184241852418624187241882418924190241912419224193241942419524196241972419824199242002420124202242032420424205242062420724208242092421024211242122421324214242152421624217242182421924220242212422224223242242422524226242272422824229242302423124232242332423424235242362423724238242392424024241242422424324244242452424624247242482424924250242512425224253242542425524256242572425824259242602426124262242632426424265242662426724268242692427024271242722427324274242752427624277242782427924280242812428224283242842428524286242872428824289242902429124292242932429424295242962429724298242992430024301243022430324304243052430624307243082430924310243112431224313243142431524316243172431824319243202432124322243232432424325243262432724328243292433024331243322433324334243352433624337243382433924340243412434224343243442434524346243472434824349243502435124352243532435424355243562435724358243592436024361243622436324364243652436624367243682436924370243712437224373243742437524376243772437824379243802438124382243832438424385243862438724388243892439024391243922439324394243952439624397243982439924400244012440224403244042440524406244072440824409244102441124412244132441424415244162441724418244192442024421244222442324424244252442624427244282442924430244312443224433244342443524436244372443824439244402444124442244432444424445244462444724448244492445024451244522445324454244552445624457244582445924460244612446224463244642446524466244672446824469244702447124472244732447424475244762447724478244792448024481244822448324484244852448624487244882448924490244912449224493244942449524496244972449824499245002450124502245032450424505245062450724508245092451024511245122451324514245152451624517245182451924520245212452224523245242452524526245272452824529245302453124532245332453424535245362453724538245392454024541245422454324544245452454624547245482454924550245512455224553245542455524556245572455824559245602456124562245632456424565245662456724568245692457024571245722457324574245752457624577245782457924580245812458224583245842458524586245872458824589245902459124592245932459424595245962459724598245992460024601246022460324604246052460624607246082460924610246112461224613246142461524616246172461824619246202462124622246232462424625246262462724628246292463024631246322463324634246352463624637246382463924640246412464224643246442464524646246472464824649246502465124652246532465424655246562465724658246592466024661246622466324664246652466624667246682466924670246712467224673246742467524676246772467824679246802468124682246832468424685246862468724688246892469024691246922469324694246952469624697246982469924700247012470224703247042470524706247072470824709247102471124712247132471424715247162471724718247192472024721247222472324724247252472624727247282472924730247312473224733247342473524736247372473824739247402474124742247432474424745247462474724748247492475024751247522475324754247552475624757247582475924760247612476224763247642476524766247672476824769247702477124772247732477424775247762477724778247792478024781247822478324784247852478624787247882478924790247912479224793247942479524796247972479824799248002480124802248032480424805248062480724808248092481024811248122481324814248152481624817248182481924820248212482224823248242482524826248272482824829248302483124832248332483424835248362483724838248392484024841248422484324844248452484624847248482484924850248512485224853248542485524856248572485824859248602486124862248632486424865248662486724868248692487024871248722487324874248752487624877248782487924880248812488224883248842488524886248872488824889248902489124892248932489424895248962489724898248992490024901249022490324904249052490624907249082490924910249112491224913249142491524916249172491824919249202492124922249232492424925249262492724928249292493024931249322493324934249352493624937249382493924940249412494224943249442494524946249472494824949249502495124952249532495424955249562495724958249592496024961249622496324964249652496624967249682496924970249712497224973249742497524976249772497824979249802498124982249832498424985249862498724988249892499024991249922499324994249952499624997249982499925000250012500225003250042500525006250072500825009250102501125012250132501425015250162501725018250192502025021250222502325024250252502625027250282502925030250312503225033250342503525036250372503825039250402504125042250432504425045250462504725048250492505025051250522505325054250552505625057250582505925060250612506225063250642506525066250672506825069250702507125072250732507425075250762507725078250792508025081250822508325084250852508625087250882508925090250912509225093250942509525096250972509825099251002510125102251032510425105251062510725108251092511025111251122511325114251152511625117251182511925120251212512225123251242512525126251272512825129251302513125132251332513425135251362513725138251392514025141251422514325144251452514625147251482514925150251512515225153251542515525156251572515825159251602516125162251632516425165251662516725168251692517025171251722517325174251752517625177251782517925180251812518225183251842518525186251872518825189251902519125192251932519425195251962519725198251992520025201252022520325204252052520625207252082520925210252112521225213252142521525216252172521825219252202522125222252232522425225252262522725228252292523025231252322523325234252352523625237252382523925240252412524225243252442524525246252472524825249252502525125252252532525425255252562525725258252592526025261252622526325264252652526625267252682526925270252712527225273252742527525276252772527825279252802528125282252832528425285252862528725288252892529025291252922529325294252952529625297252982529925300253012530225303253042530525306253072530825309253102531125312253132531425315253162531725318253192532025321253222532325324253252532625327253282532925330253312533225333253342533525336253372533825339253402534125342253432534425345253462534725348253492535025351253522535325354253552535625357253582535925360253612536225363253642536525366253672536825369253702537125372253732537425375253762537725378253792538025381253822538325384253852538625387253882538925390253912539225393253942539525396253972539825399254002540125402254032540425405254062540725408254092541025411254122541325414254152541625417254182541925420254212542225423254242542525426254272542825429254302543125432254332543425435254362543725438254392544025441254422544325444254452544625447254482544925450254512545225453254542545525456254572545825459254602546125462254632546425465254662546725468254692547025471254722547325474254752547625477254782547925480254812548225483254842548525486254872548825489254902549125492254932549425495254962549725498254992550025501255022550325504255052550625507255082550925510255112551225513255142551525516255172551825519255202552125522255232552425525255262552725528255292553025531255322553325534255352553625537255382553925540255412554225543255442554525546255472554825549255502555125552255532555425555255562555725558255592556025561255622556325564255652556625567255682556925570255712557225573255742557525576255772557825579255802558125582255832558425585255862558725588255892559025591255922559325594255952559625597255982559925600256012560225603256042560525606256072560825609256102561125612256132561425615256162561725618256192562025621256222562325624256252562625627256282562925630256312563225633256342563525636256372563825639256402564125642256432564425645256462564725648256492565025651256522565325654256552565625657256582565925660256612566225663256642566525666256672566825669256702567125672256732567425675256762567725678256792568025681256822568325684256852568625687256882568925690256912569225693256942569525696256972569825699257002570125702257032570425705257062570725708257092571025711257122571325714257152571625717257182571925720257212572225723257242572525726257272572825729257302573125732257332573425735257362573725738257392574025741257422574325744257452574625747257482574925750257512575225753257542575525756257572575825759257602576125762257632576425765257662576725768257692577025771257722577325774257752577625777257782577925780257812578225783257842578525786257872578825789257902579125792257932579425795257962579725798257992580025801258022580325804258052580625807258082580925810258112581225813258142581525816258172581825819258202582125822258232582425825258262582725828258292583025831258322583325834258352583625837258382583925840258412584225843258442584525846258472584825849258502585125852258532585425855258562585725858258592586025861258622586325864258652586625867258682586925870258712587225873258742587525876258772587825879258802588125882258832588425885258862588725888258892589025891258922589325894258952589625897258982589925900259012590225903259042590525906259072590825909259102591125912259132591425915259162591725918259192592025921259222592325924259252592625927259282592925930259312593225933259342593525936259372593825939259402594125942259432594425945259462594725948259492595025951259522595325954259552595625957259582595925960259612596225963259642596525966259672596825969259702597125972259732597425975259762597725978259792598025981259822598325984259852598625987259882598925990259912599225993259942599525996259972599825999260002600126002260032600426005260062600726008260092601026011260122601326014260152601626017260182601926020260212602226023260242602526026260272602826029260302603126032260332603426035260362603726038260392604026041260422604326044260452604626047260482604926050260512605226053260542605526056260572605826059260602606126062260632606426065260662606726068260692607026071260722607326074260752607626077260782607926080260812608226083260842608526086260872608826089260902609126092260932609426095260962609726098260992610026101261022610326104261052610626107261082610926110261112611226113261142611526116261172611826119261202612126122261232612426125261262612726128261292613026131261322613326134261352613626137261382613926140261412614226143261442614526146261472614826149261502615126152261532615426155261562615726158261592616026161261622616326164261652616626167261682616926170261712617226173261742617526176261772617826179261802618126182261832618426185261862618726188261892619026191261922619326194261952619626197261982619926200262012620226203262042620526206262072620826209262102621126212262132621426215262162621726218262192622026221262222622326224262252622626227262282622926230262312623226233262342623526236262372623826239262402624126242262432624426245262462624726248262492625026251262522625326254262552625626257262582625926260262612626226263262642626526266262672626826269262702627126272262732627426275262762627726278262792628026281262822628326284262852628626287262882628926290262912629226293262942629526296262972629826299263002630126302263032630426305263062630726308263092631026311263122631326314263152631626317263182631926320263212632226323263242632526326263272632826329263302633126332263332633426335263362633726338263392634026341263422634326344263452634626347263482634926350263512635226353263542635526356263572635826359263602636126362263632636426365263662636726368263692637026371263722637326374263752637626377263782637926380263812638226383263842638526386263872638826389263902639126392263932639426395263962639726398263992640026401264022640326404264052640626407264082640926410264112641226413264142641526416264172641826419264202642126422264232642426425264262642726428264292643026431264322643326434264352643626437264382643926440264412644226443264442644526446264472644826449264502645126452264532645426455264562645726458264592646026461264622646326464264652646626467264682646926470264712647226473264742647526476264772647826479264802648126482264832648426485264862648726488264892649026491264922649326494264952649626497264982649926500265012650226503265042650526506265072650826509265102651126512265132651426515265162651726518265192652026521265222652326524265252652626527265282652926530265312653226533265342653526536265372653826539265402654126542265432654426545265462654726548265492655026551265522655326554265552655626557265582655926560265612656226563265642656526566265672656826569265702657126572265732657426575265762657726578265792658026581265822658326584265852658626587265882658926590265912659226593265942659526596265972659826599266002660126602266032660426605266062660726608266092661026611266122661326614266152661626617266182661926620266212662226623266242662526626266272662826629266302663126632266332663426635266362663726638266392664026641266422664326644266452664626647266482664926650266512665226653266542665526656266572665826659266602666126662266632666426665266662666726668266692667026671266722667326674266752667626677266782667926680266812668226683266842668526686266872668826689266902669126692266932669426695266962669726698266992670026701267022670326704267052670626707267082670926710267112671226713267142671526716267172671826719267202672126722267232672426725267262672726728267292673026731267322673326734267352673626737267382673926740267412674226743267442674526746267472674826749267502675126752267532675426755267562675726758267592676026761267622676326764267652676626767267682676926770267712677226773267742677526776267772677826779267802678126782267832678426785267862678726788267892679026791267922679326794267952679626797267982679926800268012680226803268042680526806268072680826809268102681126812268132681426815268162681726818268192682026821268222682326824268252682626827268282682926830268312683226833268342683526836268372683826839268402684126842268432684426845268462684726848268492685026851268522685326854268552685626857268582685926860268612686226863268642686526866268672686826869268702687126872268732687426875268762687726878268792688026881268822688326884268852688626887268882688926890268912689226893268942689526896268972689826899269002690126902269032690426905269062690726908269092691026911269122691326914269152691626917269182691926920269212692226923269242692526926269272692826929269302693126932269332693426935269362693726938269392694026941269422694326944269452694626947269482694926950269512695226953269542695526956269572695826959269602696126962269632696426965269662696726968269692697026971269722697326974269752697626977269782697926980269812698226983269842698526986269872698826989269902699126992269932699426995269962699726998269992700027001270022700327004270052700627007270082700927010270112701227013270142701527016270172701827019270202702127022270232702427025270262702727028270292703027031270322703327034270352703627037270382703927040270412704227043270442704527046270472704827049270502705127052270532705427055270562705727058270592706027061270622706327064270652706627067270682706927070270712707227073270742707527076270772707827079270802708127082270832708427085270862708727088270892709027091270922709327094270952709627097270982709927100271012710227103271042710527106271072710827109271102711127112271132711427115271162711727118271192712027121271222712327124271252712627127271282712927130271312713227133271342713527136271372713827139271402714127142271432714427145271462714727148271492715027151271522715327154271552715627157271582715927160271612716227163271642716527166271672716827169271702717127172271732717427175271762717727178271792718027181271822718327184271852718627187271882718927190271912719227193271942719527196271972719827199272002720127202272032720427205272062720727208272092721027211272122721327214272152721627217272182721927220272212722227223272242722527226272272722827229272302723127232272332723427235272362723727238272392724027241272422724327244272452724627247272482724927250272512725227253272542725527256272572725827259272602726127262272632726427265272662726727268272692727027271272722727327274272752727627277272782727927280272812728227283272842728527286272872728827289272902729127292272932729427295272962729727298272992730027301273022730327304273052730627307273082730927310273112731227313273142731527316273172731827319273202732127322273232732427325273262732727328273292733027331273322733327334273352733627337273382733927340273412734227343273442734527346273472734827349273502735127352273532735427355273562735727358273592736027361273622736327364273652736627367273682736927370273712737227373273742737527376273772737827379273802738127382273832738427385273862738727388273892739027391273922739327394273952739627397273982739927400274012740227403274042740527406274072740827409274102741127412274132741427415274162741727418274192742027421274222742327424274252742627427274282742927430274312743227433274342743527436274372743827439274402744127442274432744427445274462744727448274492745027451274522745327454274552745627457274582745927460274612746227463274642746527466274672746827469274702747127472274732747427475274762747727478274792748027481274822748327484274852748627487274882748927490274912749227493274942749527496274972749827499275002750127502275032750427505275062750727508275092751027511275122751327514275152751627517275182751927520275212752227523275242752527526275272752827529275302753127532275332753427535275362753727538275392754027541275422754327544275452754627547275482754927550275512755227553275542755527556275572755827559275602756127562275632756427565275662756727568275692757027571275722757327574275752757627577275782757927580275812758227583275842758527586275872758827589275902759127592275932759427595275962759727598275992760027601276022760327604276052760627607276082760927610276112761227613276142761527616276172761827619276202762127622276232762427625276262762727628276292763027631276322763327634276352763627637276382763927640276412764227643276442764527646276472764827649276502765127652276532765427655276562765727658276592766027661276622766327664276652766627667276682766927670276712767227673276742767527676276772767827679276802768127682276832768427685276862768727688276892769027691276922769327694276952769627697276982769927700277012770227703277042770527706277072770827709277102771127712277132771427715277162771727718277192772027721277222772327724277252772627727277282772927730277312773227733277342773527736277372773827739277402774127742277432774427745277462774727748277492775027751277522775327754277552775627757277582775927760277612776227763277642776527766277672776827769277702777127772277732777427775277762777727778277792778027781277822778327784277852778627787277882778927790277912779227793277942779527796277972779827799278002780127802278032780427805278062780727808278092781027811278122781327814278152781627817278182781927820278212782227823278242782527826278272782827829278302783127832278332783427835278362783727838278392784027841278422784327844278452784627847278482784927850278512785227853278542785527856278572785827859278602786127862278632786427865278662786727868278692787027871278722787327874278752787627877278782787927880278812788227883278842788527886278872788827889278902789127892278932789427895278962789727898278992790027901279022790327904279052790627907279082790927910279112791227913279142791527916279172791827919279202792127922279232792427925279262792727928279292793027931279322793327934279352793627937279382793927940279412794227943279442794527946279472794827949279502795127952279532795427955279562795727958279592796027961279622796327964279652796627967279682796927970279712797227973279742797527976279772797827979279802798127982279832798427985279862798727988279892799027991279922799327994279952799627997279982799928000280012800228003280042800528006280072800828009280102801128012280132801428015280162801728018280192802028021280222802328024280252802628027280282802928030280312803228033280342803528036280372803828039280402804128042280432804428045280462804728048280492805028051280522805328054280552805628057280582805928060280612806228063280642806528066280672806828069280702807128072280732807428075280762807728078280792808028081280822808328084280852808628087280882808928090280912809228093280942809528096280972809828099281002810128102281032810428105281062810728108281092811028111281122811328114281152811628117281182811928120281212812228123281242812528126281272812828129281302813128132281332813428135281362813728138281392814028141281422814328144281452814628147281482814928150281512815228153281542815528156281572815828159281602816128162281632816428165281662816728168281692817028171281722817328174281752817628177281782817928180281812818228183281842818528186281872818828189281902819128192281932819428195281962819728198281992820028201282022820328204282052820628207282082820928210282112821228213282142821528216282172821828219282202822128222282232822428225282262822728228282292823028231282322823328234282352823628237282382823928240282412824228243282442824528246282472824828249282502825128252282532825428255282562825728258282592826028261282622826328264282652826628267282682826928270282712827228273282742827528276282772827828279282802828128282282832828428285282862828728288282892829028291282922829328294282952829628297282982829928300283012830228303283042830528306283072830828309283102831128312283132831428315283162831728318283192832028321283222832328324283252832628327283282832928330283312833228333283342833528336283372833828339283402834128342283432834428345283462834728348283492835028351283522835328354283552835628357283582835928360283612836228363283642836528366283672836828369283702837128372283732837428375283762837728378283792838028381283822838328384283852838628387283882838928390283912839228393283942839528396283972839828399284002840128402284032840428405284062840728408284092841028411284122841328414284152841628417284182841928420284212842228423284242842528426284272842828429284302843128432284332843428435284362843728438284392844028441284422844328444284452844628447284482844928450284512845228453284542845528456284572845828459284602846128462284632846428465284662846728468284692847028471284722847328474284752847628477284782847928480284812848228483284842848528486284872848828489284902849128492284932849428495284962849728498284992850028501285022850328504285052850628507285082850928510285112851228513285142851528516285172851828519285202852128522285232852428525285262852728528285292853028531285322853328534285352853628537285382853928540285412854228543285442854528546285472854828549285502855128552285532855428555285562855728558285592856028561285622856328564285652856628567285682856928570285712857228573285742857528576285772857828579285802858128582285832858428585285862858728588285892859028591285922859328594285952859628597285982859928600286012860228603286042860528606286072860828609286102861128612286132861428615286162861728618286192862028621286222862328624286252862628627286282862928630286312863228633286342863528636286372863828639286402864128642286432864428645286462864728648286492865028651286522865328654286552865628657286582865928660286612866228663286642866528666286672866828669286702867128672286732867428675286762867728678286792868028681286822868328684286852868628687286882868928690286912869228693286942869528696286972869828699287002870128702287032870428705287062870728708287092871028711287122871328714287152871628717287182871928720287212872228723287242872528726287272872828729287302873128732287332873428735287362873728738287392874028741287422874328744287452874628747287482874928750287512875228753287542875528756287572875828759287602876128762287632876428765287662876728768287692877028771287722877328774287752877628777287782877928780287812878228783287842878528786287872878828789287902879128792287932879428795287962879728798287992880028801288022880328804288052880628807288082880928810288112881228813288142881528816288172881828819288202882128822288232882428825288262882728828288292883028831288322883328834288352883628837288382883928840288412884228843288442884528846288472884828849288502885128852288532885428855288562885728858288592886028861288622886328864288652886628867288682886928870288712887228873288742887528876288772887828879288802888128882288832888428885288862888728888288892889028891288922889328894288952889628897288982889928900289012890228903289042890528906289072890828909289102891128912289132891428915289162891728918289192892028921289222892328924289252892628927289282892928930289312893228933289342893528936289372893828939289402894128942289432894428945289462894728948289492895028951289522895328954289552895628957289582895928960289612896228963289642896528966289672896828969289702897128972289732897428975289762897728978289792898028981289822898328984289852898628987289882898928990289912899228993289942899528996289972899828999290002900129002290032900429005290062900729008290092901029011290122901329014290152901629017290182901929020290212902229023290242902529026290272902829029290302903129032290332903429035290362903729038290392904029041290422904329044290452904629047290482904929050290512905229053290542905529056290572905829059290602906129062290632906429065290662906729068290692907029071290722907329074290752907629077290782907929080290812908229083290842908529086290872908829089290902909129092290932909429095290962909729098290992910029101291022910329104291052910629107291082910929110291112911229113291142911529116291172911829119291202912129122291232912429125291262912729128291292913029131291322913329134291352913629137291382913929140291412914229143291442914529146291472914829149291502915129152291532915429155291562915729158291592916029161291622916329164291652916629167291682916929170291712917229173291742917529176291772917829179291802918129182291832918429185291862918729188291892919029191291922919329194291952919629197291982919929200292012920229203292042920529206292072920829209292102921129212292132921429215292162921729218292192922029221292222922329224292252922629227292282922929230292312923229233292342923529236292372923829239292402924129242292432924429245292462924729248292492925029251292522925329254292552925629257292582925929260292612926229263292642926529266292672926829269292702927129272292732927429275292762927729278292792928029281292822928329284292852928629287292882928929290292912929229293292942929529296292972929829299293002930129302293032930429305293062930729308293092931029311293122931329314293152931629317293182931929320293212932229323293242932529326293272932829329293302933129332293332933429335293362933729338293392934029341293422934329344293452934629347293482934929350293512935229353293542935529356293572935829359293602936129362293632936429365293662936729368293692937029371293722937329374293752937629377293782937929380293812938229383293842938529386293872938829389293902939129392293932939429395293962939729398293992940029401294022940329404294052940629407294082940929410294112941229413294142941529416294172941829419294202942129422294232942429425294262942729428294292943029431294322943329434294352943629437294382943929440294412944229443294442944529446294472944829449294502945129452294532945429455294562945729458294592946029461294622946329464294652946629467294682946929470294712947229473294742947529476294772947829479294802948129482294832948429485294862948729488294892949029491294922949329494294952949629497294982949929500295012950229503295042950529506295072950829509295102951129512295132951429515295162951729518295192952029521295222952329524295252952629527295282952929530295312953229533295342953529536295372953829539295402954129542295432954429545295462954729548295492955029551295522955329554295552955629557295582955929560295612956229563295642956529566295672956829569295702957129572295732957429575295762957729578295792958029581295822958329584295852958629587295882958929590295912959229593295942959529596295972959829599296002960129602296032960429605296062960729608296092961029611296122961329614296152961629617296182961929620296212962229623296242962529626296272962829629296302963129632296332963429635296362963729638296392964029641296422964329644296452964629647296482964929650296512965229653296542965529656296572965829659296602966129662296632966429665296662966729668296692967029671296722967329674296752967629677296782967929680296812968229683296842968529686296872968829689296902969129692296932969429695296962969729698296992970029701297022970329704297052970629707297082970929710297112971229713297142971529716297172971829719297202972129722297232972429725297262972729728297292973029731297322973329734297352973629737297382973929740297412974229743297442974529746297472974829749297502975129752297532975429755297562975729758297592976029761297622976329764297652976629767297682976929770297712977229773297742977529776297772977829779297802978129782297832978429785297862978729788297892979029791297922979329794297952979629797297982979929800298012980229803298042980529806298072980829809298102981129812298132981429815298162981729818298192982029821298222982329824298252982629827298282982929830298312983229833298342983529836298372983829839298402984129842298432984429845298462984729848298492985029851298522985329854298552985629857298582985929860298612986229863298642986529866298672986829869298702987129872298732987429875298762987729878298792988029881298822988329884298852988629887298882988929890298912989229893298942989529896298972989829899299002990129902299032990429905299062990729908299092991029911299122991329914299152991629917299182991929920299212992229923299242992529926299272992829929299302993129932299332993429935299362993729938299392994029941299422994329944299452994629947299482994929950299512995229953299542995529956299572995829959299602996129962299632996429965299662996729968299692997029971299722997329974299752997629977299782997929980299812998229983299842998529986299872998829989299902999129992299932999429995299962999729998299993000030001300023000330004300053000630007300083000930010300113001230013300143001530016300173001830019300203002130022300233002430025300263002730028300293003030031300323003330034300353003630037300383003930040300413004230043300443004530046300473004830049300503005130052300533005430055300563005730058300593006030061300623006330064300653006630067300683006930070300713007230073300743007530076300773007830079300803008130082300833008430085300863008730088300893009030091300923009330094300953009630097300983009930100301013010230103301043010530106301073010830109301103011130112301133011430115301163011730118301193012030121301223012330124301253012630127301283012930130301313013230133301343013530136301373013830139301403014130142301433014430145301463014730148301493015030151301523015330154301553015630157301583015930160301613016230163301643016530166301673016830169301703017130172301733017430175301763017730178301793018030181301823018330184301853018630187301883018930190301913019230193301943019530196301973019830199302003020130202302033020430205302063020730208302093021030211302123021330214302153021630217302183021930220302213022230223302243022530226302273022830229302303023130232302333023430235302363023730238302393024030241302423024330244302453024630247302483024930250302513025230253302543025530256302573025830259302603026130262302633026430265302663026730268302693027030271302723027330274302753027630277302783027930280302813028230283302843028530286302873028830289302903029130292302933029430295302963029730298302993030030301303023030330304303053030630307303083030930310303113031230313303143031530316303173031830319303203032130322303233032430325303263032730328303293033030331303323033330334303353033630337303383033930340303413034230343303443034530346303473034830349303503035130352303533035430355303563035730358303593036030361303623036330364303653036630367303683036930370303713037230373303743037530376303773037830379303803038130382303833038430385303863038730388303893039030391303923039330394303953039630397303983039930400304013040230403304043040530406304073040830409304103041130412304133041430415304163041730418304193042030421304223042330424304253042630427304283042930430304313043230433304343043530436304373043830439304403044130442304433044430445304463044730448304493045030451304523045330454304553045630457304583045930460304613046230463304643046530466304673046830469304703047130472304733047430475304763047730478304793048030481304823048330484304853048630487304883048930490304913049230493304943049530496304973049830499305003050130502305033050430505305063050730508305093051030511305123051330514305153051630517305183051930520305213052230523305243052530526305273052830529305303053130532305333053430535305363053730538305393054030541305423054330544305453054630547305483054930550305513055230553305543055530556305573055830559305603056130562305633056430565305663056730568305693057030571305723057330574305753057630577305783057930580305813058230583305843058530586305873058830589305903059130592305933059430595305963059730598305993060030601306023060330604306053060630607306083060930610306113061230613306143061530616306173061830619306203062130622306233062430625306263062730628306293063030631306323063330634306353063630637306383063930640306413064230643306443064530646306473064830649306503065130652306533065430655306563065730658306593066030661306623066330664306653066630667306683066930670306713067230673306743067530676306773067830679306803068130682306833068430685306863068730688306893069030691306923069330694306953069630697306983069930700307013070230703307043070530706307073070830709307103071130712307133071430715307163071730718307193072030721307223072330724307253072630727307283072930730307313073230733307343073530736307373073830739307403074130742307433074430745307463074730748307493075030751307523075330754307553075630757307583075930760307613076230763307643076530766307673076830769307703077130772307733077430775307763077730778307793078030781307823078330784307853078630787307883078930790307913079230793307943079530796307973079830799308003080130802308033080430805308063080730808308093081030811308123081330814308153081630817308183081930820308213082230823308243082530826308273082830829308303083130832308333083430835308363083730838308393084030841308423084330844308453084630847308483084930850308513085230853308543085530856308573085830859308603086130862308633086430865308663086730868308693087030871308723087330874308753087630877308783087930880308813088230883308843088530886308873088830889308903089130892308933089430895308963089730898308993090030901309023090330904309053090630907309083090930910309113091230913309143091530916309173091830919309203092130922309233092430925309263092730928309293093030931309323093330934309353093630937309383093930940309413094230943309443094530946309473094830949309503095130952309533095430955309563095730958309593096030961309623096330964309653096630967309683096930970309713097230973309743097530976309773097830979309803098130982309833098430985309863098730988309893099030991309923099330994309953099630997309983099931000310013100231003310043100531006310073100831009310103101131012310133101431015310163101731018310193102031021310223102331024310253102631027310283102931030310313103231033310343103531036310373103831039310403104131042310433104431045310463104731048310493105031051310523105331054310553105631057310583105931060310613106231063310643106531066310673106831069310703107131072310733107431075310763107731078310793108031081310823108331084310853108631087310883108931090310913109231093310943109531096310973109831099311003110131102311033110431105311063110731108311093111031111311123111331114311153111631117311183111931120311213112231123311243112531126311273112831129311303113131132311333113431135311363113731138311393114031141311423114331144311453114631147311483114931150311513115231153311543115531156311573115831159311603116131162311633116431165311663116731168311693117031171311723117331174311753117631177311783117931180311813118231183311843118531186311873118831189311903119131192311933119431195311963119731198311993120031201312023120331204312053120631207312083120931210312113121231213312143121531216312173121831219312203122131222312233122431225312263122731228312293123031231312323123331234312353123631237312383123931240312413124231243312443124531246312473124831249312503125131252312533125431255312563125731258312593126031261312623126331264312653126631267312683126931270312713127231273312743127531276312773127831279312803128131282312833128431285312863128731288312893129031291312923129331294312953129631297312983129931300313013130231303313043130531306313073130831309313103131131312313133131431315313163131731318313193132031321313223132331324313253132631327313283132931330313313133231333313343133531336313373133831339313403134131342313433134431345313463134731348313493135031351313523135331354313553135631357313583135931360313613136231363313643136531366313673136831369313703137131372313733137431375313763137731378313793138031381313823138331384313853138631387313883138931390313913139231393313943139531396313973139831399314003140131402314033140431405314063140731408314093141031411314123141331414314153141631417314183141931420314213142231423314243142531426314273142831429314303143131432314333143431435314363143731438314393144031441314423144331444314453144631447314483144931450314513145231453314543145531456314573145831459314603146131462314633146431465314663146731468314693147031471314723147331474314753147631477314783147931480314813148231483314843148531486314873148831489314903149131492314933149431495314963149731498314993150031501315023150331504315053150631507315083150931510315113151231513315143151531516315173151831519315203152131522315233152431525315263152731528315293153031531315323153331534315353153631537315383153931540315413154231543315443154531546315473154831549315503155131552315533155431555315563155731558315593156031561315623156331564315653156631567315683156931570315713157231573315743157531576315773157831579315803158131582315833158431585315863158731588315893159031591315923159331594315953159631597315983159931600316013160231603316043160531606316073160831609316103161131612316133161431615316163161731618316193162031621316223162331624316253162631627316283162931630316313163231633316343163531636316373163831639316403164131642316433164431645316463164731648316493165031651316523165331654316553165631657316583165931660316613166231663316643166531666316673166831669316703167131672316733167431675316763167731678316793168031681316823168331684316853168631687316883168931690316913169231693316943169531696316973169831699317003170131702317033170431705317063170731708317093171031711317123171331714317153171631717317183171931720317213172231723317243172531726317273172831729317303173131732317333173431735317363173731738317393174031741317423174331744317453174631747317483174931750317513175231753317543175531756317573175831759317603176131762317633176431765317663176731768317693177031771317723177331774317753177631777317783177931780317813178231783317843178531786317873178831789317903179131792317933179431795317963179731798317993180031801318023180331804318053180631807318083180931810318113181231813318143181531816318173181831819318203182131822318233182431825318263182731828318293183031831318323183331834318353183631837318383183931840318413184231843318443184531846318473184831849318503185131852318533185431855318563185731858318593186031861318623186331864318653186631867318683186931870318713187231873318743187531876318773187831879318803188131882318833188431885318863188731888318893189031891318923189331894318953189631897318983189931900319013190231903319043190531906319073190831909319103191131912319133191431915319163191731918319193192031921319223192331924319253192631927319283192931930319313193231933319343193531936319373193831939319403194131942319433194431945319463194731948319493195031951319523195331954319553195631957319583195931960319613196231963319643196531966319673196831969319703197131972319733197431975319763197731978319793198031981319823198331984319853198631987319883198931990319913199231993319943199531996319973199831999320003200132002320033200432005320063200732008320093201032011320123201332014320153201632017320183201932020320213202232023320243202532026320273202832029320303203132032320333203432035320363203732038320393204032041320423204332044320453204632047320483204932050320513205232053320543205532056320573205832059320603206132062320633206432065320663206732068320693207032071320723207332074320753207632077320783207932080320813208232083320843208532086320873208832089320903209132092320933209432095320963209732098320993210032101321023210332104321053210632107321083210932110321113211232113321143211532116321173211832119321203212132122321233212432125321263212732128321293213032131321323213332134321353213632137321383213932140321413214232143321443214532146321473214832149321503215132152321533215432155321563215732158321593216032161321623216332164321653216632167321683216932170321713217232173321743217532176321773217832179321803218132182321833218432185321863218732188321893219032191321923219332194321953219632197321983219932200322013220232203322043220532206322073220832209322103221132212322133221432215322163221732218322193222032221322223222332224322253222632227322283222932230322313223232233322343223532236322373223832239322403224132242322433224432245322463224732248322493225032251322523225332254322553225632257322583225932260322613226232263322643226532266322673226832269322703227132272322733227432275322763227732278322793228032281322823228332284322853228632287322883228932290322913229232293322943229532296322973229832299323003230132302323033230432305323063230732308323093231032311323123231332314323153231632317323183231932320323213232232323323243232532326323273232832329323303233132332323333233432335323363233732338323393234032341323423234332344323453234632347323483234932350323513235232353323543235532356323573235832359323603236132362323633236432365323663236732368323693237032371323723237332374323753237632377323783237932380323813238232383323843238532386323873238832389323903239132392323933239432395323963239732398323993240032401324023240332404324053240632407324083240932410324113241232413324143241532416324173241832419324203242132422324233242432425324263242732428324293243032431324323243332434324353243632437324383243932440324413244232443324443244532446324473244832449324503245132452324533245432455324563245732458324593246032461324623246332464324653246632467324683246932470324713247232473324743247532476324773247832479324803248132482324833248432485324863248732488324893249032491324923249332494324953249632497324983249932500325013250232503325043250532506325073250832509325103251132512325133251432515325163251732518325193252032521325223252332524325253252632527325283252932530325313253232533325343253532536325373253832539325403254132542325433254432545325463254732548325493255032551325523255332554325553255632557325583255932560325613256232563325643256532566325673256832569325703257132572325733257432575325763257732578325793258032581325823258332584325853258632587325883258932590325913259232593325943259532596325973259832599326003260132602326033260432605326063260732608326093261032611326123261332614326153261632617326183261932620326213262232623326243262532626326273262832629326303263132632326333263432635326363263732638326393264032641326423264332644326453264632647326483264932650326513265232653326543265532656326573265832659326603266132662326633266432665326663266732668326693267032671326723267332674326753267632677326783267932680326813268232683326843268532686326873268832689326903269132692326933269432695326963269732698326993270032701327023270332704327053270632707327083270932710327113271232713327143271532716327173271832719327203272132722327233272432725327263272732728327293273032731327323273332734327353273632737327383273932740327413274232743327443274532746327473274832749327503275132752327533275432755327563275732758327593276032761327623276332764327653276632767327683276932770327713277232773327743277532776327773277832779327803278132782327833278432785327863278732788327893279032791327923279332794327953279632797327983279932800328013280232803328043280532806328073280832809328103281132812328133281432815328163281732818328193282032821328223282332824328253282632827328283282932830328313283232833328343283532836328373283832839328403284132842328433284432845328463284732848328493285032851328523285332854328553285632857328583285932860328613286232863328643286532866328673286832869328703287132872328733287432875328763287732878328793288032881328823288332884328853288632887328883288932890328913289232893328943289532896328973289832899329003290132902329033290432905329063290732908329093291032911329123291332914329153291632917329183291932920329213292232923329243292532926329273292832929329303293132932329333293432935329363293732938329393294032941329423294332944329453294632947329483294932950329513295232953329543295532956329573295832959329603296132962329633296432965329663296732968329693297032971329723297332974329753297632977329783297932980329813298232983329843298532986329873298832989329903299132992329933299432995329963299732998329993300033001330023300333004330053300633007330083300933010330113301233013330143301533016330173301833019330203302133022330233302433025330263302733028330293303033031330323303333034330353303633037330383303933040330413304233043330443304533046330473304833049330503305133052330533305433055330563305733058330593306033061330623306333064330653306633067330683306933070330713307233073330743307533076330773307833079330803308133082330833308433085330863308733088330893309033091330923309333094330953309633097330983309933100331013310233103331043310533106331073310833109331103311133112331133311433115331163311733118331193312033121331223312333124331253312633127331283312933130331313313233133331343313533136331373313833139331403314133142331433314433145331463314733148331493315033151331523315333154331553315633157331583315933160331613316233163331643316533166331673316833169331703317133172331733317433175331763317733178331793318033181331823318333184331853318633187331883318933190331913319233193331943319533196331973319833199332003320133202332033320433205332063320733208332093321033211332123321333214332153321633217332183321933220332213322233223332243322533226332273322833229332303323133232332333323433235332363323733238332393324033241332423324333244332453324633247332483324933250332513325233253332543325533256332573325833259332603326133262332633326433265332663326733268332693327033271332723327333274332753327633277332783327933280332813328233283332843328533286332873328833289332903329133292332933329433295332963329733298332993330033301333023330333304333053330633307333083330933310333113331233313333143331533316333173331833319333203332133322333233332433325333263332733328333293333033331333323333333334333353333633337333383333933340333413334233343333443334533346333473334833349333503335133352333533335433355333563335733358333593336033361333623336333364333653336633367333683336933370333713337233373333743337533376333773337833379333803338133382333833338433385333863338733388333893339033391333923339333394333953339633397333983339933400334013340233403334043340533406334073340833409334103341133412334133341433415334163341733418334193342033421334223342333424334253342633427334283342933430334313343233433334343343533436334373343833439334403344133442334433344433445334463344733448334493345033451334523345333454334553345633457334583345933460334613346233463334643346533466334673346833469334703347133472334733347433475334763347733478334793348033481334823348333484334853348633487334883348933490334913349233493334943349533496334973349833499335003350133502335033350433505335063350733508335093351033511335123351333514335153351633517335183351933520335213352233523335243352533526335273352833529335303353133532335333353433535335363353733538335393354033541335423354333544335453354633547335483354933550335513355233553335543355533556335573355833559335603356133562335633356433565335663356733568335693357033571335723357333574335753357633577335783357933580335813358233583335843358533586335873358833589335903359133592335933359433595335963359733598335993360033601336023360333604336053360633607336083360933610336113361233613336143361533616336173361833619336203362133622336233362433625336263362733628336293363033631336323363333634336353363633637336383363933640336413364233643336443364533646336473364833649336503365133652336533365433655336563365733658336593366033661336623366333664336653366633667336683366933670336713367233673336743367533676336773367833679336803368133682336833368433685336863368733688336893369033691336923369333694336953369633697336983369933700337013370233703337043370533706337073370833709337103371133712337133371433715337163371733718337193372033721337223372333724337253372633727337283372933730337313373233733337343373533736337373373833739337403374133742337433374433745337463374733748337493375033751337523375333754337553375633757337583375933760337613376233763337643376533766337673376833769337703377133772337733377433775337763377733778337793378033781337823378333784337853378633787337883378933790337913379233793337943379533796337973379833799338003380133802338033380433805338063380733808338093381033811338123381333814338153381633817338183381933820338213382233823338243382533826338273382833829338303383133832338333383433835338363383733838338393384033841338423384333844338453384633847338483384933850338513385233853338543385533856338573385833859338603386133862338633386433865338663386733868338693387033871338723387333874338753387633877338783387933880338813388233883338843388533886338873388833889338903389133892338933389433895338963389733898338993390033901339023390333904339053390633907339083390933910339113391233913339143391533916339173391833919339203392133922339233392433925339263392733928339293393033931339323393333934339353393633937339383393933940339413394233943339443394533946339473394833949339503395133952339533395433955339563395733958339593396033961339623396333964339653396633967339683396933970339713397233973339743397533976339773397833979339803398133982339833398433985339863398733988339893399033991339923399333994339953399633997339983399934000340013400234003340043400534006340073400834009340103401134012340133401434015340163401734018340193402034021340223402334024340253402634027340283402934030340313403234033340343403534036340373403834039340403404134042340433404434045340463404734048340493405034051340523405334054340553405634057340583405934060340613406234063340643406534066340673406834069340703407134072340733407434075340763407734078340793408034081340823408334084340853408634087340883408934090340913409234093340943409534096340973409834099341003410134102341033410434105341063410734108341093411034111341123411334114341153411634117341183411934120341213412234123341243412534126341273412834129341303413134132341333413434135341363413734138341393414034141341423414334144341453414634147341483414934150341513415234153341543415534156341573415834159341603416134162341633416434165341663416734168341693417034171341723417334174341753417634177341783417934180341813418234183341843418534186341873418834189341903419134192341933419434195341963419734198341993420034201342023420334204342053420634207342083420934210342113421234213342143421534216342173421834219342203422134222342233422434225342263422734228342293423034231342323423334234342353423634237342383423934240342413424234243342443424534246342473424834249342503425134252342533425434255342563425734258342593426034261342623426334264342653426634267342683426934270342713427234273342743427534276342773427834279342803428134282342833428434285342863428734288342893429034291342923429334294342953429634297342983429934300343013430234303343043430534306343073430834309343103431134312343133431434315343163431734318343193432034321343223432334324343253432634327343283432934330343313433234333343343433534336343373433834339343403434134342343433434434345343463434734348343493435034351343523435334354343553435634357343583435934360343613436234363343643436534366343673436834369343703437134372343733437434375343763437734378343793438034381343823438334384343853438634387343883438934390343913439234393343943439534396343973439834399344003440134402344033440434405344063440734408344093441034411344123441334414344153441634417344183441934420344213442234423344243442534426344273442834429344303443134432344333443434435344363443734438344393444034441344423444334444344453444634447344483444934450344513445234453344543445534456344573445834459344603446134462344633446434465344663446734468344693447034471344723447334474344753447634477344783447934480344813448234483344843448534486344873448834489344903449134492344933449434495344963449734498344993450034501345023450334504345053450634507345083450934510345113451234513345143451534516345173451834519345203452134522345233452434525345263452734528345293453034531345323453334534345353453634537345383453934540345413454234543345443454534546345473454834549345503455134552345533455434555345563455734558345593456034561345623456334564345653456634567345683456934570345713457234573345743457534576345773457834579345803458134582345833458434585345863458734588345893459034591345923459334594345953459634597345983459934600346013460234603346043460534606346073460834609346103461134612346133461434615346163461734618346193462034621346223462334624346253462634627346283462934630346313463234633346343463534636346373463834639346403464134642346433464434645346463464734648346493465034651346523465334654346553465634657346583465934660346613466234663346643466534666346673466834669346703467134672346733467434675346763467734678346793468034681346823468334684346853468634687346883468934690346913469234693346943469534696346973469834699347003470134702347033470434705347063470734708347093471034711347123471334714347153471634717347183471934720347213472234723347243472534726347273472834729347303473134732347333473434735347363473734738347393474034741347423474334744347453474634747347483474934750347513475234753347543475534756347573475834759347603476134762347633476434765347663476734768347693477034771347723477334774347753477634777347783477934780347813478234783347843478534786347873478834789347903479134792347933479434795347963479734798347993480034801348023480334804348053480634807348083480934810348113481234813348143481534816348173481834819348203482134822348233482434825348263482734828348293483034831348323483334834348353483634837348383483934840348413484234843348443484534846348473484834849348503485134852348533485434855348563485734858348593486034861348623486334864348653486634867348683486934870348713487234873348743487534876348773487834879348803488134882348833488434885348863488734888348893489034891348923489334894348953489634897348983489934900349013490234903349043490534906349073490834909349103491134912349133491434915349163491734918349193492034921349223492334924349253492634927349283492934930349313493234933349343493534936349373493834939349403494134942349433494434945349463494734948349493495034951349523495334954349553495634957349583495934960349613496234963349643496534966349673496834969349703497134972349733497434975349763497734978349793498034981349823498334984349853498634987349883498934990349913499234993349943499534996349973499834999350003500135002350033500435005350063500735008350093501035011350123501335014350153501635017350183501935020350213502235023350243502535026350273502835029350303503135032350333503435035350363503735038350393504035041350423504335044350453504635047350483504935050350513505235053350543505535056350573505835059350603506135062350633506435065350663506735068350693507035071350723507335074350753507635077350783507935080350813508235083350843508535086350873508835089350903509135092350933509435095350963509735098350993510035101351023510335104351053510635107351083510935110351113511235113351143511535116351173511835119351203512135122351233512435125351263512735128351293513035131351323513335134351353513635137351383513935140351413514235143351443514535146351473514835149351503515135152351533515435155351563515735158351593516035161351623516335164351653516635167351683516935170351713517235173351743517535176351773517835179351803518135182351833518435185351863518735188351893519035191351923519335194351953519635197351983519935200352013520235203352043520535206352073520835209352103521135212352133521435215352163521735218352193522035221352223522335224352253522635227352283522935230352313523235233352343523535236352373523835239352403524135242352433524435245352463524735248352493525035251352523525335254352553525635257352583525935260352613526235263352643526535266352673526835269352703527135272352733527435275352763527735278352793528035281352823528335284352853528635287352883528935290352913529235293352943529535296352973529835299353003530135302353033530435305353063530735308353093531035311353123531335314353153531635317353183531935320353213532235323353243532535326353273532835329353303533135332353333533435335353363533735338353393534035341353423534335344353453534635347353483534935350353513535235353353543535535356353573535835359353603536135362353633536435365353663536735368353693537035371353723537335374353753537635377353783537935380353813538235383353843538535386353873538835389353903539135392353933539435395353963539735398353993540035401354023540335404354053540635407354083540935410354113541235413354143541535416354173541835419354203542135422354233542435425354263542735428354293543035431354323543335434354353543635437354383543935440354413544235443354443544535446354473544835449354503545135452354533545435455354563545735458354593546035461354623546335464354653546635467354683546935470354713547235473354743547535476354773547835479354803548135482354833548435485354863548735488354893549035491354923549335494354953549635497354983549935500355013550235503355043550535506355073550835509355103551135512355133551435515355163551735518355193552035521355223552335524355253552635527355283552935530355313553235533355343553535536355373553835539355403554135542355433554435545355463554735548355493555035551355523555335554355553555635557355583555935560355613556235563355643556535566355673556835569355703557135572355733557435575355763557735578355793558035581355823558335584355853558635587355883558935590355913559235593355943559535596355973559835599356003560135602356033560435605356063560735608356093561035611356123561335614356153561635617356183561935620356213562235623356243562535626356273562835629356303563135632356333563435635356363563735638356393564035641356423564335644356453564635647356483564935650356513565235653356543565535656356573565835659356603566135662356633566435665356663566735668356693567035671356723567335674356753567635677356783567935680356813568235683356843568535686356873568835689356903569135692356933569435695356963569735698356993570035701357023570335704357053570635707357083570935710357113571235713357143571535716357173571835719357203572135722357233572435725357263572735728357293573035731357323573335734357353573635737357383573935740357413574235743357443574535746357473574835749357503575135752357533575435755357563575735758357593576035761357623576335764357653576635767357683576935770357713577235773357743577535776357773577835779357803578135782357833578435785357863578735788357893579035791357923579335794357953579635797357983579935800358013580235803358043580535806358073580835809358103581135812358133581435815358163581735818358193582035821358223582335824358253582635827358283582935830358313583235833358343583535836358373583835839358403584135842358433584435845358463584735848358493585035851358523585335854358553585635857358583585935860358613586235863358643586535866358673586835869358703587135872358733587435875358763587735878358793588035881358823588335884358853588635887358883588935890358913589235893358943589535896358973589835899359003590135902359033590435905359063590735908359093591035911359123591335914359153591635917359183591935920359213592235923359243592535926359273592835929359303593135932359333593435935359363593735938359393594035941359423594335944359453594635947359483594935950359513595235953359543595535956359573595835959359603596135962359633596435965359663596735968359693597035971359723597335974359753597635977359783597935980359813598235983359843598535986359873598835989359903599135992359933599435995359963599735998359993600036001360023600336004360053600636007360083600936010360113601236013360143601536016360173601836019360203602136022360233602436025360263602736028360293603036031360323603336034360353603636037360383603936040360413604236043360443604536046360473604836049360503605136052360533605436055360563605736058360593606036061360623606336064360653606636067360683606936070360713607236073360743607536076360773607836079360803608136082360833608436085360863608736088360893609036091360923609336094360953609636097360983609936100361013610236103361043610536106361073610836109361103611136112361133611436115361163611736118361193612036121361223612336124361253612636127361283612936130361313613236133361343613536136361373613836139361403614136142361433614436145361463614736148361493615036151361523615336154361553615636157361583615936160361613616236163361643616536166361673616836169361703617136172361733617436175361763617736178361793618036181361823618336184361853618636187361883618936190361913619236193361943619536196361973619836199362003620136202362033620436205362063620736208362093621036211362123621336214362153621636217362183621936220362213622236223362243622536226362273622836229362303623136232362333623436235362363623736238362393624036241362423624336244362453624636247362483624936250362513625236253362543625536256362573625836259362603626136262362633626436265362663626736268362693627036271362723627336274362753627636277362783627936280362813628236283362843628536286362873628836289362903629136292362933629436295362963629736298362993630036301363023630336304363053630636307363083630936310363113631236313363143631536316363173631836319363203632136322363233632436325363263632736328363293633036331363323633336334363353633636337363383633936340363413634236343363443634536346363473634836349363503635136352363533635436355363563635736358363593636036361363623636336364363653636636367363683636936370363713637236373363743637536376363773637836379363803638136382363833638436385363863638736388363893639036391363923639336394363953639636397363983639936400364013640236403364043640536406364073640836409364103641136412364133641436415364163641736418364193642036421364223642336424364253642636427364283642936430364313643236433364343643536436364373643836439364403644136442364433644436445364463644736448364493645036451364523645336454364553645636457364583645936460364613646236463364643646536466364673646836469364703647136472364733647436475364763647736478364793648036481364823648336484364853648636487364883648936490364913649236493364943649536496364973649836499365003650136502365033650436505365063650736508365093651036511365123651336514365153651636517365183651936520365213652236523365243652536526365273652836529365303653136532365333653436535365363653736538365393654036541365423654336544365453654636547365483654936550365513655236553365543655536556365573655836559365603656136562365633656436565365663656736568365693657036571365723657336574365753657636577365783657936580365813658236583365843658536586365873658836589365903659136592365933659436595365963659736598365993660036601366023660336604366053660636607366083660936610366113661236613366143661536616366173661836619366203662136622366233662436625366263662736628366293663036631366323663336634366353663636637366383663936640366413664236643366443664536646366473664836649366503665136652366533665436655366563665736658366593666036661366623666336664366653666636667366683666936670366713667236673366743667536676366773667836679366803668136682366833668436685366863668736688366893669036691366923669336694366953669636697366983669936700367013670236703367043670536706367073670836709367103671136712367133671436715367163671736718367193672036721367223672336724367253672636727367283672936730367313673236733367343673536736367373673836739367403674136742367433674436745367463674736748367493675036751367523675336754367553675636757367583675936760367613676236763367643676536766367673676836769367703677136772367733677436775367763677736778367793678036781367823678336784367853678636787367883678936790367913679236793367943679536796367973679836799368003680136802368033680436805368063680736808368093681036811368123681336814368153681636817368183681936820368213682236823368243682536826368273682836829368303683136832368333683436835368363683736838368393684036841368423684336844368453684636847368483684936850368513685236853368543685536856368573685836859368603686136862368633686436865368663686736868368693687036871368723687336874368753687636877368783687936880368813688236883368843688536886368873688836889368903689136892368933689436895368963689736898368993690036901369023690336904369053690636907369083690936910369113691236913369143691536916369173691836919369203692136922369233692436925369263692736928369293693036931369323693336934369353693636937369383693936940369413694236943369443694536946369473694836949369503695136952369533695436955369563695736958369593696036961369623696336964369653696636967369683696936970369713697236973369743697536976369773697836979369803698136982369833698436985369863698736988369893699036991369923699336994369953699636997369983699937000370013700237003370043700537006370073700837009370103701137012370133701437015370163701737018370193702037021370223702337024370253702637027370283702937030370313703237033370343703537036370373703837039370403704137042370433704437045370463704737048370493705037051370523705337054370553705637057370583705937060370613706237063370643706537066370673706837069370703707137072370733707437075370763707737078370793708037081370823708337084370853708637087370883708937090370913709237093370943709537096370973709837099371003710137102371033710437105371063710737108371093711037111371123711337114371153711637117371183711937120371213712237123371243712537126371273712837129371303713137132371333713437135371363713737138371393714037141371423714337144371453714637147371483714937150371513715237153371543715537156371573715837159371603716137162371633716437165371663716737168371693717037171371723717337174371753717637177371783717937180371813718237183371843718537186371873718837189371903719137192371933719437195371963719737198371993720037201372023720337204372053720637207372083720937210372113721237213372143721537216372173721837219372203722137222372233722437225372263722737228372293723037231372323723337234372353723637237372383723937240372413724237243372443724537246372473724837249372503725137252372533725437255372563725737258372593726037261372623726337264372653726637267372683726937270372713727237273372743727537276372773727837279372803728137282372833728437285372863728737288372893729037291372923729337294372953729637297372983729937300373013730237303373043730537306373073730837309373103731137312373133731437315373163731737318373193732037321373223732337324373253732637327373283732937330373313733237333373343733537336373373733837339373403734137342373433734437345373463734737348373493735037351373523735337354373553735637357373583735937360373613736237363373643736537366373673736837369373703737137372373733737437375373763737737378373793738037381373823738337384373853738637387373883738937390373913739237393373943739537396373973739837399374003740137402374033740437405374063740737408374093741037411374123741337414374153741637417374183741937420374213742237423374243742537426374273742837429374303743137432374333743437435374363743737438374393744037441374423744337444374453744637447374483744937450374513745237453374543745537456374573745837459374603746137462374633746437465374663746737468374693747037471374723747337474374753747637477374783747937480374813748237483374843748537486374873748837489374903749137492374933749437495374963749737498374993750037501375023750337504375053750637507375083750937510375113751237513375143751537516375173751837519375203752137522375233752437525375263752737528375293753037531375323753337534375353753637537375383753937540375413754237543375443754537546375473754837549375503755137552375533755437555375563755737558375593756037561375623756337564375653756637567375683756937570375713757237573375743757537576375773757837579375803758137582375833758437585375863758737588375893759037591375923759337594375953759637597375983759937600376013760237603376043760537606376073760837609376103761137612376133761437615376163761737618376193762037621376223762337624376253762637627376283762937630376313763237633376343763537636376373763837639376403764137642376433764437645376463764737648376493765037651376523765337654376553765637657376583765937660376613766237663376643766537666376673766837669376703767137672376733767437675376763767737678376793768037681376823768337684376853768637687376883768937690376913769237693376943769537696376973769837699377003770137702377033770437705377063770737708377093771037711377123771337714377153771637717377183771937720377213772237723377243772537726377273772837729377303773137732377333773437735377363773737738377393774037741377423774337744377453774637747377483774937750377513775237753377543775537756377573775837759377603776137762377633776437765377663776737768377693777037771377723777337774377753777637777377783777937780377813778237783377843778537786377873778837789377903779137792377933779437795377963779737798377993780037801378023780337804378053780637807378083780937810378113781237813378143781537816378173781837819378203782137822378233782437825378263782737828378293783037831378323783337834378353783637837378383783937840378413784237843378443784537846378473784837849378503785137852378533785437855378563785737858378593786037861378623786337864378653786637867378683786937870378713787237873378743787537876378773787837879378803788137882378833788437885378863788737888378893789037891378923789337894378953789637897378983789937900379013790237903379043790537906379073790837909379103791137912379133791437915379163791737918379193792037921379223792337924379253792637927379283792937930379313793237933379343793537936379373793837939379403794137942379433794437945379463794737948379493795037951379523795337954379553795637957379583795937960379613796237963379643796537966379673796837969379703797137972379733797437975379763797737978379793798037981379823798337984379853798637987379883798937990379913799237993379943799537996379973799837999380003800138002380033800438005380063800738008380093801038011380123801338014380153801638017380183801938020380213802238023380243802538026380273802838029380303803138032380333803438035380363803738038380393804038041380423804338044380453804638047380483804938050380513805238053380543805538056380573805838059380603806138062380633806438065380663806738068380693807038071380723807338074380753807638077380783807938080380813808238083380843808538086380873808838089380903809138092380933809438095380963809738098380993810038101381023810338104381053810638107381083810938110381113811238113381143811538116381173811838119381203812138122381233812438125381263812738128381293813038131381323813338134381353813638137381383813938140381413814238143381443814538146381473814838149381503815138152381533815438155381563815738158381593816038161381623816338164381653816638167381683816938170381713817238173381743817538176381773817838179381803818138182381833818438185381863818738188381893819038191381923819338194381953819638197381983819938200382013820238203382043820538206382073820838209382103821138212382133821438215382163821738218382193822038221382223822338224382253822638227382283822938230382313823238233382343823538236382373823838239382403824138242382433824438245382463824738248382493825038251382523825338254382553825638257382583825938260382613826238263382643826538266382673826838269382703827138272382733827438275382763827738278382793828038281382823828338284382853828638287382883828938290382913829238293382943829538296382973829838299383003830138302383033830438305383063830738308383093831038311383123831338314383153831638317383183831938320383213832238323383243832538326383273832838329383303833138332383333833438335383363833738338383393834038341383423834338344383453834638347383483834938350383513835238353383543835538356383573835838359383603836138362383633836438365383663836738368383693837038371383723837338374383753837638377383783837938380383813838238383383843838538386383873838838389383903839138392383933839438395383963839738398383993840038401384023840338404384053840638407384083840938410384113841238413384143841538416384173841838419384203842138422384233842438425384263842738428384293843038431384323843338434384353843638437384383843938440384413844238443384443844538446384473844838449384503845138452384533845438455384563845738458384593846038461384623846338464384653846638467384683846938470384713847238473384743847538476384773847838479384803848138482384833848438485384863848738488384893849038491384923849338494384953849638497384983849938500385013850238503385043850538506385073850838509385103851138512385133851438515385163851738518385193852038521385223852338524385253852638527385283852938530385313853238533385343853538536385373853838539385403854138542385433854438545385463854738548385493855038551385523855338554385553855638557385583855938560385613856238563385643856538566385673856838569385703857138572385733857438575385763857738578385793858038581385823858338584385853858638587385883858938590385913859238593385943859538596385973859838599386003860138602386033860438605386063860738608386093861038611386123861338614386153861638617386183861938620386213862238623386243862538626386273862838629386303863138632386333863438635386363863738638386393864038641386423864338644386453864638647386483864938650386513865238653386543865538656386573865838659386603866138662386633866438665386663866738668386693867038671386723867338674386753867638677386783867938680386813868238683386843868538686386873868838689386903869138692386933869438695386963869738698386993870038701387023870338704387053870638707387083870938710387113871238713387143871538716387173871838719
  1. /*******************************************************************************
  2. * OpenAjax-mashup.js
  3. *
  4. * Reference implementation of the OpenAjax Hub, as specified by OpenAjax Alliance.
  5. * Specification is under development at:
  6. *
  7. * http://www.openajax.org/member/wiki/OpenAjax_Hub_Specification
  8. *
  9. * Copyright 2006-2009 OpenAjax Alliance
  10. *
  11. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  12. * use this file except in compliance with the License. You may obtain a copy
  13. * of the License at http://www.apache.org/licenses/LICENSE-2.0 . Unless
  14. * required by applicable law or agreed to in writing, software distributed
  15. * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  16. * CONDITIONS OF ANY KIND, either express or implied. See the License for the
  17. * specific language governing permissions and limitations under the License.
  18. *
  19. ******************************************************************************/
  20. var OpenAjax = OpenAjax || {};
  21. if ( !OpenAjax.hub ) { // prevent re-definition of the OpenAjax.hub object
  22. OpenAjax.hub = function() {
  23. var libs = {};
  24. var ooh = "org.openajax.hub.";
  25. return /** @scope OpenAjax.hub */ {
  26. implementer: "http://openajax.org",
  27. implVersion: "2.0.4",
  28. specVersion: "2.0",
  29. implExtraData: {},
  30. libraries: libs,
  31. registerLibrary: function(prefix, nsURL, version, extra) {
  32. libs[prefix] = {
  33. prefix: prefix,
  34. namespaceURI: nsURL,
  35. version: version,
  36. extraData: extra
  37. };
  38. this.publish(ooh+"registerLibrary", libs[prefix]);
  39. },
  40. unregisterLibrary: function(prefix) {
  41. this.publish(ooh+"unregisterLibrary", libs[prefix]);
  42. delete libs[prefix];
  43. }
  44. };
  45. }();
  46. /**
  47. * Error
  48. *
  49. * Standard Error names used when the standard functions need to throw Errors.
  50. */
  51. OpenAjax.hub.Error = {
  52. // Either a required argument is missing or an invalid argument was provided
  53. BadParameters: "OpenAjax.hub.Error.BadParameters",
  54. // The specified hub has been disconnected and cannot perform the requested
  55. // operation:
  56. Disconnected: "OpenAjax.hub.Error.Disconnected",
  57. // Container with specified ID already exists:
  58. Duplicate: "OpenAjax.hub.Error.Duplicate",
  59. // The specified ManagedHub has no such Container (or it has been removed)
  60. NoContainer: "OpenAjax.hub.Error.NoContainer",
  61. // The specified ManagedHub or Container has no such subscription
  62. NoSubscription: "OpenAjax.hub.Error.NoSubscription",
  63. // Permission denied by manager's security policy
  64. NotAllowed: "OpenAjax.hub.Error.NotAllowed",
  65. // Wrong communications protocol identifier provided by Container or HubClient
  66. WrongProtocol: "OpenAjax.hub.Error.WrongProtocol",
  67. // A 'tunnelURI' param was specified, but current browser does not support security features
  68. IncompatBrowser: "OpenAjax.hub.Error.IncompatBrowser"
  69. };
  70. /**
  71. * SecurityAlert
  72. *
  73. * Standard codes used when attempted security violations are detected. Unlike
  74. * Errors, these codes are not thrown as exceptions but rather passed into the
  75. * SecurityAlertHandler function registered with the Hub instance.
  76. */
  77. OpenAjax.hub.SecurityAlert = {
  78. // Container did not load (possible frame phishing attack)
  79. LoadTimeout: "OpenAjax.hub.SecurityAlert.LoadTimeout",
  80. // Hub suspects a frame phishing attack against the specified container
  81. FramePhish: "OpenAjax.hub.SecurityAlert.FramePhish",
  82. // Hub detected a message forgery that purports to come to a specified
  83. // container
  84. ForgedMsg: "OpenAjax.hub.SecurityAlert.ForgedMsg"
  85. };
  86. /**
  87. * Debugging Help
  88. *
  89. * OpenAjax.hub.enableDebug
  90. *
  91. * If OpenAjax.hub.enableDebug is set to true, then the "debugger" keyword
  92. * will get hit whenever a user callback throws an exception, thereby
  93. * bringing up the JavaScript debugger.
  94. */
  95. OpenAjax.hub._debugger = function() {
  96. };
  97. ////////////////////////////////////////////////////////////////////////////////
  98. /**
  99. * OpenAjax.hub.ManagedHub
  100. *
  101. * Managed hub API for the manager application and for Containers.
  102. *
  103. * Implements OpenAjax.hub.Hub.
  104. */
  105. /**
  106. * Create a new ManagedHub instance
  107. * @constructor
  108. *
  109. * This constructor automatically sets the ManagedHub's state to
  110. * CONNECTED.
  111. *
  112. * @param {Object} params
  113. * Parameters used to instantiate the ManagedHub.
  114. * Once the constructor is called, the params object belongs exclusively to
  115. * the ManagedHub. The caller MUST not modify it.
  116. *
  117. * The params object may contain the following properties:
  118. *
  119. * @param {Function} params.onPublish
  120. * Callback function that is invoked whenever a
  121. * data value published by a Container is about
  122. * to be delivered to some (possibly the same) Container.
  123. * This callback function implements a security policy;
  124. * it returns true if the delivery of the data is
  125. * permitted and false if permission is denied.
  126. * @param {Function} params.onSubscribe
  127. * Called whenever a Container tries to subscribe
  128. * on behalf of its client.
  129. * This callback function implements a security policy;
  130. * it returns true if the subscription is permitted
  131. * and false if permission is denied.
  132. * @param {Function} [params.onUnsubscribe]
  133. * Called whenever a Container unsubscribes on behalf of its client.
  134. * Unlike the other callbacks, onUnsubscribe is intended only for
  135. * informative purposes, and is not used to implement a security
  136. * policy.
  137. * @param {Object} [params.scope]
  138. * Whenever one of the ManagedHub's callback functions is called,
  139. * references to the JavaScript "this" keyword in the callback
  140. * function refer to this scope object
  141. * If no scope is provided, default is window.
  142. * @param {Function} [params.log] Optional logger function. Would
  143. * be used to log to console.log or equivalent.
  144. *
  145. * @throws {OpenAjax.hub.Error.BadParameters} if any of the required
  146. * parameters are missing
  147. */
  148. OpenAjax.hub.ManagedHub = function( params ) {
  149. if ( ! params || ! params.onPublish || ! params.onSubscribe )
  150. throw new Error( OpenAjax.hub.Error.BadParameters );
  151. this._p = params;
  152. this._onUnsubscribe = params.onUnsubscribe ? params.onUnsubscribe : null;
  153. this._scope = params.scope || window;
  154. if ( params.log ) {
  155. var that = this;
  156. this._log = function( msg ) {
  157. try {
  158. params.log.call( that._scope, "ManagedHub: " + msg );
  159. } catch( e ) {
  160. OpenAjax.hub._debugger();
  161. }
  162. };
  163. } else {
  164. this._log = function() {};
  165. }
  166. this._subscriptions = { c:{}, s:null };
  167. this._containers = {};
  168. // Sequence # used to create IDs that are unique within this hub
  169. this._seq = 0;
  170. this._active = true;
  171. this._isPublishing = false;
  172. this._pubQ = [];
  173. };
  174. /**
  175. * Subscribe to a topic on behalf of a Container. Called only by
  176. * Container implementations, NOT by manager applications.
  177. *
  178. * This function:
  179. * 1. Checks with the ManagedHub's onSubscribe security policy
  180. * to determine whether this Container is allowed to subscribe
  181. * to this topic.
  182. * 2. If the subscribe operation is permitted, subscribes to the
  183. * topic and returns the ManagedHub's subscription ID for this
  184. * subscription.
  185. * 3. If the subscribe operation is not permitted, throws
  186. * OpenAjax.hub.Error.NotAllowed.
  187. *
  188. * When data is published on the topic, the ManagedHub's
  189. * onPublish security policy will be invoked to ensure that
  190. * this Container is permitted to receive the published data.
  191. * If the Container is allowed to receive the data, then the
  192. * Container's sendToClient function will be invoked.
  193. *
  194. * When a Container needs to create a subscription on behalf of
  195. * its client, the Container MUST use this function to create
  196. * the subscription.
  197. *
  198. * @param {OpenAjax.hub.Container} container
  199. * A Container
  200. * @param {String} topic
  201. * A valid topic
  202. * @param {String} containerSubID
  203. * Arbitrary string ID that the Container uses to
  204. * represent the subscription. Must be unique within the
  205. * context of the Container
  206. *
  207. * @returns managerSubID
  208. * Arbitrary string ID that this ManagedHub uses to
  209. * represent the subscription. Will be unique within the
  210. * context of this ManagedHub
  211. * @type {String}
  212. *
  213. * @throws {OpenAjax.hub.Error.Disconnected} if this.isConnected() returns false
  214. * @throws {OpenAjax.hub.Error.NotAllowed} if subscription request is denied by the onSubscribe security policy
  215. * @throws {OpenAjax.hub.Error.BadParameters} if one of the parameters, e.g. the topic, is invalid
  216. */
  217. OpenAjax.hub.ManagedHub.prototype.subscribeForClient = function( container, topic, containerSubID )
  218. {
  219. this._assertConn();
  220. // check subscribe permission
  221. if ( this._invokeOnSubscribe( topic, container ) ) {
  222. // return ManagedHub's subscriptionID for this subscription
  223. return this._subscribe( topic, this._sendToClient, this, { c: container, sid: containerSubID } );
  224. }
  225. throw new Error(OpenAjax.hub.Error.NotAllowed);
  226. };
  227. /**
  228. * Unsubscribe from a subscription on behalf of a Container. Called only by
  229. * Container implementations, NOT by manager application code.
  230. *
  231. * This function:
  232. * 1. Destroys the specified subscription
  233. * 2. Calls the ManagedHub's onUnsubscribe callback function
  234. *
  235. * This function can be called even if the ManagedHub is not in a CONNECTED state.
  236. *
  237. * @param {OpenAjax.hub.Container} container
  238. * container instance that is unsubscribing
  239. * @param {String} managerSubID
  240. * opaque ID of a subscription, returned by previous call to subscribeForClient()
  241. *
  242. * @throws {OpenAjax.hub.Error.NoSubscription} if subscriptionID does not refer to a valid subscription
  243. */
  244. OpenAjax.hub.ManagedHub.prototype.unsubscribeForClient = function( container, managerSubID )
  245. {
  246. this._unsubscribe( managerSubID );
  247. this._invokeOnUnsubscribe( container, managerSubID );
  248. };
  249. /**
  250. * Publish data on a topic on behalf of a Container. Called only by
  251. * Container implementations, NOT by manager application code.
  252. *
  253. * @param {OpenAjax.hub.Container} container
  254. * Container on whose behalf data should be published
  255. * @param {String} topic
  256. * Valid topic string. Must NOT contain wildcards.
  257. * @param {*} data
  258. * Valid publishable data. To be portable across different
  259. * Container implementations, this value SHOULD be serializable
  260. * as JSON.
  261. *
  262. * @throws {OpenAjax.hub.Error.Disconnected} if this.isConnected() returns false
  263. * @throws {OpenAjax.hub.Error.BadParameters} if one of the parameters, e.g. the topic, is invalid
  264. */
  265. OpenAjax.hub.ManagedHub.prototype.publishForClient = function( container, topic, data )
  266. {
  267. this._assertConn();
  268. this._publish( topic, data, container );
  269. };
  270. /**
  271. * Destroy this ManagedHub
  272. *
  273. * 1. Sets state to DISCONNECTED. All subsequent attempts to add containers,
  274. * publish or subscribe will throw the Disconnected error. We will
  275. * continue to allow "cleanup" operations such as removeContainer
  276. * and unsubscribe, as well as read-only operations such as
  277. * isConnected
  278. * 2. Remove all Containers associated with this ManagedHub
  279. */
  280. OpenAjax.hub.ManagedHub.prototype.disconnect = function()
  281. {
  282. this._active = false;
  283. for (var c in this._containers) {
  284. this.removeContainer( this._containers[c] );
  285. }
  286. };
  287. /**
  288. * Get a container belonging to this ManagedHub by its clientID, or null
  289. * if this ManagedHub has no such container
  290. *
  291. * This function can be called even if the ManagedHub is not in a CONNECTED state.
  292. *
  293. * @param {String} containerId
  294. * Arbitrary string ID associated with the container
  295. *
  296. * @returns container associated with given ID
  297. * @type {OpenAjax.hub.Container}
  298. */
  299. OpenAjax.hub.ManagedHub.prototype.getContainer = function( containerId )
  300. {
  301. var container = this._containers[containerId];
  302. return container ? container : null;
  303. };
  304. /**
  305. * Returns an array listing all containers belonging to this ManagedHub.
  306. * The order of the Containers in this array is arbitrary.
  307. *
  308. * This function can be called even if the ManagedHub is not in a CONNECTED state.
  309. *
  310. * @returns container array
  311. * @type {OpenAjax.hub.Container[]}
  312. */
  313. OpenAjax.hub.ManagedHub.prototype.listContainers = function()
  314. {
  315. var res = [];
  316. for (var c in this._containers) {
  317. res.push(this._containers[c]);
  318. }
  319. return res;
  320. };
  321. /**
  322. * Add a container to this ManagedHub.
  323. *
  324. * This function should only be called by a Container constructor.
  325. *
  326. * @param {OpenAjax.hub.Container} container
  327. * A Container to be added to this ManagedHub
  328. *
  329. * @throws {OpenAjax.hub.Error.Duplicate} if there is already a Container
  330. * in this ManagedHub whose clientId is the same as that of container
  331. * @throws {OpenAjax.hub.Error.Disconnected} if this.isConnected() returns false
  332. */
  333. OpenAjax.hub.ManagedHub.prototype.addContainer = function( container )
  334. {
  335. this._assertConn();
  336. var containerId = container.getClientID();
  337. if ( this._containers[containerId] ) {
  338. throw new Error(OpenAjax.hub.Error.Duplicate);
  339. }
  340. this._containers[containerId] = container;
  341. };
  342. /**
  343. * Remove a container from this ManagedHub immediately
  344. *
  345. * This function can be called even if the ManagedHub is not in a CONNECTED state.
  346. *
  347. * @param {OpenAjax.hub.Container} container
  348. * A Container to be removed from this ManagedHub
  349. *
  350. * @throws {OpenAjax.hub.Error.NoContainer} if no such container is found
  351. */
  352. OpenAjax.hub.ManagedHub.prototype.removeContainer = function( container )
  353. {
  354. var containerId = container.getClientID();
  355. if ( ! this._containers[ containerId ] ) {
  356. throw new Error(OpenAjax.hub.Error.NoContainer);
  357. }
  358. container.remove();
  359. delete this._containers[ containerId ];
  360. };
  361. /*** OpenAjax.hub.Hub interface implementation ***/
  362. /**
  363. * Subscribe to a topic.
  364. *
  365. * This implementation of Hub.subscribe is synchronous. When subscribe
  366. * is called:
  367. *
  368. * 1. The ManagedHub's onSubscribe callback is invoked. The
  369. * container parameter is null, because the manager application,
  370. * rather than a container, is subscribing.
  371. * 2. If onSubscribe returns true, then the subscription is created.
  372. * 3. The onComplete callback is invoked.
  373. * 4. Then this function returns.
  374. *
  375. * @param {String} topic
  376. * A valid topic string. MAY include wildcards.
  377. * @param {Function} onData
  378. * Callback function that is invoked whenever an event is
  379. * published on the topic
  380. * @param {Object} [scope]
  381. * When onData callback or onComplete callback is invoked,
  382. * the JavaScript "this" keyword refers to this scope object.
  383. * If no scope is provided, default is window.
  384. * @param {Function} [onComplete]
  385. * Invoked to tell the client application whether the
  386. * subscribe operation succeeded or failed.
  387. * @param {*} [subscriberData]
  388. * Client application provides this data, which is handed
  389. * back to the client application in the subscriberData
  390. * parameter of the onData and onComplete callback functions.
  391. *
  392. * @returns subscriptionID
  393. * Identifier representing the subscription. This identifier is an
  394. * arbitrary ID string that is unique within this Hub instance
  395. * @type {String}
  396. *
  397. * @throws {OpenAjax.hub.Error.Disconnected} if this Hub instance is not in CONNECTED state
  398. * @throws {OpenAjax.hub.Error.BadParameters} if the topic is invalid (e.g. contains an empty token)
  399. */
  400. OpenAjax.hub.ManagedHub.prototype.subscribe = function( topic, onData, scope, onComplete, subscriberData )
  401. {
  402. this._assertConn();
  403. this._assertSubTopic(topic);
  404. if ( ! onData ) {
  405. throw new Error( OpenAjax.hub.Error.BadParameters );
  406. }
  407. scope = scope || window;
  408. // check subscribe permission
  409. if ( ! this._invokeOnSubscribe( topic, null ) ) {
  410. this._invokeOnComplete( onComplete, scope, null, false, OpenAjax.hub.Error.NotAllowed );
  411. return;
  412. }
  413. // on publish event, check publish permissions
  414. var that = this;
  415. function publishCB( topic, data, sd, pcont ) {
  416. if ( that._invokeOnPublish( topic, data, pcont, null ) ) {
  417. try {
  418. onData.call( scope, topic, data, subscriberData );
  419. } catch( e ) {
  420. OpenAjax.hub._debugger();
  421. that._log( "caught error from onData callback to Hub.subscribe(): " + e.message );
  422. }
  423. }
  424. }
  425. var subID = this._subscribe( topic, publishCB, scope, subscriberData );
  426. this._invokeOnComplete( onComplete, scope, subID, true );
  427. return subID;
  428. };
  429. /**
  430. * Publish an event on a topic
  431. *
  432. * This implementation of Hub.publish is synchronous. When publish
  433. * is called:
  434. *
  435. * 1. The target subscriptions are identified.
  436. * 2. For each target subscription, the ManagedHub's onPublish
  437. * callback is invoked. Data is only delivered to a target
  438. * subscription if the onPublish callback returns true.
  439. * The pcont parameter of the onPublish callback is null.
  440. * This is because the ManagedHub, rather than a container,
  441. * is publishing the data.
  442. *
  443. * @param {String} topic
  444. * A valid topic string. MUST NOT include wildcards.
  445. * @param {*} data
  446. * Valid publishable data. To be portable across different
  447. * Container implementations, this value SHOULD be serializable
  448. * as JSON.
  449. *
  450. * @throws {OpenAjax.hub.Error.Disconnected} if this Hub instance is not in CONNECTED state
  451. * @throws {OpenAjax.hub.Error.BadParameters} if the topic cannot be published (e.g. contains
  452. * wildcards or empty tokens) or if the data cannot be published (e.g. cannot be serialized as JSON)
  453. */
  454. OpenAjax.hub.ManagedHub.prototype.publish = function( topic, data )
  455. {
  456. this._assertConn();
  457. this._assertPubTopic(topic);
  458. this._publish( topic, data, null );
  459. };
  460. /**
  461. * Unsubscribe from a subscription
  462. *
  463. * This implementation of Hub.unsubscribe is synchronous. When unsubscribe
  464. * is called:
  465. *
  466. * 1. The subscription is destroyed.
  467. * 2. The ManagedHub's onUnsubscribe callback is invoked, if there is one.
  468. * 3. The onComplete callback is invoked.
  469. * 4. Then this function returns.
  470. *
  471. * @param {String} subscriptionID
  472. * A subscriptionID returned by Hub.subscribe()
  473. * @param {Function} [onComplete]
  474. * Callback function invoked when unsubscribe completes
  475. * @param {Object} [scope]
  476. * When onComplete callback function is invoked, the JavaScript "this"
  477. * keyword refers to this scope object.
  478. * If no scope is provided, default is window.
  479. *
  480. * @throws {OpenAjax.hub.Error.Disconnected} if this Hub instance is not in CONNECTED state
  481. * @throws {OpenAjax.hub.Error.NoSubscription} if no such subscription is found
  482. */
  483. OpenAjax.hub.ManagedHub.prototype.unsubscribe = function( subscriptionID, onComplete, scope )
  484. {
  485. this._assertConn();
  486. if ( ! subscriptionID ) {
  487. throw new Error( OpenAjax.hub.Error.BadParameters );
  488. }
  489. this._unsubscribe( subscriptionID );
  490. this._invokeOnUnsubscribe( null, subscriptionID );
  491. this._invokeOnComplete( onComplete, scope, subscriptionID, true );
  492. };
  493. /**
  494. * Returns true if disconnect() has NOT been called on this ManagedHub,
  495. * else returns false
  496. *
  497. * @returns Boolean
  498. * @type {Boolean}
  499. */
  500. OpenAjax.hub.ManagedHub.prototype.isConnected = function()
  501. {
  502. return this._active;
  503. };
  504. /**
  505. * Returns the scope associated with this Hub instance and which will be used
  506. * with callback functions.
  507. *
  508. * This function can be called even if the Hub is not in a CONNECTED state.
  509. *
  510. * @returns scope object
  511. * @type {Object}
  512. */
  513. OpenAjax.hub.ManagedHub.prototype.getScope = function()
  514. {
  515. return this._scope;
  516. };
  517. /**
  518. * Returns the subscriberData parameter that was provided when
  519. * Hub.subscribe was called.
  520. *
  521. * @param subscriberID
  522. * The subscriberID of a subscription
  523. *
  524. * @returns subscriberData
  525. * @type {*}
  526. *
  527. * @throws {OpenAjax.hub.Error.Disconnected} if this Hub instance is not in CONNECTED state
  528. * @throws {OpenAjax.hub.Error.NoSubscription} if there is no such subscription
  529. */
  530. OpenAjax.hub.ManagedHub.prototype.getSubscriberData = function( subscriberID )
  531. {
  532. this._assertConn();
  533. var path = subscriberID.split(".");
  534. var sid = path.pop();
  535. var sub = this._getSubscriptionObject( this._subscriptions, path, 0, sid );
  536. if ( sub )
  537. return sub.data;
  538. throw new Error( OpenAjax.hub.Error.NoSubscription );
  539. };
  540. /**
  541. * Returns the scope associated with a specified subscription. This scope will
  542. * be used when invoking the 'onData' callback supplied to Hub.subscribe().
  543. *
  544. * @param subscriberID
  545. * The subscriberID of a subscription
  546. *
  547. * @returns scope
  548. * @type {*}
  549. *
  550. * @throws {OpenAjax.hub.Error.Disconnected} if this Hub instance is not in CONNECTED state
  551. * @throws {OpenAjax.hub.Error.NoSubscription} if there is no such subscription
  552. */
  553. OpenAjax.hub.ManagedHub.prototype.getSubscriberScope = function( subscriberID )
  554. {
  555. this._assertConn();
  556. var path = subscriberID.split(".");
  557. var sid = path.pop();
  558. var sub = this._getSubscriptionObject( this._subscriptions, path, 0, sid );
  559. if ( sub ) {
  560. return sub.scope;
  561. }
  562. throw new Error( OpenAjax.hub.Error.NoSubscription );
  563. };
  564. /**
  565. * Returns the params object associated with this Hub instance.
  566. * Allows mix-in code to access parameters passed into constructor that created
  567. * this Hub instance.
  568. *
  569. * @returns params the params object associated with this Hub instance
  570. * @type {Object}
  571. */
  572. OpenAjax.hub.ManagedHub.prototype.getParameters = function()
  573. {
  574. return this._p;
  575. };
  576. /* PRIVATE FUNCTIONS */
  577. /**
  578. * Send a message to a container's client.
  579. * This is an OAH subscriber's data callback. It is private to ManagedHub
  580. * and serves as an adapter between the OAH 1.0 API and Container.sendToClient.
  581. *
  582. * @param {String} topic Topic on which data was published
  583. * @param {Object} data Data to be delivered to the client
  584. * @param {Object} sd Object containing properties
  585. * c: container to which data must be sent
  586. * sid: subscription ID within that container
  587. * @param {Object} pcont Publishing container, or null if this data was
  588. * published by the manager
  589. */
  590. OpenAjax.hub.ManagedHub.prototype._sendToClient = function(topic, data, sd, pcont)
  591. {
  592. if (!this.isConnected()) {
  593. return;
  594. }
  595. if ( this._invokeOnPublish( topic, data, pcont, sd.c ) ) {
  596. sd.c.sendToClient( topic, data, sd.sid );
  597. }
  598. };
  599. OpenAjax.hub.ManagedHub.prototype._assertConn = function()
  600. {
  601. if (!this.isConnected()) {
  602. throw new Error(OpenAjax.hub.Error.Disconnected);
  603. }
  604. };
  605. OpenAjax.hub.ManagedHub.prototype._assertPubTopic = function(topic)
  606. {
  607. if ( !topic || topic === "" || (topic.indexOf("*") != -1) ||
  608. (topic.indexOf("..") != -1) || (topic.charAt(0) == ".") ||
  609. (topic.charAt(topic.length-1) == "."))
  610. {
  611. throw new Error(OpenAjax.hub.Error.BadParameters);
  612. }
  613. };
  614. OpenAjax.hub.ManagedHub.prototype._assertSubTopic = function(topic)
  615. {
  616. if ( ! topic ) {
  617. throw new Error(OpenAjax.hub.Error.BadParameters);
  618. }
  619. var path = topic.split(".");
  620. var len = path.length;
  621. for (var i = 0; i < len; i++) {
  622. var p = path[i];
  623. if ((p === "") ||
  624. ((p.indexOf("*") != -1) && (p != "*") && (p != "**"))) {
  625. throw new Error(OpenAjax.hub.Error.BadParameters);
  626. }
  627. if ((p == "**") && (i < len - 1)) {
  628. throw new Error(OpenAjax.hub.Error.BadParameters);
  629. }
  630. }
  631. };
  632. OpenAjax.hub.ManagedHub.prototype._invokeOnComplete = function( func, scope, item, success, errorCode )
  633. {
  634. if ( func ) { // onComplete is optional
  635. try {
  636. scope = scope || window;
  637. func.call( scope, item, success, errorCode );
  638. } catch( e ) {
  639. OpenAjax.hub._debugger();
  640. this._log( "caught error from onComplete callback: " + e.message );
  641. }
  642. }
  643. };
  644. OpenAjax.hub.ManagedHub.prototype._invokeOnPublish = function( topic, data, pcont, scont )
  645. {
  646. try {
  647. return this._p.onPublish.call( this._scope, topic, data, pcont, scont );
  648. } catch( e ) {
  649. OpenAjax.hub._debugger();
  650. this._log( "caught error from onPublish callback to constructor: " + e.message );
  651. }
  652. return false;
  653. };
  654. OpenAjax.hub.ManagedHub.prototype._invokeOnSubscribe = function( topic, container )
  655. {
  656. try {
  657. return this._p.onSubscribe.call( this._scope, topic, container );
  658. } catch( e ) {
  659. OpenAjax.hub._debugger();
  660. this._log( "caught error from onSubscribe callback to constructor: " + e.message );
  661. }
  662. return false;
  663. };
  664. OpenAjax.hub.ManagedHub.prototype._invokeOnUnsubscribe = function( container, managerSubID )
  665. {
  666. if ( this._onUnsubscribe ) {
  667. var topic = managerSubID.slice( 0, managerSubID.lastIndexOf(".") );
  668. try {
  669. this._onUnsubscribe.call( this._scope, topic, container );
  670. } catch( e ) {
  671. OpenAjax.hub._debugger();
  672. this._log( "caught error from onUnsubscribe callback to constructor: " + e.message );
  673. }
  674. }
  675. };
  676. OpenAjax.hub.ManagedHub.prototype._subscribe = function( topic, onData, scope, subscriberData )
  677. {
  678. var handle = topic + "." + this._seq;
  679. var sub = { scope: scope, cb: onData, data: subscriberData, sid: this._seq++ };
  680. var path = topic.split(".");
  681. this._recursiveSubscribe( this._subscriptions, path, 0, sub );
  682. return handle;
  683. };
  684. OpenAjax.hub.ManagedHub.prototype._recursiveSubscribe = function(tree, path, index, sub)
  685. {
  686. var token = path[index];
  687. if (index == path.length) {
  688. sub.next = tree.s;
  689. tree.s = sub;
  690. } else {
  691. if (typeof tree.c == "undefined") {
  692. tree.c = {};
  693. }
  694. if (typeof tree.c[token] == "undefined") {
  695. tree.c[token] = { c: {}, s: null };
  696. this._recursiveSubscribe(tree.c[token], path, index + 1, sub);
  697. } else {
  698. this._recursiveSubscribe( tree.c[token], path, index + 1, sub);
  699. }
  700. }
  701. };
  702. OpenAjax.hub.ManagedHub.prototype._publish = function( topic, data, pcont )
  703. {
  704. // if we are currently handling a publish event, then queue this request
  705. // and handle later, one by one
  706. if ( this._isPublishing ) {
  707. this._pubQ.push( { t: topic, d: data, p: pcont } );
  708. return;
  709. }
  710. this._safePublish( topic, data, pcont );
  711. while ( this._pubQ.length > 0 ) {
  712. var pub = this._pubQ.shift();
  713. this._safePublish( pub.t, pub.d, pub.p );
  714. }
  715. };
  716. OpenAjax.hub.ManagedHub.prototype._safePublish = function( topic, data, pcont )
  717. {
  718. this._isPublishing = true;
  719. var path = topic.split(".");
  720. this._recursivePublish( this._subscriptions, path, 0, topic, data, pcont );
  721. this._isPublishing = false;
  722. };
  723. OpenAjax.hub.ManagedHub.prototype._recursivePublish = function(tree, path, index, name, msg, pcont)
  724. {
  725. if (typeof tree != "undefined") {
  726. var node;
  727. if (index == path.length) {
  728. node = tree;
  729. } else {
  730. this._recursivePublish(tree.c[path[index]], path, index + 1, name, msg, pcont);
  731. this._recursivePublish(tree.c["*"], path, index + 1, name, msg, pcont);
  732. node = tree.c["**"];
  733. }
  734. if (typeof node != "undefined") {
  735. var sub = node.s;
  736. while ( sub ) {
  737. var sc = sub.scope;
  738. var cb = sub.cb;
  739. var d = sub.data;
  740. if (typeof cb == "string") {
  741. // get a function object
  742. cb = sc[cb];
  743. }
  744. cb.call(sc, name, msg, d, pcont);
  745. sub = sub.next;
  746. }
  747. }
  748. }
  749. };
  750. OpenAjax.hub.ManagedHub.prototype._unsubscribe = function( subscriptionID )
  751. {
  752. var path = subscriptionID.split(".");
  753. var sid = path.pop();
  754. if ( ! this._recursiveUnsubscribe( this._subscriptions, path, 0, sid ) ) {
  755. throw new Error( OpenAjax.hub.Error.NoSubscription );
  756. }
  757. };
  758. /**
  759. * @returns 'true' if properly unsubscribed; 'false' otherwise
  760. */
  761. OpenAjax.hub.ManagedHub.prototype._recursiveUnsubscribe = function(tree, path, index, sid)
  762. {
  763. if ( typeof tree == "undefined" ) {
  764. return false;
  765. }
  766. if (index < path.length) {
  767. var childNode = tree.c[path[index]];
  768. if ( ! childNode ) {
  769. return false;
  770. }
  771. this._recursiveUnsubscribe(childNode, path, index + 1, sid);
  772. if ( ! childNode.s ) {
  773. for (var x in childNode.c) {
  774. return true;
  775. }
  776. delete tree.c[path[index]];
  777. }
  778. } else {
  779. var sub = tree.s;
  780. var sub_prev = null;
  781. var found = false;
  782. while ( sub ) {
  783. if ( sid == sub.sid ) {
  784. found = true;
  785. if ( sub == tree.s ) {
  786. tree.s = sub.next;
  787. } else {
  788. sub_prev.next = sub.next;
  789. }
  790. break;
  791. }
  792. sub_prev = sub;
  793. sub = sub.next;
  794. }
  795. if ( ! found ) {
  796. return false;
  797. }
  798. }
  799. return true;
  800. };
  801. OpenAjax.hub.ManagedHub.prototype._getSubscriptionObject = function( tree, path, index, sid )
  802. {
  803. if (typeof tree != "undefined") {
  804. if (index < path.length) {
  805. var childNode = tree.c[path[index]];
  806. return this._getSubscriptionObject(childNode, path, index + 1, sid);
  807. }
  808. var sub = tree.s;
  809. while ( sub ) {
  810. if ( sid == sub.sid ) {
  811. return sub;
  812. }
  813. sub = sub.next;
  814. }
  815. }
  816. return null;
  817. };
  818. /**
  819. * OpenAjax.hub._hub is the default ManagedHub instance that we use to
  820. * provide OAH 1.0 behavior.
  821. */
  822. OpenAjax.hub._hub = new OpenAjax.hub.ManagedHub({
  823. onSubscribe: function(topic, ctnr) { return true; },
  824. onPublish: function(topic, data, pcont, scont) { return true; }
  825. });
  826. /**
  827. * Subscribe to a topic.
  828. *
  829. * @param {String} topic
  830. * A valid topic string. MAY include wildcards.
  831. * @param {Function|String} onData
  832. * Callback function that is invoked whenever an event is published on the
  833. * topic. If 'onData' is a string, then it represents the name of a
  834. * function on the 'scope' object.
  835. * @param {Object} [scope]
  836. * When onData callback is invoked,
  837. * the JavaScript "this" keyword refers to this scope object.
  838. * If no scope is provided, default is window.
  839. * @param {*} [subscriberData]
  840. * Client application provides this data, which is handed
  841. * back to the client application in the subscriberData
  842. * parameter of the onData callback function.
  843. *
  844. * @returns {String} Identifier representing the subscription.
  845. *
  846. * @throws {OpenAjax.hub.Error.BadParameters} if the topic is invalid
  847. * (e.g.contains an empty token)
  848. */
  849. OpenAjax.hub.subscribe = function(topic, onData, scope, subscriberData)
  850. {
  851. // resolve the 'onData' function if it is a string
  852. if ( typeof onData === "string" ) {
  853. scope = scope || window;
  854. onData = scope[ onData ] || null;
  855. }
  856. return OpenAjax.hub._hub.subscribe( topic, onData, scope, null, subscriberData );
  857. };
  858. /**
  859. * Unsubscribe from a subscription.
  860. *
  861. * @param {String} subscriptionID
  862. * Subscription identifier returned by subscribe()
  863. *
  864. * @throws {OpenAjax.hub.Error.NoSubscription} if no such subscription is found
  865. */
  866. OpenAjax.hub.unsubscribe = function(subscriptionID)
  867. {
  868. return OpenAjax.hub._hub.unsubscribe( subscriptionID );
  869. };
  870. /**
  871. * Publish an event on a topic.
  872. *
  873. * @param {String} topic
  874. * A valid topic string. MUST NOT include wildcards.
  875. * @param {*} data
  876. * Valid publishable data.
  877. *
  878. * @throws {OpenAjax.hub.Error.BadParameters} if the topic cannot be published
  879. * (e.g. contains wildcards or empty tokens)
  880. */
  881. OpenAjax.hub.publish = function(topic, data)
  882. {
  883. OpenAjax.hub._hub.publish(topic, data);
  884. };
  885. ////////////////////////////////////////////////////////////////////////////////
  886. // Register the OpenAjax Hub itself as a library.
  887. OpenAjax.hub.registerLibrary("OpenAjax", "http://openajax.org/hub", "2.0", {});
  888. } // !OpenAjax.hub
  889. /*
  890. Copyright 2006-2009 OpenAjax Alliance
  891. Licensed under the Apache License, Version 2.0 (the "License");
  892. you may not use this file except in compliance with the License.
  893. You may obtain a copy of the License at
  894. http://www.apache.org/licenses/LICENSE-2.0
  895. Unless required by applicable law or agreed to in writing, software
  896. distributed under the License is distributed on an "AS IS" BASIS,
  897. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  898. See the License for the specific language governing permissions and
  899. limitations under the License.
  900. */
  901. /**
  902. * Create a new Inline Container.
  903. * @constructor
  904. * @extends OpenAjax.hub.Container
  905. *
  906. * InlineContainer implements the Container interface to provide a container
  907. * that places components within the same browser frame as the main mashup
  908. * application. As such, this container does not isolate client components into
  909. * secure sandboxes.
  910. *
  911. * @param {OpenAjax.hub.ManagedHub} hub
  912. * Managed Hub instance to which this Container belongs
  913. * @param {String} clientID
  914. * A string ID that identifies a particular client of a Managed Hub. Unique
  915. * within the context of the ManagedHub.
  916. * @param {Object} params
  917. * Parameters used to instantiate the InlineContainer.
  918. * Once the constructor is called, the params object belongs exclusively to
  919. * the InlineContainer. The caller MUST not modify it.
  920. * The following are the pre-defined properties on params:
  921. * @param {Function} params.Container.onSecurityAlert
  922. * Called when an attempted security breach is thwarted. Function is defined
  923. * as follows: function(container, securityAlert)
  924. * @param {Function} [params.Container.onConnect]
  925. * Called when the client connects to the Managed Hub. Function is defined
  926. * as follows: function(container)
  927. * @param {Function} [params.Container.onDisconnect]
  928. * Called when the client disconnects from the Managed Hub. Function is
  929. * defined as follows: function(container)
  930. * @param {Object} [params.Container.scope]
  931. * Whenever one of the Container's callback functions is called, references
  932. * to "this" in the callback will refer to the scope object. If no scope is
  933. * provided, default is window.
  934. * @param {Function} [params.Container.log]
  935. * Optional logger function. Would be used to log to console.log or
  936. * equivalent.
  937. *
  938. * @throws {OpenAjax.hub.Error.BadParameters} if required params are not
  939. * present or null
  940. * @throws {OpenAjax.hub.Error.Duplicate} if a Container with this clientID
  941. * already exists in the given Managed Hub
  942. * @throws {OpenAjax.hub.Error.Disconnected} if ManagedHub is not connected
  943. */
  944. OpenAjax.hub.InlineContainer = function( hub, clientID, params )
  945. {
  946. if ( ! hub || ! clientID || ! params ||
  947. ! params.Container || ! params.Container.onSecurityAlert ) {
  948. throw new Error(OpenAjax.hub.Error.BadParameters);
  949. }
  950. var cbScope = params.Container.scope || window;
  951. var connected = false;
  952. var subs = [];
  953. var subIndex = 0;
  954. var client = null;
  955. if ( params.Container.log ) {
  956. var log = function( msg ) {
  957. try {
  958. params.Container.log.call( cbScope, "InlineContainer::" + clientID + ": " + msg );
  959. } catch( e ) {
  960. OpenAjax.hub._debugger();
  961. }
  962. };
  963. } else {
  964. log = function() {};
  965. }
  966. this._init = function() {
  967. hub.addContainer( this );
  968. };
  969. /*** OpenAjax.hub.Container interface implementation ***/
  970. this.getHub = function() {
  971. return hub;
  972. };
  973. this.sendToClient = function( topic, data, subscriptionID ) {
  974. if ( connected ) {
  975. var sub = subs[ subscriptionID ];
  976. try {
  977. sub.cb.call( sub.sc, topic, data, sub.d );
  978. } catch( e ) {
  979. OpenAjax.hub._debugger();
  980. client._log( "caught error from onData callback to HubClient.subscribe(): " + e.message );
  981. }
  982. }
  983. };
  984. this.remove = function() {
  985. if ( connected ) {
  986. finishDisconnect();
  987. }
  988. };
  989. this.isConnected = function() {
  990. return connected;
  991. };
  992. this.getClientID = function() {
  993. return clientID;
  994. };
  995. this.getPartnerOrigin = function() {
  996. if ( connected ) {
  997. return window.location.protocol + "//" + window.location.hostname;
  998. }
  999. return null;
  1000. };
  1001. this.getParameters = function() {
  1002. return params;
  1003. };
  1004. /*** OpenAjax.hub.HubClient interface implementation ***/
  1005. this.connect = function( hubClient, onComplete, scope ) {
  1006. if ( connected ) {
  1007. throw new Error( OpenAjax.hub.Error.Duplicate );
  1008. }
  1009. connected = true;
  1010. client = hubClient;
  1011. if ( params.Container.onConnect ) {
  1012. try {
  1013. params.Container.onConnect.call( cbScope, this );
  1014. } catch( e ) {
  1015. OpenAjax.hub._debugger();
  1016. log( "caught error from onConnect callback to constructor: " + e.message );
  1017. }
  1018. }
  1019. invokeOnComplete( onComplete, scope, hubClient, true );
  1020. };
  1021. this.disconnect = function( hubClient, onComplete, scope ) {
  1022. if ( ! connected ) {
  1023. throw new Error( OpenAjax.hub.Error.Disconnected );
  1024. }
  1025. finishDisconnect();
  1026. if ( params.Container.onDisconnect ) {
  1027. try {
  1028. params.Container.onDisconnect.call( cbScope, this );
  1029. } catch( e ) {
  1030. OpenAjax.hub._debugger();
  1031. log( "caught error from onDisconnect callback to constructor: " + e.message );
  1032. }
  1033. }
  1034. invokeOnComplete( onComplete, scope, hubClient, true );
  1035. };
  1036. /*** OpenAjax.hub.Hub interface implementation ***/
  1037. this.subscribe = function( topic, onData, scope, onComplete, subscriberData ) {
  1038. assertConn();
  1039. assertSubTopic( topic );
  1040. if ( ! onData ) {
  1041. throw new Error( OpenAjax.hub.Error.BadParameters );
  1042. }
  1043. var subID = "" + subIndex++;
  1044. var success = false;
  1045. var msg = null;
  1046. try {
  1047. var handle = hub.subscribeForClient( this, topic, subID );
  1048. success = true;
  1049. } catch( e ) {
  1050. // failure
  1051. subID = null;
  1052. msg = e.message;
  1053. }
  1054. scope = scope || window;
  1055. if ( success ) {
  1056. subs[ subID ] = { h: handle, cb: onData, sc: scope, d: subscriberData };
  1057. }
  1058. invokeOnComplete( onComplete, scope, subID, success, msg );
  1059. return subID;
  1060. };
  1061. this.publish = function( topic, data ) {
  1062. assertConn();
  1063. assertPubTopic( topic );
  1064. hub.publishForClient( this, topic, data );
  1065. };
  1066. this.unsubscribe = function( subscriptionID, onComplete, scope ) {
  1067. assertConn();
  1068. if ( typeof subscriptionID === "undefined" || subscriptionID === null ) {
  1069. throw new Error( OpenAjax.hub.Error.BadParameters );
  1070. }
  1071. var sub = subs[ subscriptionID ];
  1072. if ( ! sub ) {
  1073. throw new Error( OpenAjax.hub.Error.NoSubscription );
  1074. }
  1075. hub.unsubscribeForClient( this, sub.h );
  1076. delete subs[ subscriptionID ];
  1077. invokeOnComplete( onComplete, scope, subscriptionID, true );
  1078. };
  1079. this.getSubscriberData = function( subID ) {
  1080. assertConn();
  1081. return getSubscription( subID ).d;
  1082. };
  1083. this.getSubscriberScope = function( subID ) {
  1084. assertConn();
  1085. return getSubscription( subID ).sc;
  1086. };
  1087. /*** PRIVATE FUNCTIONS ***/
  1088. function invokeOnComplete( func, scope, item, success, errorCode ) {
  1089. if ( func ) { // onComplete is optional
  1090. try {
  1091. scope = scope || window;
  1092. func.call( scope, item, success, errorCode );
  1093. } catch( e ) {
  1094. OpenAjax.hub._debugger();
  1095. // invokeOnComplete is only called for client interfaces (Hub and HubClient)
  1096. client._log( "caught error from onComplete callback: " + e.message );
  1097. }
  1098. }
  1099. }
  1100. function finishDisconnect() {
  1101. for ( var subID in subs ) {
  1102. hub.unsubscribeForClient( this, subs[subID].h );
  1103. }
  1104. subs = [];
  1105. subIndex = 0;
  1106. connected = false;
  1107. }
  1108. function assertConn() {
  1109. if ( ! connected ) {
  1110. throw new Error( OpenAjax.hub.Error.Disconnected );
  1111. }
  1112. }
  1113. function assertPubTopic( topic ) {
  1114. if ((topic == null) || (topic === "") || (topic.indexOf("*") != -1) ||
  1115. (topic.indexOf("..") != -1) || (topic.charAt(0) == ".") ||
  1116. (topic.charAt(topic.length-1) == "."))
  1117. {
  1118. throw new Error(OpenAjax.hub.Error.BadParameters);
  1119. }
  1120. }
  1121. function assertSubTopic( topic ) {
  1122. if ( ! topic ) {
  1123. throw new Error(OpenAjax.hub.Error.BadParameters);
  1124. }
  1125. var path = topic.split(".");
  1126. var len = path.length;
  1127. for (var i = 0; i < len; i++) {
  1128. var p = path[i];
  1129. if ((p === "") ||
  1130. ((p.indexOf("*") != -1) && (p != "*") && (p != "**"))) {
  1131. throw new Error(OpenAjax.hub.Error.BadParameters);
  1132. }
  1133. if ((p == "**") && (i < len - 1)) {
  1134. throw new Error(OpenAjax.hub.Error.BadParameters);
  1135. }
  1136. }
  1137. }
  1138. function getSubscription( subID ) {
  1139. var sub = subs[ subID ];
  1140. if ( sub ) {
  1141. return sub;
  1142. }
  1143. throw new Error( OpenAjax.hub.Error.NoSubscription );
  1144. }
  1145. this._init();
  1146. };
  1147. ////////////////////////////////////////////////////////////////////////////////
  1148. /**
  1149. * Create a new InlineHubClient.
  1150. * @constructor
  1151. * @extends OpenAjax.hub.HubClient
  1152. *
  1153. * @param {Object} params
  1154. * Parameters used to instantiate the HubClient.
  1155. * Once the constructor is called, the params object belongs to the
  1156. * HubClient. The caller MUST not modify it.
  1157. * The following are the pre-defined properties on params:
  1158. * @param {Function} params.HubClient.onSecurityAlert
  1159. * Called when an attempted security breach is thwarted
  1160. * @param {Object} [params.HubClient.scope]
  1161. * Whenever one of the HubClient's callback functions is called,
  1162. * references to "this" in the callback will refer to the scope object.
  1163. * If not provided, the default is window.
  1164. * @param {Function} [params.HubClient.log]
  1165. * Optional logger function. Would be used to log to console.log or
  1166. * equivalent.
  1167. * @param {OpenAjax.hub.InlineContainer} params.InlineHubClient.container
  1168. * Specifies the InlineContainer to which this HubClient will connect
  1169. *
  1170. * @throws {OpenAjax.hub.Error.BadParameters} if any of the required
  1171. * parameters are missing
  1172. */
  1173. OpenAjax.hub.InlineHubClient = function( params )
  1174. {
  1175. if ( ! params || ! params.HubClient || ! params.HubClient.onSecurityAlert ||
  1176. ! params.InlineHubClient || ! params.InlineHubClient.container ) {
  1177. throw new Error(OpenAjax.hub.Error.BadParameters);
  1178. }
  1179. var container = params.InlineHubClient.container;
  1180. var scope = params.HubClient.scope || window;
  1181. if ( params.HubClient.log ) {
  1182. var log = function( msg ) {
  1183. try {
  1184. params.HubClient.log.call( scope, "InlineHubClient::" + container.getClientID() + ": " + msg );
  1185. } catch( e ) {
  1186. OpenAjax.hub._debugger();
  1187. }
  1188. };
  1189. } else {
  1190. log = function() {};
  1191. }
  1192. this._log = log;
  1193. /*** OpenAjax.hub.HubClient interface implementation ***/
  1194. /**
  1195. * Requests a connection to the ManagedHub, via the InlineContainer
  1196. * associated with this InlineHubClient.
  1197. *
  1198. * If the Container accepts the connection request, this HubClient's
  1199. * state is set to CONNECTED and the HubClient invokes the
  1200. * onComplete callback function.
  1201. *
  1202. * If the Container refuses the connection request, the HubClient
  1203. * invokes the onComplete callback function with an error code.
  1204. * The error code might, for example, indicate that the Container
  1205. * is being destroyed.
  1206. *
  1207. * If the HubClient is already connected, calling connect will cause
  1208. * the HubClient to immediately invoke the onComplete callback with
  1209. * the error code OpenAjax.hub.Error.Duplicate.
  1210. *
  1211. * @param {Function} [onComplete]
  1212. * Callback function to call when this operation completes.
  1213. * @param {Object} [scope]
  1214. * When the onComplete function is invoked, the JavaScript "this"
  1215. * keyword refers to this scope object.
  1216. * If no scope is provided, default is window.
  1217. *
  1218. * In this implementation of InlineHubClient, this function operates
  1219. * SYNCHRONOUSLY, so the onComplete callback function is invoked before
  1220. * this connect function returns. Developers are cautioned that in
  1221. * IframeHubClient implementations, this is not the case.
  1222. *
  1223. * A client application may call InlineHubClient.disconnect and then call
  1224. * InlineHubClient.connect to reconnect to the Managed Hub.
  1225. */
  1226. this.connect = function( onComplete, scope ) {
  1227. container.connect( this, onComplete, scope );
  1228. };
  1229. /**
  1230. * Disconnect from the ManagedHub
  1231. *
  1232. * Disconnect immediately:
  1233. *
  1234. * 1. Sets the HubClient's state to DISCONNECTED.
  1235. * 2. Causes the HubClient to send a Disconnect request to the
  1236. * associated Container.
  1237. * 3. Ensures that the client application will receive no more
  1238. * onData or onComplete callbacks associated with this
  1239. * connection, except for the disconnect function's own
  1240. * onComplete callback.
  1241. * 4. Automatically destroys all of the HubClient's subscriptions.
  1242. *
  1243. * @param {Function} [onComplete]
  1244. * Callback function to call when this operation completes.
  1245. * @param {Object} [scope]
  1246. * When the onComplete function is invoked, the JavaScript "this"
  1247. * keyword refers to the scope object.
  1248. * If no scope is provided, default is window.
  1249. *
  1250. * In this implementation of InlineHubClient, the disconnect function operates
  1251. * SYNCHRONOUSLY, so the onComplete callback function is invoked before
  1252. * this function returns. Developers are cautioned that in IframeHubClient
  1253. * implementations, this is not the case.
  1254. *
  1255. * A client application is allowed to call HubClient.disconnect and
  1256. * then call HubClient.connect in order to reconnect.
  1257. */
  1258. this.disconnect = function( onComplete, scope ) {
  1259. container.disconnect( this, onComplete, scope );
  1260. };
  1261. this.getPartnerOrigin = function() {
  1262. return container.getPartnerOrigin();
  1263. };
  1264. this.getClientID = function() {
  1265. return container.getClientID();
  1266. };
  1267. /*** OpenAjax.hub.Hub interface implementation ***/
  1268. /**
  1269. * Subscribe to a topic.
  1270. *
  1271. * @param {String} topic
  1272. * A valid topic string. MAY include wildcards.
  1273. * @param {Function} onData
  1274. * Callback function that is invoked whenever an event is
  1275. * published on the topic
  1276. * @param {Object} [scope]
  1277. * When onData callback or onComplete callback is invoked,
  1278. * the JavaScript "this" keyword refers to this scope object.
  1279. * If no scope is provided, default is window.
  1280. * @param {Function} [onComplete]
  1281. * Invoked to tell the client application whether the
  1282. * subscribe operation succeeded or failed.
  1283. * @param {*} [subscriberData]
  1284. * Client application provides this data, which is handed
  1285. * back to the client application in the subscriberData
  1286. * parameter of the onData and onComplete callback functions.
  1287. *
  1288. * @returns subscriptionID
  1289. * Identifier representing the subscription. This identifier is an
  1290. * arbitrary ID string that is unique within this Hub instance
  1291. * @type {String}
  1292. *
  1293. * @throws {OpenAjax.hub.Error.Disconnected} if this Hub instance is not in CONNECTED state
  1294. * @throws {OpenAjax.hub.Error.BadParameters} if the topic is invalid (e.g. contains an empty token)
  1295. *
  1296. * In this implementation of InlineHubClient, the subscribe function operates
  1297. * Thus, onComplete is invoked before this function returns. Developers are
  1298. * cautioned that in most implementations of HubClient, onComplete is invoked
  1299. * after this function returns.
  1300. *
  1301. * If unsubscribe is called before subscribe completes, the subscription is
  1302. * immediately terminated, and onComplete is never invoked.
  1303. */
  1304. this.subscribe = function( topic, onData, scope, onComplete, subscriberData ) {
  1305. return container.subscribe( topic, onData, scope, onComplete, subscriberData );
  1306. };
  1307. /**
  1308. * Publish an event on 'topic' with the given data.
  1309. *
  1310. * @param {String} topic
  1311. * A valid topic string. MUST NOT include wildcards.
  1312. * @param {*} data
  1313. * Valid publishable data. To be portable across different
  1314. * Container implementations, this value SHOULD be serializable
  1315. * as JSON.
  1316. *
  1317. * @throws {OpenAjax.hub.Error.Disconnected} if this Hub instance
  1318. * is not in CONNECTED state
  1319. *
  1320. * In this implementation, publish operates SYNCHRONOUSLY.
  1321. * Data will be delivered to subscribers after this function returns.
  1322. * In most implementations, publish operates synchronously,
  1323. * delivering its data to the clients before this function returns.
  1324. */
  1325. this.publish = function( topic, data ) {
  1326. container.publish( topic, data );
  1327. };
  1328. /**
  1329. * Unsubscribe from a subscription
  1330. *
  1331. * @param {String} subscriptionID
  1332. * A subscriptionID returned by InlineHubClient.prototype.subscribe()
  1333. * @param {Function} [onComplete]
  1334. * Callback function invoked when unsubscribe completes
  1335. * @param {Object} [scope]
  1336. * When onComplete callback function is invoked, the JavaScript "this"
  1337. * keyword refers to this scope object.
  1338. *
  1339. * @throws {OpenAjax.hub.Error.NoSubscription} if no such subscription is found
  1340. *
  1341. * To facilitate cleanup, it is possible to call unsubscribe even
  1342. * when the HubClient is in a DISCONNECTED state.
  1343. *
  1344. * In this implementation of HubClient, this function operates SYNCHRONOUSLY.
  1345. * Thus, onComplete is invoked before this function returns. Developers are
  1346. * cautioned that in most implementations of HubClient, onComplete is invoked
  1347. * after this function returns.
  1348. */
  1349. this.unsubscribe = function( subscriptionID, onComplete, scope ) {
  1350. container.unsubscribe( subscriptionID, onComplete, scope );
  1351. };
  1352. this.isConnected = function() {
  1353. return container.isConnected();
  1354. };
  1355. this.getScope = function() {
  1356. return scope;
  1357. };
  1358. this.getSubscriberData = function( subID ) {
  1359. return container.getSubscriberData( subID );
  1360. };
  1361. this.getSubscriberScope = function( subID ) {
  1362. return container.getSubscriberScope( subID );
  1363. };
  1364. /**
  1365. * Returns the params object associated with this Hub instance.
  1366. * Allows mix-in code to access parameters passed into constructor that created
  1367. * this Hub instance.
  1368. *
  1369. * @returns params the params object associated with this Hub instance
  1370. * @type {Object}
  1371. */
  1372. this.getParameters = function() {
  1373. return params;
  1374. };
  1375. };/*
  1376. Copyright 2006-2009 OpenAjax Alliance
  1377. Licensed under the Apache License, Version 2.0 (the "License");
  1378. you may not use this file except in compliance with the License.
  1379. You may obtain a copy of the License at
  1380. http://www.apache.org/licenses/LICENSE-2.0
  1381. Unless required by applicable law or agreed to in writing, software
  1382. distributed under the License is distributed on an "AS IS" BASIS,
  1383. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1384. See the License for the specific language governing permissions and
  1385. limitations under the License.
  1386. */
  1387. var OpenAjax = OpenAjax || {};
  1388. OpenAjax.hub = OpenAjax.hub || {};
  1389. OpenAjax.gadgets = typeof OpenAjax.gadgets === 'object' ? OpenAjax.gadgets :
  1390. typeof gadgets === 'object' ? gadgets :
  1391. {};
  1392. OpenAjax.gadgets.rpctx = OpenAjax.gadgets.rpctx || {};
  1393. (function() {
  1394. // For now, we only use "oaaConfig" for the global "gadgets" object. If the "gadgets" global
  1395. // already exists, then there is no reason to check for "oaaConfig". In the future, if we use
  1396. // "oaaConfig" for other purposes, we'll need to remove the check for "!window.gadgets".
  1397. if (typeof gadgets === 'undefined') {
  1398. // "oaaConfig" can be specified as a global object. If not found, then look for it as an
  1399. // attribute on the script line for the OpenAjax Hub JS file.
  1400. if (typeof oaaConfig === 'undefined') {
  1401. var scripts = document.getElementsByTagName("script");
  1402. // match "OpenAjax-mashup.js", "OpenAjaxManagedHub-all*.js", "OpenAjaxManagedHub-core*.js"
  1403. var reHub = /openajax(?:managedhub-(?:all|core).*|-mashup)\.js$/i;
  1404. for ( var i = scripts.length - 1; i >= 0; i-- ) {
  1405. var src = scripts[i].getAttribute( "src" );
  1406. if ( !src ) {
  1407. continue;
  1408. }
  1409. var m = src.match( reHub );
  1410. if ( m ) {
  1411. var config = scripts[i].getAttribute( "oaaConfig" );
  1412. if ( config ) {
  1413. try {
  1414. oaaConfig = eval( "({ " + config + " })" );
  1415. } catch (e) {}
  1416. }
  1417. break;
  1418. }
  1419. }
  1420. }
  1421. if (typeof oaaConfig !== 'undefined' && oaaConfig.gadgetsGlobal) {
  1422. gadgets = OpenAjax.gadgets;
  1423. }
  1424. }
  1425. })();
  1426. if (!OpenAjax.hub.IframeContainer) {
  1427. (function(){
  1428. /**
  1429. * Create a new Iframe Container.
  1430. * @constructor
  1431. * @extends OpenAjax.hub.Container
  1432. *
  1433. * IframeContainer implements the Container interface to provide a container
  1434. * that isolates client components into secure sandboxes by leveraging the
  1435. * isolation features provided by browser iframes.
  1436. *
  1437. * SECURITY
  1438. *
  1439. * In order for the connection between the IframeContainer and IframeHubClient
  1440. * to be fully secure, you must specify a valid 'tunnelURI'. Note that if you
  1441. * do specify a 'tunnelURI', then only the WPM and NIX transports are used,
  1442. * covering the following browsers:
  1443. * IE 6+, Firefox 3+, Safari 4+, Chrome 2+, Opera 9+.
  1444. *
  1445. * If no 'tunnelURI' is specified, then some security features are disabled:
  1446. * the IframeContainer will not report FramePhish errors, and on some browsers
  1447. * IframeContainer and IframeHubClient will not be able to validate the
  1448. * identity of their partner (i.e. getPartnerOrigin() will return 'null').
  1449. * However, not providing 'tunnelURI' allows the additional use of the RMR
  1450. * and FE transports -- in addition to the above browsers, the Hub code will
  1451. * also work on:
  1452. * Firefox 1 & 2, Safari 2 & 3, Chrome 1.
  1453. *
  1454. * @param {OpenAjax.hub.ManagedHub} hub
  1455. * Managed Hub instance to which this Container belongs
  1456. * @param {String} clientID
  1457. * A string ID that identifies a particular client of a Managed Hub. Unique
  1458. * within the context of the ManagedHub.
  1459. * @param {Object} params
  1460. * Parameters used to instantiate the IframeContainer.
  1461. * Once the constructor is called, the params object belongs exclusively to
  1462. * the IframeContainer. The caller MUST not modify it.
  1463. * The following are the pre-defined properties on params:
  1464. * @param {Function} params.Container.onSecurityAlert
  1465. * Called when an attempted security breach is thwarted. Function is defined
  1466. * as follows: function(container, securityAlert)
  1467. * @param {Function} [params.Container.onConnect]
  1468. * Called when the client connects to the Managed Hub. Function is defined
  1469. * as follows: function(container)
  1470. * @param {Function} [params.Container.onDisconnect]
  1471. * Called when the client disconnects from the Managed Hub. Function is
  1472. * defined as follows: function(container)
  1473. * @param {Object} [params.Container.scope]
  1474. * Whenever one of the Container's callback functions is called, references
  1475. * to "this" in the callback will refer to the scope object. If no scope is
  1476. * provided, default is window.
  1477. * @param {Function} [params.Container.log]
  1478. * Optional logger function. Would be used to log to console.log or
  1479. * equivalent.
  1480. * @param {Object} params.IframeContainer.parent
  1481. * DOM element that is to be parent of iframe
  1482. * @param {String} params.IframeContainer.uri
  1483. * Initial Iframe URI (Container will add parameters to this URI)
  1484. * @param {String} [params.IframeContainer.tunnelURI]
  1485. * URI of the tunnel iframe. Must be from the same origin as the page which
  1486. * instantiates the IframeContainer. If not specified, connection will not
  1487. * be fully secure (see SECURITY section).
  1488. * @param {Object} [params.IframeContainer.iframeAttrs]
  1489. * Attributes to add to IFRAME DOM entity. For example:
  1490. * { style: { width: "100%",
  1491. * height: "100%" },
  1492. * className: "some_class" }
  1493. * @param {Number} [params.IframeContainer.timeout]
  1494. * Load timeout in milliseconds. If not specified, defaults to 15000. If
  1495. * the client at params.IframeContainer.uri does not establish a connection
  1496. * with this container in the given time, the onSecurityAlert callback is
  1497. * called with a LoadTimeout error code.
  1498. * @param {Function} [params.IframeContainer.seed]
  1499. * A function that returns a string that will be used to seed the
  1500. * pseudo-random number generator, which is used to create the security
  1501. * tokens. An implementation of IframeContainer may choose to ignore this
  1502. * value.
  1503. * @param {Number} [params.IframeContainer.tokenLength]
  1504. * Length of the security tokens used when transmitting messages. If not
  1505. * specified, defaults to 6. An implementation of IframeContainer may choose
  1506. * to ignore this value.
  1507. *
  1508. * @throws {OpenAjax.hub.Error.BadParameters} if required params are not
  1509. * present or null
  1510. * @throws {OpenAjax.hub.Error.Duplicate} if a Container with this clientID
  1511. * already exists in the given Managed Hub
  1512. * @throws {OpenAjax.hub.Error.Disconnected} if hub is not connected
  1513. */
  1514. OpenAjax.hub.IframeContainer = function( hub, clientID, params )
  1515. {
  1516. assertValidParams( arguments );
  1517. var container = this;
  1518. var scope = params.Container.scope || window;
  1519. var connected = false;
  1520. var subs = {};
  1521. var securityToken;
  1522. var internalID;
  1523. var timeout = params.IframeContainer.timeout || 15000;
  1524. var loadTimer;
  1525. if ( params.Container.log ) {
  1526. var log = function( msg ) {
  1527. try {
  1528. params.Container.log.call( scope, "IframeContainer::" + clientID + ": " + msg );
  1529. } catch( e ) {
  1530. OpenAjax.hub._debugger();
  1531. }
  1532. };
  1533. } else {
  1534. log = function() {};
  1535. }
  1536. this._init = function() {
  1537. // add to ManagedHub first, to see if clientID is a duplicate
  1538. hub.addContainer( this );
  1539. // Create an "internal" ID, which is guaranteed to be unique within the
  1540. // window, not just within the hub.
  1541. internalID = OpenAjax.hub.IframeContainer._rpcRouter.add( clientID, this );
  1542. securityToken = generateSecurityToken( params, scope, log );
  1543. var relay = null;
  1544. var transportName = OpenAjax.gadgets.rpc.getRelayChannel();
  1545. if ( params.IframeContainer.tunnelURI ) {
  1546. if ( transportName !== "wpm" && transportName !== "nix" ) {
  1547. throw new Error( OpenAjax.hub.Error.IncompatBrowser );
  1548. }
  1549. } else {
  1550. log( "WARNING: Parameter 'IframeContaienr.tunnelURI' not specified. Connection will not be fully secure." );
  1551. if ( transportName === "rmr" ) {
  1552. relay = OpenAjax.gadgets.rpc.getOrigin( params.IframeContainer.uri ) + "/robots.txt";
  1553. }
  1554. }
  1555. // Create IFRAME to hold the client
  1556. createIframe();
  1557. OpenAjax.gadgets.rpc.setupReceiver( internalID, relay );
  1558. startLoadTimer();
  1559. };
  1560. /*** OpenAjax.hub.Container interface ***/
  1561. this.sendToClient = function( topic, data, subscriptionID ) {
  1562. OpenAjax.gadgets.rpc.call( internalID, "openajax.pubsub", null, "pub", topic, data,
  1563. subscriptionID );
  1564. };
  1565. this.remove = function() {
  1566. finishDisconnect();
  1567. clearTimeout( loadTimer );
  1568. OpenAjax.gadgets.rpc.removeReceiver( internalID );
  1569. var iframe = document.getElementById( internalID );
  1570. iframe.parentNode.removeChild( iframe );
  1571. OpenAjax.hub.IframeContainer._rpcRouter.remove( internalID );
  1572. };
  1573. this.isConnected = function() {
  1574. return connected;
  1575. };
  1576. this.getClientID = function() {
  1577. return clientID;
  1578. };
  1579. this.getPartnerOrigin = function() {
  1580. if ( connected ) {
  1581. var origin = OpenAjax.gadgets.rpc.getReceiverOrigin( internalID );
  1582. if ( origin ) {
  1583. // remove port if present
  1584. return ( /^([a-zA-Z]+:\/\/[^:]+).*/.exec( origin )[1] );
  1585. }
  1586. }
  1587. return null;
  1588. };
  1589. this.getParameters = function() {
  1590. return params;
  1591. };
  1592. this.getHub = function() {
  1593. return hub;
  1594. };
  1595. /*** OpenAjax.hub.IframeContainer interface ***/
  1596. /**
  1597. * Get the iframe associated with this iframe container
  1598. *
  1599. * This function returns the iframe associated with an IframeContainer,
  1600. * allowing the Manager Application to change its size, styles, scrollbars, etc.
  1601. *
  1602. * CAUTION: The iframe is owned exclusively by the IframeContainer. The Manager
  1603. * Application MUST NOT destroy the iframe directly. Also, if the iframe is
  1604. * hidden and disconnected, the Manager Application SHOULD NOT attempt to make
  1605. * it visible. The Container SHOULD automatically hide the iframe when it is
  1606. * disconnected; to make it visible would introduce security risks.
  1607. *
  1608. * @returns iframeElement
  1609. * @type {Object}
  1610. */
  1611. this.getIframe = function() {
  1612. return document.getElementById( internalID );
  1613. };
  1614. /*** private functions ***/
  1615. function assertValidParams( args ) {
  1616. var hub = args[0],
  1617. clientID = args[1],
  1618. params = args[2];
  1619. if ( ! hub || ! clientID || ! params || ! params.Container ||
  1620. ! params.Container.onSecurityAlert || ! params.IframeContainer ||
  1621. ! params.IframeContainer.parent || ! params.IframeContainer.uri ) {
  1622. throw new Error( OpenAjax.hub.Error.BadParameters );
  1623. }
  1624. }
  1625. this._handleIncomingRPC = function( command, topic, data ) {
  1626. switch ( command ) {
  1627. // publish
  1628. // 'data' is topic message
  1629. case "pub":
  1630. hub.publishForClient( container, topic, data );
  1631. break;
  1632. // subscribe
  1633. // 'data' is subscription ID
  1634. case "sub":
  1635. var errCode = ""; // empty string is success
  1636. try {
  1637. subs[ data ] = hub.subscribeForClient( container, topic, data );
  1638. } catch( e ) {
  1639. errCode = e.message;
  1640. }
  1641. return errCode;
  1642. // unsubscribe
  1643. // 'data' is subscription ID
  1644. case "uns":
  1645. var handle = subs[ data ];
  1646. hub.unsubscribeForClient( container, handle );
  1647. delete subs[ data ];
  1648. return data;
  1649. // connect
  1650. case "con":
  1651. finishConnect();
  1652. return true;
  1653. // disconnect
  1654. case "dis":
  1655. startLoadTimer();
  1656. finishDisconnect();
  1657. if ( params.Container.onDisconnect ) {
  1658. try {
  1659. params.Container.onDisconnect.call( scope, container );
  1660. } catch( e ) {
  1661. OpenAjax.hub._debugger();
  1662. log( "caught error from onDisconnect callback to constructor: " + e.message );
  1663. }
  1664. }
  1665. return true;
  1666. }
  1667. };
  1668. this._onSecurityAlert = function( error ) {
  1669. invokeSecurityAlert( rpcErrorsToOAA[ error ] );
  1670. };
  1671. // The RPC code requires that the 'name' attribute be properly set on the
  1672. // iframe. However, setting the 'name' property on the iframe object
  1673. // returned from 'createElement("iframe")' doesn't work on IE --
  1674. // 'window.name' returns null for the code within the iframe. The
  1675. // workaround is to set the 'innerHTML' of a span to the iframe's HTML code,
  1676. // with 'name' and other attributes properly set.
  1677. function createIframe() {
  1678. var span = document.createElement( "span" );
  1679. params.IframeContainer.parent.appendChild( span );
  1680. var iframeText = '<iframe id="' + internalID + '" name="' + internalID +
  1681. '" src="javascript:\'<html></html>\'"';
  1682. // Add iframe attributes
  1683. var styleText = '';
  1684. var attrs = params.IframeContainer.iframeAttrs;
  1685. if ( attrs ) {
  1686. for ( var attr in attrs ) {
  1687. switch ( attr ) {
  1688. case "style":
  1689. for ( var style in attrs.style ) {
  1690. styleText += style + ':' + attrs.style[ style ] + ';';
  1691. }
  1692. break;
  1693. case "className":
  1694. iframeText += ' class="' + attrs[ attr ] + '"';
  1695. break;
  1696. default:
  1697. iframeText += ' ' + attr + '="' + attrs[ attr ] + '"';
  1698. }
  1699. }
  1700. }
  1701. // initially hide IFRAME content, in order to lessen frame phishing impact
  1702. styleText += 'visibility:hidden;';
  1703. iframeText += ' style="' + styleText + '"></iframe>';
  1704. span.innerHTML = iframeText;
  1705. var tunnel = params.IframeContainer.tunnelURI;
  1706. document.getElementById( internalID ).src = params.IframeContainer.uri +
  1707. "#rpctoken=" + securityToken +
  1708. (tunnel ? "&parent=" + encodeURIComponent( tunnel ) + "&forcesecure=true" :
  1709. "&oaaParent=" + encodeURIComponent( OpenAjax.gadgets.rpc.getOrigin( window.location.href )));
  1710. }
  1711. // If the relay iframe used by RPC has not been loaded yet, then we won't have unload protection
  1712. // at this point. Since we can't detect when the relay iframe has loaded, we use a two stage
  1713. // connection process. First, the child sends a connection msg and the container sends an ack.
  1714. // Then the container sends a connection msg and the child replies with an ack. Since the
  1715. // container can only send a message if the relay iframe has loaded, then we know if we get an
  1716. // ack here that the relay iframe is ready. And we are fully connected.
  1717. function finishConnect() {
  1718. // connect acknowledgement
  1719. function callback( result ) {
  1720. if ( result ) {
  1721. connected = true;
  1722. clearTimeout( loadTimer );
  1723. document.getElementById( internalID ).style.visibility = "visible";
  1724. if ( params.Container.onConnect ) {
  1725. try {
  1726. params.Container.onConnect.call( scope, container );
  1727. } catch( e ) {
  1728. OpenAjax.hub._debugger();
  1729. log( "caught error from onConnect callback to constructor: " + e.message );
  1730. }
  1731. }
  1732. }
  1733. }
  1734. OpenAjax.gadgets.rpc.call( internalID, "openajax.pubsub", callback, "cmd", "con" );
  1735. }
  1736. function finishDisconnect() {
  1737. if ( connected ) {
  1738. connected = false;
  1739. document.getElementById( internalID ).style.visibility = "hidden";
  1740. // unsubscribe from all subs
  1741. for ( var s in subs ) {
  1742. hub.unsubscribeForClient( container, subs[s] );
  1743. }
  1744. subs = {};
  1745. }
  1746. }
  1747. function invokeSecurityAlert( errorMsg ) {
  1748. try {
  1749. params.Container.onSecurityAlert.call( scope, container, errorMsg );
  1750. } catch( e ) {
  1751. OpenAjax.hub._debugger();
  1752. log( "caught error from onSecurityAlert callback to constructor: " + e.message );
  1753. }
  1754. }
  1755. function startLoadTimer() {
  1756. loadTimer = setTimeout(
  1757. function() {
  1758. // alert the security alert callback
  1759. invokeSecurityAlert( OpenAjax.hub.SecurityAlert.LoadTimeout );
  1760. // don't receive any more messages from HubClient
  1761. container._handleIncomingRPC = function() {};
  1762. },
  1763. timeout
  1764. );
  1765. }
  1766. this._init();
  1767. };
  1768. ////////////////////////////////////////////////////////////////////////////////
  1769. /**
  1770. * Create a new IframeHubClient.
  1771. * @constructor
  1772. * @extends OpenAjax.hub.HubClient
  1773. *
  1774. * @param {Object} params
  1775. * Once the constructor is called, the params object belongs to the
  1776. * HubClient. The caller MUST not modify it.
  1777. * The following are the pre-defined properties on params:
  1778. * @param {Function} params.HubClient.onSecurityAlert
  1779. * Called when an attempted security breach is thwarted
  1780. * @param {Object} [params.HubClient.scope]
  1781. * Whenever one of the HubClient's callback functions is called,
  1782. * references to "this" in the callback will refer to the scope object.
  1783. * If not provided, the default is window.
  1784. * @param {Function} [params.HubClient.log]
  1785. * Optional logger function. Would be used to log to console.log or
  1786. * equivalent.
  1787. * @param {Boolean} [params.IframeHubClient.requireParentVerifiable]
  1788. * Set to true in order to require that this IframeHubClient use a
  1789. * transport that can verify the parent Container's identity.
  1790. * @param {Function} [params.IframeHubClient.seed]
  1791. * A function that returns a string that will be used to seed the
  1792. * pseudo-random number generator, which is used to create the security
  1793. * tokens. An implementation of IframeHubClient may choose to ignore
  1794. * this value.
  1795. * @param {Number} [params.IframeHubClient.tokenLength]
  1796. * Length of the security tokens used when transmitting messages. If
  1797. * not specified, defaults to 6. An implementation of IframeHubClient
  1798. * may choose to ignore this value.
  1799. *
  1800. * @throws {OpenAjax.hub.Error.BadParameters} if any of the required
  1801. * parameters is missing, or if a parameter value is invalid in
  1802. * some way.
  1803. */
  1804. OpenAjax.hub.IframeHubClient = function( params )
  1805. {
  1806. if ( ! params || ! params.HubClient || ! params.HubClient.onSecurityAlert ) {
  1807. throw new Error( OpenAjax.hub.Error.BadParameters );
  1808. }
  1809. var client = this;
  1810. var scope = params.HubClient.scope || window;
  1811. var connected = false;
  1812. var subs = {};
  1813. var subIndex = 0;
  1814. var clientID;
  1815. // var securityToken; // XXX still need "securityToken"?
  1816. if ( params.HubClient.log ) {
  1817. var log = function( msg ) {
  1818. try {
  1819. params.HubClient.log.call( scope, "IframeHubClient::" + clientID + ": " + msg );
  1820. } catch( e ) {
  1821. OpenAjax.hub._debugger();
  1822. }
  1823. };
  1824. } else {
  1825. log = function() {};
  1826. }
  1827. this._init = function() {
  1828. var urlParams = OpenAjax.gadgets.util.getUrlParameters();
  1829. if ( ! urlParams.parent ) {
  1830. // The RMR transport does not require a valid relay file, but does need a URL
  1831. // in the parent's domain. The URL does not need to point to valid file, so just
  1832. // point to 'robots.txt' file. See RMR transport code for more info.
  1833. var parent = urlParams.oaaParent + "/robots.txt";
  1834. OpenAjax.gadgets.rpc.setupReceiver( "..", parent );
  1835. }
  1836. if ( params.IframeHubClient && params.IframeHubClient.requireParentVerifiable &&
  1837. OpenAjax.gadgets.rpc.getReceiverOrigin( ".." ) === null ) {
  1838. // If user set 'requireParentVerifiable' to true but RPC transport does not
  1839. // support this, throw error.
  1840. OpenAjax.gadgets.rpc.removeReceiver( ".." );
  1841. throw new Error( OpenAjax.hub.Error.IncompatBrowser );
  1842. }
  1843. OpenAjax.hub.IframeContainer._rpcRouter.add( "..", this );
  1844. // XXX The RPC layer initializes immediately on load, in the child (IframeHubClient). So it is too
  1845. // late here to specify a security token for the RPC layer. At the moment, only the NIX
  1846. // transport requires a child token (IFPC [aka FIM] is not supported).
  1847. // securityToken = generateSecurityToken( params, scope, log );
  1848. var internalID = OpenAjax.gadgets.rpc.RPC_ID;
  1849. if ( ! internalID ) {
  1850. throw new Error( OpenAjax.hub.Error.WrongProtocol );
  1851. }
  1852. clientID = internalID.substr( internalID.indexOf("_") + 1 );
  1853. };
  1854. /*** HubClient interface ***/
  1855. this.connect = function( onComplete, scope ) {
  1856. if ( connected ) {
  1857. throw new Error( OpenAjax.hub.Error.Duplicate );
  1858. }
  1859. // connect acknowledgement
  1860. function callback( result ) {
  1861. if ( result ) {
  1862. connected = true;
  1863. if ( onComplete ) {
  1864. try {
  1865. onComplete.call( scope || window, client, true );
  1866. } catch( e ) {
  1867. OpenAjax.hub._debugger();
  1868. log( "caught error from onComplete callback to connect(): " + e.message );
  1869. }
  1870. }
  1871. }
  1872. }
  1873. OpenAjax.gadgets.rpc.call( "..", "openajax.pubsub", callback, "con" );
  1874. };
  1875. this.disconnect = function( onComplete, scope ) {
  1876. if ( !connected ) {
  1877. throw new Error( OpenAjax.hub.Error.Disconnected );
  1878. }
  1879. connected = false;
  1880. // disconnect acknowledgement
  1881. var callback = null;
  1882. if ( onComplete ) {
  1883. callback = function( result ) {
  1884. try {
  1885. onComplete.call( scope || window, client, true );
  1886. } catch( e ) {
  1887. OpenAjax.hub._debugger();
  1888. log( "caught error from onComplete callback to disconnect(): " + e.message );
  1889. }
  1890. };
  1891. }
  1892. OpenAjax.gadgets.rpc.call( "..", "openajax.pubsub", callback, "dis" );
  1893. };
  1894. this.getPartnerOrigin = function() {
  1895. if ( connected ) {
  1896. var origin = OpenAjax.gadgets.rpc.getReceiverOrigin( ".." );
  1897. if ( origin ) {
  1898. // remove port if present
  1899. return ( /^([a-zA-Z]+:\/\/[^:]+).*/.exec( origin )[1] );
  1900. }
  1901. }
  1902. return null;
  1903. };
  1904. this.getClientID = function() {
  1905. return clientID;
  1906. };
  1907. /*** Hub interface ***/
  1908. this.subscribe = function( topic, onData, scope, onComplete, subscriberData ) {
  1909. assertConn();
  1910. assertSubTopic( topic );
  1911. if ( ! onData ) {
  1912. throw new Error( OpenAjax.hub.Error.BadParameters );
  1913. }
  1914. scope = scope || window;
  1915. var subID = "" + subIndex++;
  1916. subs[ subID ] = { cb: onData, sc: scope, d: subscriberData };
  1917. // subscribe acknowledgement
  1918. function callback( result ) {
  1919. if ( result !== '' ) { // error
  1920. delete subs[ subID ];
  1921. }
  1922. if ( onComplete ) {
  1923. try {
  1924. onComplete.call( scope, subID, result === "", result );
  1925. } catch( e ) {
  1926. OpenAjax.hub._debugger();
  1927. log( "caught error from onComplete callback to subscribe(): " + e.message );
  1928. }
  1929. }
  1930. }
  1931. OpenAjax.gadgets.rpc.call( "..", "openajax.pubsub", callback, "sub", topic, subID );
  1932. return subID;
  1933. };
  1934. this.publish = function( topic, data ) {
  1935. assertConn();
  1936. assertPubTopic( topic );
  1937. OpenAjax.gadgets.rpc.call( "..", "openajax.pubsub", null, "pub", topic, data );
  1938. };
  1939. this.unsubscribe = function( subscriptionID, onComplete, scope ) {
  1940. assertConn();
  1941. if ( ! subscriptionID ) {
  1942. throw new Error( OpenAjax.hub.Error.BadParameters );
  1943. }
  1944. // if no such subscriptionID, or in process of unsubscribing given ID, throw error
  1945. if ( ! subs[ subscriptionID ] || subs[ subscriptionID ].uns ) {
  1946. throw new Error( OpenAjax.hub.Error.NoSubscription );
  1947. }
  1948. // unsubscribe in progress
  1949. subs[ subscriptionID ].uns = true;
  1950. // unsubscribe acknowledgement
  1951. function callback( result ) {
  1952. delete subs[ subscriptionID ];
  1953. if ( onComplete ) {
  1954. try {
  1955. onComplete.call( scope || window, subscriptionID, true );
  1956. } catch( e ) {
  1957. OpenAjax.hub._debugger();
  1958. log( "caught error from onComplete callback to unsubscribe(): " + e.message );
  1959. }
  1960. }
  1961. }
  1962. OpenAjax.gadgets.rpc.call( "..", "openajax.pubsub", callback, "uns", null, subscriptionID );
  1963. };
  1964. this.isConnected = function() {
  1965. return connected;
  1966. };
  1967. this.getScope = function() {
  1968. return scope;
  1969. };
  1970. this.getSubscriberData = function( subscriptionID ) {
  1971. assertConn();
  1972. if ( subs[ subscriptionID ] ) {
  1973. return subs[ subscriptionID ].d;
  1974. }
  1975. throw new Error( OpenAjax.hub.Error.NoSubscription );
  1976. };
  1977. this.getSubscriberScope = function( subscriptionID ) {
  1978. assertConn();
  1979. if ( subs[ subscriptionID ] ) {
  1980. return subs[ subscriptionID ].sc;
  1981. }
  1982. throw new Error( OpenAjax.hub.Error.NoSubscription );
  1983. };
  1984. this.getParameters = function() {
  1985. return params;
  1986. };
  1987. /*** private functions ***/
  1988. this._handleIncomingRPC = function( command, topic, data, subscriptionID ) {
  1989. if ( command === "pub" ) {
  1990. // if subscription exists and we are not in process of unsubscribing...
  1991. if ( subs[ subscriptionID ] && ! subs[ subscriptionID ].uns ) {
  1992. try {
  1993. subs[ subscriptionID ].cb.call( subs[ subscriptionID ].sc, topic,
  1994. data, subs[ subscriptionID ].d );
  1995. } catch( e ) {
  1996. OpenAjax.hub._debugger();
  1997. log( "caught error from onData callback to subscribe(): " + e.message );
  1998. }
  1999. }
  2000. }
  2001. // else if command === "cmd"...
  2002. // First time this function is called, topic should be "con". This is the 2nd stage of the
  2003. // connection process. Simply need to return "true" in order to send an acknowledgement
  2004. // back to container. See finishConnect() in the container object.
  2005. if ( topic === "con" ) {
  2006. return true;
  2007. }
  2008. return false;
  2009. };
  2010. function assertConn() {
  2011. if ( ! connected ) {
  2012. throw new Error( OpenAjax.hub.Error.Disconnected );
  2013. }
  2014. }
  2015. function assertSubTopic( topic )
  2016. {
  2017. if ( ! topic ) {
  2018. throw new Error( OpenAjax.hub.Error.BadParameters );
  2019. }
  2020. var path = topic.split(".");
  2021. var len = path.length;
  2022. for (var i = 0; i < len; i++) {
  2023. var p = path[i];
  2024. if ((p === "") ||
  2025. ((p.indexOf("*") != -1) && (p != "*") && (p != "**"))) {
  2026. throw new Error( OpenAjax.hub.Error.BadParameters );
  2027. }
  2028. if ((p == "**") && (i < len - 1)) {
  2029. throw new Error( OpenAjax.hub.Error.BadParameters );
  2030. }
  2031. }
  2032. }
  2033. function assertPubTopic( topic ) {
  2034. if ( !topic || topic === "" || (topic.indexOf("*") != -1) ||
  2035. (topic.indexOf("..") != -1) || (topic.charAt(0) == ".") ||
  2036. (topic.charAt(topic.length-1) == "."))
  2037. {
  2038. throw new Error( OpenAjax.hub.Error.BadParameters );
  2039. }
  2040. }
  2041. this._init();
  2042. };
  2043. ////////////////////////////////////////////////////////////////////////////////
  2044. // RPC object contents:
  2045. // s: Service Name
  2046. // f: From
  2047. // c: The callback ID or 0 if none.
  2048. // a: The arguments for this RPC call.
  2049. // t: The authentication token.
  2050. OpenAjax.hub.IframeContainer._rpcRouter = function() {
  2051. var receivers = {};
  2052. function router() {
  2053. var r = receivers[ this.f ];
  2054. if ( r ) {
  2055. return r._handleIncomingRPC.apply( r, arguments );
  2056. }
  2057. }
  2058. function onSecurityAlert( receiverId, error ) {
  2059. var r = receivers[ receiverId ];
  2060. if ( r ) {
  2061. r._onSecurityAlert.call( r, error );
  2062. }
  2063. }
  2064. return {
  2065. add: function( id, receiver ) {
  2066. function _add( id, receiver ) {
  2067. if ( id === ".." ) {
  2068. if ( ! receivers[ ".." ] ) {
  2069. receivers[ ".." ] = receiver;
  2070. }
  2071. return;
  2072. }
  2073. do {
  2074. // a client with the specified ID already exists on this page;
  2075. // create a unique ID
  2076. newID = ((0x7fff * Math.random()) | 0).toString(16) + "_" + id;
  2077. } while ( receivers[ newID ] );
  2078. receivers[ newID ] = receiver;
  2079. return newID;
  2080. }
  2081. // when this function is first called, register the RPC service
  2082. OpenAjax.gadgets.rpc.register( "openajax.pubsub", router );
  2083. OpenAjax.gadgets.rpc.config({
  2084. securityCallback: onSecurityAlert
  2085. });
  2086. rpcErrorsToOAA[ OpenAjax.gadgets.rpc.SEC_ERROR_LOAD_TIMEOUT ] = OpenAjax.hub.SecurityAlert.LoadTimeout;
  2087. rpcErrorsToOAA[ OpenAjax.gadgets.rpc.SEC_ERROR_FRAME_PHISH ] = OpenAjax.hub.SecurityAlert.FramePhish;
  2088. rpcErrorsToOAA[ OpenAjax.gadgets.rpc.SEC_ERROR_FORGED_MSG ] = OpenAjax.hub.SecurityAlert.ForgedMsg;
  2089. this.add = _add;
  2090. return _add( id, receiver );
  2091. },
  2092. remove: function( id ) {
  2093. delete receivers[ id ];
  2094. }
  2095. };
  2096. }();
  2097. var rpcErrorsToOAA = {};
  2098. ////////////////////////////////////////////////////////////////////////////////
  2099. function generateSecurityToken( params, scope, log ) {
  2100. if ( ! OpenAjax.hub.IframeContainer._prng ) {
  2101. // create pseudo-random number generator with a default seed
  2102. var seed = new Date().getTime() + Math.random() + document.cookie;
  2103. OpenAjax.hub.IframeContainer._prng = OpenAjax._smash.crypto.newPRNG( seed );
  2104. }
  2105. var p = params.IframeContainer || params.IframeHubClient;
  2106. if ( p && p.seed ) {
  2107. try {
  2108. var extraSeed = p.seed.call( scope );
  2109. OpenAjax.hub.IframeContainer._prng.addSeed( extraSeed );
  2110. } catch( e ) {
  2111. OpenAjax.hub._debugger();
  2112. log( "caught error from 'seed' callback: " + e.message );
  2113. }
  2114. }
  2115. var tokenLength = (p && p.tokenLength) || 6;
  2116. return OpenAjax.hub.IframeContainer._prng.nextRandomB64Str( tokenLength );
  2117. }
  2118. })();
  2119. }/*
  2120. Copyright 2006-2009 OpenAjax Alliance
  2121. Licensed under the Apache License, Version 2.0 (the "License");
  2122. you may not use this file except in compliance with the License.
  2123. You may obtain a copy of the License at
  2124. http://www.apache.org/licenses/LICENSE-2.0
  2125. Unless required by applicable law or agreed to in writing, software
  2126. distributed under the License is distributed on an "AS IS" BASIS,
  2127. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  2128. See the License for the specific language governing permissions and
  2129. limitations under the License.
  2130. */
  2131. // SMASH.CRYPTO
  2132. //
  2133. // Small library containing some minimal crypto functionality for a
  2134. // - a hash-function: SHA-1 (see FIPS PUB 180-2 for definition)
  2135. // BigEndianWord[5] <- smash.crypto.sha1( BigEndianWord[*] dataWA, int lenInBits)
  2136. //
  2137. // - a message authentication code (MAC): HMAC-SHA-1 (RFC2104/2202)
  2138. // BigEndianWord[5] <- smash.crypto.hmac_sha1(
  2139. // BigEndianWord[3-16] keyWA,
  2140. // Ascii or Unicode string dataS,
  2141. // int chrsz (8 for Asci/16 for Unicode)
  2142. //
  2143. // - pseudo-random number generator (PRNG): HMAC-SHA-1 in counter mode, following
  2144. // Barak & Halevi, An architecture for robust pseudo-random generation and applications to /dev/random, CCS 2005
  2145. // rngObj <- smash.crypto.newPRNG( String[>=12] seedS)
  2146. // where rngObj has methods
  2147. // addSeed(String seed)
  2148. // BigEndianWord[len] <- nextRandomOctets(int len)
  2149. // Base64-String[len] <- nextRandomB64Str(int len)
  2150. // Note: HMAC-SHA1 in counter-mode does not provide forward-security on corruption.
  2151. // However, the PRNG state is kept inside a closure. So if somebody can break the closure, he probably could
  2152. // break a whole lot more and forward-security of the prng is not the highest of concerns anymore :-)
  2153. if ( typeof OpenAjax._smash == 'undefined' ) { OpenAjax._smash = {}; }
  2154. OpenAjax._smash.crypto = {
  2155. // Some utilities
  2156. // convert a string to an array of big-endian words
  2157. 'strToWA': function (/* Ascii or Unicode string */ str, /* int 8 for Asci/16 for Unicode */ chrsz){
  2158. var bin = Array();
  2159. var mask = (1 << chrsz) - 1;
  2160. for(var i = 0; i < str.length * chrsz; i += chrsz)
  2161. bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (32 - chrsz - i%32);
  2162. return bin;
  2163. },
  2164. // MAC
  2165. 'hmac_sha1' : function(
  2166. /* BigEndianWord[3-16]*/ keyWA,
  2167. /* Ascii or Unicode string */ dataS,
  2168. /* int 8 for Asci/16 for Unicode */ chrsz)
  2169. {
  2170. // write our own hmac derived from paj's so we do not have to do constant key conversions and length checking ...
  2171. var ipad = Array(16), opad = Array(16);
  2172. for(var i = 0; i < 16; i++) {
  2173. ipad[i] = keyWA[i] ^ 0x36363636;
  2174. opad[i] = keyWA[i] ^ 0x5C5C5C5C;
  2175. }
  2176. var hash = this.sha1( ipad.concat(this.strToWA(dataS, chrsz)), 512 + dataS.length * chrsz);
  2177. return this.sha1( opad.concat(hash), 512 + 160);
  2178. },
  2179. // PRNG factory method
  2180. // see below 'addSeed', 'nextRandomOctets' & 'nextRandomB64Octets' for public methods of returnd prng object
  2181. 'newPRNG' : function (/* String[>=12] */ seedS) {
  2182. var that = this;
  2183. // parameter checking
  2184. // We cannot really verify entropy but obviously the string must have at least a minimal length to have enough entropy
  2185. // However, a 2^80 security seems ok, so we check only that at least 12 chars assuming somewhat random ASCII
  2186. if ( (typeof seedS != 'string') || (seedS.length < 12) ) {
  2187. alert("WARNING: Seed length too short ...");
  2188. }
  2189. // constants
  2190. var __refresh_keyWA = [ 0xA999, 0x3E36, 0x4706, 0x816A,
  2191. 0x2571, 0x7850, 0xC26C, 0x9CD0,
  2192. 0xBA3E, 0xD89D, 0x1233, 0x9525,
  2193. 0xff3C, 0x1A83, 0xD491, 0xFF15 ]; // some random key for refresh ...
  2194. // internal state
  2195. var _keyWA = []; // BigEndianWord[5]
  2196. var _cnt = 0; // int
  2197. function extract(seedS) {
  2198. return that.hmac_sha1(__refresh_keyWA, seedS, 8);
  2199. }
  2200. function refresh(seedS) {
  2201. // HMAC-SHA1 is not ideal, Rijndal 256bit block/key in CBC mode with fixed key might be better
  2202. // but to limit the primitives and given that we anyway have only limited entropy in practise
  2203. // this seems good enough
  2204. var uniformSeedWA = extract(seedS);
  2205. for(var i = 0; i < 5; i++) {
  2206. _keyWA[i] ^= uniformSeedWA[i];
  2207. }
  2208. }
  2209. // inital state seeding
  2210. refresh(seedS);
  2211. // public methods
  2212. return {
  2213. // Mix some additional seed into the PRNG state
  2214. 'addSeed' : function (/* String */ seed) {
  2215. // no parameter checking. Any added entropy should be fine ...
  2216. refresh(seed);
  2217. },
  2218. // Get an array of len random octets
  2219. 'nextRandomOctets' : /* BigEndianWord[len] <- */ function (/* int */ len) {
  2220. var randOctets = [];
  2221. while (len > 0) {
  2222. _cnt+=1;
  2223. var nextBlock = that.hmac_sha1(_keyWA, (_cnt).toString(16), 8);
  2224. for (var i=0; (i < 20) & (len > 0); i++, len--) {
  2225. randOctets.push( (nextBlock[i>>2] >> (i % 4) ) % 256);
  2226. }
  2227. // Note: if len was not a multiple 20, some random octets are ignored here but who cares ..
  2228. }
  2229. return randOctets;
  2230. },
  2231. // Get a random string of Base64-like (see below) chars of length len
  2232. // Note: there is a slightly non-standard Base64 with no padding and '-' and '_' for '+' and '/', respectively
  2233. 'nextRandomB64Str' : /* Base64-String <- */ function (/* int */ len) {
  2234. var b64StrMap = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
  2235. var randOctets = this.nextRandomOctets(len);
  2236. var randB64Str = '';
  2237. for (var i=0; i < len; i++) {
  2238. randB64Str += b64StrMap.charAt(randOctets[i] & 0x3F);
  2239. }
  2240. return randB64Str;
  2241. }
  2242. };
  2243. },
  2244. // Digest function:
  2245. // BigEndianWord[5] <- sha1( BigEndianWord[*] dataWA, int lenInBits)
  2246. 'sha1' : function(){
  2247. // Note: all Section references below refer to FIPS 180-2.
  2248. // private utility functions
  2249. // - 32bit addition with wrap-around
  2250. var add_wa = function (x, y){
  2251. var lsw = (x & 0xFFFF) + (y & 0xFFFF);
  2252. var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
  2253. return (msw << 16) | (lsw & 0xFFFF);
  2254. };
  2255. // - 32bit rotatate left
  2256. var rol = function(num, cnt) {
  2257. return (num << cnt) | (num >>> (32 - cnt));
  2258. };
  2259. // - round-dependent function f_t from Section 4.1.1
  2260. function sha1_ft(t, b, c, d) {
  2261. if(t < 20) return (b & c) | ((~b) & d);
  2262. if(t < 40) return b ^ c ^ d;
  2263. if(t < 60) return (b & c) | (b & d) | (c & d);
  2264. return b ^ c ^ d;
  2265. }
  2266. // - round-dependent SHA-1 constants from Section 4.2.1
  2267. function sha1_kt(t) {
  2268. return (t < 20) ? 1518500249 :
  2269. (t < 40) ? 1859775393 :
  2270. (t < 60) ? -1894007588 :
  2271. /* (t < 80) */ -899497514 ;
  2272. }
  2273. // main algorithm.
  2274. return function( /* BigEndianWord[*] */ dataWA, /* int */ lenInBits) {
  2275. // Section 6.1.1: Preprocessing
  2276. //-----------------------------
  2277. // 1. padding: (see also Section 5.1.1)
  2278. // - append one 1 followed by 0 bits filling up 448 bits of last (512bit) block
  2279. dataWA[lenInBits >> 5] |= 0x80 << (24 - lenInBits % 32);
  2280. // - encode length in bits in last 64 bits
  2281. // Note: we rely on javascript to zero file elements which are beyond last (partial) data-block
  2282. // but before this length encoding!
  2283. dataWA[((lenInBits + 64 >> 9) << 4) + 15] = lenInBits;
  2284. // 2. 512bit blocks (actual split done ondemand later)
  2285. var W = Array(80);
  2286. // 3. initial hash using SHA-1 constants on page 13
  2287. var H0 = 1732584193;
  2288. var H1 = -271733879;
  2289. var H2 = -1732584194;
  2290. var H3 = 271733878;
  2291. var H4 = -1009589776;
  2292. // 6.1.2 SHA-1 Hash Computation
  2293. for(var i = 0; i < dataWA.length; i += 16) {
  2294. // 1. Message schedule, done below
  2295. // 2. init working variables
  2296. var a = H0; var b = H1; var c = H2; var d = H3; var e = H4;
  2297. // 3. round-functions
  2298. for(var j = 0; j < 80; j++)
  2299. {
  2300. // postponed step 2
  2301. W[j] = ( (j < 16) ? dataWA[i+j] : rol(W[j-3] ^ W[j-8] ^ W[j-14] ^ W[j-16], 1));
  2302. var T = add_wa( add_wa( rol(a, 5), sha1_ft(j, b, c, d)),
  2303. add_wa( add_wa(e, W[j]), sha1_kt(j)) );
  2304. e = d;
  2305. d = c;
  2306. c = rol(b, 30);
  2307. b = a;
  2308. a = T;
  2309. }
  2310. // 4. intermediate hash
  2311. H0 = add_wa(a, H0);
  2312. H1 = add_wa(b, H1);
  2313. H2 = add_wa(c, H2);
  2314. H3 = add_wa(d, H3);
  2315. H4 = add_wa(e, H4);
  2316. }
  2317. return Array(H0, H1, H2, H3, H4);
  2318. };
  2319. }()
  2320. };
  2321. /*
  2322. http://www.JSON.org/json2.js
  2323. 2008-11-19
  2324. Public Domain.
  2325. NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
  2326. See http://www.JSON.org/js.html
  2327. This file creates a global JSON object containing two methods: stringify
  2328. and parse.
  2329. JSON.stringify(value, replacer, space)
  2330. value any JavaScript value, usually an object or array.
  2331. replacer an optional parameter that determines how object
  2332. values are stringified for objects. It can be a
  2333. function or an array of strings.
  2334. space an optional parameter that specifies the indentation
  2335. of nested structures. If it is omitted, the text will
  2336. be packed without extra whitespace. If it is a number,
  2337. it will specify the number of spaces to indent at each
  2338. level. If it is a string (such as '\t' or '&nbsp;'),
  2339. it contains the characters used to indent at each level.
  2340. This method produces a JSON text from a JavaScript value.
  2341. When an object value is found, if the object contains a toJSON
  2342. method, its toJSON method will be called and the result will be
  2343. stringified. A toJSON method does not serialize: it returns the
  2344. value represented by the name/value pair that should be serialized,
  2345. or undefined if nothing should be serialized. The toJSON method
  2346. will be passed the key associated with the value, and this will be
  2347. bound to the object holding the key.
  2348. For example, this would serialize Dates as ISO strings.
  2349. Date.prototype.toJSON = function (key) {
  2350. function f(n) {
  2351. // Format integers to have at least two digits.
  2352. return n < 10 ? '0' + n : n;
  2353. }
  2354. return this.getUTCFullYear() + '-' +
  2355. f(this.getUTCMonth() + 1) + '-' +
  2356. f(this.getUTCDate()) + 'T' +
  2357. f(this.getUTCHours()) + ':' +
  2358. f(this.getUTCMinutes()) + ':' +
  2359. f(this.getUTCSeconds()) + 'Z';
  2360. };
  2361. You can provide an optional replacer method. It will be passed the
  2362. key and value of each member, with this bound to the containing
  2363. object. The value that is returned from your method will be
  2364. serialized. If your method returns undefined, then the member will
  2365. be excluded from the serialization.
  2366. If the replacer parameter is an array of strings, then it will be
  2367. used to select the members to be serialized. It filters the results
  2368. such that only members with keys listed in the replacer array are
  2369. stringified.
  2370. Values that do not have JSON representations, such as undefined or
  2371. functions, will not be serialized. Such values in objects will be
  2372. dropped; in arrays they will be replaced with null. You can use
  2373. a replacer function to replace those with JSON values.
  2374. JSON.stringify(undefined) returns undefined.
  2375. The optional space parameter produces a stringification of the
  2376. value that is filled with line breaks and indentation to make it
  2377. easier to read.
  2378. If the space parameter is a non-empty string, then that string will
  2379. be used for indentation. If the space parameter is a number, then
  2380. the indentation will be that many spaces.
  2381. Example:
  2382. text = JSON.stringify(['e', {pluribus: 'unum'}]);
  2383. // text is '["e",{"pluribus":"unum"}]'
  2384. text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
  2385. // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
  2386. text = JSON.stringify([new Date()], function (key, value) {
  2387. return this[key] instanceof Date ?
  2388. 'Date(' + this[key] + ')' : value;
  2389. });
  2390. // text is '["Date(---current time---)"]'
  2391. JSON.parse(text, reviver)
  2392. This method parses a JSON text to produce an object or array.
  2393. It can throw a SyntaxError exception.
  2394. The optional reviver parameter is a function that can filter and
  2395. transform the results. It receives each of the keys and values,
  2396. and its return value is used instead of the original value.
  2397. If it returns what it received, then the structure is not modified.
  2398. If it returns undefined then the member is deleted.
  2399. Example:
  2400. // Parse the text. Values that look like ISO date strings will
  2401. // be converted to Date objects.
  2402. myData = JSON.parse(text, function (key, value) {
  2403. var a;
  2404. if (typeof value === 'string') {
  2405. a =
  2406. /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
  2407. if (a) {
  2408. return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
  2409. +a[5], +a[6]));
  2410. }
  2411. }
  2412. return value;
  2413. });
  2414. myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
  2415. var d;
  2416. if (typeof value === 'string' &&
  2417. value.slice(0, 5) === 'Date(' &&
  2418. value.slice(-1) === ')') {
  2419. d = new Date(value.slice(5, -1));
  2420. if (d) {
  2421. return d;
  2422. }
  2423. }
  2424. return value;
  2425. });
  2426. This is a reference implementation. You are free to copy, modify, or
  2427. redistribute.
  2428. This code should be minified before deployment.
  2429. See http://javascript.crockford.com/jsmin.html
  2430. USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
  2431. NOT CONTROL.
  2432. */
  2433. /*jslint evil: true */
  2434. /*global JSON */
  2435. /*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
  2436. call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
  2437. getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
  2438. lastIndex, length, parse, prototype, push, replace, slice, stringify,
  2439. test, toJSON, toString, valueOf
  2440. */
  2441. // Create a JSON object only if one does not already exist. We create the
  2442. // methods in a closure to avoid creating global variables.
  2443. if (!this.JSON) {
  2444. JSON = {};
  2445. }
  2446. (function () {
  2447. function f(n) {
  2448. // Format integers to have at least two digits.
  2449. return n < 10 ? '0' + n : n;
  2450. }
  2451. if (typeof Date.prototype.toJSON !== 'function') {
  2452. Date.prototype.toJSON = function (key) {
  2453. return this.getUTCFullYear() + '-' +
  2454. f(this.getUTCMonth() + 1) + '-' +
  2455. f(this.getUTCDate()) + 'T' +
  2456. f(this.getUTCHours()) + ':' +
  2457. f(this.getUTCMinutes()) + ':' +
  2458. f(this.getUTCSeconds()) + 'Z';
  2459. };
  2460. String.prototype.toJSON =
  2461. Number.prototype.toJSON =
  2462. Boolean.prototype.toJSON = function (key) {
  2463. return this.valueOf();
  2464. };
  2465. }
  2466. var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
  2467. escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
  2468. gap,
  2469. indent,
  2470. meta = { // table of character substitutions
  2471. '\b': '\\b',
  2472. '\t': '\\t',
  2473. '\n': '\\n',
  2474. '\f': '\\f',
  2475. '\r': '\\r',
  2476. '"' : '\\"',
  2477. '\\': '\\\\'
  2478. },
  2479. rep;
  2480. function quote(string) {
  2481. // If the string contains no control characters, no quote characters, and no
  2482. // backslash characters, then we can safely slap some quotes around it.
  2483. // Otherwise we must also replace the offending characters with safe escape
  2484. // sequences.
  2485. escapable.lastIndex = 0;
  2486. return escapable.test(string) ?
  2487. '"' + string.replace(escapable, function (a) {
  2488. var c = meta[a];
  2489. return typeof c === 'string' ? c :
  2490. '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
  2491. }) + '"' :
  2492. '"' + string + '"';
  2493. }
  2494. function str(key, holder) {
  2495. // Produce a string from holder[key].
  2496. var i, // The loop counter.
  2497. k, // The member key.
  2498. v, // The member value.
  2499. length,
  2500. mind = gap,
  2501. partial,
  2502. value = holder[key];
  2503. // If the value has a toJSON method, call it to obtain a replacement value.
  2504. if (value && typeof value === 'object' &&
  2505. typeof value.toJSON === 'function') {
  2506. value = value.toJSON(key);
  2507. }
  2508. // If we were called with a replacer function, then call the replacer to
  2509. // obtain a replacement value.
  2510. if (typeof rep === 'function') {
  2511. value = rep.call(holder, key, value);
  2512. }
  2513. // What happens next depends on the value's type.
  2514. switch (typeof value) {
  2515. case 'string':
  2516. return quote(value);
  2517. case 'number':
  2518. // JSON numbers must be finite. Encode non-finite numbers as null.
  2519. return isFinite(value) ? String(value) : 'null';
  2520. case 'boolean':
  2521. case 'null':
  2522. // If the value is a boolean or null, convert it to a string. Note:
  2523. // typeof null does not produce 'null'. The case is included here in
  2524. // the remote chance that this gets fixed someday.
  2525. return String(value);
  2526. // If the type is 'object', we might be dealing with an object or an array or
  2527. // null.
  2528. case 'object':
  2529. // Due to a specification blunder in ECMAScript, typeof null is 'object',
  2530. // so watch out for that case.
  2531. if (!value) {
  2532. return 'null';
  2533. }
  2534. // Make an array to hold the partial results of stringifying this object value.
  2535. gap += indent;
  2536. partial = [];
  2537. // Is the value an array?
  2538. if (Object.prototype.toString.apply(value) === '[object Array]') {
  2539. // The value is an array. Stringify every element. Use null as a placeholder
  2540. // for non-JSON values.
  2541. length = value.length;
  2542. for (i = 0; i < length; i += 1) {
  2543. partial[i] = str(i, value) || 'null';
  2544. }
  2545. // Join all of the elements together, separated with commas, and wrap them in
  2546. // brackets.
  2547. v = partial.length === 0 ? '[]' :
  2548. gap ? '[\n' + gap +
  2549. partial.join(',\n' + gap) + '\n' +
  2550. mind + ']' :
  2551. '[' + partial.join(',') + ']';
  2552. gap = mind;
  2553. return v;
  2554. }
  2555. // If the replacer is an array, use it to select the members to be stringified.
  2556. if (rep && typeof rep === 'object') {
  2557. length = rep.length;
  2558. for (i = 0; i < length; i += 1) {
  2559. k = rep[i];
  2560. if (typeof k === 'string') {
  2561. v = str(k, value);
  2562. if (v) {
  2563. partial.push(quote(k) + (gap ? ': ' : ':') + v);
  2564. }
  2565. }
  2566. }
  2567. } else {
  2568. // Otherwise, iterate through all of the keys in the object.
  2569. for (k in value) {
  2570. if (Object.hasOwnProperty.call(value, k)) {
  2571. v = str(k, value);
  2572. if (v) {
  2573. partial.push(quote(k) + (gap ? ': ' : ':') + v);
  2574. }
  2575. }
  2576. }
  2577. }
  2578. // Join all of the member texts together, separated with commas,
  2579. // and wrap them in braces.
  2580. v = partial.length === 0 ? '{}' :
  2581. gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
  2582. mind + '}' : '{' + partial.join(',') + '}';
  2583. gap = mind;
  2584. return v;
  2585. }
  2586. }
  2587. // If the JSON object does not yet have a stringify method, give it one.
  2588. if (typeof JSON.stringify !== 'function') {
  2589. JSON.stringify = function (value, replacer, space) {
  2590. // The stringify method takes a value and an optional replacer, and an optional
  2591. // space parameter, and returns a JSON text. The replacer can be a function
  2592. // that can replace values, or an array of strings that will select the keys.
  2593. // A default replacer method can be provided. Use of the space parameter can
  2594. // produce text that is more easily readable.
  2595. var i;
  2596. gap = '';
  2597. indent = '';
  2598. // If the space parameter is a number, make an indent string containing that
  2599. // many spaces.
  2600. if (typeof space === 'number') {
  2601. for (i = 0; i < space; i += 1) {
  2602. indent += ' ';
  2603. }
  2604. // If the space parameter is a string, it will be used as the indent string.
  2605. } else if (typeof space === 'string') {
  2606. indent = space;
  2607. }
  2608. // If there is a replacer, it must be a function or an array.
  2609. // Otherwise, throw an error.
  2610. rep = replacer;
  2611. if (replacer && typeof replacer !== 'function' &&
  2612. (typeof replacer !== 'object' ||
  2613. typeof replacer.length !== 'number')) {
  2614. throw new Error('JSON.stringify');
  2615. }
  2616. // Make a fake root object containing our value under the key of ''.
  2617. // Return the result of stringifying the value.
  2618. return str('', {'': value});
  2619. };
  2620. }
  2621. // If the JSON object does not yet have a parse method, give it one.
  2622. if (typeof JSON.parse !== 'function') {
  2623. JSON.parse = function (text, reviver) {
  2624. // The parse method takes a text and an optional reviver function, and returns
  2625. // a JavaScript value if the text is a valid JSON text.
  2626. var j;
  2627. function walk(holder, key) {
  2628. // The walk method is used to recursively walk the resulting structure so
  2629. // that modifications can be made.
  2630. var k, v, value = holder[key];
  2631. if (value && typeof value === 'object') {
  2632. for (k in value) {
  2633. if (Object.hasOwnProperty.call(value, k)) {
  2634. v = walk(value, k);
  2635. if (v !== undefined) {
  2636. value[k] = v;
  2637. } else {
  2638. delete value[k];
  2639. }
  2640. }
  2641. }
  2642. }
  2643. return reviver.call(holder, key, value);
  2644. }
  2645. // Parsing happens in four stages. In the first stage, we replace certain
  2646. // Unicode characters with escape sequences. JavaScript handles many characters
  2647. // incorrectly, either silently deleting them, or treating them as line endings.
  2648. cx.lastIndex = 0;
  2649. if (cx.test(text)) {
  2650. text = text.replace(cx, function (a) {
  2651. return '\\u' +
  2652. ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
  2653. });
  2654. }
  2655. // In the second stage, we run the text against regular expressions that look
  2656. // for non-JSON patterns. We are especially concerned with '()' and 'new'
  2657. // because they can cause invocation, and '=' because it can cause mutation.
  2658. // But just to be safe, we want to reject all unexpected forms.
  2659. // We split the second stage into 4 regexp operations in order to work around
  2660. // crippling inefficiencies in IE's and Safari's regexp engines. First we
  2661. // replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
  2662. // replace all simple value tokens with ']' characters. Third, we delete all
  2663. // open brackets that follow a colon or comma or that begin the text. Finally,
  2664. // we look to see that the remaining characters are only whitespace or ']' or
  2665. // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
  2666. if (/^[\],:{}\s]*$/.
  2667. test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
  2668. replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
  2669. replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
  2670. // In the third stage we use the eval function to compile the text into a
  2671. // JavaScript structure. The '{' operator is subject to a syntactic ambiguity
  2672. // in JavaScript: it can begin a block or an object literal. We wrap the text
  2673. // in parens to eliminate the ambiguity.
  2674. j = eval('(' + text + ')');
  2675. // In the optional fourth stage, we recursively walk the new structure, passing
  2676. // each name/value pair to a reviver function for possible transformation.
  2677. return typeof reviver === 'function' ?
  2678. walk({'': j}, '') : j;
  2679. }
  2680. // If the text is not JSON parseable, then a SyntaxError is thrown.
  2681. throw new SyntaxError('JSON.parse');
  2682. };
  2683. }
  2684. })();
  2685. /*
  2686. * Licensed to the Apache Software Foundation (ASF) under one
  2687. * or more contributor license agreements. See the NOTICE file
  2688. * distributed with this work for additional information
  2689. * regarding copyright ownership. The ASF licenses this file
  2690. * to you under the Apache License, Version 2.0 (the
  2691. * "License"); you may not use this file except in compliance
  2692. * with the License. You may obtain a copy of the License at
  2693. *
  2694. * http://www.apache.org/licenses/LICENSE-2.0
  2695. *
  2696. * Unless required by applicable law or agreed to in writing,
  2697. * software distributed under the License is distributed on an
  2698. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  2699. * KIND, either express or implied. See the License for the
  2700. * specific language governing permissions and limitations
  2701. * under the License.
  2702. */
  2703. /**
  2704. * @fileoverview External functions used by the OpenSocial RPC code. This file
  2705. * is for use by OpenAjax only.
  2706. */
  2707. //--- from core.util/util.js ---//
  2708. /**
  2709. * @static
  2710. * @class Provides general-purpose utility functions.
  2711. * @name gadgets.util
  2712. */
  2713. OpenAjax.gadgets.util = function() {
  2714. /**
  2715. * Parses URL parameters into an object.
  2716. * @param {string} url - the url parameters to parse
  2717. * @return {Array.<string>} The parameters as an array
  2718. */
  2719. function parseUrlParams(url) {
  2720. // Get settings from url, 'hash' takes precedence over 'search' component
  2721. // don't use document.location.hash due to browser differences.
  2722. var query;
  2723. var queryIdx = url.indexOf("?");
  2724. var hashIdx = url.indexOf("#");
  2725. if (hashIdx === -1) {
  2726. query = url.substr(queryIdx + 1);
  2727. } else {
  2728. // essentially replaces "#" with "&"
  2729. query = [url.substr(queryIdx + 1, hashIdx - queryIdx - 1), "&",
  2730. url.substr(hashIdx + 1)].join("");
  2731. }
  2732. return query.split("&");
  2733. }
  2734. var parameters = null;
  2735. var onLoadHandlers = [];
  2736. return /** @scope gadgets.util */ {
  2737. /**
  2738. * Gets the URL parameters.
  2739. *
  2740. * @param {string=} opt_url Optional URL whose parameters to parse.
  2741. * Defaults to window's current URL.
  2742. * @return {Object} Parameters passed into the query string
  2743. * @member gadgets.util
  2744. * @private Implementation detail.
  2745. */
  2746. getUrlParameters : function (opt_url) {
  2747. if (parameters !== null && typeof opt_url === "undefined") {
  2748. // "parameters" is a cache of current window params only.
  2749. return parameters;
  2750. }
  2751. var parsed = {};
  2752. var pairs = parseUrlParams(opt_url || document.location.href);
  2753. var unesc = window.decodeURIComponent ? decodeURIComponent : unescape;
  2754. for (var i = 0, j = pairs.length; i < j; ++i) {
  2755. var pos = pairs[i].indexOf('=');
  2756. if (pos === -1) {
  2757. continue;
  2758. }
  2759. var argName = pairs[i].substring(0, pos);
  2760. var value = pairs[i].substring(pos + 1);
  2761. // difference to IG_Prefs, is that args doesn't replace spaces in
  2762. // argname. Unclear on if it should do:
  2763. // argname = argname.replace(/\+/g, " ");
  2764. value = value.replace(/\+/g, " ");
  2765. parsed[argName] = unesc(value);
  2766. }
  2767. if (typeof opt_url === "undefined") {
  2768. // Cache current-window params in parameters var.
  2769. parameters = parsed;
  2770. }
  2771. return parsed;
  2772. },
  2773. /**
  2774. * Registers an onload handler.
  2775. * @param {function()} callback The handler to run
  2776. *
  2777. * @member gadgets.util
  2778. */
  2779. registerOnLoadHandler : function (callback) {
  2780. onLoadHandlers.push(callback);
  2781. },
  2782. /**
  2783. * Runs all functions registered via registerOnLoadHandler.
  2784. * @private Only to be used by the container, not gadgets.
  2785. */
  2786. runOnLoadHandlers : function () {
  2787. for (var i = 0, j = onLoadHandlers.length; i < j; ++i) {
  2788. onLoadHandlers[i]();
  2789. }
  2790. },
  2791. /**
  2792. * Attach an event listener to given DOM element
  2793. *
  2794. * @param {object} elem DOM element on which to attach event.
  2795. * @param {string} eventName Event type to listen for.
  2796. * @param {function} callback Invoked when specified event occurs.
  2797. * @param {boolean} useCapture If true, initiates capture.
  2798. */
  2799. 'attachBrowserEvent': function(elem, eventName, callback, useCapture) {
  2800. if (elem.addEventListener) {
  2801. elem.addEventListener(eventName, callback, useCapture);
  2802. } else if (elem.attachEvent) {
  2803. elem.attachEvent('on' + eventName, callback);
  2804. }
  2805. },
  2806. /**
  2807. * Remove event listener
  2808. *
  2809. * @param {object} elem DOM element from which to remove event.
  2810. * @param {string} eventName Event type to remove.
  2811. * @param {function} callback Listener to remove.
  2812. * @param {boolean} useCapture Specifies whether listener being removed was added with
  2813. * capture enabled.
  2814. */
  2815. 'removeBrowserEvent': function(elem, eventName, callback, useCapture) {
  2816. if (elem.removeEventListener) {
  2817. elem.removeEventListener(eventName, callback, useCapture);
  2818. } else if (elem.detachEvent){
  2819. elem.detachEvent('on' + eventName, callback);
  2820. }
  2821. }
  2822. };
  2823. }();
  2824. // Initialize url parameters so that hash data is pulled in before it can be
  2825. // altered by a click.
  2826. OpenAjax.gadgets.util.getUrlParameters();
  2827. //--- from core.json/json.js ---//
  2828. OpenAjax.gadgets.json = OpenAjax.gadgets.json || {};
  2829. if ( ! OpenAjax.gadgets.json.stringify ) {
  2830. OpenAjax.gadgets.json = {
  2831. parse: function(str) {
  2832. try {
  2833. if (str==="postmessage.test"){return false;}
  2834. return window.JSON.parse(str);
  2835. } catch (e) {
  2836. return false;
  2837. }
  2838. },
  2839. stringify: function(obj) {
  2840. try {
  2841. return window.JSON.stringify(obj);
  2842. } catch (e) {
  2843. return null;
  2844. }
  2845. }
  2846. };
  2847. }
  2848. //--- from core.log/log.js ---//
  2849. /**
  2850. * Log an informational message
  2851. */
  2852. OpenAjax.gadgets.log = function(message) {
  2853. OpenAjax.gadgets.log.logAtLevel(OpenAjax.gadgets.log.INFO, message);
  2854. };
  2855. /**
  2856. * Log a warning
  2857. */
  2858. OpenAjax.gadgets.warn = function(message) {
  2859. OpenAjax.gadgets.log.logAtLevel(OpenAjax.gadgets.log.WARNING, message);
  2860. };
  2861. /**
  2862. * Log an error
  2863. */
  2864. OpenAjax.gadgets.error = function(message) {
  2865. OpenAjax.gadgets.log.logAtLevel(OpenAjax.gadgets.log.ERROR, message);
  2866. };
  2867. /**
  2868. * Sets the log level threshold.
  2869. * @param {Number} logLevel - New log level threshold.
  2870. * @static
  2871. */
  2872. OpenAjax.gadgets.setLogLevel = function(logLevel) {
  2873. OpenAjax.gadgets.log.logLevelThreshold_ = logLevel;
  2874. };
  2875. /**
  2876. * Logs a log message if output console is available, and log threshold is met.
  2877. * @param {Number} level - the level to log with. Optional, defaults to
  2878. * @param {Object} message - The message to log
  2879. * gadgets.log.INFO.
  2880. * @static
  2881. */
  2882. OpenAjax.gadgets.log.logAtLevel = function(level, message) {
  2883. if (level < OpenAjax.gadgets.log.logLevelThreshold_ || !OpenAjax.gadgets.log._console) {
  2884. return;
  2885. }
  2886. var gadgetconsole = OpenAjax.gadgets.log._console;
  2887. if (level == OpenAjax.gadgets.log.WARNING && gadgetconsole.warn) {
  2888. gadgetconsole.warn(message);
  2889. } else if (level == OpenAjax.gadgets.log.ERROR && gadgetconsole.error) {
  2890. gadgetconsole.error(message);
  2891. } else if (gadgetconsole.log) {
  2892. gadgetconsole.log(message);
  2893. }
  2894. };
  2895. /**
  2896. * Log level for informational logging.
  2897. * @static
  2898. */
  2899. OpenAjax.gadgets.log.INFO = 1;
  2900. /**
  2901. * Log level for warning logging.
  2902. * @static
  2903. */
  2904. OpenAjax.gadgets.log.WARNING = 2;
  2905. /**
  2906. * Log level for error logging.
  2907. * @static
  2908. */
  2909. OpenAjax.gadgets.log.ERROR = 3;
  2910. /**
  2911. * Log level for no logging
  2912. * @static
  2913. */
  2914. OpenAjax.gadgets.log.NONE = 4;
  2915. /**
  2916. * Current log level threshold.
  2917. * @type Number
  2918. * @private
  2919. * @static
  2920. */
  2921. OpenAjax.gadgets.log.logLevelThreshold_ = OpenAjax.gadgets.log.INFO;
  2922. /**
  2923. * Console to log to
  2924. * @private
  2925. * @static
  2926. */
  2927. OpenAjax.gadgets.log._console = window.console ? window.console :
  2928. window.opera ? window.opera.postError : undefined;
  2929. ////////////////////////////////////////////////////////////////////////////////////////////////////
  2930. // onload handler compatibility code
  2931. ////////////////////////////////////////////////////////////////////////////////////////////////////
  2932. (function() {
  2933. // XXX What if this script file (iframe.js) is dynamically loaded after the page has loaded.
  2934. if ( ! window.__isgadget ) {
  2935. var loaded = false;
  2936. function onload() {
  2937. if ( ! loaded ) {
  2938. loaded = true;
  2939. // This is necessary for the RMR and FE transports.
  2940. OpenAjax.gadgets.util.runOnLoadHandlers();
  2941. // Since the page has now loaded, change registerOnLoadHandler() to immediately fire
  2942. // callback.
  2943. OpenAjax.gadgets.util.registerOnLoadHandler = function( callback ) {
  2944. setTimeout( callback, 0 );
  2945. };
  2946. // prevent IE memory leak
  2947. if ( window.detachEvent ) {
  2948. window.detachEvent( "onload", onload );
  2949. }
  2950. }
  2951. }
  2952. if ( window.addEventListener ) {
  2953. document.addEventListener( "DOMContentLoaded", onload, false );
  2954. window.addEventListener( "load", onload, false );
  2955. } else if ( window.attachEvent ) {
  2956. // XXX use doScroll trick?
  2957. window.attachEvent( "onload", onload );
  2958. }
  2959. }
  2960. })();
  2961. /*
  2962. * Licensed to the Apache Software Foundation (ASF) under one
  2963. * or more contributor license agreements. See the NOTICE file
  2964. * distributed with this work for additional information
  2965. * regarding copyright ownership. The ASF licenses this file
  2966. * to you under the Apache License, Version 2.0 (the
  2967. * "License"); you may not use this file except in compliance
  2968. * with the License. You may obtain a copy of the License at
  2969. *
  2970. * http://www.apache.org/licenses/LICENSE-2.0
  2971. *
  2972. * Unless required by applicable law or agreed to in writing,
  2973. * software distributed under the License is distributed on an
  2974. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  2975. * KIND, either express or implied. See the License for the
  2976. * specific language governing permissions and limitations under the License.
  2977. */
  2978. OpenAjax.gadgets.rpctx = OpenAjax.gadgets.rpctx || {};
  2979. /*
  2980. * For Gecko-based browsers, the security model allows a child to call a
  2981. * function on the frameElement of the iframe, even if the child is in
  2982. * a different domain. This method is dubbed "frameElement" (fe).
  2983. *
  2984. * The ability to add and call such functions on the frameElement allows
  2985. * a bidirectional channel to be setup via the adding of simple function
  2986. * references on the frameElement object itself. In this implementation,
  2987. * when the container sets up the authentication information for that gadget
  2988. * (by calling setAuth(...)) it as well adds a special function on the
  2989. * gadget's iframe. This function can then be used by the gadget to send
  2990. * messages to the container. In turn, when the gadget tries to send a
  2991. * message, it checks to see if this function has its own function stored
  2992. * that can be used by the container to call the gadget. If not, the
  2993. * function is created and subsequently used by the container.
  2994. * Note that as a result, FE can only be used by a container to call a
  2995. * particular gadget *after* that gadget has called the container at
  2996. * least once via FE.
  2997. *
  2998. * fe: Gecko-specific frameElement trick.
  2999. * - Firefox 1+
  3000. */
  3001. if (!OpenAjax.gadgets.rpctx.frameElement) { // make lib resilient to double-inclusion
  3002. OpenAjax.gadgets.rpctx.frameElement = function() {
  3003. // Consts for FrameElement.
  3004. var FE_G2C_CHANNEL = '__g2c_rpc';
  3005. var FE_C2G_CHANNEL = '__c2g_rpc';
  3006. var process;
  3007. var ready;
  3008. function callFrameElement(targetId, from, rpc) {
  3009. try {
  3010. if (from !== '..') {
  3011. // Call from gadget to the container.
  3012. var fe = window.frameElement;
  3013. if (typeof fe[FE_G2C_CHANNEL] === 'function') {
  3014. // Complete the setup of the FE channel if need be.
  3015. if (typeof fe[FE_G2C_CHANNEL][FE_C2G_CHANNEL] !== 'function') {
  3016. fe[FE_G2C_CHANNEL][FE_C2G_CHANNEL] = function(args) {
  3017. process(OpenAjax.gadgets.json.parse(args));
  3018. };
  3019. }
  3020. // Conduct the RPC call.
  3021. fe[FE_G2C_CHANNEL](OpenAjax.gadgets.json.stringify(rpc));
  3022. return;
  3023. }
  3024. } else {
  3025. // Call from container to gadget[targetId].
  3026. var frame = document.getElementById(targetId);
  3027. if (typeof frame[FE_G2C_CHANNEL] === 'function' &&
  3028. typeof frame[FE_G2C_CHANNEL][FE_C2G_CHANNEL] === 'function') {
  3029. // Conduct the RPC call.
  3030. frame[FE_G2C_CHANNEL][FE_C2G_CHANNEL](OpenAjax.gadgets.json.stringify(rpc));
  3031. return;
  3032. }
  3033. }
  3034. } catch (e) {
  3035. }
  3036. return true;
  3037. }
  3038. return {
  3039. getCode: function() {
  3040. return 'fe';
  3041. },
  3042. isParentVerifiable: function() {
  3043. return false;
  3044. },
  3045. init: function(processFn, readyFn) {
  3046. // No global setup.
  3047. process = processFn;
  3048. ready = readyFn;
  3049. return true;
  3050. },
  3051. setup: function(receiverId, token) {
  3052. // Indicate OK to call to container. This will be true
  3053. // by the end of this method.
  3054. if (receiverId !== '..') {
  3055. try {
  3056. var frame = document.getElementById(receiverId);
  3057. frame[FE_G2C_CHANNEL] = function(args) {
  3058. process(OpenAjax.gadgets.json.parse(args));
  3059. };
  3060. } catch (e) {
  3061. return false;
  3062. }
  3063. }
  3064. if (receiverId === '..') {
  3065. ready('..', true);
  3066. var ackFn = function() {
  3067. window.setTimeout(function() {
  3068. OpenAjax.gadgets.rpc.call(receiverId, OpenAjax.gadgets.rpc.ACK);
  3069. }, 500);
  3070. };
  3071. // Setup to container always happens before onload.
  3072. // If it didn't, the correct fix would be in gadgets.util.
  3073. OpenAjax.gadgets.util.registerOnLoadHandler(ackFn);
  3074. }
  3075. return true;
  3076. },
  3077. call: function(targetId, from, rpc) {
  3078. callFrameElement(targetId, from, rpc);
  3079. }
  3080. };
  3081. }();
  3082. } // !end of double-inclusion guard
  3083. /*
  3084. * Licensed to the Apache Software Foundation (ASF) under one
  3085. * or more contributor license agreements. See the NOTICE file
  3086. * distributed with this work for additional information
  3087. * regarding copyright ownership. The ASF licenses this file
  3088. * to you under the Apache License, Version 2.0 (the
  3089. * "License"); you may not use this file except in compliance
  3090. * with the License. You may obtain a copy of the License at
  3091. *
  3092. * http://www.apache.org/licenses/LICENSE-2.0
  3093. *
  3094. * Unless required by applicable law or agreed to in writing,
  3095. * software distributed under the License is distributed on an
  3096. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  3097. * KIND, either express or implied. See the License for the
  3098. * specific language governing permissions and limitations under the License.
  3099. */
  3100. OpenAjax.gadgets.rpctx = OpenAjax.gadgets.rpctx || {};
  3101. /*
  3102. * For all others, we have a fallback mechanism known as "ifpc". IFPC
  3103. * exploits the fact that while same-origin policy prohibits a frame from
  3104. * accessing members on a window not in the same domain, that frame can,
  3105. * however, navigate the window heirarchy (via parent). This is exploited by
  3106. * having a page on domain A that wants to talk to domain B create an iframe
  3107. * on domain B pointing to a special relay file and with a message encoded
  3108. * after the hash (#). This relay, in turn, finds the page on domain B, and
  3109. * can call a receipt function with the message given to it. The relay URL
  3110. * used by each caller is set via the gadgets.rpc.setRelayUrl(..) and
  3111. * *must* be called before the call method is used.
  3112. *
  3113. * ifpc: Iframe-based method, utilizing a relay page, to send a message.
  3114. * - No known major browsers still use this method, but it remains
  3115. * useful as a catch-all fallback for the time being.
  3116. */
  3117. if (!OpenAjax.gadgets.rpctx.ifpc) { // make lib resilient to double-inclusion
  3118. OpenAjax.gadgets.rpctx.ifpc = function() {
  3119. var iframePool = [];
  3120. var callId = 0;
  3121. var ready;
  3122. /**
  3123. * Encodes arguments for the legacy IFPC wire format.
  3124. *
  3125. * @param {Object} args
  3126. * @return {string} the encoded args
  3127. */
  3128. function encodeLegacyData(args) {
  3129. var argsEscaped = [];
  3130. for(var i = 0, j = args.length; i < j; ++i) {
  3131. argsEscaped.push(encodeURIComponent(OpenAjax.gadgets.json.stringify(args[i])));
  3132. }
  3133. return argsEscaped.join('&');
  3134. }
  3135. /**
  3136. * Helper function to emit an invisible IFrame.
  3137. * @param {string} src SRC attribute of the IFrame to emit.
  3138. * @private
  3139. */
  3140. function emitInvisibleIframe(src) {
  3141. var iframe;
  3142. // Recycle IFrames
  3143. for (var i = iframePool.length - 1; i >=0; --i) {
  3144. var ifr = iframePool[i];
  3145. try {
  3146. if (ifr && (ifr.recyclable || ifr.readyState === 'complete')) {
  3147. ifr.parentNode.removeChild(ifr);
  3148. if (window.ActiveXObject) {
  3149. // For MSIE, delete any iframes that are no longer being used. MSIE
  3150. // cannot reuse the IFRAME because a navigational click sound will
  3151. // be triggered when we set the SRC attribute.
  3152. // Other browsers scan the pool for a free iframe to reuse.
  3153. iframePool[i] = ifr = null;
  3154. iframePool.splice(i, 1);
  3155. } else {
  3156. ifr.recyclable = false;
  3157. iframe = ifr;
  3158. break;
  3159. }
  3160. }
  3161. } catch (e) {
  3162. // Ignore; IE7 throws an exception when trying to read readyState and
  3163. // readyState isn't set.
  3164. }
  3165. }
  3166. // Create IFrame if necessary
  3167. if (!iframe) {
  3168. iframe = document.createElement('iframe');
  3169. iframe.style.border = iframe.style.width = iframe.style.height = '0px';
  3170. iframe.style.visibility = 'hidden';
  3171. iframe.style.position = 'absolute';
  3172. iframe.onload = function() { this.recyclable = true; };
  3173. iframePool.push(iframe);
  3174. }
  3175. iframe.src = src;
  3176. window.setTimeout(function() { document.body.appendChild(iframe); }, 0);
  3177. }
  3178. return {
  3179. getCode: function() {
  3180. return 'ifpc';
  3181. },
  3182. isParentVerifiable: function() {
  3183. return true;
  3184. },
  3185. init: function(processFn, readyFn) {
  3186. // No global setup.
  3187. ready = readyFn;
  3188. ready('..', true); // Ready immediately.
  3189. return true;
  3190. },
  3191. setup: function(receiverId, token) {
  3192. // Indicate readiness to send to receiver.
  3193. ready(receiverId, true);
  3194. return true;
  3195. },
  3196. call: function(targetId, from, rpc) {
  3197. // Retrieve the relay file used by IFPC. Note that
  3198. // this must be set before the call, and so we conduct
  3199. // an extra check to ensure it is not blank.
  3200. var relay = OpenAjax.gadgets.rpc.getRelayUrl(targetId);
  3201. ++callId;
  3202. if (!relay) {
  3203. OpenAjax.gadgets.warn('No relay file assigned for IFPC');
  3204. return;
  3205. }
  3206. // The RPC mechanism supports two formats for IFPC (legacy and current).
  3207. var src = null;
  3208. if (rpc.l) {
  3209. // Use legacy protocol.
  3210. // Format: #iframe_id&callId&num_packets&packet_num&block_of_data
  3211. var callArgs = rpc.a;
  3212. src = [relay, '#', encodeLegacyData([from, callId, 1, 0,
  3213. encodeLegacyData([from, rpc.s, '', '', from].concat(
  3214. callArgs))])].join('');
  3215. } else {
  3216. // Format: #targetId & sourceId@callId & packetNum & packetId & packetData
  3217. src = [relay, '#', targetId, '&', from, '@', callId,
  3218. '&1&0&', encodeURIComponent(OpenAjax.gadgets.json.stringify(rpc))].join('');
  3219. }
  3220. // Conduct the IFPC call by creating the Iframe with
  3221. // the relay URL and appended message.
  3222. emitInvisibleIframe(src);
  3223. return true;
  3224. }
  3225. };
  3226. }();
  3227. } // !end of double inclusion guard
  3228. /*
  3229. * Licensed to the Apache Software Foundation (ASF) under one
  3230. * or more contributor license agreements. See the NOTICE file
  3231. * distributed with this work for additional information
  3232. * regarding copyright ownership. The ASF licenses this file
  3233. * to you under the Apache License, Version 2.0 (the
  3234. * "License"); you may not use this file except in compliance
  3235. * with the License. You may obtain a copy of the License at
  3236. *
  3237. * http://www.apache.org/licenses/LICENSE-2.0
  3238. *
  3239. * Unless required by applicable law or agreed to in writing,
  3240. * software distributed under the License is distributed on an
  3241. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  3242. * KIND, either express or implied. See the License for the
  3243. * specific language governing permissions and limitations under the License.
  3244. */
  3245. OpenAjax.gadgets.rpctx = OpenAjax.gadgets.rpctx || {};
  3246. /**
  3247. * For Internet Explorer before version 8, the security model allows anyone
  3248. * parent to set the value of the "opener" property on another window,
  3249. * with only the receiving window able to read it.
  3250. * This method is dubbed "Native IE XDC" (NIX).
  3251. *
  3252. * This method works by placing a handler object in the "opener" property
  3253. * of a gadget when the container sets up the authentication information
  3254. * for that gadget (by calling setAuthToken(...)). At that point, a NIX
  3255. * wrapper is created and placed into the gadget by calling
  3256. * theframe.contentWindow.opener = wrapper. Note that as a result, NIX can
  3257. * only be used by a container to call a particular gadget *after* that
  3258. * gadget has called the container at least once via NIX.
  3259. *
  3260. * The NIX wrappers in this RPC implementation are instances of a VBScript
  3261. * class that is created when this implementation loads. The reason for
  3262. * using a VBScript class stems from the fact that any object can be passed
  3263. * into the opener property.
  3264. * While this is a good thing, as it lets us pass functions and setup a true
  3265. * bidirectional channel via callbacks, it opens a potential security hole
  3266. * by which the other page can get ahold of the "window" or "document"
  3267. * objects in the parent page and in turn wreak havok. This is due to the
  3268. * fact that any JS object useful for establishing such a bidirectional
  3269. * channel (such as a function) can be used to access a function
  3270. * (eg. obj.toString, or a function itself) created in a specific context,
  3271. * in particular the global context of the sender. Suppose container
  3272. * domain C passes object obj to gadget on domain G. Then the gadget can
  3273. * access C's global context using:
  3274. * var parentWindow = (new obj.toString.constructor("return window;"))();
  3275. * Nulling out all of obj's properties doesn't fix this, since IE helpfully
  3276. * restores them to their original values if you do something like:
  3277. * delete obj.toString; delete obj.toString;
  3278. * Thus, we wrap the necessary functions and information inside a VBScript
  3279. * object. VBScript objects in IE, like DOM objects, are in fact COM
  3280. * wrappers when used in JavaScript, so we can safely pass them around
  3281. * without worrying about a breach of context while at the same time
  3282. * allowing them to act as a pass-through mechanism for information
  3283. * and function calls. The implementation details of this VBScript wrapper
  3284. * can be found in the setupChannel() method below.
  3285. *
  3286. * nix: Internet Explorer-specific window.opener trick.
  3287. * - Internet Explorer 6
  3288. * - Internet Explorer 7
  3289. */
  3290. if (!OpenAjax.gadgets.rpctx.nix) { // make lib resilient to double-inclusion
  3291. OpenAjax.gadgets.rpctx.nix = function() {
  3292. // Consts for NIX. VBScript doesn't
  3293. // allow items to start with _ for some reason,
  3294. // so we need to make these names quite unique, as
  3295. // they will go into the global namespace.
  3296. var NIX_WRAPPER = 'GRPC____NIXVBS_wrapper';
  3297. var NIX_GET_WRAPPER = 'GRPC____NIXVBS_get_wrapper';
  3298. var NIX_HANDLE_MESSAGE = 'GRPC____NIXVBS_handle_message';
  3299. var NIX_CREATE_CHANNEL = 'GRPC____NIXVBS_create_channel';
  3300. var MAX_NIX_SEARCHES = 10;
  3301. var NIX_SEARCH_PERIOD = 500;
  3302. // JavaScript reference to the NIX VBScript wrappers.
  3303. // Gadgets will have but a single channel under
  3304. // nix_channels['..'] while containers will have a channel
  3305. // per gadget stored under the gadget's ID.
  3306. var nix_channels = {};
  3307. var isForceSecure = {};
  3308. // Store the ready signal method for use on handshake complete.
  3309. var ready;
  3310. var numHandlerSearches = 0;
  3311. // Search for NIX handler to parent. Tries MAX_NIX_SEARCHES times every
  3312. // NIX_SEARCH_PERIOD milliseconds.
  3313. function conductHandlerSearch() {
  3314. // Call from gadget to the container.
  3315. var handler = nix_channels['..'];
  3316. if (handler) {
  3317. return;
  3318. }
  3319. if (++numHandlerSearches > MAX_NIX_SEARCHES) {
  3320. // Handshake failed. Will fall back.
  3321. OpenAjax.gadgets.warn('Nix transport setup failed, falling back...');
  3322. ready('..', false);
  3323. return;
  3324. }
  3325. // If the gadget has yet to retrieve a reference to
  3326. // the NIX handler, try to do so now. We don't do a
  3327. // typeof(window.opener.GetAuthToken) check here
  3328. // because it means accessing that field on the COM object, which,
  3329. // being an internal function reference, is not allowed.
  3330. // "in" works because it merely checks for the prescence of
  3331. // the key, rather than actually accessing the object's property.
  3332. // This is just a sanity check, not a validity check.
  3333. if (!handler && window.opener && "GetAuthToken" in window.opener) {
  3334. handler = window.opener;
  3335. // Create the channel to the parent/container.
  3336. // First verify that it knows our auth token to ensure it's not
  3337. // an impostor.
  3338. if (handler.GetAuthToken() == OpenAjax.gadgets.rpc.getAuthToken('..')) {
  3339. // Auth match - pass it back along with our wrapper to finish.
  3340. // own wrapper and our authentication token for co-verification.
  3341. var token = OpenAjax.gadgets.rpc.getAuthToken('..');
  3342. handler.CreateChannel(window[NIX_GET_WRAPPER]('..', token),
  3343. token);
  3344. // Set channel handler
  3345. nix_channels['..'] = handler;
  3346. window.opener = null;
  3347. // Signal success and readiness to send to parent.
  3348. // Container-to-gadget bit flipped in CreateChannel.
  3349. ready('..', true);
  3350. return;
  3351. }
  3352. }
  3353. // Try again.
  3354. window.setTimeout(function() { conductHandlerSearch(); },
  3355. NIX_SEARCH_PERIOD);
  3356. }
  3357. // Returns current window location, without hash values
  3358. function getLocationNoHash() {
  3359. var loc = window.location.href;
  3360. var idx = loc.indexOf('#');
  3361. if (idx == -1) {
  3362. return loc;
  3363. }
  3364. return loc.substring(0, idx);
  3365. }
  3366. // When "forcesecure" is set to true, use the relay file and a simple variant of IFPC to first
  3367. // authenticate the container and gadget with each other. Once that is done, then initialize
  3368. // the NIX protocol.
  3369. function setupSecureRelayToParent(rpctoken) {
  3370. // To the parent, transmit the child's URL, the passed in auth
  3371. // token, and another token generated by the child.
  3372. var childToken = (0x7FFFFFFF * Math.random()) | 0; // TODO expose way to have child set this value
  3373. var data = [
  3374. getLocationNoHash(),
  3375. childToken
  3376. ];
  3377. OpenAjax.gadgets.rpc._createRelayIframe(rpctoken, data);
  3378. // listen for response from parent
  3379. var hash = window.location.href.split('#')[1] || '';
  3380. function relayTimer() {
  3381. var newHash = window.location.href.split('#')[1] || '';
  3382. if (newHash !== hash) {
  3383. clearInterval(relayTimerId);
  3384. var params = OpenAjax.gadgets.util.getUrlParameters(window.location.href);
  3385. if (params.childtoken == childToken) {
  3386. // parent has been authenticated; now init NIX
  3387. conductHandlerSearch();
  3388. return;
  3389. }
  3390. // security error -- token didn't match
  3391. ready('..', false);
  3392. }
  3393. }
  3394. var relayTimerId = setInterval( relayTimer, 100 );
  3395. }
  3396. return {
  3397. getCode: function() {
  3398. return 'nix';
  3399. },
  3400. isParentVerifiable: function(opt_receiverId) {
  3401. // NIX is only parent verifiable if a receiver was setup with "forcesecure" set to TRUE.
  3402. if (opt_receiverId) {
  3403. return isForceSecure[opt_receiverId];
  3404. }
  3405. return false;
  3406. },
  3407. init: function(processFn, readyFn) {
  3408. ready = readyFn;
  3409. // Ensure VBScript wrapper code is in the page and that the
  3410. // global Javascript handlers have been set.
  3411. // VBScript methods return a type of 'unknown' when
  3412. // checked via the typeof operator in IE. Fortunately
  3413. // for us, this only applies to COM objects, so we
  3414. // won't see this for a real Javascript object.
  3415. if (typeof window[NIX_GET_WRAPPER] !== 'unknown') {
  3416. window[NIX_HANDLE_MESSAGE] = function(data) {
  3417. window.setTimeout(
  3418. function() { processFn(OpenAjax.gadgets.json.parse(data)); }, 0);
  3419. };
  3420. window[NIX_CREATE_CHANNEL] = function(name, channel, token) {
  3421. // Verify the authentication token of the gadget trying
  3422. // to create a channel for us.
  3423. if (OpenAjax.gadgets.rpc.getAuthToken(name) === token) {
  3424. nix_channels[name] = channel;
  3425. ready(name, true);
  3426. }
  3427. };
  3428. // Inject the VBScript code needed.
  3429. var vbscript =
  3430. // We create a class to act as a wrapper for
  3431. // a Javascript call, to prevent a break in of
  3432. // the context.
  3433. 'Class ' + NIX_WRAPPER + '\n '
  3434. // An internal member for keeping track of the
  3435. // name of the document (container or gadget)
  3436. // for which this wrapper is intended. For
  3437. // those wrappers created by gadgets, this is not
  3438. // used (although it is set to "..")
  3439. + 'Private m_Intended\n'
  3440. // Stores the auth token used to communicate with
  3441. // the gadget. The GetChannelCreator method returns
  3442. // an object that returns this auth token. Upon matching
  3443. // that with its own, the gadget uses the object
  3444. // to actually establish the communication channel.
  3445. + 'Private m_Auth\n'
  3446. // Method for internally setting the value
  3447. // of the m_Intended property.
  3448. + 'Public Sub SetIntendedName(name)\n '
  3449. + 'If isEmpty(m_Intended) Then\n'
  3450. + 'm_Intended = name\n'
  3451. + 'End If\n'
  3452. + 'End Sub\n'
  3453. // Method for internally setting the value of the m_Auth property.
  3454. + 'Public Sub SetAuth(auth)\n '
  3455. + 'If isEmpty(m_Auth) Then\n'
  3456. + 'm_Auth = auth\n'
  3457. + 'End If\n'
  3458. + 'End Sub\n'
  3459. // A wrapper method which actually causes a
  3460. // message to be sent to the other context.
  3461. + 'Public Sub SendMessage(data)\n '
  3462. + NIX_HANDLE_MESSAGE + '(data)\n'
  3463. + 'End Sub\n'
  3464. // Returns the auth token to the gadget, so it can
  3465. // confirm a match before initiating the connection
  3466. + 'Public Function GetAuthToken()\n '
  3467. + 'GetAuthToken = m_Auth\n'
  3468. + 'End Function\n'
  3469. // Method for setting up the container->gadget
  3470. // channel. Not strictly needed in the gadget's
  3471. // wrapper, but no reason to get rid of it. Note here
  3472. // that we pass the intended name to the NIX_CREATE_CHANNEL
  3473. // method so that it can save the channel in the proper place
  3474. // *and* verify the channel via the authentication token passed
  3475. // here.
  3476. + 'Public Sub CreateChannel(channel, auth)\n '
  3477. + 'Call ' + NIX_CREATE_CHANNEL + '(m_Intended, channel, auth)\n'
  3478. + 'End Sub\n'
  3479. + 'End Class\n'
  3480. // Function to get a reference to the wrapper.
  3481. + 'Function ' + NIX_GET_WRAPPER + '(name, auth)\n'
  3482. + 'Dim wrap\n'
  3483. + 'Set wrap = New ' + NIX_WRAPPER + '\n'
  3484. + 'wrap.SetIntendedName name\n'
  3485. + 'wrap.SetAuth auth\n'
  3486. + 'Set ' + NIX_GET_WRAPPER + ' = wrap\n'
  3487. + 'End Function';
  3488. try {
  3489. window.execScript(vbscript, 'vbscript');
  3490. } catch (e) {
  3491. return false;
  3492. }
  3493. }
  3494. return true;
  3495. },
  3496. setup: function(receiverId, token, forcesecure) {
  3497. isForceSecure[receiverId] = !!forcesecure;
  3498. if (receiverId === '..') {
  3499. if (forcesecure) {
  3500. setupSecureRelayToParent(token);
  3501. } else {
  3502. conductHandlerSearch();
  3503. }
  3504. return true;
  3505. }
  3506. try {
  3507. var frame = document.getElementById(receiverId);
  3508. var wrapper = window[NIX_GET_WRAPPER](receiverId, token);
  3509. frame.contentWindow.opener = wrapper;
  3510. } catch (e) {
  3511. return false;
  3512. }
  3513. return true;
  3514. },
  3515. call: function(targetId, from, rpc) {
  3516. try {
  3517. // If we have a handler, call it.
  3518. if (nix_channels[targetId]) {
  3519. nix_channels[targetId].SendMessage(OpenAjax.gadgets.json.stringify(rpc));
  3520. }
  3521. } catch (e) {
  3522. return false;
  3523. }
  3524. return true;
  3525. },
  3526. // data = [child URL, child auth token]
  3527. relayOnload: function(receiverId, data) {
  3528. // transmit childtoken back to child to complete authentication
  3529. var src = data[0] + '#childtoken=' + data[1];
  3530. var childIframe = document.getElementById(receiverId);
  3531. childIframe.src = src;
  3532. }
  3533. };
  3534. }();
  3535. } // !end of double-inclusion guard
  3536. /*
  3537. * Licensed to the Apache Software Foundation (ASF) under one
  3538. * or more contributor license agreements. See the NOTICE file
  3539. * distributed with this work for additional information
  3540. * regarding copyright ownership. The ASF licenses this file
  3541. * to you under the Apache License, Version 2.0 (the
  3542. * "License"); you may not use this file except in compliance
  3543. * with the License. You may obtain a copy of the License at
  3544. *
  3545. * http://www.apache.org/licenses/LICENSE-2.0
  3546. *
  3547. * Unless required by applicable law or agreed to in writing,
  3548. * software distributed under the License is distributed on an
  3549. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  3550. * KIND, either express or implied. See the License for the
  3551. * specific language governing permissions and limitations under the License.
  3552. */
  3553. OpenAjax.gadgets.rpctx = OpenAjax.gadgets.rpctx || {};
  3554. /*
  3555. * For older WebKit-based browsers, the security model does not allow for any
  3556. * known "native" hacks for conducting cross browser communication. However,
  3557. * a variation of the IFPC (see below) can be used, entitled "RMR". RMR is
  3558. * a technique that uses the resize event of the iframe to indicate that a
  3559. * message was sent (instead of the much slower/performance heavy polling
  3560. * technique used when a defined relay page is not avaliable). Simply put,
  3561. * RMR uses the same "pass the message by the URL hash" trick that IFPC
  3562. * uses to send a message, but instead of having an active relay page that
  3563. * runs a piece of code when it is loaded, RMR merely changes the URL
  3564. * of the relay page (which does not even have to exist on the domain)
  3565. * and then notifies the other party by resizing the relay iframe. RMR
  3566. * exploits the fact that iframes in the dom of page A can be resized
  3567. * by page A while the onresize event will be fired in the DOM of page B,
  3568. * thus providing a single bit channel indicating "message sent to you".
  3569. * This method has the added benefit that the relay need not be active,
  3570. * nor even exist: a 404 suffices just as well.
  3571. *
  3572. * rmr: WebKit-specific resizing trick.
  3573. * - Safari 2+
  3574. * - Chrome 1
  3575. */
  3576. if (!OpenAjax.gadgets.rpctx.rmr) { // make lib resilient to double-inclusion
  3577. OpenAjax.gadgets.rpctx.rmr = function() {
  3578. // Consts for RMR, including time in ms RMR uses to poll for
  3579. // its relay frame to be created, and the max # of polls it does.
  3580. var RMR_SEARCH_TIMEOUT = 500;
  3581. var RMR_MAX_POLLS = 10;
  3582. // JavaScript references to the channel objects used by RMR.
  3583. // Gadgets will have but a single channel under
  3584. // rmr_channels['..'] while containers will have a channel
  3585. // per gadget stored under the gadget's ID.
  3586. var rmr_channels = {};
  3587. var process;
  3588. var ready;
  3589. /**
  3590. * Append an RMR relay frame to the document. This allows the receiver
  3591. * to start receiving messages.
  3592. *
  3593. * @param {Node} channelFrame Relay frame to add to the DOM body.
  3594. * @param {string} relayUri Base URI for the frame.
  3595. * @param {string} data to pass along to the frame.
  3596. * @param {string=} opt_frameId ID of frame for which relay is being appended (optional).
  3597. */
  3598. function appendRmrFrame(channelFrame, relayUri, data, opt_frameId) {
  3599. var appendFn = function() {
  3600. // Append the iframe.
  3601. document.body.appendChild(channelFrame);
  3602. // Set the src of the iframe to 'about:blank' first and then set it
  3603. // to the relay URI. This prevents the iframe from maintaining a src
  3604. // to the 'old' relay URI if the page is returned to from another.
  3605. // In other words, this fixes the bfcache issue that causes the iframe's
  3606. // src property to not be updated despite us assigning it a new value here.
  3607. channelFrame.src = 'about:blank';
  3608. if (opt_frameId) {
  3609. // Process the initial sent payload (typically sent by container to
  3610. // child/gadget) only when the relay frame has finished loading. We
  3611. // do this to ensure that, in processRmrData(...), the ACK sent due
  3612. // to processing can actually be sent. Before this time, the frame's
  3613. // contentWindow is null, making it impossible to do so.
  3614. channelFrame.onload = function() {
  3615. processRmrData(opt_frameId);
  3616. };
  3617. }
  3618. channelFrame.src = relayUri + '#' + data;
  3619. };
  3620. if (document.body) {
  3621. appendFn();
  3622. } else {
  3623. // Common gadget case: attaching header during in-gadget handshake,
  3624. // when we may still be in script in head. Attach onload.
  3625. OpenAjax.gadgets.util.registerOnLoadHandler(function() { appendFn(); });
  3626. }
  3627. }
  3628. /**
  3629. * Sets up the RMR transport frame for the given frameId. For gadgets
  3630. * calling containers, the frameId should be '..'.
  3631. *
  3632. * @param {string} frameId The ID of the frame.
  3633. */
  3634. function setupRmr(frameId) {
  3635. if (typeof rmr_channels[frameId] === "object") {
  3636. // Sanity check. Already done.
  3637. return;
  3638. }
  3639. var channelFrame = document.createElement('iframe');
  3640. var frameStyle = channelFrame.style;
  3641. frameStyle.position = 'absolute';
  3642. frameStyle.top = '0px';
  3643. frameStyle.border = '0';
  3644. frameStyle.opacity = '0';
  3645. // The width here is important as RMR
  3646. // makes use of the resize handler for the frame.
  3647. // Do not modify unless you test thoroughly!
  3648. frameStyle.width = '10px';
  3649. frameStyle.height = '1px';
  3650. channelFrame.id = 'rmrtransport-' + frameId;
  3651. channelFrame.name = channelFrame.id;
  3652. // Use the explicitly set relay, if one exists. Otherwise,
  3653. // Construct one using the parent parameter plus robots.txt
  3654. // as a synthetic relay. This works since browsers using RMR
  3655. // treat 404s as legitimate for the purposes of cross domain
  3656. // communication.
  3657. var relayUri = OpenAjax.gadgets.rpc.getRelayUrl(frameId);
  3658. if (!relayUri) {
  3659. relayUri =
  3660. OpenAjax.gadgets.rpc.getOrigin(OpenAjax.gadgets.util.getUrlParameters()["parent"]) +
  3661. '/robots.txt';
  3662. }
  3663. rmr_channels[frameId] = {
  3664. frame: channelFrame,
  3665. receiveWindow: null,
  3666. relayUri: relayUri,
  3667. searchCounter : 0,
  3668. width: 10,
  3669. // Waiting means "waiting for acknowledgement to be received."
  3670. // Acknowledgement always comes as a special ACK
  3671. // message having been received. This message is received
  3672. // during handshake in different ways by the container and
  3673. // gadget, and by normal RMR message passing once the handshake
  3674. // is complete.
  3675. waiting: true,
  3676. queue: [],
  3677. // Number of non-ACK messages that have been sent to the recipient
  3678. // and have been acknowledged.
  3679. sendId: 0,
  3680. // Number of messages received and processed from the sender.
  3681. // This is the number that accompanies every ACK to tell the
  3682. // sender to clear its queue.
  3683. recvId: 0
  3684. };
  3685. if (frameId !== '..') {
  3686. // Container always appends a relay to the gadget, before
  3687. // the gadget appends its own relay back to container. The
  3688. // gadget, in the meantime, refuses to attach the container
  3689. // relay until it finds this one. Thus, the container knows
  3690. // for certain that gadget to container communication is set
  3691. // up by the time it finds its own relay. In addition to
  3692. // establishing a reliable handshake protocol, this also
  3693. // makes it possible for the gadget to send an initial batch
  3694. // of messages to the container ASAP.
  3695. appendRmrFrame(channelFrame, relayUri, getRmrData(frameId));
  3696. }
  3697. // Start searching for our own frame on the other page.
  3698. conductRmrSearch(frameId);
  3699. }
  3700. /**
  3701. * Searches for a relay frame, created by the sender referenced by
  3702. * frameId, with which this context receives messages. Once
  3703. * found with proper permissions, attaches a resize handler which
  3704. * signals messages to be sent.
  3705. *
  3706. * @param {string} frameId Frame ID of the prospective sender.
  3707. */
  3708. function conductRmrSearch(frameId) {
  3709. var channelWindow = null;
  3710. // Increment the search counter.
  3711. rmr_channels[frameId].searchCounter++;
  3712. try {
  3713. var targetWin = OpenAjax.gadgets.rpc._getTargetWin(frameId);
  3714. if (frameId === '..') {
  3715. // We are a gadget.
  3716. channelWindow = targetWin.frames['rmrtransport-' + OpenAjax.gadgets.rpc.RPC_ID];
  3717. } else {
  3718. // We are a container.
  3719. channelWindow = targetWin.frames['rmrtransport-..'];
  3720. }
  3721. } catch (e) {
  3722. // Just in case; may happen when relay is set to about:blank or unset.
  3723. // Catching exceptions here ensures that the timeout to continue the
  3724. // search below continues to work.
  3725. }
  3726. var status = false;
  3727. if (channelWindow) {
  3728. // We have a valid reference to "our" RMR transport frame.
  3729. // Register the proper event handlers.
  3730. status = registerRmrChannel(frameId, channelWindow);
  3731. }
  3732. if (!status) {
  3733. // Not found yet. Continue searching, but only if the counter
  3734. // has not reached the threshold.
  3735. if (rmr_channels[frameId].searchCounter > RMR_MAX_POLLS) {
  3736. // If we reach this point, then RMR has failed and we
  3737. // fall back to IFPC.
  3738. return;
  3739. }
  3740. window.setTimeout(function() {
  3741. conductRmrSearch(frameId);
  3742. }, RMR_SEARCH_TIMEOUT);
  3743. }
  3744. }
  3745. /**
  3746. * Attempts to conduct an RPC call to the specified
  3747. * target with the specified data via the RMR
  3748. * method. If this method fails, the system attempts again
  3749. * using the known default of IFPC.
  3750. *
  3751. * @param {string} targetId Module Id of the RPC service provider.
  3752. * @param {string} serviceName Name of the service to call.
  3753. * @param {string} from Module Id of the calling provider.
  3754. * @param {Object} rpc The RPC data for this call.
  3755. */
  3756. function callRmr(targetId, serviceName, from, rpc) {
  3757. var handler = null;
  3758. if (from !== '..') {
  3759. // Call from gadget to the container.
  3760. handler = rmr_channels['..'];
  3761. } else {
  3762. // Call from container to the gadget.
  3763. handler = rmr_channels[targetId];
  3764. }
  3765. if (handler) {
  3766. // Queue the current message if not ACK.
  3767. // ACK is always sent through getRmrData(...).
  3768. if (serviceName !== OpenAjax.gadgets.rpc.ACK) {
  3769. handler.queue.push(rpc);
  3770. }
  3771. if (handler.waiting ||
  3772. (handler.queue.length === 0 &&
  3773. !(serviceName === OpenAjax.gadgets.rpc.ACK && rpc && rpc.ackAlone === true))) {
  3774. // If we are awaiting a response from any previously-sent messages,
  3775. // or if we don't have anything new to send, just return.
  3776. // Note that we don't short-return if we're ACKing just-received
  3777. // messages.
  3778. return true;
  3779. }
  3780. if (handler.queue.length > 0) {
  3781. handler.waiting = true;
  3782. }
  3783. var url = handler.relayUri + "#" + getRmrData(targetId);
  3784. try {
  3785. // Update the URL with the message.
  3786. handler.frame.contentWindow.location = url;
  3787. // Resize the frame.
  3788. var newWidth = handler.width == 10 ? 20 : 10;
  3789. handler.frame.style.width = newWidth + 'px';
  3790. handler.width = newWidth;
  3791. // Done!
  3792. } catch (e) {
  3793. // Something about location-setting or resizing failed.
  3794. // This should never happen, but if it does, fall back to
  3795. // the default transport.
  3796. return false;
  3797. }
  3798. }
  3799. return true;
  3800. }
  3801. /**
  3802. * Returns as a string the data to be appended to an RMR relay frame,
  3803. * constructed from the current request queue plus an ACK message indicating
  3804. * the currently latest-processed message ID.
  3805. *
  3806. * @param {string} toFrameId Frame whose sendable queued data to retrieve.
  3807. */
  3808. function getRmrData(toFrameId) {
  3809. var channel = rmr_channels[toFrameId];
  3810. var rmrData = {id: channel.sendId};
  3811. if (channel) {
  3812. rmrData.d = Array.prototype.slice.call(channel.queue, 0);
  3813. rmrData.d.push({s:OpenAjax.gadgets.rpc.ACK, id:channel.recvId});
  3814. }
  3815. return OpenAjax.gadgets.json.stringify(rmrData);
  3816. }
  3817. /**
  3818. * Retrieve data from the channel keyed by the given frameId,
  3819. * processing it as a batch. All processed data is assumed to have been
  3820. * generated by getRmrData(...), pairing that method with this.
  3821. *
  3822. * @param {string} fromFrameId Frame from which data is being retrieved.
  3823. */
  3824. function processRmrData(fromFrameId) {
  3825. var channel = rmr_channels[fromFrameId];
  3826. var data = channel.receiveWindow.location.hash.substring(1);
  3827. // Decode the RPC object array.
  3828. var rpcObj = OpenAjax.gadgets.json.parse(decodeURIComponent(data)) || {};
  3829. var rpcArray = rpcObj.d || [];
  3830. var nonAckReceived = false;
  3831. var noLongerWaiting = false;
  3832. var numBypassed = 0;
  3833. var numToBypass = (channel.recvId - rpcObj.id);
  3834. for (var i = 0; i < rpcArray.length; ++i) {
  3835. var rpc = rpcArray[i];
  3836. // If we receive an ACK message, then mark the current
  3837. // handler as no longer waiting and send out the next
  3838. // queued message.
  3839. if (rpc.s === OpenAjax.gadgets.rpc.ACK) {
  3840. // ACK received - whether this came from a handshake or
  3841. // an active call, in either case it indicates readiness to
  3842. // send messages to the from frame.
  3843. ready(fromFrameId, true);
  3844. if (channel.waiting) {
  3845. noLongerWaiting = true;
  3846. }
  3847. channel.waiting = false;
  3848. var newlyAcked = Math.max(0, rpc.id - channel.sendId);
  3849. channel.queue.splice(0, newlyAcked);
  3850. channel.sendId = Math.max(channel.sendId, rpc.id || 0);
  3851. continue;
  3852. }
  3853. // If we get here, we've received > 0 non-ACK messages to
  3854. // process. Indicate this bit for later.
  3855. nonAckReceived = true;
  3856. // Bypass any messages already received.
  3857. if (++numBypassed <= numToBypass) {
  3858. continue;
  3859. }
  3860. ++channel.recvId;
  3861. process(rpc); // actually dispatch the message
  3862. }
  3863. // Send an ACK indicating that we got/processed the message(s).
  3864. // Do so if we've received a message to process or if we were waiting
  3865. // before but a received ACK has cleared our waiting bit, and we have
  3866. // more messages to send. Performing this operation causes additional
  3867. // messages to be sent.
  3868. if (nonAckReceived ||
  3869. (noLongerWaiting && channel.queue.length > 0)) {
  3870. var from = (fromFrameId === '..') ? OpenAjax.gadgets.rpc.RPC_ID : '..';
  3871. callRmr(fromFrameId, OpenAjax.gadgets.rpc.ACK, from, {ackAlone: nonAckReceived});
  3872. }
  3873. }
  3874. /**
  3875. * Registers the RMR channel handler for the given frameId and associated
  3876. * channel window.
  3877. *
  3878. * @param {string} frameId The ID of the frame for which this channel is being
  3879. * registered.
  3880. * @param {Object} channelWindow The window of the receive frame for this
  3881. * channel, if any.
  3882. *
  3883. * @return {boolean} True if the frame was setup successfully, false
  3884. * otherwise.
  3885. */
  3886. function registerRmrChannel(frameId, channelWindow) {
  3887. var channel = rmr_channels[frameId];
  3888. // Verify that the channel is ready for receiving.
  3889. try {
  3890. var canAccess = false;
  3891. // Check to see if the document is in the window. For Chrome, this
  3892. // will return 'false' if the channelWindow is inaccessible by this
  3893. // piece of JavaScript code, meaning that the URL of the channelWindow's
  3894. // parent iframe has not yet changed from 'about:blank'. We do this
  3895. // check this way because any true *access* on the channelWindow object
  3896. // will raise a security exception, which, despite the try-catch, still
  3897. // gets reported to the debugger (it does not break execution, the try
  3898. // handles that problem, but it is still reported, which is bad form).
  3899. // This check always succeeds in Safari 3.1 regardless of the state of
  3900. // the window.
  3901. canAccess = 'document' in channelWindow;
  3902. if (!canAccess) {
  3903. return false;
  3904. }
  3905. // Check to see if the document is an object. For Safari 3.1, this will
  3906. // return undefined if the page is still inaccessible. Unfortunately, this
  3907. // *will* raise a security issue in the debugger.
  3908. // TODO Find a way around this problem.
  3909. canAccess = typeof channelWindow['document'] == 'object';
  3910. if (!canAccess) {
  3911. return false;
  3912. }
  3913. // Once we get here, we know we can access the document (and anything else)
  3914. // on the window object. Therefore, we check to see if the location is
  3915. // still about:blank (this takes care of the Safari 3.2 case).
  3916. var loc = channelWindow.location.href;
  3917. // Check if this is about:blank for Safari.
  3918. if (loc === 'about:blank') {
  3919. return false;
  3920. }
  3921. } catch (ex) {
  3922. // For some reason, the iframe still points to about:blank. We try
  3923. // again in a bit.
  3924. return false;
  3925. }
  3926. // Save a reference to the receive window.
  3927. channel.receiveWindow = channelWindow;
  3928. // Register the onresize handler.
  3929. function onresize() {
  3930. processRmrData(frameId);
  3931. }
  3932. if (typeof channelWindow.attachEvent === "undefined") {
  3933. channelWindow.onresize = onresize;
  3934. } else {
  3935. channelWindow.attachEvent("onresize", onresize);
  3936. }
  3937. if (frameId === '..') {
  3938. // Gadget to container. Signal to the container that the gadget
  3939. // is ready to receive messages by attaching the g -> c relay.
  3940. // As a nice optimization, pass along any gadget to container
  3941. // queued messages that have backed up since then. ACK is enqueued in
  3942. // getRmrData to ensure that the container's waiting flag is set to false
  3943. // (this happens in the below code run on the container side).
  3944. appendRmrFrame(channel.frame, channel.relayUri, getRmrData(frameId), frameId);
  3945. } else {
  3946. // Process messages that the gadget sent in its initial relay payload.
  3947. // We can do this immediately because the container has already appended
  3948. // and loaded a relay frame that can be used to ACK the messages the gadget
  3949. // sent. In the preceding if-block, however, the processRmrData(...) call
  3950. // must wait. That's because appendRmrFrame may not actually append the
  3951. // frame - in the context of a gadget, this code may be running in the
  3952. // head element, so it cannot be appended to body. As a result, the
  3953. // gadget cannot ACK the container for messages it received.
  3954. processRmrData(frameId);
  3955. }
  3956. return true;
  3957. }
  3958. return {
  3959. getCode: function() {
  3960. return 'rmr';
  3961. },
  3962. isParentVerifiable: function() {
  3963. return true;
  3964. },
  3965. init: function(processFn, readyFn) {
  3966. // No global setup.
  3967. process = processFn;
  3968. ready = readyFn;
  3969. return true;
  3970. },
  3971. setup: function(receiverId, token) {
  3972. try {
  3973. setupRmr(receiverId);
  3974. } catch (e) {
  3975. OpenAjax.gadgets.warn('Caught exception setting up RMR: ' + e);
  3976. return false;
  3977. }
  3978. return true;
  3979. },
  3980. call: function(targetId, from, rpc) {
  3981. return callRmr(targetId, rpc.s, from, rpc);
  3982. }
  3983. };
  3984. }();
  3985. } // !end of double-inclusion guard
  3986. /*
  3987. * Licensed to the Apache Software Foundation (ASF) under one
  3988. * or more contributor license agreements. See the NOTICE file
  3989. * distributed with this work for additional information
  3990. * regarding copyright ownership. The ASF licenses this file
  3991. * to you under the Apache License, Version 2.0 (the
  3992. * "License"); you may not use this file except in compliance
  3993. * with the License. You may obtain a copy of the License at
  3994. *
  3995. * http://www.apache.org/licenses/LICENSE-2.0
  3996. *
  3997. * Unless required by applicable law or agreed to in writing,
  3998. * software distributed under the License is distributed on an
  3999. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  4000. * KIND, either express or implied. See the License for the
  4001. * specific language governing permissions and limitations under the License.
  4002. */
  4003. OpenAjax.gadgets.rpctx = OpenAjax.gadgets.rpctx || {};
  4004. /**
  4005. * Transport for browsers that support native messaging (various implementations
  4006. * of the HTML5 postMessage method). Officially defined at
  4007. * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html.
  4008. *
  4009. * postMessage is a native implementation of XDC. A page registers that
  4010. * it would like to receive messages by listening the the "message" event
  4011. * on the window (document in DPM) object. In turn, another page can
  4012. * raise that event by calling window.postMessage (document.postMessage
  4013. * in DPM) with a string representing the message and a string
  4014. * indicating on which domain the receiving page must be to receive
  4015. * the message. The target page will then have its "message" event raised
  4016. * if the domain matches and can, in turn, check the origin of the message
  4017. * and process the data contained within.
  4018. *
  4019. * wpm: postMessage on the window object.
  4020. * - Internet Explorer 8+
  4021. * - Safari 4+
  4022. * - Chrome 2+
  4023. * - Webkit nightlies
  4024. * - Firefox 3+
  4025. * - Opera 9+
  4026. */
  4027. if (!OpenAjax.gadgets.rpctx.wpm) { // make lib resilient to double-inclusion
  4028. OpenAjax.gadgets.rpctx.wpm = function() {
  4029. var process, ready;
  4030. var postMessage;
  4031. var pmSync = false;
  4032. var pmEventDomain = false;
  4033. // Some browsers (IE, Opera) have an implementation of postMessage that is
  4034. // synchronous, although HTML5 specifies that it should be asynchronous. In
  4035. // order to make all browsers behave consistently, we run a small test to detect
  4036. // if postMessage is asynchronous or not. If not, we wrap calls to postMessage
  4037. // in a setTimeout with a timeout of 0.
  4038. // Also, Opera's "message" event does not have an "origin" property (at least,
  4039. // it doesn't in version 9.64; presumably, it will in version 10). If
  4040. // event.origin does not exist, use event.domain. The other difference is that
  4041. // while event.origin looks like <scheme>://<hostname>:<port>, event.domain
  4042. // consists only of <hostname>.
  4043. //
  4044. function testPostMessage() {
  4045. var hit = false;
  4046. function receiveMsg(event) {
  4047. if (event.data == "postmessage.test") {
  4048. hit = true;
  4049. if (typeof event.origin === "undefined") {
  4050. pmEventDomain = true;
  4051. }
  4052. }
  4053. }
  4054. OpenAjax.gadgets.util.attachBrowserEvent(window, "message", receiveMsg, false);
  4055. window.postMessage("postmessage.test", "*");
  4056. // if 'hit' is true here, then postMessage is synchronous
  4057. if (hit) {
  4058. pmSync = true;
  4059. }
  4060. OpenAjax.gadgets.util.removeBrowserEvent(window, "message", receiveMsg, false);
  4061. }
  4062. function onmessage(packet) {
  4063. var rpc = OpenAjax.gadgets.json.parse(packet.data);
  4064. if (!rpc || !rpc.f) {
  4065. return;
  4066. }
  4067. // for security, check origin against expected value
  4068. var origRelay = OpenAjax.gadgets.rpc.getRelayUrl(rpc.f) ||
  4069. OpenAjax.gadgets.util.getUrlParameters()["parent"];
  4070. var origin = OpenAjax.gadgets.rpc.getOrigin(origRelay);
  4071. if (!pmEventDomain ? packet.origin !== origin :
  4072. packet.domain !== /^.+:\/\/([^:]+).*/.exec( origin )[1]) {
  4073. return;
  4074. }
  4075. process(rpc);
  4076. }
  4077. return {
  4078. getCode: function() {
  4079. return 'wpm';
  4080. },
  4081. isParentVerifiable: function() {
  4082. return true;
  4083. },
  4084. init: function(processFn, readyFn) {
  4085. process = processFn;
  4086. ready = readyFn;
  4087. testPostMessage();
  4088. if (!pmSync) {
  4089. postMessage = function(win, msg, origin) {
  4090. win.postMessage(msg, origin);
  4091. };
  4092. } else {
  4093. postMessage = function(win, msg, origin) {
  4094. window.setTimeout( function() {
  4095. win.postMessage(msg, origin);
  4096. }, 0);
  4097. };
  4098. }
  4099. // Set up native postMessage handler.
  4100. OpenAjax.gadgets.util.attachBrowserEvent(window, 'message', onmessage, false);
  4101. ready('..', true); // Immediately ready to send to parent.
  4102. return true;
  4103. },
  4104. setup: function(receiverId, token, forcesecure) {
  4105. // If we're a gadget, send an ACK message to indicate to container
  4106. // that we're ready to receive messages.
  4107. if (receiverId === '..') {
  4108. if (forcesecure) {
  4109. OpenAjax.gadgets.rpc._createRelayIframe(token);
  4110. } else {
  4111. OpenAjax.gadgets.rpc.call(receiverId, OpenAjax.gadgets.rpc.ACK);
  4112. }
  4113. }
  4114. return true;
  4115. },
  4116. call: function(targetId, from, rpc) {
  4117. var targetWin = OpenAjax.gadgets.rpc._getTargetWin(targetId);
  4118. // targetOrigin = canonicalized relay URL
  4119. var origRelay = OpenAjax.gadgets.rpc.getRelayUrl(targetId) ||
  4120. OpenAjax.gadgets.util.getUrlParameters()["parent"];
  4121. var origin = OpenAjax.gadgets.rpc.getOrigin(origRelay);
  4122. if (origin) {
  4123. postMessage(targetWin, OpenAjax.gadgets.json.stringify(rpc), origin);
  4124. } else {
  4125. OpenAjax.gadgets.error("No relay set (used as window.postMessage targetOrigin)" +
  4126. ", cannot send cross-domain message");
  4127. }
  4128. return true;
  4129. },
  4130. relayOnload: function(receiverId, data) {
  4131. ready(receiverId, true);
  4132. }
  4133. };
  4134. }();
  4135. } // !end of double-inclusion guard
  4136. /*
  4137. * Licensed to the Apache Software Foundation (ASF) under one
  4138. * or more contributor license agreements. See the NOTICE file
  4139. * distributed with this work for additional information
  4140. * regarding copyright ownership. The ASF licenses this file
  4141. * to you under the Apache License, Version 2.0 (the
  4142. * "License"); you may not use this file except in compliance
  4143. * with the License. You may obtain a copy of the License at
  4144. *
  4145. * http://www.apache.org/licenses/LICENSE-2.0
  4146. *
  4147. * Unless required by applicable law or agreed to in writing,
  4148. * software distributed under the License is distributed on an
  4149. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  4150. * KIND, either express or implied. See the License for the
  4151. * specific language governing permissions and limitations under the License.
  4152. */
  4153. /**
  4154. * @fileoverview Remote procedure call library for gadget-to-container,
  4155. * container-to-gadget, and gadget-to-gadget (thru container) communication.
  4156. */
  4157. /**
  4158. * gadgets.rpc Transports
  4159. *
  4160. * All transports are stored in object gadgets.rpctx, and are provided
  4161. * to the core gadgets.rpc library by various build rules.
  4162. *
  4163. * Transports used by core gadgets.rpc code to actually pass messages.
  4164. * each transport implements the same interface exposing hooks that
  4165. * the core library calls at strategic points to set up and use
  4166. * the transport.
  4167. *
  4168. * The methods each transport must implement are:
  4169. * + getCode(): returns a string identifying the transport. For debugging.
  4170. * + isParentVerifiable(): indicates (via boolean) whether the method
  4171. * has the property that its relay URL verifies for certain the
  4172. * receiver's protocol://host:port.
  4173. * + init(processFn, readyFn): Performs any global initialization needed. Called
  4174. * before any other gadgets.rpc methods are invoked. processFn is
  4175. * the function in gadgets.rpc used to process an rpc packet. readyFn is
  4176. * a function that must be called when the transport is ready to send
  4177. * and receive messages bidirectionally. Returns
  4178. * true if successful, false otherwise.
  4179. * + setup(receiverId, token): Performs per-receiver initialization, if any.
  4180. * receiverId will be '..' for gadget-to-container. Returns true if
  4181. * successful, false otherwise.
  4182. * + call(targetId, from, rpc): Invoked to send an actual
  4183. * message to the given targetId, with the given serviceName, from
  4184. * the sender identified by 'from'. Payload is an rpc packet. Returns
  4185. * true if successful, false otherwise.
  4186. */
  4187. if (!OpenAjax.gadgets.rpc) { // make lib resilient to double-inclusion
  4188. /**
  4189. * @static
  4190. * @namespace Provides operations for making rpc calls.
  4191. * @name gadgets.rpc
  4192. */
  4193. OpenAjax.gadgets.rpc = function() {
  4194. /**
  4195. * @const
  4196. * @private
  4197. */
  4198. var CALLBACK_NAME = '__cb';
  4199. /**
  4200. * @const
  4201. * @private
  4202. */
  4203. var DEFAULT_NAME = '';
  4204. /** Exported constant, for use by transports only.
  4205. * @const
  4206. * @type {string}
  4207. * @member gadgets.rpc
  4208. */
  4209. var ACK = '__ack';
  4210. /**
  4211. * Timeout and number of attempts made to setup a transport receiver.
  4212. * @const
  4213. * @private
  4214. */
  4215. var SETUP_FRAME_TIMEOUT = 500;
  4216. /**
  4217. * @const
  4218. * @private
  4219. */
  4220. var SETUP_FRAME_MAX_TRIES = 10;
  4221. var services = {};
  4222. var relayUrl = {};
  4223. var useLegacyProtocol = {};
  4224. var authToken = {};
  4225. var callId = 0;
  4226. var callbacks = {};
  4227. var setup = {};
  4228. var sameDomain = {};
  4229. var params = {};
  4230. var receiverTx = {};
  4231. var earlyRpcQueue = {};
  4232. // isGadget =~ isChild for the purposes of rpc (used only in setup).
  4233. var isChild = (window.top !== window.self);
  4234. // Set the current rpc ID from window.name immediately, to prevent
  4235. // shadowing of window.name by a "var name" declaration, or similar.
  4236. var rpcId = window.name;
  4237. var securityCallback = function() {};
  4238. var LOAD_TIMEOUT = 0;
  4239. var FRAME_PHISH = 1;
  4240. var FORGED_MSG = 2;
  4241. // Fallback transport is simply a dummy impl that emits no errors
  4242. // and logs info on calls it receives, to avoid undesired side-effects
  4243. // from falling back to IFPC or some other transport.
  4244. var fallbackTransport = (function() {
  4245. function logFn(name) {
  4246. return function() {
  4247. OpenAjax.gadgets.log("gadgets.rpc." + name + "(" +
  4248. OpenAjax.gadgets.json.stringify(Array.prototype.slice.call(arguments)) +
  4249. "): call ignored. [caller: " + document.location +
  4250. ", isChild: " + isChild + "]");
  4251. };
  4252. }
  4253. return {
  4254. getCode: function() {
  4255. return "noop";
  4256. },
  4257. isParentVerifiable: function() {
  4258. return true; // Not really, but prevents transport assignment to IFPC.
  4259. },
  4260. init: logFn("init"),
  4261. setup: logFn("setup"),
  4262. call: logFn("call")
  4263. };
  4264. })();
  4265. // Load the authentication token for speaking to the container
  4266. // from the gadget's parameters, or default to '0' if not found.
  4267. if (OpenAjax.gadgets.util) {
  4268. params = OpenAjax.gadgets.util.getUrlParameters();
  4269. }
  4270. /**
  4271. * Return a transport representing the best available cross-domain
  4272. * message-passing mechanism available to the browser.
  4273. *
  4274. * <p>Transports are selected on a cascading basis determined by browser
  4275. * capability and other checks. The order of preference is:
  4276. * <ol>
  4277. * <li> wpm: Uses window.postMessage standard.
  4278. * <li> dpm: Uses document.postMessage, similar to wpm but pre-standard.
  4279. * <li> nix: Uses IE-specific browser hacks.
  4280. * <li> rmr: Signals message passing using relay file's onresize handler.
  4281. * <li> fe: Uses FF2-specific window.frameElement hack.
  4282. * <li> ifpc: Sends messages via active load of a relay file.
  4283. * </ol>
  4284. * <p>See each transport's commentary/documentation for details.
  4285. * @return {Object}
  4286. * @member gadgets.rpc
  4287. */
  4288. function getTransport() {
  4289. return typeof window.postMessage === 'function' ? OpenAjax.gadgets.rpctx.wpm :
  4290. typeof window.postMessage === 'object' ? OpenAjax.gadgets.rpctx.wpm :
  4291. window.ActiveXObject ? OpenAjax.gadgets.rpctx.nix :
  4292. navigator.userAgent.indexOf('WebKit') > 0 ? OpenAjax.gadgets.rpctx.rmr :
  4293. navigator.product === 'Gecko' ? OpenAjax.gadgets.rpctx.frameElement :
  4294. OpenAjax.gadgets.rpctx.ifpc;
  4295. }
  4296. /**
  4297. * Function passed to, and called by, a transport indicating it's ready to
  4298. * send and receive messages.
  4299. */
  4300. function transportReady(receiverId, readySuccess) {
  4301. var tx = transport;
  4302. if (!readySuccess) {
  4303. tx = fallbackTransport;
  4304. }
  4305. receiverTx[receiverId] = tx;
  4306. // If there are any early-queued messages, send them now directly through
  4307. // the needed transport.
  4308. var earlyQueue = earlyRpcQueue[receiverId] || [];
  4309. for (var i = 0; i < earlyQueue.length; ++i) {
  4310. var rpc = earlyQueue[i];
  4311. // There was no auth/rpc token set before, so set it now.
  4312. rpc.t = getAuthToken(receiverId);
  4313. tx.call(receiverId, rpc.f, rpc);
  4314. }
  4315. // Clear the queue so it won't be sent again.
  4316. earlyRpcQueue[receiverId] = [];
  4317. }
  4318. // Track when this main page is closed or navigated to a different location
  4319. // ("unload" event).
  4320. // NOTE: The use of the "unload" handler here and for the relay iframe
  4321. // prevents the use of the in-memory page cache in modern browsers.
  4322. // See: https://developer.mozilla.org/en/using_firefox_1.5_caching
  4323. // See: http://webkit.org/blog/516/webkit-page-cache-ii-the-unload-event/
  4324. var mainPageUnloading = false,
  4325. hookedUnload = false;
  4326. function hookMainPageUnload() {
  4327. if ( hookedUnload ) {
  4328. return;
  4329. }
  4330. function onunload() {
  4331. mainPageUnloading = true;
  4332. }
  4333. OpenAjax.gadgets.util.attachBrowserEvent(window, 'unload', onunload, false);
  4334. hookedUnload = true;
  4335. }
  4336. function relayOnload(targetId, sourceId, token, data, relayWindow) {
  4337. // Validate auth token.
  4338. if (!authToken[sourceId] || authToken[sourceId] !== token) {
  4339. OpenAjax.gadgets.error("Invalid auth token. " + authToken[sourceId] + " vs " + token);
  4340. securityCallback(sourceId, FORGED_MSG);
  4341. }
  4342. relayWindow.onunload = function() {
  4343. if (setup[sourceId] && !mainPageUnloading) {
  4344. securityCallback(sourceId, FRAME_PHISH);
  4345. OpenAjax.gadgets.rpc.removeReceiver(sourceId);
  4346. }
  4347. };
  4348. hookMainPageUnload();
  4349. data = OpenAjax.gadgets.json.parse(decodeURIComponent(data));
  4350. transport.relayOnload(sourceId, data);
  4351. }
  4352. /**
  4353. * Helper function to process an RPC request
  4354. * @param {Object} rpc RPC request object
  4355. * @private
  4356. */
  4357. function process(rpc) {
  4358. //
  4359. // RPC object contents:
  4360. // s: Service Name
  4361. // f: From
  4362. // c: The callback ID or 0 if none.
  4363. // a: The arguments for this RPC call.
  4364. // t: The authentication token.
  4365. //
  4366. if (rpc && typeof rpc.s === 'string' && typeof rpc.f === 'string' &&
  4367. rpc.a instanceof Array) {
  4368. // Validate auth token.
  4369. if (authToken[rpc.f]) {
  4370. // We don't do type coercion here because all entries in the authToken
  4371. // object are strings, as are all url params. See setupReceiver(...).
  4372. if (authToken[rpc.f] !== rpc.t) {
  4373. OpenAjax.gadgets.error("Invalid auth token. " + authToken[rpc.f] + " vs " + rpc.t);
  4374. securityCallback(rpc.f, FORGED_MSG);
  4375. }
  4376. }
  4377. if (rpc.s === ACK) {
  4378. // Acknowledgement API, used to indicate a receiver is ready.
  4379. window.setTimeout(function() { transportReady(rpc.f, true); }, 0);
  4380. return;
  4381. }
  4382. // If there is a callback for this service, attach a callback function
  4383. // to the rpc context object for asynchronous rpc services.
  4384. //
  4385. // Synchronous rpc request handlers should simply ignore it and return a
  4386. // value as usual.
  4387. // Asynchronous rpc request handlers, on the other hand, should pass its
  4388. // result to this callback function and not return a value on exit.
  4389. //
  4390. // For example, the following rpc handler passes the first parameter back
  4391. // to its rpc client with a one-second delay.
  4392. //
  4393. // function asyncRpcHandler(param) {
  4394. // var me = this;
  4395. // setTimeout(function() {
  4396. // me.callback(param);
  4397. // }, 1000);
  4398. // }
  4399. if (rpc.c) {
  4400. rpc.callback = function(result) {
  4401. OpenAjax.gadgets.rpc.call(rpc.f, CALLBACK_NAME, null, rpc.c, result);
  4402. };
  4403. }
  4404. // Call the requested RPC service.
  4405. var result = (services[rpc.s] ||
  4406. services[DEFAULT_NAME]).apply(rpc, rpc.a);
  4407. // If the rpc request handler returns a value, immediately pass it back
  4408. // to the callback. Otherwise, do nothing, assuming that the rpc handler
  4409. // will make an asynchronous call later.
  4410. if (rpc.c && typeof result !== 'undefined') {
  4411. OpenAjax.gadgets.rpc.call(rpc.f, CALLBACK_NAME, null, rpc.c, result);
  4412. }
  4413. }
  4414. }
  4415. /**
  4416. * Helper method returning a canonicalized protocol://host[:port] for
  4417. * a given input URL, provided as a string. Used to compute convenient
  4418. * relay URLs and to determine whether a call is coming from the same
  4419. * domain as its receiver (bypassing the try/catch capability detection
  4420. * flow, thereby obviating Firebug and other tools reporting an exception).
  4421. *
  4422. * @param {string} url Base URL to canonicalize.
  4423. * @memberOf gadgets.rpc
  4424. */
  4425. function getOrigin(url) {
  4426. if (!url) {
  4427. return "";
  4428. }
  4429. url = url.toLowerCase();
  4430. if (url.indexOf("//") == 0) {
  4431. url = window.location.protocol + url;
  4432. }
  4433. if (url.indexOf("://") == -1) {
  4434. // Assumed to be schemaless. Default to current protocol.
  4435. url = window.location.protocol + "//" + url;
  4436. }
  4437. // At this point we guarantee that "://" is in the URL and defines
  4438. // current protocol. Skip past this to search for host:port.
  4439. var host = url.substring(url.indexOf("://") + 3);
  4440. // Find the first slash char, delimiting the host:port.
  4441. var slashPos = host.indexOf("/");
  4442. if (slashPos != -1) {
  4443. host = host.substring(0, slashPos);
  4444. }
  4445. var protocol = url.substring(0, url.indexOf("://"));
  4446. // Use port only if it's not default for the protocol.
  4447. var portStr = "";
  4448. var portPos = host.indexOf(":");
  4449. if (portPos != -1) {
  4450. var port = host.substring(portPos + 1);
  4451. host = host.substring(0, portPos);
  4452. if ((protocol === "http" && port !== "80") ||
  4453. (protocol === "https" && port !== "443")) {
  4454. portStr = ":" + port;
  4455. }
  4456. }
  4457. // Return <protocol>://<host>[<port>]
  4458. return protocol + "://" + host + portStr;
  4459. }
  4460. function getTargetWin(id) {
  4461. if (typeof id === "undefined" ||
  4462. id === "..") {
  4463. return window.parent;
  4464. }
  4465. // Cast to a String to avoid an index lookup.
  4466. id = String(id);
  4467. // Try window.frames first
  4468. var target = window.frames[id];
  4469. if (target) {
  4470. return target;
  4471. }
  4472. // Fall back to getElementById()
  4473. target = document.getElementById(id);
  4474. if (target && target.contentWindow) {
  4475. return target.contentWindow;
  4476. }
  4477. return null;
  4478. }
  4479. // Pick the most efficient RPC relay mechanism.
  4480. var transport = getTransport();
  4481. // Create the Default RPC handler.
  4482. services[DEFAULT_NAME] = function() {
  4483. OpenAjax.gadgets.warn('Unknown RPC service: ' + this.s);
  4484. };
  4485. // Create a Special RPC handler for callbacks.
  4486. services[CALLBACK_NAME] = function(callbackId, result) {
  4487. var callback = callbacks[callbackId];
  4488. if (callback) {
  4489. delete callbacks[callbackId];
  4490. callback(result);
  4491. }
  4492. };
  4493. /**
  4494. * Conducts any frame-specific work necessary to setup
  4495. * the channel type chosen. This method is called when
  4496. * the container page first registers the gadget in the
  4497. * RPC mechanism. Gadgets, in turn, will complete the setup
  4498. * of the channel once they send their first messages.
  4499. */
  4500. function setupFrame(frameId, token, forcesecure) {
  4501. if (setup[frameId] === true) {
  4502. return;
  4503. }
  4504. if (typeof setup[frameId] === 'undefined') {
  4505. setup[frameId] = 0;
  4506. }
  4507. var tgtFrame = document.getElementById(frameId);
  4508. if (frameId === '..' || tgtFrame != null) {
  4509. if (transport.setup(frameId, token, forcesecure) === true) {
  4510. setup[frameId] = true;
  4511. return;
  4512. }
  4513. }
  4514. if (setup[frameId] !== true && setup[frameId]++ < SETUP_FRAME_MAX_TRIES) {
  4515. // Try again in a bit, assuming that frame will soon exist.
  4516. window.setTimeout(function() { setupFrame(frameId, token, forcesecure); },
  4517. SETUP_FRAME_TIMEOUT);
  4518. } else {
  4519. // Fail: fall back for this gadget.
  4520. receiverTx[frameId] = fallbackTransport;
  4521. setup[frameId] = true;
  4522. }
  4523. }
  4524. /**
  4525. * Attempts to make an rpc by calling the target's receive method directly.
  4526. * This works when gadgets are rendered on the same domain as their container,
  4527. * a potentially useful optimization for trusted content which keeps
  4528. * RPC behind a consistent interface.
  4529. *
  4530. * @param {string} target Module id of the rpc service provider
  4531. * @param {Object} rpc RPC data
  4532. * @return {boolean}
  4533. */
  4534. function callSameDomain(target, rpc) {
  4535. if (typeof sameDomain[target] === 'undefined') {
  4536. // Seed with a negative, typed value to avoid
  4537. // hitting this code path repeatedly.
  4538. sameDomain[target] = false;
  4539. var targetRelay = OpenAjax.gadgets.rpc.getRelayUrl(target);
  4540. if (getOrigin(targetRelay) !== getOrigin(window.location.href)) {
  4541. // Not worth trying -- avoid the error and just return.
  4542. return false;
  4543. }
  4544. var targetEl = getTargetWin(target);
  4545. try {
  4546. // If this succeeds, then same-domain policy applied
  4547. sameDomain[target] = targetEl.OpenAjax.gadgets.rpc.receiveSameDomain;
  4548. } catch (e) {
  4549. // Shouldn't happen due to origin check. Caught to emit
  4550. // more meaningful error to the caller.
  4551. OpenAjax.gadgets.error("Same domain call failed: parent= incorrectly set.");
  4552. }
  4553. }
  4554. if (typeof sameDomain[target] === 'function') {
  4555. // Call target's receive method
  4556. sameDomain[target](rpc);
  4557. return true;
  4558. }
  4559. return false;
  4560. }
  4561. /**
  4562. * Sets the relay URL of a target frame.
  4563. * @param {string} targetId Name of the target frame.
  4564. * @param {string} url Full relay URL of the target frame.
  4565. * @param {boolean=} opt_useLegacy True if this relay needs the legacy IFPC
  4566. * wire format.
  4567. *
  4568. * @member gadgets.rpc
  4569. * @deprecated
  4570. */
  4571. function setRelayUrl(targetId, url, opt_useLegacy) {
  4572. // make URL absolute if necessary
  4573. if (!/http(s)?:\/\/.+/.test(url)) {
  4574. if (url.indexOf("//") == 0) {
  4575. url = window.location.protocol + url;
  4576. } else if (url.charAt(0) == '/') {
  4577. url = window.location.protocol + "//" + window.location.host + url;
  4578. } else if (url.indexOf("://") == -1) {
  4579. // Assumed to be schemaless. Default to current protocol.
  4580. url = window.location.protocol + "//" + url;
  4581. }
  4582. }
  4583. relayUrl[targetId] = url;
  4584. useLegacyProtocol[targetId] = !!opt_useLegacy;
  4585. }
  4586. /**
  4587. * Helper method to retrieve the authToken for a given gadget.
  4588. * Not to be used directly.
  4589. * @member gadgets.rpc
  4590. * @return {string}
  4591. */
  4592. function getAuthToken(targetId) {
  4593. return authToken[targetId];
  4594. }
  4595. /**
  4596. * Sets the auth token of a target frame.
  4597. * @param {string} targetId Name of the target frame.
  4598. * @param {string} token The authentication token to use for all
  4599. * calls to or from this target id.
  4600. *
  4601. * @member gadgets.rpc
  4602. * @deprecated
  4603. */
  4604. function setAuthToken(targetId, token, forcesecure) {
  4605. token = token || "";
  4606. // Coerce token to a String, ensuring that all authToken values
  4607. // are strings. This ensures correct comparison with URL params
  4608. // in the process(rpc) method.
  4609. authToken[targetId] = String(token);
  4610. setupFrame(targetId, token, forcesecure);
  4611. }
  4612. function setupContainerGadgetContext(rpctoken, opt_forcesecure) {
  4613. /**
  4614. * Initializes gadget to container RPC params from the provided configuration.
  4615. */
  4616. function init(config) {
  4617. var configRpc = config ? config.rpc : {};
  4618. var parentRelayUrl = configRpc.parentRelayUrl;
  4619. // Allow for wild card parent relay files as long as it's from a
  4620. // white listed domain. This is enforced by the rendering servlet.
  4621. if (parentRelayUrl.substring(0, 7) !== 'http://' &&
  4622. parentRelayUrl.substring(0, 8) !== 'https://' &&
  4623. parentRelayUrl.substring(0, 2) !== '//') {
  4624. // Relative path: we append to the parent.
  4625. // We're relying on the server validating the parent parameter in this
  4626. // case. Because of this, parent may only be passed in the query, not fragment.
  4627. if (typeof params.parent === "string" && params.parent !== "") {
  4628. // Otherwise, relayUrl['..'] will be null, signaling transport
  4629. // code to ignore rpc calls since they cannot work without a
  4630. // relay URL with host qualification.
  4631. if (parentRelayUrl.substring(0, 1) !== '/') {
  4632. // Path-relative. Trust that parent is passed in appropriately.
  4633. var lastSlash = params.parent.lastIndexOf('/');
  4634. parentRelayUrl = params.parent.substring(0, lastSlash + 1) + parentRelayUrl;
  4635. } else {
  4636. // Host-relative.
  4637. parentRelayUrl = getOrigin(params.parent) + parentRelayUrl;
  4638. }
  4639. }
  4640. }
  4641. var useLegacy = !!configRpc.useLegacyProtocol;
  4642. setRelayUrl('..', parentRelayUrl, useLegacy);
  4643. if (useLegacy) {
  4644. transport = OpenAjax.gadgets.rpctx.ifpc;
  4645. transport.init(process, transportReady);
  4646. }
  4647. // Sets the auth token and signals transport to setup connection to container.
  4648. var forceSecure = opt_forcesecure || params.forcesecure || false;
  4649. setAuthToken('..', rpctoken, forceSecure);
  4650. }
  4651. var requiredConfig = {
  4652. parentRelayUrl : OpenAjax.gadgets.config.NonEmptyStringValidator
  4653. };
  4654. OpenAjax.gadgets.config.register("rpc", requiredConfig, init);
  4655. }
  4656. function setupContainerGenericIframe(rpctoken, opt_parent, opt_forcesecure) {
  4657. // Generic child IFRAME setting up connection w/ its container.
  4658. // Use the opt_parent param if provided, or the "parent" query param
  4659. // if found -- otherwise, do nothing since this call might be initiated
  4660. // automatically at first, then actively later in IFRAME code.
  4661. var forcesecure = opt_forcesecure || params.forcesecure || false;
  4662. var parent = opt_parent || params.parent;
  4663. if (parent) {
  4664. setRelayUrl('..', parent);
  4665. setAuthToken('..', rpctoken, forcesecure);
  4666. }
  4667. }
  4668. function setupChildIframe(gadgetId, opt_frameurl, opt_authtoken, opt_forcesecure) {
  4669. if (!OpenAjax.gadgets.util) {
  4670. return;
  4671. }
  4672. var childIframe = document.getElementById(gadgetId);
  4673. if (!childIframe) {
  4674. throw new Error("Cannot set up gadgets.rpc receiver with ID: " + gadgetId +
  4675. ", element not found.");
  4676. }
  4677. // The "relay URL" can either be explicitly specified or is set as
  4678. // the child IFRAME URL verbatim.
  4679. var relayUrl = opt_frameurl || childIframe.src;
  4680. setRelayUrl(gadgetId, relayUrl);
  4681. // The auth token is parsed from child params (rpctoken) or overridden.
  4682. var childParams = OpenAjax.gadgets.util.getUrlParameters(childIframe.src);
  4683. var rpctoken = opt_authtoken || childParams.rpctoken;
  4684. var forcesecure = opt_forcesecure || childParams.forcesecure;
  4685. setAuthToken(gadgetId, rpctoken, forcesecure);
  4686. }
  4687. /**
  4688. * Sets up the gadgets.rpc library to communicate with the receiver.
  4689. * <p>This method replaces setRelayUrl(...) and setAuthToken(...)
  4690. *
  4691. * <p>Simplified instructions - highly recommended:
  4692. * <ol>
  4693. * <li> Generate &lt;iframe id="&lt;ID&gt;" src="...#parent=&lt;PARENTURL&gt;&rpctoken=&lt;RANDOM&gt;"/&gt;
  4694. * and add to DOM.
  4695. * <li> Call gadgets.rpc.setupReceiver("&lt;ID>");
  4696. * <p>All parent/child communication initializes automatically from here.
  4697. * Naturally, both sides need to include the library.
  4698. * </ol>
  4699. *
  4700. * <p>Detailed container/parent instructions:
  4701. * <ol>
  4702. * <li> Create the target IFRAME (eg. gadget) with a given &lt;ID> and params
  4703. * rpctoken=<token> (eg. #rpctoken=1234), which is a random/unguessbable
  4704. * string, and parent=&lt;url>, where &lt;url> is the URL of the container.
  4705. * <li> Append IFRAME to the document.
  4706. * <li> Call gadgets.rpc.setupReceiver(&lt;ID>)
  4707. * <p>[Optional]. Strictly speaking, you may omit rpctoken and parent. This
  4708. * practice earns little but is occasionally useful for testing.
  4709. * If you omit parent, you MUST pass your container URL as the 2nd
  4710. * parameter to this method.
  4711. * </ol>
  4712. *
  4713. * <p>Detailed gadget/child IFRAME instructions:
  4714. * <ol>
  4715. * <li> If your container/parent passed parent and rpctoken params (query string
  4716. * or fragment are both OK), you needn't do anything. The library will self-
  4717. * initialize.
  4718. * <li> If "parent" is omitted, you MUST call this method with targetId '..'
  4719. * and the second param set to the parent URL.
  4720. * <li> If "rpctoken" is omitted, but the container set an authToken manually
  4721. * for this frame, you MUST pass that ID (however acquired) as the 2nd param
  4722. * to this method.
  4723. * </ol>
  4724. *
  4725. * @member gadgets.rpc
  4726. * @param {string} targetId
  4727. * @param {string=} opt_receiverurl
  4728. * @param {string=} opt_authtoken
  4729. * @param {boolean=} opt_forcesecure
  4730. */
  4731. function setupReceiver(targetId, opt_receiverurl, opt_authtoken, opt_forcesecure) {
  4732. if (targetId === '..') {
  4733. // Gadget/IFRAME to container.
  4734. var rpctoken = opt_authtoken || params.rpctoken || params.ifpctok || "";
  4735. if (window['__isgadget'] === true) {
  4736. setupContainerGadgetContext(rpctoken, opt_forcesecure);
  4737. } else {
  4738. setupContainerGenericIframe(rpctoken, opt_receiverurl, opt_forcesecure);
  4739. }
  4740. } else {
  4741. // Container to child.
  4742. setupChildIframe(targetId, opt_receiverurl, opt_authtoken, opt_forcesecure);
  4743. }
  4744. }
  4745. return /** @scope gadgets.rpc */ {
  4746. config: function(config) {
  4747. if (typeof config.securityCallback === 'function') {
  4748. securityCallback = config.securityCallback;
  4749. }
  4750. },
  4751. /**
  4752. * Registers an RPC service.
  4753. * @param {string} serviceName Service name to register.
  4754. * @param {function(Object,Object)} handler Service handler.
  4755. *
  4756. * @member gadgets.rpc
  4757. */
  4758. register: function(serviceName, handler) {
  4759. if (serviceName === CALLBACK_NAME || serviceName === ACK) {
  4760. throw new Error("Cannot overwrite callback/ack service");
  4761. }
  4762. if (serviceName === DEFAULT_NAME) {
  4763. throw new Error("Cannot overwrite default service:"
  4764. + " use registerDefault");
  4765. }
  4766. services[serviceName] = handler;
  4767. },
  4768. /**
  4769. * Unregisters an RPC service.
  4770. * @param {string} serviceName Service name to unregister.
  4771. *
  4772. * @member gadgets.rpc
  4773. */
  4774. unregister: function(serviceName) {
  4775. if (serviceName === CALLBACK_NAME || serviceName === ACK) {
  4776. throw new Error("Cannot delete callback/ack service");
  4777. }
  4778. if (serviceName === DEFAULT_NAME) {
  4779. throw new Error("Cannot delete default service:"
  4780. + " use unregisterDefault");
  4781. }
  4782. delete services[serviceName];
  4783. },
  4784. /**
  4785. * Registers a default service handler to processes all unknown
  4786. * RPC calls which raise an exception by default.
  4787. * @param {function(Object,Object)} handler Service handler.
  4788. *
  4789. * @member gadgets.rpc
  4790. */
  4791. registerDefault: function(handler) {
  4792. services[DEFAULT_NAME] = handler;
  4793. },
  4794. /**
  4795. * Unregisters the default service handler. Future unknown RPC
  4796. * calls will fail silently.
  4797. *
  4798. * @member gadgets.rpc
  4799. */
  4800. unregisterDefault: function() {
  4801. delete services[DEFAULT_NAME];
  4802. },
  4803. /**
  4804. * Forces all subsequent calls to be made by a transport
  4805. * method that allows the caller to verify the message receiver
  4806. * (by way of the parent parameter, through getRelayUrl(...)).
  4807. * At present this means IFPC or WPM.
  4808. * @member gadgets.rpc
  4809. */
  4810. forceParentVerifiable: function() {
  4811. if (!transport.isParentVerifiable()) {
  4812. transport = OpenAjax.gadgets.rpctx.ifpc;
  4813. }
  4814. },
  4815. /**
  4816. * Calls an RPC service.
  4817. * @param {string} targetId Module Id of the RPC service provider.
  4818. * Empty if calling the parent container.
  4819. * @param {string} serviceName Service name to call.
  4820. * @param {function()|null} callback Callback function (if any) to process
  4821. * the return value of the RPC request.
  4822. * @param {*} var_args Parameters for the RPC request.
  4823. *
  4824. * @member gadgets.rpc
  4825. */
  4826. call: function(targetId, serviceName, callback, var_args) {
  4827. targetId = targetId || '..';
  4828. // Default to the container calling.
  4829. var from = '..';
  4830. if (targetId === '..') {
  4831. from = rpcId;
  4832. }
  4833. ++callId;
  4834. if (callback) {
  4835. callbacks[callId] = callback;
  4836. }
  4837. var rpc = {
  4838. s: serviceName,
  4839. f: from,
  4840. c: callback ? callId : 0,
  4841. a: Array.prototype.slice.call(arguments, 3),
  4842. t: authToken[targetId],
  4843. l: useLegacyProtocol[targetId]
  4844. };
  4845. if (targetId !== '..' && !document.getElementById(targetId)) {
  4846. // The target has been removed from the DOM. Don't even try.
  4847. OpenAjax.gadgets.log("WARNING: attempted send to nonexistent frame: " + targetId);
  4848. return;
  4849. }
  4850. // If target is on the same domain, call method directly
  4851. if (callSameDomain(targetId, rpc)) {
  4852. return;
  4853. }
  4854. // Attempt to make call via a cross-domain transport.
  4855. // Retrieve the transport for the given target - if one
  4856. // target is misconfigured, it won't affect the others.
  4857. var channel = receiverTx[targetId];
  4858. if (!channel) {
  4859. // Not set up yet. Enqueue the rpc for such time as it is.
  4860. if (!earlyRpcQueue[targetId]) {
  4861. earlyRpcQueue[targetId] = [ rpc ];
  4862. } else {
  4863. earlyRpcQueue[targetId].push(rpc);
  4864. }
  4865. return;
  4866. }
  4867. // If we are told to use the legacy format, then we must
  4868. // default to IFPC.
  4869. if (useLegacyProtocol[targetId]) {
  4870. channel = OpenAjax.gadgets.rpctx.ifpc;
  4871. }
  4872. if (channel.call(targetId, from, rpc) === false) {
  4873. // Fall back to IFPC. This behavior may be removed as IFPC is as well.
  4874. receiverTx[targetId] = fallbackTransport;
  4875. transport.call(targetId, from, rpc);
  4876. }
  4877. },
  4878. /**
  4879. * Gets the relay URL of a target frame.
  4880. * @param {string} targetId Name of the target frame.
  4881. * @return {string|undefined} Relay URL of the target frame.
  4882. *
  4883. * @member gadgets.rpc
  4884. */
  4885. getRelayUrl: function(targetId) {
  4886. var url = relayUrl[targetId];
  4887. // Some RPC methods (wpm, for one) are unhappy with schemeless URLs.
  4888. if (url && url.substring(0,1) === '/') {
  4889. if (url.substring(1,2) === '/') { // starts with '//'
  4890. url = document.location.protocol + url;
  4891. } else { // relative URL, starts with '/'
  4892. url = document.location.protocol + '//' + document.location.host + url;
  4893. }
  4894. }
  4895. return url;
  4896. },
  4897. setRelayUrl: setRelayUrl,
  4898. setAuthToken: setAuthToken,
  4899. setupReceiver: setupReceiver,
  4900. getAuthToken: getAuthToken,
  4901. // Note: Does not delete iframe
  4902. removeReceiver: function(receiverId) {
  4903. delete relayUrl[receiverId];
  4904. delete useLegacyProtocol[receiverId];
  4905. delete authToken[receiverId];
  4906. delete setup[receiverId];
  4907. delete sameDomain[receiverId];
  4908. delete receiverTx[receiverId];
  4909. },
  4910. /**
  4911. * Gets the RPC relay mechanism.
  4912. * @return {string} RPC relay mechanism. See above for
  4913. * a list of supported types.
  4914. *
  4915. * @member gadgets.rpc
  4916. */
  4917. getRelayChannel: function() {
  4918. return transport.getCode();
  4919. },
  4920. /**
  4921. * Receives and processes an RPC request. (Not to be used directly.)
  4922. * Only used by IFPC.
  4923. * @param {Array.<string>} fragment An RPC request fragment encoded as
  4924. * an array. The first 4 elements are target id, source id & call id,
  4925. * total packet number, packet id. The last element stores the actual
  4926. * JSON-encoded and URI escaped packet data.
  4927. *
  4928. * @member gadgets.rpc
  4929. * @deprecated
  4930. */
  4931. receive: function(fragment, otherWindow) {
  4932. if (fragment.length > 4) {
  4933. process(OpenAjax.gadgets.json.parse(
  4934. decodeURIComponent(fragment[fragment.length - 1])));
  4935. } else {
  4936. relayOnload.apply(null, fragment.concat(otherWindow));
  4937. }
  4938. },
  4939. /**
  4940. * Receives and processes an RPC request sent via the same domain.
  4941. * (Not to be used directly). Converts the inbound rpc object's
  4942. * Array into a local Array to pass the process() Array test.
  4943. * @param {Object} rpc RPC object containing all request params
  4944. * @member gadgets.rpc
  4945. */
  4946. receiveSameDomain: function(rpc) {
  4947. // Pass through to local process method but converting to a local Array
  4948. rpc.a = Array.prototype.slice.call(rpc.a);
  4949. window.setTimeout(function() { process(rpc); }, 0);
  4950. },
  4951. // Helper method to get the protocol://host:port of an input URL.
  4952. // see docs above
  4953. getOrigin: getOrigin,
  4954. getReceiverOrigin: function(receiverId) {
  4955. var channel = receiverTx[receiverId];
  4956. if (!channel) {
  4957. // not set up yet
  4958. return null;
  4959. }
  4960. if (!channel.isParentVerifiable(receiverId)) {
  4961. // given transport cannot verify receiver origin
  4962. return null;
  4963. }
  4964. var origRelay = OpenAjax.gadgets.rpc.getRelayUrl(receiverId) ||
  4965. OpenAjax.gadgets.util.getUrlParameters().parent;
  4966. return OpenAjax.gadgets.rpc.getOrigin(origRelay);
  4967. },
  4968. /**
  4969. * Internal-only method used to initialize gadgets.rpc.
  4970. * @member gadgets.rpc
  4971. */
  4972. init: function() {
  4973. // Conduct any global setup necessary for the chosen transport.
  4974. // Do so after gadgets.rpc definition to allow transport to access
  4975. // gadgets.rpc methods.
  4976. if (transport.init(process, transportReady) === false) {
  4977. transport = fallbackTransport;
  4978. }
  4979. if (isChild) {
  4980. setupReceiver('..');
  4981. }
  4982. },
  4983. /** Returns the window keyed by the ID. null/".." for parent, else child */
  4984. _getTargetWin: getTargetWin,
  4985. /** Create an iframe for loading the relay URL. Used by child only. */
  4986. _createRelayIframe: function(token, data) {
  4987. var relay = OpenAjax.gadgets.rpc.getRelayUrl('..');
  4988. if (!relay) {
  4989. return;
  4990. }
  4991. // Format: #targetId & sourceId & authToken & data
  4992. var src = relay + '#..&' + rpcId + '&' + token + '&' +
  4993. encodeURIComponent(OpenAjax.gadgets.json.stringify(data));
  4994. var iframe = document.createElement('iframe');
  4995. iframe.style.border = iframe.style.width = iframe.style.height = '0px';
  4996. iframe.style.visibility = 'hidden';
  4997. iframe.style.position = 'absolute';
  4998. function appendFn() {
  4999. // Append the iframe.
  5000. document.body.appendChild(iframe);
  5001. // Set the src of the iframe to 'about:blank' first and then set it
  5002. // to the relay URI. This prevents the iframe from maintaining a src
  5003. // to the 'old' relay URI if the page is returned to from another.
  5004. // In other words, this fixes the bfcache issue that causes the iframe's
  5005. // src property to not be updated despite us assigning it a new value here.
  5006. iframe.src = 'javascript:"<html></html>"';
  5007. iframe.src = src;
  5008. }
  5009. if (document.body) {
  5010. appendFn();
  5011. } else {
  5012. OpenAjax.gadgets.util.registerOnLoadHandler(function() { appendFn(); });
  5013. }
  5014. return iframe;
  5015. },
  5016. ACK: ACK,
  5017. RPC_ID: rpcId,
  5018. SEC_ERROR_LOAD_TIMEOUT: LOAD_TIMEOUT,
  5019. SEC_ERROR_FRAME_PHISH: FRAME_PHISH,
  5020. SEC_ERROR_FORGED_MSG : FORGED_MSG
  5021. };
  5022. }();
  5023. // Initialize library/transport.
  5024. OpenAjax.gadgets.rpc.init();
  5025. } // !end of double-inclusion guard
  5026. /** Licensed Materials - Property of IBM, 5724-U69, (C) Copyright IBM Corp. 2008, 2012 - All Rights reserved. **/
  5027. require(["dojo/_base/connect", "dojo/string", "dojo/back", "dojox/xml/parser", "dojox/uuid/generateRandomUuid"], function(dConnect, dString, dBack){
  5028. dojo.provide("com.ibm.mm.enabler.core");
  5029. dojo.i18n._preloadLocalizations("com.ibm.mm.enabler.nls.enabler", ["ROOT","ar","ca","cs","da","de","el","en","es","fi","fr","he","hr","hu","it","ja","ko","nb","nl","no","pl","pt","pt-br","ro","ru","sk","sl","sv","th","tr","uk","zh","zh-tw"]);
  5030. (function() {
  5031. var ver = "3.0.0.20110927-1750".split(".");
  5032. var flag = "enabler.core";
  5033. if (flag) {
  5034. flag = "_" + flag;
  5035. }
  5036. if (ver.length == 4) {
  5037. dojo.setObject("com.ibm.mashups.enabler.version",{
  5038. major: ver[0],
  5039. minor: ver[1],
  5040. patch: ver[2],
  5041. "flag": flag,
  5042. revision: ver[3],
  5043. toString: function() {
  5044. return this.major + "." + this.minor + "." + this.patch + (this.flag || "") + " (" + this.revision + ")"; // String
  5045. }
  5046. });
  5047. }
  5048. })();
  5049. if(!dojo._hasResource["com.ibm.mashups.enabler.Deferred_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  5050. dojo._hasResource["com.ibm.mashups.enabler.Deferred_API"] = true;
  5051. dojo.provide("com.ibm.mashups.enabler.Deferred_API");
  5052. dojo.provide("com.ibm.mashups.enabler.Deferred");
  5053. /**
  5054. * Base interface for all classes which handle actions asynchronously.
  5055. * An action may involve one or more operations, for example creating or
  5056. * updating a model resource, which in turn may involve one or more HTTP
  5057. * requests. The Deferred interface allows to trigger a callback after
  5058. * the entire action, i.e. all involved HTTP requests, is finished. Thus,
  5059. * the Deferred interface may be used to get the overall result of an action.
  5060. * @ibm-api
  5061. * @ibm-module Base2
  5062. */
  5063. dojo.declare( "com.ibm.mashups.enabler.Deferred", null, {
  5064. /**
  5065. * Sets the handler of the deferred action. It is called when the entire
  5066. * action has finished.<br>
  5067. * Please note that the status of the action is transported only with
  5068. * callbacks, even if you use synchronous mode. If you need to check the status,
  5069. * you must use callback functions.
  5070. * @param {Object} callback the callback funtion in the format of <code>Function(Object resource, int statusCode, Object[] params)</code>.
  5071. * Must not be <code>null</code><br>
  5072. * &nbsp;&nbsp;&nbsp;&nbsp;<b>Callbackparameters</b><br>
  5073. * &nbsp;&nbsp;&nbsp;&nbsp;<code>resource</code> - resource object or id string
  5074. * of the related resource.
  5075. * May be <code>null</code> in case the action does not relate
  5076. * to a particular resource. In case multiple resources are involved in the
  5077. * action, the DeferredOperation interface may be used to obtain the resource
  5078. * objects or string <code>id</code>s of those resources.<br>
  5079. * &nbsp;&nbsp;&nbsp;&nbsp;<code>statusCode</code> - the overall HTTP status
  5080. * code of the action (the highest status code of the involved operations).<br>
  5081. * &nbsp;&nbsp;&nbsp;&nbsp;<code>params</code> - the parameters
  5082. * passed into the callback
  5083. * @param {Object[]} parameters optional array of parameters to be
  5084. * passed on to the callback function. May be <code>null</code>
  5085. * @return {com.ibm.mashups.enabler.Deferred} the deferred object
  5086. */
  5087. setFinishedCallback: function(callback, parameters) {
  5088. },
  5089. /**
  5090. * Executes the deferred action and invokes the callback functions set
  5091. * with the deferred object.
  5092. * @param {Boolean} sync indicates if the deferred action is executed
  5093. * synchronously or asynchronously. Optional, defaults to true.
  5094. * @return {Object} resource if called asynchronously, the return value is
  5095. * <code>undefined</code>, otherwise a resource object or id string of the
  5096. * related resource is returned.<br> In order to obtain information on
  5097. * the resource as well as on the status code of the operation, you
  5098. * must use the callback functions of the deferred object.
  5099. */
  5100. start: function(sync) {
  5101. return {};
  5102. }
  5103. });
  5104. }
  5105. if(!dojo._hasResource["com.ibm.mm.enabler.DeferredImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  5106. dojo._hasResource["com.ibm.mm.enabler.DeferredImpl"] = true;
  5107. dojo.provide("com.ibm.mm.enabler.DeferredImpl");
  5108. // base
  5109. dojo.declare("com.ibm.mm.enabler.DeferredImpl", [com.ibm.mashups.enabler.Deferred], {
  5110. _chainedDeferred: null,
  5111. _sync: false,
  5112. _previous: null,
  5113. // If you mixin the DeferredImpl into your class, you may use a different
  5114. // set of parameters for the constructor, but then you do not have access
  5115. // to the parameters 'context', 'startfn', as well as 'params' and thus,
  5116. // you need to overwrite the start function, which accesses those parameters.
  5117. // If you want to use the start function defined in DeferredImpl, you need
  5118. // to make sure, the parameters 'context', 'startfn', as well as 'params'
  5119. // are set in the constructor of DeferredImpl.
  5120. constructor: function(context, startfn, params){
  5121. // context for start function
  5122. this.context = context;
  5123. // start function
  5124. this.startfn = startfn;
  5125. // parameters to pass to start function
  5126. this.params = params;
  5127. },
  5128. // deprecated
  5129. addErrorCallback: function(callback, parameters){
  5130. dojo.deprecated("com.ibm.mashups.enabler.Deferred.addErrorCallback()", "use com.ibm.mashups.enabler.Deferred.setFinishedCallback() instead");
  5131. this.errorCallback = callback;
  5132. this.errorCallbackParameters = parameters;
  5133. },
  5134. // deprecated
  5135. addFinishedCallback: function(callback, parameters){
  5136. dojo.deprecated("com.ibm.mashups.enabler.Deferred.addFinishedCallback()", "use com.ibm.mashups.enabler.Deferred.setFinishedCallback() instead");
  5137. this.finishedCallback = callback;
  5138. this.finishedCallbackParameters = parameters;
  5139. // forward compatibility
  5140. //this.setFinishedCallback(callback, parameters);
  5141. },
  5142. setFinishedCallback: function(callback, parameters){
  5143. this.finishedCallback2 = callback;
  5144. this.finishedCallbackParameters2 = parameters;
  5145. return this;
  5146. },
  5147. start: function(sync, previous){
  5148. this._sync = (sync || typeof(sync) == 'undefined');
  5149. var ret = null;
  5150. if (dojo.isFunction(this.startfn)) {
  5151. ret = dojo.hitch(this.context || null, this.startfn)(this, this._sync, this.params, previous || null);
  5152. }
  5153. return ret;
  5154. },
  5155. getFinishedCallback: function(){
  5156. return this.finishedCallback2;
  5157. },
  5158. getFinishedCallbackParameters: function(){
  5159. return this.finishedCallbackParameters2;
  5160. },
  5161. setChainedDeferred: function(deferred){
  5162. this._chainedDeferred = deferred;
  5163. },
  5164. getChainedDeferred: function(){
  5165. return this._chainedDeferred;
  5166. },
  5167. getPrevious: function(){
  5168. return this._previous;
  5169. },
  5170. _setPreviousDeferred: function(deferred, result, status){
  5171. this._previous = {
  5172. deferred: deferred,
  5173. result: result,
  5174. status: status
  5175. };
  5176. },
  5177. removeChainedDeferred: function(){
  5178. this._chainedDeferred = null;
  5179. },
  5180. /**
  5181. * call this at the end of whatever you are doing
  5182. *
  5183. * @param {Object} result
  5184. * @param {Object} status
  5185. */
  5186. finish: function(result, status){
  5187. try {
  5188. if (dojo.isFunction(this.getFinishedCallback())) {
  5189. // call callback
  5190. dojo.partial(this.getFinishedCallback())(result, status, this.getFinishedCallbackParameters());
  5191. }
  5192. else {
  5193. if (dojo.isFunction(this.finishedCallback) && ("" + status).indexOf('2') === 0) {
  5194. // backwards compatibility
  5195. dojo.partial(this.finishedCallback)(result, this.finishedCallbackParameters);
  5196. }
  5197. else {
  5198. if (dojo.isFunction(this.errorCallback) && status >= 400) {
  5199. dojo.partial(this.errorCallback)(result, this.errorCallbackParameters);
  5200. }
  5201. }
  5202. }
  5203. }
  5204. catch (e) {
  5205. }
  5206. if (this._chainedDeferred) {
  5207. this._chainedDeferred._setPreviousDeferred(this, result, status);
  5208. this._chainedDeferred.start(this._sync);
  5209. }
  5210. }
  5211. });
  5212. }
  5213. if(!dojo._hasResource["com.ibm.mashups.enabler.Deferred"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  5214. dojo._hasResource["com.ibm.mashups.enabler.Deferred"] = true;
  5215. dojo.provide( "com.ibm.mashups.enabler.Deferred");
  5216. dojo.require( "com.ibm.mm.enabler.DeferredImpl" );
  5217. }
  5218. if(!dojo._hasResource["com.ibm.mashups.enabler.context.LocalizedContext_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  5219. dojo._hasResource["com.ibm.mashups.enabler.context.LocalizedContext_API"] = true;
  5220. dojo.provide("com.ibm.mashups.enabler.context.LocalizedContext_API");
  5221. dojo.provide("com.ibm.mashups.enabler.context.LocalizedContext");
  5222. /**
  5223. * LocalizedContext to get the preferred locale, the default locale, as well as
  5224. * titles and descriptions of localized resources within this localized context.
  5225. *
  5226. * @ibm-api
  5227. * @ibm-module Base2
  5228. */
  5229. dojo.declare("com.ibm.mashups.enabler.context.LocalizedContext", null, {
  5230. /**
  5231. * Returns the preferred locale of this LocalizedContext.
  5232. * @ibm-api
  5233. * @type {String}
  5234. * @return the preferred locale
  5235. */
  5236. getPreferredLocale : function() {
  5237. },
  5238. /**
  5239. * Returns the default locale of this LocalizedContext.
  5240. * @ibm-api
  5241. * @type {String}
  5242. * @return the default locale
  5243. */
  5244. getDefaultLocale : function() {
  5245. },
  5246. /**
  5247. * Returns the locale of the localized resource, which matches best the locale set with
  5248. * the browser.
  5249. * @ibm-api
  5250. * @param {com.ibm.mashups.enabler.Localized} localized resource implementing the Localized interface; must not be <code>null</code>
  5251. * @type {String}
  5252. * @return the preferred locale. Returns <code>null</code> if no locale is available.
  5253. */
  5254. getLocale : function(localized) {
  5255. },
  5256. /**
  5257. * Returns the display locale set with the browser matching the specified locale.
  5258. * @ibm-api
  5259. * @param {String} locale; mandatory, must not be <code>null</code>
  5260. * @type {String}
  5261. * @return the display locale. Returns <code>null</code> if no display locale is available.
  5262. */
  5263. getDisplayLocale : function(locale) {
  5264. },
  5265. /**
  5266. * Returns the title of the localized resource in the locale, which matches best the locale
  5267. * set with the browser.
  5268. * @ibm-api
  5269. * @param {com.ibm.mashups.enabler.Localized} localized resource implementing the Localized interface; must not be <code>null</code>
  5270. * @type {String}
  5271. * @return the title string in the preferred locale. Returns <code>null</code> if no locale is available.
  5272. */
  5273. getTitle : function(localized) {
  5274. },
  5275. /**
  5276. * Returns the description of the localized resource in the locale, which matches best the
  5277. * locale set with the browser.
  5278. * @ibm-api
  5279. * @param {com.ibm.mashups.enabler.Localized} localized resource implementing the Localized interface; must not be <code>null</code>
  5280. * @type {String}
  5281. * @return the description string in the preferred locale. Returns <code>null</code> if no locale is available.
  5282. */
  5283. getDescription : function(localized) {
  5284. }
  5285. });
  5286. }
  5287. if(!dojo._hasResource["com.ibm.mashups.enabler.xml.XPath_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  5288. dojo._hasResource["com.ibm.mashups.enabler.xml.XPath_API"] = true;
  5289. dojo.provide("com.ibm.mashups.enabler.xml.XPath_API");
  5290. dojo.provide("com.ibm.mashups.enabler.xml.XPath");
  5291. /**
  5292. * Interface provides functions to select nodes by evaluating XPATH expression
  5293. *
  5294. * @ibm-api
  5295. * @ibm-module Base2
  5296. */
  5297. dojo.declare("com.ibm.mashups.enabler.xml.XPath", null, {
  5298. /**
  5299. * This interface returns a list of XMLNodes upon XPATH evaluation.
  5300. * @param {String} xpathExpr the xpath expression (i.e. /atom:content). Must not be NULL.
  5301. * @param {XMLDocument} doc the XML document. Must not be NULL.
  5302. * @param {JSON} namespaces the namespaces used as part of the xpath expression. The json must be of the format {"prefix": "URL", ... }; must not be NULL.<br>
  5303. * Example: { "atom" : "http://www.w3.org/2005/Atom", "app" : "http://www.w3.org/2007/app" };
  5304. *
  5305. * @return {XMLNodeList} select nodes from XML document with xpath; may be <code>null</code>.
  5306. */
  5307. evaluateXPath : function(xpathExpr, doc, namespaces) {
  5308. },
  5309. /**
  5310. * This interface returns a single Entry upon XPATH evaluation or null if the entry is not present.
  5311. *
  5312. * @param {String} xpathExpr the xpath expression (i.e. /atom:content). Must not be NULL.
  5313. * @param {XMLDocument} doc the XML document. Must not be NULL.
  5314. * @param {JSON} namespaces the namespaces used as part of the xpath expression. The json must be of the format {"prefix": "URL", ... }; must not be NULL.<br>
  5315. * Example: { "atom" : "http://www.w3.org/2005/Atom", "app" : "http://www.w3.org/2007/app" };
  5316. *
  5317. * @return {Object}
  5318. */
  5319. evaluateEntry: function(xpathExpr, doc, namespaces) {
  5320. },
  5321. /**
  5322. * This interface returns a boolean upon XPATH evaluation. Returns false if the result is not valid (e.g. node does not exist, etc.).
  5323. *
  5324. * @param {String} xpathExpr the xpath expression (i.e. /atom:content). Must not be NULL.
  5325. * @param {XMLDocument} doc the XML document. Must not be NULL.
  5326. * @param {JSON} namespaces the namespaces used as part of the xpath expression. The json must be of the format {"prefix": "URL", ... }; must not be NULL.<br>
  5327. * Example: { "atom" : "http://www.w3.org/2005/Atom", "app" : "http://www.w3.org/2007/app" };
  5328. *
  5329. * @return {Boolean}
  5330. */
  5331. evaluateBoolean: function(xpathExpr, doc, namespaces) {
  5332. },
  5333. /**
  5334. * This interface returns a String upon XPATH evaluation. Returns an empty String if the result is not valid (e.g. node does not exist, etc.).
  5335. * If you want to check for existence of an attribute/element use either evaluateBoolean (which returns false if the element is not present) or evaluateEntry (which returns null if the element is not present).
  5336. *
  5337. * @param {String} xpathExpr the xpath expression (i.e. /atom:content). Must not be NULL.
  5338. * @param {XMLDocument} doc the XML document. Must not be NULL.
  5339. * @param {JSON} namespaces the namespaces used as part of the xpath expression. The json must be of the format {"prefix": "URL", ... }; must not be NULL.<br>
  5340. * Example: { "atom" : "http://www.w3.org/2005/Atom", "app" : "http://www.w3.org/2007/app" };
  5341. *
  5342. * @return {String}
  5343. */
  5344. evaluateString: function(xpathExpr, doc, namespaces) {
  5345. },
  5346. /**
  5347. * This interface returns a Number upon XPATH evaluation. Returns zero (0) if the result is not valid (e.g. node does not exist, etc.).
  5348. * If you want to check for existence of an attribute/element use either evaluateBoolean (which returns false if the element is not present) or evaluateEntry (which returns null if the element is not present).
  5349. *
  5350. * @param {String} xpathExpr the xpath expression (i.e. /atom:content). Must not be NULL.
  5351. * @param {XMLDocument} doc the XML document. Must not be NULL.
  5352. * @param {JSON} namespaces the namespaces used as part of the xpath expression. The json must be of the format {"prefix": "URL", ... }; must not be NULL.<br>
  5353. * Example: { "atom" : "http://www.w3.org/2005/Atom", "app" : "http://www.w3.org/2007/app" };
  5354. *
  5355. * @return {Number}
  5356. */
  5357. evaluateNumber: function(xpathExpr, doc, namespaces) {
  5358. }
  5359. });
  5360. }
  5361. if(!dojo._hasResource["com.ibm.mm.enabler.utils.Dom"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  5362. dojo._hasResource["com.ibm.mm.enabler.utils.Dom"] = true;
  5363. dojo.provide("com.ibm.mm.enabler.utils.Dom");
  5364. com.ibm.mm.enabler.utils.Dom = {
  5365. getAttributeWithNS: function(element, attName, localAttName, nsUri) {
  5366. if (!element) {
  5367. return null;
  5368. }
  5369. if (!attName) {
  5370. return null;
  5371. }
  5372. if (!localAttName) {
  5373. return null;
  5374. }
  5375. if (!nsUri) {
  5376. return null;
  5377. }
  5378. var value = null;
  5379. if (dojo.isIE) {
  5380. // IE with no namepsace
  5381. value = element.getAttribute(attName);
  5382. if (value === null || value == "") {
  5383. // IE with namepsace
  5384. var attributes = element.attributes;
  5385. for (var i = attributes.length; i > 0; i--) {
  5386. if (attributes[i - 1].baseName == localAttName && attributes[i - 1].namespaceURI == nsUri) {
  5387. value = attributes[i - 1].value;
  5388. break;
  5389. }
  5390. }
  5391. }
  5392. }
  5393. else {
  5394. // Safari & Firefox
  5395. value = element.getAttributeNS(nsUri, localAttName);
  5396. }
  5397. return value;
  5398. },
  5399. setAttributeWithNS: function(dom, element, attName, localAttName, nsUri, value) {
  5400. if (!dojo.isObject(element)) {
  5401. throw new Error("element must be a DOMNode");
  5402. }
  5403. if (dojo.isIE) {
  5404. var attr = dom.createNode(2, attName, nsUri);
  5405. // set value
  5406. if (value === null || value === undefined) {
  5407. value = "";
  5408. }
  5409. attr.nodeValue = value;
  5410. // attach to element
  5411. element.setAttributeNode(attr);
  5412. }
  5413. else {
  5414. element.setAttributeNS(nsUri, attName, value);
  5415. }
  5416. },
  5417. textContent: function(node, text) {
  5418. if (!node) {
  5419. return "";
  5420. }
  5421. if (arguments.length > 1) {
  5422. var doc = node.ownerDocument;
  5423. var aNode = doc.createTextNode(text || ""); // IE8 createTextNode fails when text == null
  5424. com.ibm.mm.enabler.utils.Dom.replaceChildren(node, aNode);
  5425. return;
  5426. }
  5427. else {
  5428. var tc = dojox.xml.parser.textContent(node);
  5429. if (tc) {
  5430. return tc;
  5431. }
  5432. return dojo.map(node.childNodes || [], function(node) {
  5433. return (node.nodeType > 0 && node.nodeType < 4) ? node.nodeValue : "";
  5434. }).join("");
  5435. }
  5436. },
  5437. createElement: function(dom, name, ns) {
  5438. var newElem;
  5439. if (dojo.isIE) {
  5440. if (ns) {
  5441. newElem = dom.createNode(1, name, ns);
  5442. }
  5443. else {
  5444. newElem = dom.createElement(name);
  5445. }
  5446. }
  5447. else {
  5448. newElem = dom.createElementNS(ns, name);
  5449. }
  5450. return newElem;
  5451. },
  5452. destroyNode: function(node) {
  5453. //avoid pseudo leaks since our webpage are open for long long time!
  5454. var garbageBin = dojo.byId('IELeakGarbageBin');
  5455. if (!garbageBin) {
  5456. garbageBin = dojo.create("div",{
  5457. id: "IELeakGarbageBin",
  5458. style: {display: "none"}
  5459. }, dojo.body());
  5460. }
  5461. // move the element to the garbage bin
  5462. dojo.place(node,garbageBin);
  5463. dojo.attr(garbageBin,'innerHTML','');
  5464. if (node.nodeType != 3) { // ingore TEXT_NODE
  5465. if (dojo.isIE) {
  5466. dojo.attr(node,'outerHTML',''); //prevent ugly IE mem leak
  5467. }
  5468. }
  5469. },
  5470. createDocument: function(/*string?*/str, /*string?*/ mimetype) {
  5471. return dojox.xml.parser.parse(str, mimetype);
  5472. },
  5473. replaceChildren: function(/*Element*/node, /*Node || array*/ newChildren) {
  5474. return dojox.xml.parser.replaceChildren(node, newChildren);
  5475. },
  5476. innerXML: function(node) {
  5477. return node ? dojox.xml.parser.innerXML(node) : null;
  5478. },
  5479. removeChildren: function(node) {
  5480. return dojox.xml.parser.removeChildren(node);
  5481. },
  5482. copyChildren: function(/*Element*/srcNode, /*Element*/ destNode, /*boolean?*/ trim) {
  5483. var clonedNode = srcNode.cloneNode(true);
  5484. return this.moveChildren(clonedNode, destNode, trim); // number
  5485. },
  5486. moveChildren: function(srcNode, destNode, trim) {
  5487. var count = 0;
  5488. if (trim) {
  5489. while (srcNode.hasChildNodes() &&
  5490. srcNode.firstChild.nodeType == 3) {
  5491. srcNode.removeChild(srcNode.firstChild);
  5492. }
  5493. while (srcNode.hasChildNodes() &&
  5494. srcNode.lastChild.nodeType == 3) {
  5495. srcNode.removeChild(srcNode.lastChild);
  5496. }
  5497. }
  5498. while (srcNode.hasChildNodes()) {
  5499. destNode.appendChild(srcNode.firstChild);
  5500. count++;
  5501. }
  5502. return count; // number
  5503. },
  5504. /**
  5505. * Get's the local name of the node passed in as parameter
  5506. *
  5507. * @param {Node} node the node of which to get the local name
  5508. * @return {String} the local name of the node or <tt>null</tt> if the node doesn't have a local name
  5509. */
  5510. getLocalName: function(node) {
  5511. if (!node) {
  5512. return null;
  5513. }
  5514. switch (node.nodeType) {
  5515. case 3:
  5516. return "#text";
  5517. case 1:
  5518. return node.localName || com.ibm.mm.enabler.utils.Dom.removeNodeNS(node.nodeName);
  5519. }
  5520. return null;
  5521. },
  5522. /**
  5523. * Get's the namespace prefix from the given nodename or <tt>null</tt> if there is no NS Prefix.
  5524. *
  5525. * @param {String} nodeName The name of the node
  5526. * @return {String} the namespace prefix of the node name or <tt>null</tt> if there is none.
  5527. */
  5528. getNodeNSPrefix: function(nodeName) {
  5529. var tN = '' + nodeName;
  5530. var hasColon = tN.indexOf(':');
  5531. return (hasColon != -1) ? tN.substring(0, hasColon) : null;
  5532. },
  5533. /**
  5534. * Removes the namespace from a node name.
  5535. * This is a copy of com.ibm.mashups.widget.dijit.url.util.Dom.removeNodeNs and should
  5536. * replace this method in case, this one here becomes public.
  5537. *
  5538. * @private
  5539. * @param {String} nodeName the node name with or without namespace
  5540. * @return {String} the node name without namespace
  5541. * @see com.ibm.mashups.widget.dijit.url.util.Dom#removeNodeNs(String)
  5542. */
  5543. removeNodeNS: function(nodeName) {
  5544. var tN = '' + nodeName;
  5545. var hasColon = tN.indexOf(':');
  5546. return (hasColon != -1) ? tN.substring(1 + hasColon) : nodeName;
  5547. },
  5548. /**
  5549. * Looks up the namespace for the specified prefix
  5550. * @param {Node} node the node for which to lookup the namespace
  5551. * @param {String} prefix the prefix to lookup the namespace for.
  5552. * @return {String} the namespace for the specified prefix or <tt>null</tt> if the namespace for the prefix wasn't found.
  5553. */
  5554. lookupNamespaceURI: function(node, prefix) {
  5555. // If we are not on IE, we have native support for this
  5556. if (!dojo.isIE) {
  5557. return node.lookupNamespaceURI(prefix);
  5558. }
  5559. // seems we are on IE, so let's do some magic here
  5560. var lastNode = node;
  5561. // while node != null and node isn't a document
  5562. while (lastNode && lastNode.nodeType != 9) {
  5563. var attrValue = lastNode.getAttribute("xmlns:" + prefix);
  5564. if (attrValue) {
  5565. return attrValue;
  5566. }
  5567. lastNode = lastNode.parentNode;
  5568. }
  5569. return null;
  5570. }
  5571. };
  5572. }
  5573. if(!dojo._hasResource["com.ibm.mm.enabler.xml.xpath._Generic"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  5574. dojo._hasResource["com.ibm.mm.enabler.xml.xpath._Generic"] = true;
  5575. dojo.provide("com.ibm.mm.enabler.xml.xpath._Generic");
  5576. // generic impl
  5577. dojo.declare("com.ibm.mm.enabler.xml.xpath._Generic", null, {
  5578. constructor: function(){
  5579. },
  5580. _evaluateXPath: function(/*String*/xpathExpr, /*DOMDocument*/ doc, /*Object{prefix:ns,prefix2:ns2,...}*/ namespaces){
  5581. if (dojo.isSafari) {
  5582. return this._safariEvaluateXPath(xpathExpr, doc, namespaces);
  5583. } else if (dojo.isIE) {
  5584. return this._ieEvaluateXPath(xpathExpr, doc, namespaces);
  5585. } else {
  5586. return this._geckoEvaluateXPath(xpathExpr, doc, namespaces);
  5587. }
  5588. },
  5589. _transformNode: function(result, resType){
  5590. if (typeof XPathResult != "undefined" && result instanceof XPathResult) {
  5591. return this._xpathResultValue(result, resType);
  5592. } else {
  5593. if (resType == com.ibm.mm.enabler.xml.xpath._Generic.ANY_TYPE) {
  5594. return result;
  5595. } else if (resType == com.ibm.mm.enabler.xml.xpath._Generic.NUMBER_TYPE) {
  5596. return parseFloat(com.ibm.mm.enabler.utils.Dom.textContent(result));
  5597. } else if (resType == com.ibm.mm.enabler.xml.xpath._Generic.STRING_TYPE) {
  5598. return com.ibm.mm.enabler.utils.Dom.textContent(result);
  5599. } else if (resType == com.ibm.mm.enabler.xml.xpath._Generic.BOOLEAN_TYPE) {
  5600. return !!result;
  5601. }
  5602. }
  5603. return null;
  5604. },
  5605. _xpathResultValue: function(node, resType){
  5606. if (resType == com.ibm.mm.enabler.xml.xpath._Generic.ANY_TYPE) {
  5607. return node;
  5608. } else if (resType == com.ibm.mm.enabler.xml.xpath._Generic.NUMBER_TYPE) {
  5609. return node.numberValue;
  5610. } else if (resType == com.ibm.mm.enabler.xml.xpath._Generic.STRING_TYPE) {
  5611. return node.stringValue;
  5612. } else if (resType == com.ibm.mm.enabler.xml.xpath._Generic.BOOLEAN_TYPE) {
  5613. return node.booleanValue;
  5614. }
  5615. return null;
  5616. },
  5617. _evaluateXPathSingle: function(xpathExpr, doc, namespaces, resType){
  5618. resType = resType || com.ibm.mm.enabler.xml.xpath._Generic.ANY_TYPE;
  5619. var result;
  5620. if (dojo.isSafari) {
  5621. result = this._safariEvaluateXPathRaw(xpathExpr, doc, namespaces, resType);
  5622. if (XPathResult && result instanceof XPathResult) {
  5623. if (resType == com.ibm.mm.enabler.xml.xpath._Generic.ANY_TYPE) {
  5624. return result.iterateNext();
  5625. }
  5626. return this._transformNode(result, resType);
  5627. } else if (result) {
  5628. return this._transformNode(result[0], resType);
  5629. }
  5630. } else if (dojo.isIE) {
  5631. result = this._ieEvaluateXPathRawSingle(xpathExpr, doc, namespaces);
  5632. if (result || result === null) {
  5633. return this._transformNode(result, resType);
  5634. }
  5635. } else {
  5636. result = this._geckoEvaluateXPathRaw(xpathExpr, doc, namespaces, resType);
  5637. if (result && resType == com.ibm.mm.enabler.xml.xpath._Generic.ANY_TYPE) {
  5638. return result.iterateNext();
  5639. } else {
  5640. return this._transformNode(result, resType);
  5641. }
  5642. }
  5643. return result || null;
  5644. },
  5645. _geckoEvaluateXPath: function(/*String*/xpathExpr, /*DOMDocument*/ doc, /*Object{prefix:ns,prefix2:ns2,...}*/ namespaces){
  5646. var result = this._geckoEvaluateXPathRaw(xpathExpr, doc, namespaces, com.ibm.mm.enabler.xml.xpath._Generic.ANY_TYPE);
  5647. var resultSet = [];
  5648. if (result) {
  5649. var thisResult;
  5650. while ((thisResult = result.iterateNext())) {
  5651. resultSet.push(thisResult);
  5652. }
  5653. }
  5654. return resultSet;
  5655. },
  5656. _geckoEvaluateXPathRaw: function(xpathExpr, doc, namespaces, type){
  5657. var xmlDocument = doc;
  5658. if (doc.nodeType != 9) {
  5659. xmlDocument = doc.ownerDocument;
  5660. }
  5661. return xmlDocument.evaluate(xpathExpr, doc, function(prefix){
  5662. return namespaces[prefix] ? namespaces[prefix].toString() : null;
  5663. }, type, null);
  5664. },
  5665. _ieEvaluateXPath: function(/*String*/xpathExpr, /*DOMDocument*/ doc, /*Object{prefix:ns,prefix2:ns2,...}*/ namespaces){
  5666. var result = this._ieEvaluateXPathRaw(xpathExpr, doc, namespaces);
  5667. return result || [];
  5668. },
  5669. _setIeNamespaces: function(doc, namespaces) {
  5670. if (namespaces) {
  5671. var ns = [];
  5672. var item;
  5673. for (var prop in namespaces) { // JSLINT-IGNORE: Filtering for prototype properties must not be done here, as namespaces often use dojo.delegate to save memory - dojo.delegate uses the prototype functionality for doing so - we use dojo.isFunction() which should suffice.
  5674. // ATTENTION: DON'T ADD .hasOwnProperty() CHECK HERE!
  5675. item = namespaces[prop];
  5676. if (prop != "xml") { // we cannot use !dojo.isFunction(item) as it costs too much performance
  5677. // There is no automatic namespace recognition, this is a workaround
  5678. ns.push("xmlns:", prop, "='", item, "' ");
  5679. }
  5680. }
  5681. if(dojo.isIE !=11){
  5682. var sDoc = doc.ownerDocument || doc;
  5683. sDoc.setProperty("SelectionNamespaces", ns.join(""));
  5684. sDoc.setProperty("SelectionLanguage", "XPath");
  5685. }
  5686. }
  5687. },
  5688. _ieEvaluateXPathRaw: function(xpathExpr, doc, namespaces){
  5689. this._setIeNamespaces(doc, namespaces);
  5690. return doc.selectNodes(xpathExpr);
  5691. },
  5692. _ieEvaluateXPathRawSingle: function(xpathExpr, doc, namespaces){
  5693. this._setIeNamespaces(doc, namespaces);
  5694. return doc.selectSingleNode(xpathExpr);
  5695. },
  5696. _safariEvaluateXPath: function(/*String*/xpathExpr, /*DOMDocument*/ doc, /*Object{prefix:ns,prefix2:ns2,...}*/ namespaces){
  5697. var result = this._safariEvaluateXPathRaw(xpathExpr, doc, namespaces, com.ibm.mm.enabler.xml.xpath._Generic.ANY_TYPE);
  5698. if (XPathResult && result instanceof XPathResult) {
  5699. var resultSet = [];
  5700. var thisResult;
  5701. while ((thisResult = result.iterateNext())) {
  5702. resultSet.push(thisResult);
  5703. }
  5704. return resultSet;
  5705. }
  5706. return result || [];
  5707. },
  5708. _safariEvaluateXPathRaw: function(xpathExpr, doc, namespaces, type){
  5709. if (typeof XPathResult != "undefined") {
  5710. //use build in xpath support for Safari 3.0
  5711. return document.evaluate(xpathExpr, doc, function(prefix){
  5712. return namespaces[prefix] ? namespaces[prefix].toString() : null;
  5713. }, type, null);
  5714. } else if (doc.selectNodes) {
  5715. //use javeline Safari2 xpath support
  5716. return doc.selectNodes(xpathExpr);
  5717. }
  5718. }
  5719. });
  5720. com.ibm.mm.enabler.xml.xpath._Generic.ANY_TYPE = 0;
  5721. com.ibm.mm.enabler.xml.xpath._Generic.NUMBER_TYPE = 1;
  5722. com.ibm.mm.enabler.xml.xpath._Generic.STRING_TYPE = 2;
  5723. com.ibm.mm.enabler.xml.xpath._Generic.BOOLEAN_TYPE = 3;
  5724. }
  5725. if(!dojo._hasResource["com.ibm.mm.enabler.xml.XPathImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  5726. dojo._hasResource["com.ibm.mm.enabler.xml.XPathImpl"] = true;
  5727. dojo.provide("com.ibm.mm.enabler.xml.XPathImpl");
  5728. dojo.declare("com.ibm.mm.enabler.xml.XPathImpl", [com.ibm.mashups.enabler.xml.XPath, com.ibm.mm.enabler.xml.xpath._Generic], {
  5729. modelMessages: null,
  5730. constructor: function() {
  5731. this.modelMessages = dojo.i18n.getLocalization("com.ibm.mm.enabler", "modelMessages");
  5732. },
  5733. ANY_TYPE: com.ibm.mm.enabler.xml.xpath._Generic.ANY_TYPE,
  5734. NUMBER_TYPE: com.ibm.mm.enabler.xml.xpath._Generic.NUMBER_TYPE,
  5735. STRING_TYPE: com.ibm.mm.enabler.xml.xpath._Generic.STRING_TYPE,
  5736. BOOLEAN_TYPE: com.ibm.mm.enabler.xml.xpath._Generic.BOOLEAN_TYPE,
  5737. evaluateXPath: function(xpathExpr, doc, namespaces) {
  5738. if(!dojo.isString(xpathExpr) || xpathExpr.length === 0) {
  5739. throw new Error(this.modelMessages.E_INVALID_XPATH_EXPR_0);
  5740. }
  5741. if(!doc) {
  5742. throw new Error(this.modelMessages.E_INVALID_DOCUMENT_0);
  5743. }
  5744. var ret = this._evaluateXPath(xpathExpr, doc, namespaces);
  5745. return ret;
  5746. },
  5747. evaluateSingle: function(xpathExpr, doc, namespaces, type) {
  5748. if(!dojo.isString(xpathExpr) || xpathExpr.length === 0) {
  5749. throw new Error(this.modelMessages.E_INVALID_XPATH_EXPR_0);
  5750. }
  5751. if(!doc) {
  5752. throw new Error(this.modelMessages.E_INVALID_DOCUMENT_0);
  5753. }
  5754. return this._evaluateXPathSingle(xpathExpr, doc, namespaces, type);
  5755. },
  5756. evaluateEntry: function(xpathExpr, doc, namespaces) {
  5757. return this.evaluateSingle(xpathExpr, doc, namespaces, com.ibm.mashups.enabler.xml.XPath.ANY_TYPE);
  5758. },
  5759. evaluateBoolean: function(xpathExpr, doc, namespaces) {
  5760. return this.evaluateSingle(xpathExpr, doc, namespaces, com.ibm.mashups.enabler.xml.XPath.BOOLEAN_TYPE);
  5761. },
  5762. evaluateString: function(xpathExpr, doc, namespaces) {
  5763. return this.evaluateSingle(xpathExpr, doc, namespaces, com.ibm.mashups.enabler.xml.XPath.STRING_TYPE);
  5764. },
  5765. evaluateNumber: function(xpathExpr, doc, namespaces) {
  5766. return this.evaluateSingle(xpathExpr, doc, namespaces, com.ibm.mashups.enabler.xml.XPath.NUMBER_TYPE);
  5767. },
  5768. /**
  5769. * evaluates the specified xpath, but creates xml elements, which are not part
  5770. * of the document; please note that attributes are not supported
  5771. *
  5772. * @param {Object} xPath
  5773. * @param {Object} node
  5774. * @param {Object} namespaces
  5775. */
  5776. createXPath: function(xPath, node, namespaces) {
  5777. // split off first part of xpath
  5778. var xPathParts = xPath.split("/");
  5779. // handle head
  5780. var qName = xPathParts[0];
  5781. // extract name and name space
  5782. var qNameParts = qName.split(":");
  5783. var name, namespace;
  5784. if (qNameParts.length > 1) {
  5785. namespace = qNameParts[0];
  5786. name = qNameParts[1];
  5787. }
  5788. else {
  5789. name = qNameParts[0];
  5790. }
  5791. // search for first part of xpath (what about case insensitive search for attributes, especially "_" vs "-" in locales?)
  5792. var names = com.ibm.mashups.enabler.xml.XPath.evaluateXPath((namespace ? namespace + ":" : "") + name, node, namespaces);
  5793. var result;
  5794. if (names && names.length > 0) {
  5795. // use existing xml element
  5796. result = names[0];
  5797. }
  5798. else {
  5799. // what about attributes?
  5800. // create xml element
  5801. result = com.ibm.mm.enabler.utils.Dom.createElement(node.ownerDocument, (namespace ? namespace + ":" : "") + name, namespace ? namespaces[namespace] : null);
  5802. node.appendChild(result);
  5803. }
  5804. // handle remaining parts of xpath
  5805. if (xPathParts.length > 1) {
  5806. // recursive call with remaining xpath part
  5807. result = com.ibm.mashups.enabler.xml.XPath.createXPath(xPath.substr(xPath.indexOf("/") + 1), result, namespaces);
  5808. }
  5809. return result;
  5810. }
  5811. });
  5812. // create the singleton
  5813. com.ibm.mashups.enabler.xml.XPath = new com.ibm.mm.enabler.xml.XPathImpl();
  5814. // backwards compatibility - still needed?
  5815. // TODO remove this in next enabler version
  5816. com.ibm.mm.enabler.xml.xpath.evaluateXPath = function(xpathExpr, doc, namespaces) {
  5817. dojo.deprecated("com.ibm.mm.enabler.xml.xpath.evaluateXPath", "The method com.ibm.mm.enabler.xml.xpath.evaluateXPath is deprecated, please use com.ibm.mashups.enabler.xml.XPath.evaluateXPath instead");
  5818. return com.ibm.mm.enabler.xml.xpath._Generic.evaluateXPath.apply(null, arguments);
  5819. };
  5820. }
  5821. if(!dojo._hasResource["com.ibm.mashups.enabler.xml.XPath"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  5822. dojo._hasResource["com.ibm.mashups.enabler.xml.XPath"] = true;
  5823. dojo.provide("com.ibm.mashups.enabler.xml.XPath");
  5824. }
  5825. if(!dojo._hasResource["com.ibm.mm.enabler.utils.LocaleHelper"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  5826. dojo._hasResource["com.ibm.mm.enabler.utils.LocaleHelper"] = true;
  5827. dojo.provide("com.ibm.mm.enabler.utils.LocaleHelper");
  5828. com.ibm.mm.enabler.utils.LocaleHelper = {
  5829. getLocale:function(/*com.ibm.mashups.enabler.Localized*/localized,aLocale,defaultLocale){
  5830. if (typeof localized == "undefined" || localized === null) {
  5831. return null;
  5832. }
  5833. var localeArr = localized.getLocales();
  5834. if (typeof localeArr == "undefined" || localeArr === null || !dojo.isArray(localeArr)) {
  5835. return null;
  5836. }
  5837. if (localeArr.length === 0) {
  5838. return null;
  5839. }
  5840. var returnLocale = null;
  5841. if (localeArr.length === 1) {
  5842. returnLocale = localeArr[0];
  5843. }
  5844. var arr = {};
  5845. for (var i in localeArr) {
  5846. if (Object.prototype.hasOwnProperty.call(localeArr,i)) {
  5847. var temp = localeArr[i];
  5848. arr[temp] = temp;
  5849. }
  5850. }
  5851. var tempArr;
  5852. if (returnLocale === null) {
  5853. if (typeof aLocale != "undefined" && aLocale !== null) {
  5854. returnLocale = this.findMatchLocale(arr, aLocale);
  5855. if (returnLocale === null) {
  5856. tempArr = aLocale.split(/-|_/);
  5857. if (tempArr.length == 2) {
  5858. var iLocale = tempArr[0];
  5859. if (typeof arr[iLocale] != "undefined" && arr[iLocale] !== null) {
  5860. returnLocale = iLocale;
  5861. }
  5862. }
  5863. }
  5864. }
  5865. }
  5866. if (returnLocale === null) {
  5867. //get browser locale
  5868. var browserLocale = (dojo.isIE ? navigator.userLanguage : navigator.language).toLowerCase();
  5869. if (typeof ibmConfig != "undefined" && ibmConfig && typeof(ibmConfig.locale) != "undefined" && ibmConfig.locale) {
  5870. browserLocale = ibmConfig.locale;
  5871. }
  5872. if (browserLocale !== null) {
  5873. //browserLocale = browserLocale.replace(/-/,"_");
  5874. returnLocale = this.findMatchLocale(arr, browserLocale);
  5875. if (returnLocale === null) {
  5876. tempArr = browserLocale.split(/-|_/);
  5877. if (tempArr.length == 2) {
  5878. var tempLocale = tempArr[0];
  5879. if (typeof arr[tempLocale] != "undefined" && arr[tempLocale] !== null) {
  5880. returnLocale = tempLocale;
  5881. }
  5882. }
  5883. }
  5884. }
  5885. }
  5886. if (returnLocale === null) {
  5887. if (defaultLocale) {
  5888. returnLocale = defaultLocale;
  5889. }
  5890. }
  5891. if (returnLocale === null) {
  5892. if (arr.en) {
  5893. returnLocale = "en";
  5894. }
  5895. }
  5896. if (returnLocale === null) {
  5897. returnLocale = localeArr[0];
  5898. }
  5899. return returnLocale;
  5900. },
  5901. findMatchLocale:function(arr,locale){
  5902. var returnLocale = null;
  5903. if (arr[locale]) {
  5904. returnLocale = locale;
  5905. }
  5906. var serverLocale = this.toServerLocale(locale);
  5907. if (returnLocale === null && arr[serverLocale]) {
  5908. returnLocale = serverLocale;
  5909. }
  5910. var serverLocaleLowercase = serverLocale.toLowerCase();
  5911. if (returnLocale === null && arr[serverLocaleLowercase]) {
  5912. returnLocale = serverLocaleLowercase;
  5913. }
  5914. return returnLocale;
  5915. },
  5916. /**
  5917. * match a locale against an array of locales
  5918. *
  5919. * TODO: also allow preferred to be an array
  5920. *
  5921. * @param {String} preferred
  5922. * @param {Array} available
  5923. */
  5924. matchLocale: function(preferred, available) {
  5925. return com.ibm.mm.enabler.utils.LocaleHelper._matchLocale(
  5926. com.ibm.mm.enabler.utils.LocaleHelper._getLocaleObj(preferred),
  5927. com.ibm.mm.enabler.utils.LocaleHelper.normalizeLocale(available));
  5928. },
  5929. /**
  5930. * match a normalized locale against an array of normalized locales
  5931. *
  5932. * FIXME: we need to add handling of multiple possible locales matching against multiple available ones,
  5933. * keeping in mind the order the user defined and also handling for exceptions
  5934. * (e.g. pt-br must not fall back to pt, sh traditional must fall back to simplified, etc.)
  5935. *
  5936. * @param {Object} locale an locale object
  5937. * @param {Array} locales an Array of normalized locale strings
  5938. */
  5939. _matchLocale: function(locale, locales, stop) {
  5940. // console.debug("match locale:",locale,"against",locales);
  5941. var _origLocale = locale;
  5942. var match = null;
  5943. var found = dojo.some(locales, function(item) {
  5944. if (item == com.ibm.mm.enabler.utils.LocaleHelper.normalizeLocale(locale.toString())) {
  5945. match = item;
  5946. return true;
  5947. }
  5948. });
  5949. if (found && match) {
  5950. return match;
  5951. }
  5952. if (locale.variant) {
  5953. // try without variant
  5954. locale.variant = null;
  5955. return com.ibm.mm.enabler.utils.LocaleHelper._matchLocale(locale, locales);
  5956. }
  5957. if (locale.country) {
  5958. // try without country
  5959. locale.country = null;
  5960. return com.ibm.mm.enabler.utils.LocaleHelper._matchLocale(locale, locales);
  5961. }
  5962. if (!stop) {
  5963. // TODO: make list of aliases [he,iw], to automate this for other fallbacks.
  5964. locale = _origLocale;
  5965. switch (locale.language) {
  5966. case 'he':
  5967. // special handling for hebrew (he and iw (old) are equal)
  5968. locale.language = "iw";
  5969. break;
  5970. case 'iw':
  5971. // special handling for hebrew (he and iw (old) are equal)
  5972. locale.language = "he";
  5973. break;
  5974. }
  5975. return com.ibm.mm.enabler.utils.LocaleHelper._matchLocale(locale, locales, true);
  5976. }
  5977. return null;
  5978. },
  5979. /**
  5980. * (DE_dE_VariAnt -> de_DE)
  5981. * removes the variant part to sustain backwards compatibility - please use com.ibm.mm.enabler.utils.LocaleHelper.normalizeLocale
  5982. * whitespaces are trimmed at the beginning and end
  5983. *
  5984. * @deprecated
  5985. *
  5986. * @param {Object} locale
  5987. */
  5988. toServerLocale:function(locale) {
  5989. if (!locale) {
  5990. return null;
  5991. }
  5992. if (locale.indexOf("-") < 0) {
  5993. return locale;
  5994. }
  5995. locale = locale.replace(/-/, "_");
  5996. var tempArr = locale.split('_');
  5997. var lang = tempArr[0];
  5998. var country = tempArr[1].toUpperCase();
  5999. var returnLocale = lang + "_" + country;
  6000. return returnLocale;
  6001. },
  6002. /**
  6003. * returns a locale object with normalized parts
  6004. *
  6005. * (DE_dE_VariAnt -> {language: 'de', country: 'DE', variant: 'VariAnt'})
  6006. * whitespaces are trimmed at the beginning and end
  6007. *
  6008. * @param {String|Array} locale
  6009. *
  6010. */
  6011. _getLocaleObj: function(locale) {
  6012. if (dojo.isArray(locale)) {
  6013. return dojo.map(locale, function(item) {
  6014. return com.ibm.mm.enabler.utils.LocaleHelper._getLocaleObj(item);
  6015. });
  6016. }
  6017. else if (dojo.isString(locale) && dojo.string.trim(locale).length > 0) {
  6018. var localeObj = {
  6019. language: null,
  6020. country: null,
  6021. variant: null,
  6022. toString: function() {
  6023. return (this.language ? this.language + (this.country ? "_" + this.country + (this.variant ? "_" + this.variant : "") : "") : "");
  6024. },
  6025. isValid: function() {
  6026. return !!this.language;
  6027. }
  6028. };
  6029. var parts = dojo.string.trim(locale).replace(/-/g, "_").split('_');
  6030. switch (parts.length) {
  6031. case 3:
  6032. // we have got a variant
  6033. localeObj.variant = parts[2]; // JSLINT-IGNORE: NO BREAK HERE
  6034. // ATTN: no break here
  6035. case 2:
  6036. // we have got a country
  6037. localeObj.country = parts[1].toUpperCase(); // JSLINT-IGNORE: NO BREAK HERE
  6038. // ATTN: no break here
  6039. case 1:
  6040. // and we have got a language
  6041. localeObj.language = parts[0].toLowerCase();
  6042. break;
  6043. }
  6044. return localeObj;
  6045. }
  6046. else {
  6047. return null;
  6048. }
  6049. },
  6050. /**
  6051. * normalizes a locale or an array of locales
  6052. *
  6053. * (DE_dE_VariAnt -> de-DE_VariAnt)
  6054. * whitespaces are trimmed at the beginning and end
  6055. * @param {String|Array} locale
  6056. */
  6057. normalizeLocale: function(locale) {
  6058. if (dojo.isArray(locale)) {
  6059. return dojo.map(locale, function(item) {
  6060. return com.ibm.mm.enabler.utils.LocaleHelper.normalizeLocale(item);
  6061. });
  6062. }
  6063. else if (locale && dojo.isString(locale)) {
  6064. return locale.replace(/_/g, "-").toLowerCase();
  6065. }
  6066. else {
  6067. return null;
  6068. }
  6069. }
  6070. };
  6071. }
  6072. if(!dojo._hasResource["com.ibm.mm.enabler.model.NameSpaceFactory"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  6073. dojo._hasResource["com.ibm.mm.enabler.model.NameSpaceFactory"] = true;
  6074. dojo.provide("com.ibm.mm.enabler.model.NameSpaceFactory");
  6075. dojo.declare( "com.ibm.mm.enabler.model.NameSpaceFactoryImpl", null,
  6076. {
  6077. constructor:function () {
  6078. // name space prefixes
  6079. this.NS_APP = "app";
  6080. this.NS_ATOM = "atom";
  6081. this.NS_THR = "thr";
  6082. this.NS_UM = "um";
  6083. this.NS_XHTML = "xhtml";
  6084. this.NS_XML = "xml";
  6085. this.NS_XSI = "xsi";
  6086. this.NS_OPENSEARCH = "opensearch";
  6087. this.NS_CM = "cm";
  6088. this.NS_CA = "ca";
  6089. this.NS_AC = "ac";
  6090. this.NS_EVENT_DATATYPES = "event-datatypes";
  6091. this.NS_XMLNS = "xmlns";
  6092. this.NS_XSD = "xsd";
  6093. this.NS_JS = "js";
  6094. // name space URIs
  6095. this.namespaces = {};
  6096. this.namespaces[this.NS_APP] = "http://www.w3.org/2007/app";
  6097. this.namespaces[this.NS_ATOM] = "http://www.w3.org/2005/Atom";
  6098. this.namespaces[this.NS_THR] = "http://purl.org/syndication/thread/1.0";
  6099. this.namespaces[this.NS_UM] = "http://www.ibm.com/xmlns/prod/websphere/um.xsd";
  6100. this.namespaces[this.NS_XHTML] = "http://www.w3.org/1999/xhtml";
  6101. this.namespaces[this.NS_XML] = "http://www.w3.org/XML/1998/namespace";
  6102. this.namespaces[this.NS_XSI] = "http://www.w3.org/2001/XMLSchema-instance";
  6103. this.namespaces[this.NS_XMLNS] = "http://www.w3.org/2000/xmlns/";
  6104. this.namespaces[this.NS_OPENSEARCH] = "http://a9.com/-/spec/opensearch/1.1/";
  6105. this.namespaces[this.NS_CM] = "http://www.ibm.com/xmlns/prod/composite-applications/v1.0";
  6106. this.namespaces[this.NS_CA] = "http://www.ibm.com/xmlns/prod/composite-applications/v1.0";
  6107. this.namespaces[this.NS_AC] = "http://www.ibm.com/xmlns/prod/lotus/access-control/v1.0";
  6108. this.namespaces[this.NS_EVENT_DATATYPES] = "http://www.ibm.com/xmlns/prod/lotus/mashups/event-datatypes";
  6109. this.namespaces[this.NS_XSD] = "http://www.w3.org/2001/XMLSchema";
  6110. this.namespaces[this.NS_JS] = "text/javascript";
  6111. },
  6112. /**
  6113. * Returns an object with a property for each element in the
  6114. * passed in array and the corresponding name space uri as value
  6115. * @param {Array} prefixes
  6116. */
  6117. getNameSpaces: function(prefixes) {
  6118. var result = {};
  6119. var len = prefixes.length;
  6120. for (var i=0; i<len; i++) {
  6121. var name = prefixes[i];
  6122. result[name] = this.namespaces[name];
  6123. }
  6124. return result;
  6125. },
  6126. /**
  6127. * Returns the name space uri that corresponds to the passed in prefix
  6128. */
  6129. getNameSpaceUri: function(prefix) {
  6130. return this.namespaces[prefix];
  6131. }
  6132. }
  6133. );
  6134. //internal
  6135. com.ibm.mm.enabler.model.NameSpaceFactory = new com.ibm.mm.enabler.model.NameSpaceFactoryImpl();
  6136. }
  6137. if(!dojo._hasResource["com.ibm.mm.enabler.context.LocalizedContextImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  6138. dojo._hasResource["com.ibm.mm.enabler.context.LocalizedContextImpl"] = true;
  6139. dojo.provide("com.ibm.mm.enabler.context.LocalizedContextImpl");
  6140. dojo.declare("com.ibm.mm.enabler.context.LocalizedContextImpl", [com.ibm.mashups.enabler.context.LocalizedContext], {
  6141. constructor: function(preferredLocale, defaultLocale){
  6142. var nsf = com.ibm.mm.enabler.model.NameSpaceFactory;
  6143. this.ns = nsf.getNameSpaces([nsf.NS_ATOM, nsf.NS_XML]);
  6144. // if no locales are specified for this context, use the
  6145. // basic fallback mechanism (atom:title, atom:summary)
  6146. this.basicFallback = !(preferredLocale || defaultLocale);
  6147. // preferred locale
  6148. this.preferredLocale = preferredLocale || null;
  6149. if (this.preferredLocale === null) {
  6150. // get browser locale, respectively locale set with ibmConfig
  6151. if (typeof ibmConfig != "undefined" && ibmConfig !== null && typeof(ibmConfig.locale) != "undefined" && ibmConfig.locale !== null) {
  6152. this.preferredLocale = ibmConfig.locale;
  6153. }
  6154. else {
  6155. this.preferredLocale = (dojo.isIE ? navigator.userLanguage : navigator.language).toLowerCase();
  6156. }
  6157. }
  6158. // default locale
  6159. this.defaultLocale = defaultLocale || "en";
  6160. // title element
  6161. this._DEFAULT_TITLE = "atom:title";
  6162. // summary element
  6163. this._DEFAULT_DESCRIPTION = "atom:summary";
  6164. // title element language
  6165. this._DEFAULT_LOCALE = this._DEFAULT_TITLE + "/@xml:lang";
  6166. },
  6167. getPreferredLocale: function(){
  6168. return this.preferredLocale;
  6169. },
  6170. getDefaultLocale: function(){
  6171. return this.defaultLocale;
  6172. },
  6173. getLocale: function(localized){
  6174. // if no localized resource is specified, return null
  6175. if (typeof localized == "undefined" || localized === null) {
  6176. return null;
  6177. }
  6178. // check for default locale
  6179. if (this.basicFallback && dojo.isFunction(localized.getDefaultLocale)) {
  6180. // TODO only if localized object is not dirty
  6181. return localized.getDefaultLocale();
  6182. }
  6183. // resource locales
  6184. var localesArray = localized.getLocales();
  6185. switch (localesArray.length) {
  6186. case 0:
  6187. // there is no localization
  6188. return null;
  6189. case 1:
  6190. // there is only one localization, so use that
  6191. return com.ibm.mm.enabler.utils.LocaleHelper.normalizeLocale(localesArray[0]);
  6192. default:
  6193. var preferredMatch = com.ibm.mm.enabler.utils.LocaleHelper.matchLocale(this.preferredLocale, localesArray);
  6194. if (preferredMatch) {
  6195. // preferred was matched
  6196. return preferredMatch;
  6197. }
  6198. var defaultMatch = com.ibm.mm.enabler.utils.LocaleHelper.matchLocale(this.defaultLocale, localesArray);
  6199. if (defaultMatch) {
  6200. // default was matched
  6201. return defaultMatch;
  6202. }
  6203. // nothing was matched, return first (as defaultLocale is not available)
  6204. return com.ibm.mm.enabler.utils.LocaleHelper.normalizeLocale(localesArray[0]);
  6205. }
  6206. },
  6207. getTitle: function(localized){
  6208. // if no localized resource is specified, return null
  6209. if (typeof localized == "undefined" || localized === null) {
  6210. return null;
  6211. }
  6212. var title;
  6213. if (this.basicFallback && dojo.isFunction(localized.getDefaultTitle)) {
  6214. // TODO only if localized object is not dirty
  6215. title = localized.getDefaultTitle();
  6216. }
  6217. if (!title) {
  6218. var locale = this.getLocale(localized);
  6219. if (locale) {
  6220. title = localized.getTitle(locale);
  6221. }
  6222. }
  6223. if (typeof title == "undefined") {
  6224. title = null;
  6225. }
  6226. return title;
  6227. },
  6228. getDescription: function(localized){
  6229. // if no localized resource is specified, return null
  6230. if (typeof localized == "undefined" || localized === null) {
  6231. return null;
  6232. }
  6233. var description;
  6234. // basic fallback
  6235. if (this.basicFallback && dojo.isFunction(localized.getDefaultDescription)) {
  6236. // TODO only if localized object is not dirty
  6237. description = localized.getDefaultDescription();
  6238. }
  6239. if (!description) {
  6240. var locale = this.getLocale(localized);
  6241. if (locale) {
  6242. description = localized.getDescription(locale);
  6243. }
  6244. }
  6245. if (typeof description == "undefined") {
  6246. description = null;
  6247. }
  6248. return description;
  6249. },
  6250. getDisplayLocale: function(locales){
  6251. var localesArray = dojo.isArray(locales) ? locales : [locales];
  6252. if (ibmConfig && ibmConfig.displayLocale) {
  6253. var displayLocalesArray = ibmConfig.displayLocale.split(",");
  6254. com.ibm.mm.enabler.utils.LocaleHelper.normalizeLocale(displayLocalesArray);
  6255. for (var i = 0; i < displayLocalesArray.length; i++) {
  6256. var displayLocale = displayLocalesArray[i];
  6257. if (displayLocale) {
  6258. var match = com.ibm.mm.enabler.utils.LocaleHelper.matchLocale(displayLocale, localesArray);
  6259. if (match) {
  6260. return displayLocale;
  6261. }
  6262. }
  6263. }
  6264. }
  6265. return localesArray[0];
  6266. }
  6267. });
  6268. }
  6269. if(!dojo._hasResource["com.ibm.mashups.enabler.context.LocalizedContext"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  6270. dojo._hasResource["com.ibm.mashups.enabler.context.LocalizedContext"] = true;
  6271. dojo.provide("com.ibm.mashups.enabler.context.LocalizedContext");
  6272. }
  6273. if(!dojo._hasResource["com.ibm.mashups.enabler.context.PageContext_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  6274. dojo._hasResource["com.ibm.mashups.enabler.context.PageContext_API"] = true;
  6275. dojo.provide("com.ibm.mashups.enabler.context.PageContext_API");
  6276. dojo.provide("com.ibm.mashups.enabler.context.PageContext");
  6277. /**
  6278. * Page context to set the page title.
  6279. *
  6280. * @since 2.4
  6281. *
  6282. * @ibm-spi
  6283. * @ibm-module Base2
  6284. */
  6285. dojo.declare("com.ibm.mashups.enabler.context.PageContext", null, {
  6286. /**
  6287. * Sets the browser title. Note that the browser title is
  6288. * not persisted.
  6289. *
  6290. * @param {String} title the browser title
  6291. * @return {void}
  6292. */
  6293. setBrowserTitle: function(title){
  6294. }
  6295. });
  6296. }
  6297. if(!dojo._hasResource["com.ibm.mm.enabler.context.PageContextImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  6298. dojo._hasResource["com.ibm.mm.enabler.context.PageContextImpl"] = true;
  6299. dojo.provide("com.ibm.mm.enabler.context.PageContextImpl");
  6300. dojo.declare("com.ibm.mm.enabler.context.PageContextImpl", [com.ibm.mashups.enabler.context.PageContext], {
  6301. constructor: function(){
  6302. },
  6303. setBrowserTitle: function(title){
  6304. // decode &, < and >
  6305. dojo.doc.title = title.replace(/&amp;/g,"&").replace(/&quot;/g,"\"").replace(/&gt;/g,">").replace(/&lt;/g,"<");
  6306. }
  6307. });
  6308. com.ibm.mm.enabler.context.PageContext = new com.ibm.mm.enabler.context.PageContextImpl();
  6309. }
  6310. if(!dojo._hasResource["com.ibm.mashups.enabler.context.PageContext"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  6311. dojo._hasResource["com.ibm.mashups.enabler.context.PageContext"] = true;
  6312. dojo.provide("com.ibm.mashups.enabler.context.PageContext");
  6313. }
  6314. if(!dojo._hasResource["com.ibm.mashups.enabler.context.Factory_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  6315. dojo._hasResource["com.ibm.mashups.enabler.context.Factory_API"] = true;
  6316. dojo.provide("com.ibm.mashups.enabler.context.Factory_API");
  6317. dojo.provide("com.ibm.mashups.enabler.context.Factory");
  6318. /**
  6319. * Factory to get context objects.
  6320. *
  6321. * @ibm-module Base2
  6322. */
  6323. dojo.declare("com.ibm.mashups.enabler.context.Factory", null, {
  6324. /**
  6325. * Returns a LocalizedContext.
  6326. *
  6327. * @ibm-api
  6328. *
  6329. * @return {com.ibm.mashups.enabler.context.LocalizedContext} localized context.
  6330. */
  6331. getLocalizedContext: function(){
  6332. },
  6333. /**
  6334. * Returns a LocalizedContext for the specified locales.
  6335. *
  6336. * @ibm-spi
  6337. *
  6338. * @param {String} preferredLocale preferred locale to use; optional, defaults to the preferred
  6339. * locale set with the browser.
  6340. * @param {String} defaultLocale default locale to use; optional, defaults to the locale "en"
  6341. * @return {com.ibm.mashups.enabler.context.LocalizedContext} localized context for the specified locales.
  6342. */
  6343. getLocalizedContext: function(preferredLocale, defaultLocale){ // JSLINT-IGNORE: separation between public API and SPI
  6344. },
  6345. /**
  6346. * Returns a PageContext.
  6347. *
  6348. * @ibm-spi
  6349. * @since 2.4
  6350. *
  6351. * @return {com.ibm.mashups.enabler.context.PageContext} the page context
  6352. */
  6353. getPageContext: function(){
  6354. }
  6355. });
  6356. }
  6357. if(!dojo._hasResource["com.ibm.mm.enabler.context.FactoryImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  6358. dojo._hasResource["com.ibm.mm.enabler.context.FactoryImpl"] = true;
  6359. dojo.provide("com.ibm.mm.enabler.context.FactoryImpl");
  6360. // factory implementation
  6361. dojo.declare( "com.ibm.mm.enabler.context.FactoryImpl", [com.ibm.mashups.enabler.context.Factory],
  6362. {
  6363. constructor:function () {
  6364. },
  6365. getLocalizedContext: function(preferredLocale, defaultLocale) {
  6366. return new com.ibm.mm.enabler.context.LocalizedContextImpl(preferredLocale, defaultLocale);
  6367. },
  6368. getPageContext: function() {
  6369. return new com.ibm.mm.enabler.context.PageContextImpl();
  6370. }
  6371. }
  6372. );
  6373. // factory singleton
  6374. com.ibm.mashups.enabler.context.Factory = new com.ibm.mm.enabler.context.FactoryImpl();
  6375. }
  6376. if(!dojo._hasResource["com.ibm.mashups.enabler.context.Factory"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  6377. dojo._hasResource["com.ibm.mashups.enabler.context.Factory"] = true;
  6378. dojo.provide("com.ibm.mashups.enabler.context.Factory");
  6379. }
  6380. if(!dojo._hasResource["com.ibm.mashups.enabler.services.ConfigConstants"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  6381. dojo._hasResource["com.ibm.mashups.enabler.services.ConfigConstants"] = true;
  6382. dojo.provide("com.ibm.mashups.enabler.services.ConfigConstants");
  6383. /**
  6384. * This constants class contains well defined constants available to the config service.
  6385. * They are defined in the ConfigService.properties
  6386. * @ibm-spi
  6387. * @ibm-module Base2
  6388. */
  6389. dojo.declare("com.ibm.mashups.enabler.services.ConfigConstants", null, {
  6390. /**
  6391. * URL pointing to the proxy
  6392. * @type String
  6393. */
  6394. PROXY_URL: "com.ibm.mashups.proxy.url",
  6395. /**
  6396. * URL pointing to the hub
  6397. * @type String
  6398. */
  6399. HUB_URL: "com.ibm.mashups.hub.url",
  6400. /**
  6401. * URL pointing to login
  6402. * @type String
  6403. */
  6404. LOGIN_URL: "com.ibm.mashups.url.login",
  6405. /**
  6406. * URL pointing to logout
  6407. * @type String
  6408. */
  6409. LOGOUT_URL: "com.ibm.mashups.url.logout",
  6410. /**
  6411. * context root of the server
  6412. * @type String
  6413. */
  6414. CONTEXT_ROOT: "com.ibm.mashups.contextroot",
  6415. /**
  6416. * context root of the enabler component
  6417. * @type String
  6418. */
  6419. CONTEXT_ROOT_ENABLER: "com.ibm.mashups.contextroot.enabler",
  6420. /**
  6421. * context root of the builder component
  6422. * @type String
  6423. */
  6424. CONTEXT_ROOT_BUILDER: "com.ibm.mashups.contextroot.builder",
  6425. /**
  6426. * public name of the content handler servlet
  6427. * @type String
  6428. */
  6429. CONTENTHANDLER_PUBLIC: "com.ibm.mashups.contenthandler.public",
  6430. /**
  6431. * private name of the content handler servlet
  6432. * @type String
  6433. */
  6434. CONTENTHANDLER_PRIVATE: "com.ibm.mashups.contenthandler.private",
  6435. /**
  6436. * public name of the embedding handler servlet
  6437. * @type String
  6438. */
  6439. EMBEDDING_PUBLIC: "com.ibm.mashups.embedding.public",
  6440. /**
  6441. * private name of the content handler servlet
  6442. * @type String
  6443. */
  6444. EMBEDDING_PRIVATE: "com.ibm.mashups.embedding.private",
  6445. /**
  6446. * TBD
  6447. * @type String
  6448. */
  6449. THEMES_FEEDS_EXPIRATION: "themes.feed.expiration",
  6450. /**
  6451. * comma separated list of all available locales in the system
  6452. * @type String
  6453. */
  6454. AVAILABLE_LOCALES: "availableLocales",
  6455. /**
  6456. * the default locale of the mashups system
  6457. * @type String
  6458. */
  6459. DEFAULT_LOCALE: "default.locale",
  6460. /**
  6461. * the default locale that's based on user preference for UI components to display date,currency etc.
  6462. * @type String
  6463. */
  6464. DISPLAY_LOCALE: "displayLocale",
  6465. /**
  6466. * defines whether PUT/DELETE tunneling over POST should be used
  6467. * @type String
  6468. */
  6469. TUNNEL_MODE: "tunnel.mode",
  6470. /**
  6471. * turns on debugging
  6472. * @type String
  6473. */
  6474. CLIENT_IS_DEBUG: "isDebug",
  6475. /**
  6476. * BiDi setting
  6477. * @type String
  6478. */
  6479. CLIENT_IS_BIDI: "isBidi",
  6480. /**
  6481. * Definition Url list of the widgets which is sandbox disabled: /dataEditor/dataEditor.xml,id1,id2
  6482. * @type String
  6483. */
  6484. WIDGETDEFID_SANDBOX_DISABLED: "com.ibm.mashups.sandbox.force.disable",
  6485. /**
  6486. * Trace configuration for the client runtime
  6487. * @type String
  6488. */
  6489. TRACE_CONFIG: "traceConfig",
  6490. /**
  6491. * tbd
  6492. * @type String
  6493. */
  6494. CLIENT_POPUP_CONSOLE: "popupConsole",
  6495. /**
  6496. * tbd
  6497. * @type String
  6498. */
  6499. CLIENT_ALLOW_PUBLISH_LOGGING: "allowPublishLogging",
  6500. /**
  6501. * tbd
  6502. * @type String
  6503. */
  6504. CLIENT_ALLOW_PUBLISH_TRACING: "allowPublishTracing",
  6505. /**
  6506. * tbd
  6507. * @type String
  6508. */
  6509. CLIENT_ADDITIONAL_SERVICES: "additionalServices",
  6510. /**
  6511. * Theme id used in case no theme is set.
  6512. * @type String
  6513. */
  6514. CLIENT_DEFAULT_THEME_ID: "com.ibm.mashups.theme.defaultThemeId",
  6515. /**
  6516. * tbd
  6517. * @type String
  6518. */
  6519. CLIENT_PAGE_SOURCE_READ_ONLY: "pageSourceReadOnly",
  6520. /**
  6521. * Group name used for auto accepting pages
  6522. * @type String
  6523. */
  6524. CLIENT_AUTO_ACCEPT_SHARED_GROUPNAME: "autoAcceptSharedGroupName",
  6525. /**
  6526. * Default value for page level auto wiring enablement
  6527. * @type String
  6528. */
  6529. AUTO_WIRING_DEFAULT_ENABLED: "autoWiringDefaultEnabled",
  6530. /**
  6531. * tbd
  6532. * @type String
  6533. */
  6534. CLIENT_USER_ID_KEY: "userIdKey",
  6535. /**
  6536. * tbd
  6537. * @type String
  6538. */
  6539. CLIENT_GROUP_CN_KEY: "groupCNKey",
  6540. /**
  6541. * Url used to fetch the service document
  6542. * @type String
  6543. */
  6544. SERVICE_DOCUMENT_URL: "serviceDocumentUrl",
  6545. /**
  6546. * turns on multipart support
  6547. * @type String
  6548. */
  6549. MULTIPART_ENABLED: "com.ibm.mashups.multipart.enabled",
  6550. /**
  6551. * if multipart support is enabled, determines if requests are correlated
  6552. * by hostname
  6553. * @type String
  6554. */
  6555. MULTIPART_CORRELATE_HOSTS: "com.ibm.mashups.multipart.correlatehosts",
  6556. /**
  6557. * if multipart support is enabled, should URLs with query strings be
  6558. * considered cacheable
  6559. * @type String
  6560. */
  6561. MULTIPART_CACHE_QUERIES: "com.ibm.mashups.multipart.cachequeries",
  6562. /**
  6563. * Returns the semicolon separated list of Endpoint IDs
  6564. * @type String
  6565. */
  6566. ENDPOINTS: "endpointIDs",
  6567. /**
  6568. * Returns the name of the Endpoints Config Provider
  6569. * @type String
  6570. */
  6571. ENDPOINT_CONFIG_PROVIDER: "Endpoints",
  6572. /**
  6573. * Returns the name of the Anonymous User Config setting
  6574. * @type {String}
  6575. */
  6576. ANONYMOUS_USER: "anonymousUser",
  6577. /**
  6578. * MetaData name used to recognize whether a page is hidden or not
  6579. * @type String
  6580. */
  6581. NAVIGATION_HIDDEN: "com.ibm.mashups.navigation.hidden",
  6582. /**
  6583. * MetaData name used to recognize whether a space is hidden or not
  6584. * @type String
  6585. */
  6586. SPACE_HIDDEN: "com.ibm.mashups.space.hidden",
  6587. /**
  6588. * Returns the name of the current User Config setting
  6589. * @type String
  6590. */
  6591. USER: "user",
  6592. /**
  6593. * Returns the name of subdomains Config setting, subdomains are used to create sandboxed iwidgets
  6594. * @type String
  6595. */
  6596. SUBDOMAINS: "subdomains",
  6597. /**
  6598. * Returns the name of server domain Config setting
  6599. * @type String
  6600. */
  6601. SERVERDOMAIN: "serverdomain",
  6602. /**
  6603. * Returns the name of sandboxenabled Config setting, sandboxed feature is disabled if this configuration is set to false
  6604. * @type String
  6605. */
  6606. SANDBOXENABLED: "sandboxenabled",
  6607. /**
  6608. * Returns the name of config setting that decides if subdomain should be reused when an existing sandboxed iwidget is removed from the page.
  6609. * @type String
  6610. */
  6611. SUBDOMAINREUSE: "subdomainreuse",
  6612. /**
  6613. * MetaData name used to indicate attributes that need to added to url
  6614. * @type String
  6615. */
  6616. NAVSTATE_PERSISTENCE_URL: "navstate.persistence.url",
  6617. /**
  6618. * MetaData name used to indicate attributes that need to added to persistence store
  6619. * @type String
  6620. */
  6621. NAVSTATE_PERSISTENCE_PSTORE: "navstate.persistence.pstore",
  6622. /**
  6623. * MetaData name used to indicate number of widgets whose navigation state will be added to url
  6624. * @type String
  6625. */
  6626. NAVSTATE_PERSISTENCE_URL_LIMIT: "navstate.persistence.url.limit",
  6627. /**
  6628. * MetaData name used to indicate number of sharedparametersets whose navigation state will be added to url
  6629. * @type String
  6630. */
  6631. NAVSTATE_PERSISTENCE_URL_SPLIMIT: "navstate.persistence.url.splimit",
  6632. /**
  6633. * MetaData name used to indicate if navigation state is huffmann encoded or not
  6634. * @type String
  6635. */
  6636. NAVSTATE_HUFFMANNENCODE_ENABLED: "navstate.huffmannencode.enabled",
  6637. /**
  6638. * MetaData name used to indicate the html fragment that's displayed when a widget is under loading
  6639. * @type String
  6640. */
  6641. LOADING_HTML: "loadingHTML",
  6642. /**
  6643. * Specified whether pageloading should be optimized (Multipart)
  6644. * @type String
  6645. */
  6646. PAGE_LOAD_OPTIMIZATION: "pageLoadOptimization",
  6647. /**
  6648. * Specified whether pageloading should be optimized for themes (Multipart)
  6649. * @type String
  6650. */
  6651. PAGE_LOAD_OPTIMIZATION_THEME: "pageLoadOptimizationTheme",
  6652. /**
  6653. * Specifies whether application widgets should be optimized (Multipart)
  6654. * @type String
  6655. */
  6656. PAGE_LOAD_OPTIMIZATION_APP_WIDGETS: "pageLoadOptimizationAppWidgets",
  6657. /**
  6658. * Allows to create New Spaces and Pages for anonymous users
  6659. * @type String
  6660. */
  6661. ANONYMOUS_ALLOW_CREATE: "com.ibm.mashups.anonymous.allow.create",
  6662. /**
  6663. * If displayName is not sent from server use this property for User Display Name
  6664. * @type String
  6665. */
  6666. DEFAULT_USER_DISPLAY_PROP: "com.ibm.mashups.default.user.display.prop",
  6667. /**
  6668. * The product name which will show up in the browser title, other product can replace it.
  6669. * @type String
  6670. */
  6671. PRODUCT_NAME: "com.ibm.mashups.productname",
  6672. /**
  6673. * If displayName is not sent from server use this property for Group Display Name
  6674. * @type String
  6675. */
  6676. DEFAULT_GROUP_DISPLAY_PROP: "com.ibm.mashups.default.group.display.prop",
  6677. /**
  6678. * The unique name of the welcome space
  6679. * @type String
  6680. */
  6681. WELCOME_SPACE_ID: "com.ibm.mashups.welcome.space.name",
  6682. /**
  6683. * The filter as regexp for characters used on page and space title.
  6684. * @type String
  6685. */
  6686. BUILDER_TITLE_FILTER_REGEXP : "com.ibm.mashups.builder.filter.title.regexp",
  6687. /**
  6688. * ID of the Anonymous Virtual User
  6689. * @type String
  6690. */
  6691. ANON_VIRTUAL_USER_ID : "com.ibm.mashups.anonUserId",
  6692. /**
  6693. * ID of the All Authenticated Users Virtual Group
  6694. * @type String
  6695. */
  6696. ALL_AUTH_VIRTUAL_GROUP_ID : "com.ibm.mashups.allAuthGroupId",
  6697. /**
  6698. * The server type this enabler is connected to. It can be either SERVER_TYPE_MASHUPS or SERVER_TYPE_PORTAL
  6699. * @type String
  6700. */
  6701. SERVER_TYPE : "com.ibm.mashups.server",
  6702. /**
  6703. * The server type value for Lotus Mashups
  6704. * @type String
  6705. */
  6706. SERVER_TYPE_MASHUPS : "Lotus_Mashups",
  6707. /**
  6708. * The server type value for WebSphere Portal
  6709. * @type String
  6710. */
  6711. SERVER_TYPE_PORTAL : "WebSphere_Portal",
  6712. /**
  6713. * The server type value for Business Space
  6714. */
  6715. SERVER_TYPE_BSPACE : "Business_Space",
  6716. /**
  6717. * Anonymous mode enabled default is false
  6718. * @type String
  6719. */
  6720. ANON_MODE_ENABLED : "com.ibm.mashups.anonymous.mode",
  6721. /**
  6722. * Setting to true will prevent search clients for automatically adding wildcards
  6723. * to user and group searches. Default is false.
  6724. * @type String
  6725. */
  6726. AUTO_WILDCARD_DISABLED : "com.ibm.mashups.autoWildcardSearchDisabled",
  6727. /**
  6728. * Sets the name of the property in the ContextMenu_Provider to use for the
  6729. * context menu
  6730. * @type String
  6731. */
  6732. CONTEXT_MENU_NAME : "com.ibm.mashups.contextmenu.name",
  6733. WIDGET_BUILDER_ENABLED : "com.ibm.mashups.widgetBuilder.enabled",
  6734. CREATE_SPACE_TEMPLATE_MODE: "createSpaceOnTemplateMode",
  6735. FAVORITE_SPACES_MAXIMUM_NUMBER: "favorite.spaces.maximum.number",
  6736. RECENT_SPACES_MAXIMUM_NUMBER: "recent.spaces.maximum.number",
  6737. /**
  6738. * Register resources that's preloaded with enabler so enabler won't load it anymore
  6739. * For example:
  6740. * [{globalid: "lconn.coreUtilities", version: "2.5"}, {globalid: "lconn.coreCSS", version: "2.5"}]
  6741. * @type String
  6742. */
  6743. REGISTER_LOADEDRESOURCES:"register.loadedresources",
  6744. /**
  6745. * Defines the persistence mode that should be used by the iContext. Default is <tt>DOM</tt>.
  6746. */
  6747. PERSISTENCE_MODE: "com.ibm.mashups.enabler.icontext.persistence.mode",
  6748. /**
  6749. * Defines the read-only persistence mode for the event provider that is used by the iContext. It overwrites any mode defined as part of <tt>PERSISTENCE_MODE</tt>.Default is <tt>DOM</tt>.
  6750. */
  6751. PERSISTENCE_MODE_EVENTS: "com.ibm.mashups.enabler.icontext.persistence.mode.events",
  6752. /**
  6753. * Defines the modifiable persistence mode for the event provider that is used by the iContext. It overwrites any mode defined as part of <tt>PERSISTENCE_MODE</tt>.Default is <tt>DOM</tt>.
  6754. */
  6755. PERSISTENCE_MODE_EVENTS_MODIFIABLE: "com.ibm.mashups.enabler.icontext.persistence.mode.events.modifiable",
  6756. /**
  6757. * Defines the read-only persistence mode for the wire provider that is used by the iContext. It overwrites any mode defined as part of <tt>PERSISTENCE_MODE</tt>.Default is <tt>DOM</tt>.
  6758. */
  6759. PERSISTENCE_MODE_WIRES: "com.ibm.mashups.enabler.icontext.persistence.mode.wires",
  6760. /**
  6761. * Defines the modifiable persistence mode for the wire provider that is used by the iContext. It overwrites any mode defined as part of <tt>PERSISTENCE_MODE</tt>.Default is <tt>DOM</tt>.
  6762. */
  6763. PERSISTENCE_MODE_WIRES_MODIFIABLE: "com.ibm.mashups.enabler.icontext.persistence.mode.wires.modifiable",
  6764. /**
  6765. * Defines the read-only persistence mode for the attributes provider that is used by the iContext. It overwrites any mode defined as part of <tt>PERSISTENCE_MODE</tt>.Default is <tt>DOM</tt>.
  6766. */
  6767. PERSISTENCE_MODE_ATTRIBUTES: "com.ibm.mashups.enabler.icontext.persistence.mode.attributes",
  6768. /**
  6769. * Defines the modifiable persistence mode for the attributes provider that is used by the iContext. It overwrites any mode defined as part of <tt>PERSISTENCE_MODE</tt>.Default is <tt>DOM</tt>.
  6770. */
  6771. PERSISTENCE_MODE_ATTRIBUTES_MODIFIABLE: "com.ibm.mashups.enabler.icontext.persistence.mode.attributes.modifiable",
  6772. /**
  6773. * Defines whether the json attributes implementation will be injecting the attributes defined in the widget xml
  6774. * as well into the attributes map. This will only apply if the json attributes have been enabled through the PERSISTENCE_MODE_ATTRIBUTES setting.
  6775. */
  6776. PERSISTENCE_MODE_ATTRIBUTES_JSON_INJECTXML: "com.ibm.mashups.enabler.icontext.attributes.json.injectxml",
  6777. /**
  6778. * Defines whether autocommit is enabled on the iContext. If set to <tt>true</tt> the iContext will automatically commit data to the
  6779. * backend if commit is called on e.g. the iWidgetAttributes.
  6780. */
  6781. ICONTEXT_AUTO_COMMIT: "com.ibm.mashups.enabler.icontext.autocommit",
  6782. ID_PREFIX: "com.ibm.mashups.iWidget.idPrefix",
  6783. /**
  6784. * Defines how violations of enabler usage is prompted to the user; see
  6785. * <ul>
  6786. * <li><code>API_ENFORCEMENT_MODE_WARN</code></li>
  6787. * <li><code>API_ENFORCEMENT_MODE_ERROR</code></li>
  6788. * </ul>
  6789. * Defaults to <code>API_ENFORCEMENT_MODE_WARN</code>.
  6790. * @type String
  6791. * @private
  6792. */
  6793. API_ENFORCEMENT_MODE: "com.ibm.mashups.enabler.enforcement",
  6794. /**
  6795. * Warnings will be prompted in the console denoting usage errors of the enabler api.
  6796. * @type String
  6797. * @private
  6798. */
  6799. API_ENFORCEMENT_MODE_WARN: "warning",
  6800. /**
  6801. * Errors will be thrown denoting usage errors of the enabler api, note that
  6802. * this potentially breaks the driver if the api is used incorrectly.
  6803. * @type String
  6804. * @private
  6805. */
  6806. API_ENFORCEMENT_MODE_ERROR: "error",
  6807. /**
  6808. * With this option the location (a URL) of the widget which will be displayed for non previewable content can be defined.
  6809. * If empty (thats the default) the widget delivered with the enabler will be used.
  6810. *
  6811. * @since 3.0
  6812. * @type String
  6813. */
  6814. NON_PREVIEWABLE_WIDGET_LOCATION: "com.ibm.mashups.enabler.layout.widget.NonPreviewableContentWidget.location",
  6815. /**
  6816. * Size limit of page descriptions, implied from persistence
  6817. * @since 3.0
  6818. * @type String
  6819. */
  6820. LIMIT_PAGE_DESCRIPTION: "com.ibm.mashups.persistence.page.description.limit",
  6821. /**
  6822. * Defines whether personalize is allowed or not for users. Defaults to true.
  6823. * @since 3.0
  6824. * @type Boolean
  6825. */
  6826. WIDGET_PERSONALIZE_ENABLED: "com.ibm.mashups.widget.attributes.personalize.enabled",
  6827. /**
  6828. * Defines maximum page number when creating page base on page from hub. Defaults to 50.
  6829. * @since 3.0
  6830. * @type String
  6831. */
  6832. SPACEMANAGER_PAGE_QUERYCOUNT : "com.ibm.mashups.spacemanager.page.queryCount",
  6833. /**
  6834. * Defines the search keyword when pages in hub are queried. Keep it empty will return all pages.
  6835. * @since 3.0
  6836. * @type String
  6837. */
  6838. SPACEMANAGER_PAGE_QUERYKEYWORD : "com.ibm.mashups.spacemanager.page.queryKeyword",
  6839. /**
  6840. * Defines maximum space number when creating space base on space from hub. Defaults to 50.
  6841. * @since 3.0
  6842. * @type String
  6843. */
  6844. SPACEMANAGER_SPACE_QUERYCOUNT : "com.ibm.mashups.spacemanager.spacetemplate.queryCount",
  6845. /**
  6846. * Defines the search keyword when spaces in hub are queried. Keep it empty will return all spaces.
  6847. * @since 3.0
  6848. * @type String
  6849. */
  6850. SPACEMANAGER_SPACE_QUERYKEYWORD : "com.ibm.mashups.spacemanager.spacetemplate.queryKeyword",
  6851. /**
  6852. * Defines the search keyword when spaces in hub are queried. Keep it empty will return all spaces.
  6853. * @since 3.0
  6854. * @type String
  6855. */
  6856. LOCALAPPS_REGEX : "com.ibm.mashups.multipart.localapps.regex",
  6857. /**
  6858. * Defines the format (as a regular expression) of the server side object IDs.
  6859. * @since 3.0
  6860. * @type String
  6861. */
  6862. SERVER_OBJECT_ID_FORMAT: "com.ibm.mashups.server.oid.format",
  6863. /**
  6864. * Defines whether to use queued widget rendering. Default to true.
  6865. * @since 3.0.0.1
  6866. * @type Boolean
  6867. */
  6868. QUEUE_RENDERING: "com.ibm.mashups.queueRendering"
  6869. });
  6870. com.ibm.mashups.enabler.services.ConfigConstants = new com.ibm.mashups.enabler.services.ConfigConstants();
  6871. }
  6872. if(!dojo._hasResource["com.ibm.mashups.enabler.services.ConfigObject_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  6873. dojo._hasResource["com.ibm.mashups.enabler.services.ConfigObject_API"] = true;
  6874. dojo.provide("com.ibm.mashups.enabler.services.ConfigObject_API");
  6875. dojo.provide("com.ibm.mashups.enabler.services.ConfigObject");
  6876. /**
  6877. * The Config Object allows to access config variables as defined by the system.
  6878. * for a specific config provider.
  6879. * @ibm-spi
  6880. * @ibm-module Base2
  6881. */
  6882. dojo.declare("com.ibm.mashups.enabler.services.ConfigObject", null, {
  6883. /**
  6884. * This method returns the value of the config variable as defined by the system
  6885. * @param {String} name the name of the config variable
  6886. * @return {String} the value of the config variable. Maybe be NULL.
  6887. */
  6888. getValue: function(name) {
  6889. return null;
  6890. },
  6891. /**
  6892. * This method returns the value of the config variable as defined by the system in a async way
  6893. * @param {String} name the name of the config variable
  6894. * @return {com.ibm.mashups.enabler.Deferred} a deferred object used to start this operation. The return value
  6895. * when executed through the deferred object is the value of the config variable. Maybe be NULL
  6896. */
  6897. getValueDeferred: function(name) {
  6898. return null;
  6899. }
  6900. });
  6901. }
  6902. if(!dojo._hasResource["com.ibm.mm.enabler.services.ConfigObjectDefaultImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  6903. dojo._hasResource["com.ibm.mm.enabler.services.ConfigObjectDefaultImpl"] = true;
  6904. dojo.provide("com.ibm.mm.enabler.services.ConfigObjectDefaultImpl");
  6905. dojo.declare("com.ibm.mm.enabler.services.ConfigObjectDefaultImpl", [com.ibm.mashups.enabler.services.ConfigObject], {
  6906. constructor: function(provider, configService) {
  6907. this.provider = provider;
  6908. this.configService = configService;
  6909. this.ns = {};
  6910. this.ns.app = "http://www.w3.org/2007/app";
  6911. this.ns.atom = "http://www.w3.org/2005/Atom";
  6912. },
  6913. /**
  6914. * @deprecated
  6915. */
  6916. getPreferenceValue: function( /*string*/name) {
  6917. if (this.provider == "all") {
  6918. return this.configService.getValue(name);
  6919. }
  6920. else {
  6921. return this._getValue(this.provider, name);
  6922. }
  6923. return null;
  6924. },
  6925. getValue: function( /*string*/name) {
  6926. if (this.provider == "all") {
  6927. return this.configService.getValue(name, internal);
  6928. }
  6929. else {
  6930. return this._getValue(this.provider, name);
  6931. }
  6932. return null;
  6933. },
  6934. _getValue: function(/*string*/provider, /*string*/ name) {
  6935. return null;
  6936. },
  6937. getValueDeferred: function(/*string*/name){
  6938. if (this.provider == "all") {
  6939. return new com.ibm.mm.enabler.DeferredImpl(this, function(deferred, sync, name) {
  6940. var callBack = deferred.getFinishedCallback();
  6941. var retValue = this.configService.getValue(name, internal);
  6942. if (retValue && callBack ) {
  6943. callBack(retValue, com.ibm.mm.enabler.model.HttpStatusCodes.HTTP_OK, deferred.getFinishedCallbackParameters());
  6944. }
  6945. return retValue;
  6946. });
  6947. }
  6948. else {
  6949. return this._getValueDeferred(this.provider, name);
  6950. }
  6951. },
  6952. _getValueDeferred: function(/*string*/provider, /*string*/ name) {
  6953. return null;
  6954. }
  6955. });
  6956. // IMPORTANT
  6957. // ibmConfig.enablerLayerModules is a comma separated string of all supported modules at runtime
  6958. // This section dynamically loads the Extended representation when the variable enablerLayerModules contains the given module
  6959. if ((ibmConfig.enablerLayerModules) && (dojo.indexOf(ibmConfig.enablerLayerModules, "Base")>=0)) {
  6960. dojo["require"]("com.ibm.mm.enabler.services.ConfigObjectExtendedImpl"); // JSLINT-IGNORE: This needs to be done to allow modularization and to support the minimal layer
  6961. }
  6962. }
  6963. if(!dojo._hasResource["com.ibm.mashups.enabler.services.ConfigObject"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  6964. dojo._hasResource["com.ibm.mashups.enabler.services.ConfigObject"] = true;
  6965. dojo.provide("com.ibm.mashups.enabler.services.ConfigObject");
  6966. }
  6967. if(!dojo._hasResource["com.ibm.mashups.enabler.services.ConfigService_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  6968. dojo._hasResource["com.ibm.mashups.enabler.services.ConfigService_API"] = true;
  6969. dojo.provide("com.ibm.mashups.enabler.services.ConfigService_API");
  6970. dojo.provide("com.ibm.mashups.enabler.services.ConfigService");
  6971. /**
  6972. * The Config Service allows to access config variables as defined by the system.
  6973. * The service can be retrieved using the following code: <br>
  6974. * <code>var configService = com.ibm.mashups.services.ServiceManager.getService(<br/>
  6975. * &nbsp;&nbsp;&nbsp;&nbsp;com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);</code><br/>
  6976. * @ibm-spi
  6977. * @ibm-module Base2
  6978. */
  6979. dojo.declare("com.ibm.mashups.enabler.services.ConfigService", null, {
  6980. /**
  6981. * The service name to be used to fetch the service from the ServiceManager
  6982. * @type String
  6983. */
  6984. SERVICE_NAME: "configService",
  6985. /**
  6986. * This method returns the value of the config variable as defined by the system
  6987. * @param {String} name the name of the config variable
  6988. * @return {String} the value of the config variable. Maybe be NULL.
  6989. */
  6990. getValue: function(name) {
  6991. return null;
  6992. },
  6993. /**
  6994. * This method returns the value of the config object for a config provider
  6995. * @param {String} name the name of the config provider
  6996. * @return {com.ibm.mashups.enabler.services.ConfigObject} the config provider. Maybe be NULL.
  6997. */
  6998. getConfigObject: function(name) {
  6999. return null;
  7000. },
  7001. /**
  7002. * This method returns the Config Provider names. Each Config Provider will
  7003. * have a corresponding ConfigObject.
  7004. * @return {String[]} the config provider names. Never NULL.
  7005. */
  7006. getConfigProviderNames: function() {
  7007. return null;
  7008. }
  7009. });
  7010. // make sure we can reference this globally
  7011. com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME = "configService";
  7012. }
  7013. if(!dojo._hasResource["com.ibm.mashups.services.ServiceManager_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7014. dojo._hasResource["com.ibm.mashups.services.ServiceManager_API"] = true;
  7015. dojo.provide("com.ibm.mashups.services.ServiceManager_API");
  7016. dojo.provide("com.ibm.mashups.services.ServiceManager");
  7017. /**
  7018. * This interface manages services that are provided to the system, i.e. to iWidgets and other components.<br/>
  7019. * It provides capability to access Services in Lotus Mashups. <br/>
  7020. * By default EventService and ConfigService are provided.<br/>
  7021. * Page components are able to use event services by using following api:<p/>
  7022. * <code>var eventService = com.ibm.mashups.services.ServiceManager.getService(<br/>
  7023. * &nbsp;&nbsp;&nbsp;&nbsp;com.ibm.mashups.iwidget.services.EventService.SERVICE_NAME);</code><br/>
  7024. * <p/><p/>
  7025. * <b>Configuration of services:</b><br/>
  7026. * This section describes how each service is configured and how additional services can be added.<p/>
  7027. *
  7028. * Through the ConfigService.properties one can define an additional property named "additionalServices"
  7029. * defining additional services besides EventService and ConfigService.<p/>
  7030. * Each entry should have the following format.<p />
  7031. * <code>"name": service name.</code><br/>
  7032. * <code>"path": url that point to the service js file.</code><br/>
  7033. * <code>"baseClass": the class that implements the service. one instance of this class will be generated.</code><br />
  7034. * <p/>
  7035. * Example:<br/>
  7036. * &nbsp;&nbsp;&nbsp;additionalServices = [<br/>
  7037. * &nbsp;&nbsp;&nbsp;{ "name":"SecurityService",<br/>
  7038. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"path":"/mum/js/com/ibm/enabler/iw/securityservices.js",<br/>
  7039. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"baseClass":"com.ibm.mm.iwidget.services.SecurityService"}<br/>
  7040. * &nbsp;&nbsp;&nbsp;] <p />
  7041. *
  7042. * @ibm-spi
  7043. * @ibm-module Base2
  7044. */
  7045. dojo.declare("com.ibm.mashups.services.ServiceManager",null,
  7046. {
  7047. /**
  7048. * @private
  7049. */
  7050. constructor:function(){
  7051. },
  7052. /**
  7053. This interface allow page components to get the required service.
  7054. @param{String} serviceName required service name that's used to uniquely identify a service .
  7055. @type Object
  7056. @returns{Object} an instance of required service. NULL if configured incorrectly.
  7057. */
  7058. getService:function(serviceName) {
  7059. }
  7060. }
  7061. );
  7062. }
  7063. if(!dojo._hasResource["com.ibm.mashups.services.ServiceManager"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7064. dojo._hasResource["com.ibm.mashups.services.ServiceManager"] = true;
  7065. dojo.provide("com.ibm.mashups.services.ServiceManager");
  7066. }
  7067. if(!dojo._hasResource["com.ibm.mm.services.ServiceManagerImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7068. dojo._hasResource["com.ibm.mm.services.ServiceManagerImpl"] = true;
  7069. dojo.provide("com.ibm.mm.services.ServiceManagerImpl");
  7070. dojo.declare("com.ibm.mm.services.ServiceManagerImpl", com.ibm.mashups.services.ServiceManager, {
  7071. constructor: function() {
  7072. this._serviceEntries = {};
  7073. //allow overwritten if ibmConfig.loadServices is set
  7074. ibmConfig = ibmConfig || {};
  7075. ibmConfig.additionalServices = ibmConfig.additionalServices || null;
  7076. if (ibmConfig.additionalServices) {
  7077. var entries = dojo.fromJson(ibmConfig.additionalServices);
  7078. for (var i in entries) {
  7079. if (Object.prototype.hasOwnProperty.call(entries,i)) {
  7080. var anEntry = entries[i];
  7081. this._serviceEntries[anEntry.name] = anEntry;
  7082. }
  7083. }
  7084. }
  7085. },
  7086. getService: function(serviceName) {
  7087. var serviceEntry = this._serviceEntries[serviceName];
  7088. serviceEntry = serviceEntry || null;
  7089. if (serviceEntry !== null) {
  7090. var serviceHandler = serviceEntry.serviceHandler;
  7091. serviceHandler = serviceHandler || null;
  7092. if (serviceHandler === null) {
  7093. // assume js is already loaded, create service object
  7094. serviceHandler = this._createService(serviceEntry);
  7095. serviceHandler = serviceHandler || null;
  7096. if (serviceHandler === null) {
  7097. this._loadScript(serviceEntry);
  7098. // serviceHandler = this._createService(serviceEntry);
  7099. }
  7100. else {
  7101. this._serviceEntries[serviceName].serviceHandler = serviceHandler;
  7102. }
  7103. }
  7104. }
  7105. return this._serviceEntries[serviceName].serviceHandler;
  7106. },
  7107. //if serviceHandler is String, then it's baseClass
  7108. //if it's object, then it's the service handler instance
  7109. setService: function(serviceName, serviceHandler) {
  7110. serviceHandler = serviceHandler || null;
  7111. if (serviceHandler === null) {
  7112. return null;
  7113. }
  7114. //create new service or overwrite an existing service
  7115. var serviceEntry = this._serviceEntries[serviceName];
  7116. serviceEntry = serviceEntry || null;
  7117. if (serviceEntry !== null) {
  7118. delete this._serviceEntries[serviceName];
  7119. }
  7120. if (!this._serviceEntries[serviceName]) {
  7121. this._serviceEntries[serviceName] = {};
  7122. }
  7123. if (dojo.isString(serviceHandler)) {
  7124. this._serviceEntries[serviceName].baseClass = serviceHandler;
  7125. }
  7126. else {
  7127. this._serviceEntries[serviceName].serviceHandler = serviceHandler;
  7128. }
  7129. },
  7130. _loadScript: function(serviceEntry) {
  7131. var me = this;
  7132. dojo.xhrGet({
  7133. url: serviceEntry.path,
  7134. handleAs: "text",
  7135. sync: true,
  7136. load: function(result) {
  7137. dojo.eval(result); // JSLINT-IGNORE: We have to evaluate the services JavaScript in this case
  7138. var serviceHandler = me._createService(serviceEntry);
  7139. if (typeof serviceHandler != "undefined" && serviceHandler !== null) {
  7140. var serviceName = serviceEntry.name;
  7141. serviceEntry.serviceHandler = serviceHandler;
  7142. }
  7143. },
  7144. error: function(data, ioArgs) {
  7145. }
  7146. });
  7147. },
  7148. _createService: function(serviceEntry) {
  7149. var service = null;
  7150. try {
  7151. service = new (dojo.getObject(serviceEntry.baseClass))();
  7152. }
  7153. catch (err) {
  7154. }
  7155. return service;
  7156. }
  7157. });
  7158. com.ibm.mashups.services.ServiceManager = new com.ibm.mm.services.ServiceManagerImpl();
  7159. }
  7160. if(!dojo._hasResource["com.ibm.mm.enabler.services.AbstractConfigServiceImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7161. dojo._hasResource["com.ibm.mm.enabler.services.AbstractConfigServiceImpl"] = true;
  7162. dojo.provide("com.ibm.mm.enabler.services.AbstractConfigServiceImpl");
  7163. dojo.declare("com.ibm.mm.enabler.services.AbstractConfigServiceImpl", com.ibm.mashups.enabler.services.ConfigService, {
  7164. constructor: function(){
  7165. },
  7166. /**
  7167. * @deprecated
  7168. */
  7169. getPreferenceValue: function( /*string*/name){
  7170. return this.getValue(name);
  7171. },
  7172. getValue: function( /*string*/name, internal){
  7173. var value = ibmConfig[name];
  7174. return value;
  7175. },
  7176. getConfigObject: function(/*string*/configProvider){
  7177. return null;
  7178. },
  7179. getConfigProviderNames: function(){
  7180. return null;
  7181. }
  7182. });
  7183. }
  7184. if(!dojo._hasResource["com.ibm.mm.enabler.services.ConfigServiceDefaultImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7185. dojo._hasResource["com.ibm.mm.enabler.services.ConfigServiceDefaultImpl"] = true;
  7186. dojo.provide("com.ibm.mm.enabler.services.ConfigServiceDefaultImpl");
  7187. // inject this service into the ServiceManager at the end. Therefore we have to require the implementation
  7188. //
  7189. //
  7190. //
  7191. dojo.declare("com.ibm.mm.enabler.services.ConfigServiceDefaultImpl", [com.ibm.mm.enabler.services.AbstractConfigServiceImpl], {
  7192. constructor: function() {
  7193. },
  7194. _getConfigObject: function(/*string*/configProvider) {
  7195. if (!ibmConfig["CO_" + configProvider]) {
  7196. var co = new com.ibm.mm.enabler.services.ConfigObjectDefaultImpl(configProvider, this);
  7197. ibmConfig["CO_" + configProvider] = co;
  7198. }
  7199. return ibmConfig["CO_" + configProvider];
  7200. },
  7201. _getConfigProviderNames: function() {
  7202. var ret = [];
  7203. ret.push("all");
  7204. return ret;
  7205. },
  7206. getValue: function(name) {
  7207. var ret = this.inherited(arguments, [name, true]);
  7208. return ret;
  7209. },
  7210. getConfigObject: function(name) {
  7211. var ret = this._getConfigObject(name);
  7212. return ret;
  7213. },
  7214. getConfigProviderNames: function() {
  7215. var ret = this._getConfigProviderNames();
  7216. return ret;
  7217. }
  7218. });
  7219. com.ibm.mashups.services.ServiceManager.setService("configService", "com.ibm.mm.enabler.services.ConfigServiceDefaultImpl");
  7220. // IMPORTANT
  7221. // ibmConfig.enablerLayerModules is a comma separated string of all supported modules at runtime
  7222. // This section dynamically loads the Extended representation when the variable enablerLayerModules contains the given module
  7223. if ((ibmConfig.enablerLayerModules) && (dojo.indexOf(ibmConfig.enablerLayerModules, "Base")>=0)) {
  7224. dojo["require"]("com.ibm.mm.enabler.services.ConfigServiceExtendedImpl"); // JSLINT-IGNORE: This needs to be done to allow modularization and to support the minimal layer
  7225. }
  7226. }
  7227. if(!dojo._hasResource["com.ibm.mashups.enabler.services.ConfigService"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7228. dojo._hasResource["com.ibm.mashups.enabler.services.ConfigService"] = true;
  7229. dojo.provide("com.ibm.mashups.enabler.services.ConfigService");
  7230. }
  7231. if(!dojo._hasResource["com.ibm.mashups.enabler.utils.EndpointHelper_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7232. dojo._hasResource["com.ibm.mashups.enabler.utils.EndpointHelper_API"] = true;
  7233. dojo.provide("com.ibm.mashups.enabler.utils.EndpointHelper_API");
  7234. dojo.provide("com.ibm.mashups.enabler.utils.EndpointHelper");
  7235. /**
  7236. * Helper utility for endpoint encoded urls.
  7237. *
  7238. * @ibm-module Base2
  7239. * TODO: Change/Remove
  7240. */
  7241. dojo.declare("com.ibm.mashups.enabler.utils.EndpointHelper", null, {
  7242. /**
  7243. * This method resolves endpoint://{endpointid}/relativeurl
  7244. *
  7245. * @param {String} url the url to resolve for endpoints
  7246. * @return {String} the url with endpoints resolved
  7247. */
  7248. resolve: function(url) {
  7249. return null;
  7250. }
  7251. });
  7252. }
  7253. if(!dojo._hasResource["com.ibm.mm.enabler.EndpointUtils"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7254. dojo._hasResource["com.ibm.mm.enabler.EndpointUtils"] = true;
  7255. dojo.provide("com.ibm.mm.enabler.EndpointUtils");
  7256. dojo.declare("com.ibm.mm.enabler.EndpointUtilsDefaultImpl", null, {
  7257. constructor: function(){
  7258. },
  7259. checkForEndpoints: function(/*String*/url){
  7260. return null;
  7261. }
  7262. });
  7263. com.ibm.mm.enabler.EndpointUtils = new com.ibm.mm.enabler.EndpointUtilsDefaultImpl();
  7264. // IMPORTANT
  7265. // ibmConfig.enablerLayerModules is a comma separated string of all supported modules at runtime
  7266. // This section dynamically loads the Extended representation when the variable enablerLayerModules contains the given module
  7267. if ((ibmConfig.enablerLayerModules) && (dojo.indexOf(ibmConfig.enablerLayerModules, "iWidget")>=0)) {
  7268. dojo["require"]("com.ibm.mm.enabler.EndpointUtilsExtendedImpl"); // JSLINT-IGNORE: This needs to be done to allow modularization and to support the minimal layer
  7269. }
  7270. }
  7271. if(!dojo._hasResource["com.ibm.mm.enabler.utils.EndpointHelperImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7272. dojo._hasResource["com.ibm.mm.enabler.utils.EndpointHelperImpl"] = true;
  7273. dojo.provide("com.ibm.mm.enabler.utils.EndpointHelperImpl");
  7274. dojo.declare("com.ibm.mm.enabler.utils.EndpointHelperImpl", null,
  7275. {
  7276. resolve: function(url) {
  7277. if (!url) {
  7278. return url;
  7279. }
  7280. var url2 = com.ibm.mm.enabler.EndpointUtils.checkForEndpoints(url);
  7281. if (url2) {
  7282. return url2;
  7283. }
  7284. return url;
  7285. }
  7286. }
  7287. );
  7288. com.ibm.mashups.enabler.utils.EndpointHelper = new com.ibm.mm.enabler.utils.EndpointHelperImpl();
  7289. }
  7290. if(!dojo._hasResource["com.ibm.mashups.enabler.utils.EndpointHelper"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7291. dojo._hasResource["com.ibm.mashups.enabler.utils.EndpointHelper"] = true;
  7292. dojo.provide("com.ibm.mashups.enabler.utils.EndpointHelper");
  7293. }
  7294. if(!dojo._hasResource["com.ibm.mashups.enabler.utils.URLHelper_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7295. dojo._hasResource["com.ibm.mashups.enabler.utils.URLHelper_API"] = true;
  7296. dojo.provide("com.ibm.mashups.enabler.utils.URLHelper_API");
  7297. dojo.provide("com.ibm.mashups.enabler.utils.URLHelper");
  7298. /**
  7299. * Helper utility for encoding urls.
  7300. *
  7301. * @ibm-module Base2
  7302. */
  7303. dojo.declare("com.ibm.mashups.enabler.utils.URLHelper", null, {
  7304. /**
  7305. * This method rewrites a url and takes care for instance to proxify the given url
  7306. *
  7307. * @ibm-api
  7308. *
  7309. * @param {String} url the url to rewrite
  7310. * @return {String} the encoded url
  7311. */
  7312. rewriteURL: function(targetUrl){
  7313. return null;
  7314. }
  7315. });
  7316. }
  7317. if(!dojo._hasResource["com.ibm.mm.enabler.utils.Misc"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7318. dojo._hasResource["com.ibm.mm.enabler.utils.Misc"] = true;
  7319. dojo.provide("com.ibm.mm.enabler.utils.Misc");
  7320. com.ibm.mm.enabler.utils.Misc = {
  7321. /**
  7322. * Example usage:
  7323. *
  7324. *
  7325. *
  7326. * var myObj = {a: 1, b: "bla", c: function(){}};
  7327. *
  7328. * com.ibm.mm.enabler.utils.Misc.forIn(myObj,function(item,idx,arr) {
  7329. * console.debug(arguments);
  7330. * });
  7331. * // prints:
  7332. * // [1, "a", Object { a=1, more...}]
  7333. * // ["bla", "b", Object { a=1, more...}]
  7334. * // [function(), "c", Object { a=1, more...}]
  7335. *
  7336. *
  7337. * var myScope = {
  7338. * count: 0,
  7339. * f: function(item,idx,arr) {
  7340. * this.count++;
  7341. * }
  7342. * }
  7343. * com.ibm.mm.enabler.utils.Misc.forIn(myObj,'f',myScope);
  7344. *
  7345. * console.debug(myScope.count); // prints: 3
  7346. * @param {Object} obj The object to iterate over
  7347. * @param {Function|String} func The function to call on each object with three parameters: value, key, object
  7348. * @param {Object} scope Optional, the scope to call the function on.
  7349. */
  7350. forIn: function(obj, func, scope) {
  7351. if(!obj || typeof obj != "object") {
  7352. return;
  7353. }
  7354. scope = scope || null;
  7355. var item;
  7356. for(var idx in obj) {
  7357. if(Object.prototype.hasOwnProperty.call(obj,idx)) {
  7358. item = obj[idx];
  7359. dojo.hitch(scope,func)(item,idx,obj);
  7360. }
  7361. }
  7362. },
  7363. encodePath: function(path, decoded) {
  7364. if (path.length === 0) {
  7365. return path;
  7366. }
  7367. var parts = path.split("/");
  7368. for (var i=0; i<parts.length; ++i) {
  7369. parts[i] = decoded ? com.ibm.mm.enabler.utils.Misc._pathPartUnescape(parts[i]) :
  7370. com.ibm.mm.enabler.utils.Misc._pathPartEscape(com.ibm.mm.enabler.utils.Misc._pathPartUnescape(parts[i]));
  7371. }
  7372. return parts.join("/");
  7373. },
  7374. // Acccording to RFC 1738
  7375. // those are the allowed characters in a path element
  7376. // reserved: ";" | "/" | "?" | ":" | "@" | "&" | "="
  7377. // allowed in path: ";" | ":" | "@" | "&" | "="
  7378. _pathPartUnescape:function(pathPart) {
  7379. pathPart = decodeURIComponent(pathPart);
  7380. /* Removed per #18252
  7381. pathPart = pathPart.replace(/%2F/g, '/');
  7382. pathPart = pathPart.replace(/%2f/g, '/');
  7383. pathPart = pathPart.replace(/%3F/g, '?');
  7384. pathPart = pathPart.replace(/%3f/g, '?');
  7385. */
  7386. return pathPart;
  7387. },
  7388. _pathPartEscape:function(pathPart) {
  7389. pathPart = encodeURIComponent(pathPart);
  7390. /* Removed per #18252
  7391. pathPart = pathPart.replace(/\//g, '%2F');
  7392. pathPart = pathPart.replace(/\?/g, '%3F');
  7393. */
  7394. // we do not encode a colon as this is allowed by the spec and the OpenSocial container requires it
  7395. pathPart = pathPart.replace(/%3a/g, ':');
  7396. pathPart = pathPart.replace(/%3A/g, ':');
  7397. return pathPart;
  7398. },
  7399. inStringArray:function(str,/*[]*/arrayObj)
  7400. {
  7401. var rc = false;
  7402. for (var i in arrayObj) {
  7403. if (Object.prototype.hasOwnProperty.call(arrayObj,i)) {
  7404. var temp1 = arrayObj[i];
  7405. if (temp1 == str) {
  7406. rc = true;
  7407. break;
  7408. }
  7409. }
  7410. }
  7411. return rc;
  7412. },
  7413. isEmpty: function (object) {
  7414. if(object === null || typeof object == "undefined") {
  7415. return true;
  7416. } else if(dojo.isString(object)) {
  7417. return object.length === 0;
  7418. } else {
  7419. for (var i in object) {
  7420. if (Object.prototype.hasOwnProperty.call(object, i)) {
  7421. return false;
  7422. }
  7423. }
  7424. return true;
  7425. }
  7426. },
  7427. encodeModelID4Uri:function(uri)
  7428. {
  7429. // encode uri part correctly
  7430. var pos = uri.indexOf(":");
  7431. if (pos != -1) {
  7432. var start = uri.slice(0,pos+1);
  7433. var end = uri.slice(pos+1);
  7434. uri = start + encodeURIComponent(end);
  7435. }
  7436. return encodeURIComponent(uri);
  7437. },
  7438. preloadImage:function(path,width,height){
  7439. var image = (width && height) ? new Image(width, height) : new Image();
  7440. image.src = path;
  7441. return image;
  7442. },
  7443. isInstanceOf:function(obj1, obj2) {
  7444. if (obj1 && obj2) {
  7445. if (typeof obj1.isInstanceOf == "function") {
  7446. if (obj1.isInstanceOf(obj2)) {
  7447. return true;
  7448. }
  7449. }
  7450. return (obj1 instanceof obj2);
  7451. }
  7452. return false;
  7453. },
  7454. isPocUrl: function(urlString) {
  7455. var supportedSchema = {
  7456. http: "http",
  7457. https: "https",
  7458. file: "file" //not resolver will handle web dav:/ url
  7459. };
  7460. var rc = false;
  7461. if (urlString.indexOf(":") > 0) {
  7462. if (urlString.indexOf("/") === 0) {
  7463. return false;
  7464. }
  7465. if (urlString.indexOf("?") === 0) {
  7466. return false;
  7467. }
  7468. var schema = urlString.substring(0, urlString.indexOf(":"));
  7469. if (!supportedSchema[schema]) {
  7470. rc = true;
  7471. }
  7472. }
  7473. return rc;
  7474. }
  7475. };
  7476. }
  7477. if(!dojo._hasResource["com.ibm.mm.enabler.utils.HttpUrl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7478. dojo._hasResource["com.ibm.mm.enabler.utils.HttpUrl"] = true;
  7479. dojo.provide("com.ibm.mm.enabler.utils.HttpUrl");
  7480. dojo.declare("com.ibm.mm.enabler.utils.HttpUrl", null, {
  7481. constructor: function( /*String*/urlString, /*boolean*/ resolveEndpoints){
  7482. if (resolveEndpoints !== false) {
  7483. var resolved = com.ibm.mm.enabler.EndpointUtils.checkForEndpoints(urlString);
  7484. if (resolved) {
  7485. urlString = resolved;
  7486. }
  7487. }
  7488. this.pocurl = this._resolvePocUrl(urlString);
  7489. if (!this.pocurl) {
  7490. this.scheme = this._extractScheme(urlString);
  7491. this.server = this._extractServer(urlString);
  7492. this.port = this._extractPort(urlString);
  7493. this.path = this._extractPath(urlString);
  7494. this.parameters = this._extractQuery(urlString);
  7495. this.anchor = this._extractAnchor(urlString);
  7496. }
  7497. },
  7498. _resolvePocUrl: function(urlString){
  7499. var rv = null;
  7500. if (com.ibm.mm.enabler.utils.Misc.isPocUrl(urlString)) {
  7501. var prefix = this._getPrefix();
  7502. urlString = escape(unescape(urlString)); // encode before adding as parameter
  7503. rv = prefix.concat(urlString);
  7504. }
  7505. return rv;
  7506. },
  7507. _getPrefix: function(){
  7508. var cs = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);
  7509. var serverRoot = cs.getValue(com.ibm.mashups.enabler.services.ConfigConstants.CONTEXT_ROOT);
  7510. var anonymousUser = cs.getValue(com.ibm.mashups.enabler.services.ConfigConstants.ANONYMOUS_USER);
  7511. var contenthandlerPath;
  7512. if (anonymousUser) {
  7513. contenthandlerPath = cs.getValue(com.ibm.mashups.enabler.services.ConfigConstants.CONTENTHANDLER_PUBLIC);
  7514. }
  7515. else {
  7516. contenthandlerPath = cs.getValue(com.ibm.mashups.enabler.services.ConfigConstants.CONTENTHANDLER_PRIVATE);
  7517. }
  7518. var rv = serverRoot.concat(contenthandlerPath).concat("?uri=");
  7519. return rv;
  7520. },
  7521. addParameter: function( /*String*/name, /*String*/ value){
  7522. if (dojo.isString(this.parameters[name])) {
  7523. this.parameters[name] = [this.parameters[name], value];
  7524. }
  7525. else
  7526. if (dojo.isArray(this.parameters[name])) {
  7527. this.parameters[name].push(value);
  7528. }
  7529. else {
  7530. this.parameters[name] = value;
  7531. }
  7532. },
  7533. setParameter: function(/*String*/name, /*Object*/ value){
  7534. if (!this.parameters) {
  7535. this.parameters = {};
  7536. }
  7537. this.parameters[name] = value;
  7538. },
  7539. getParameter: function(/*String*/name){
  7540. if (!this.parameters) {
  7541. return false;
  7542. }
  7543. return this.parameters[name];
  7544. },
  7545. getParameters: function(){
  7546. return this.parameters;
  7547. },
  7548. isProxyNeeded: function(){
  7549. var loc = document.location;
  7550. // first test the scheme:
  7551. if (loc.protocol != this.scheme) {
  7552. return true;
  7553. }
  7554. // test the host
  7555. if (!this._equalsServer(loc.hostname)) {
  7556. return true;
  7557. }
  7558. // simplest case, ports are the same, return false
  7559. if (loc.port == this.port) {
  7560. return false;
  7561. }
  7562. var defaultPort;
  7563. // tests for http with default port
  7564. if (this.scheme == "http:") {
  7565. defaultPort = "80";
  7566. if ((loc.port == "" && this.port == defaultPort) ||
  7567. (loc.port == defaultPort && this.port == "")) {
  7568. return false;
  7569. }
  7570. }
  7571. // tests for https with default port
  7572. if (this.scheme == "https:") {
  7573. defaultPort = "443";
  7574. if ((loc.port == "" && this.port == defaultPort) ||
  7575. (loc.port == defaultPort && this.port == "")) {
  7576. return false;
  7577. }
  7578. }
  7579. return true;
  7580. },
  7581. toServerRelativeString: function(decoded){
  7582. if (this.pocurl) {
  7583. return this.pocurl;
  7584. }
  7585. var str = "";
  7586. if (this.path != "") {
  7587. str += "/" + com.ibm.mm.enabler.utils.Misc.encodePath(this.path, decoded);
  7588. }
  7589. if (!com.ibm.mm.enabler.utils.Misc.isEmpty(this.parameters)) {
  7590. str += "?" + (decoded ? this._parametersToQuery(this.parameters) : dojo.objectToQuery(this.parameters));
  7591. }
  7592. if (this.anchor != "") {
  7593. str += "#" + this.anchor;
  7594. }
  7595. return str;
  7596. },
  7597. toProxifiedString: function(){
  7598. //check if we need the proxy
  7599. if (this.pocurl) {
  7600. return this.pocurl;
  7601. }
  7602. if (typeof ibmConfig == 'undefined') {
  7603. return this.toString();
  7604. }
  7605. var newURL = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME).getValue(com.ibm.mashups.enabler.services.ConfigConstants.PROXY_URL);
  7606. if (!newURL) {
  7607. return this.toString();
  7608. }
  7609. newURL += "/";
  7610. if (window.location.protocol == this.scheme && this._equalsServer(window.location.hostname)) {
  7611. if (window.location.port == this.port) {
  7612. return this.toString();
  7613. }
  7614. else
  7615. if (this.scheme == "http:" && window.location.port == "" && this.port == "80") {
  7616. return this.toString();
  7617. }
  7618. else
  7619. if (this.scheme == "https:" && window.location.port == "" && this.port == "443") {
  7620. return this.toString();
  7621. }
  7622. else
  7623. if (this.scheme == "http:" && window.location.port == "80" && this.port == "") {
  7624. return this.toString();
  7625. }
  7626. else
  7627. if (this.scheme == "https:" && window.location.port == "443" && this.port == "") {
  7628. return this.toString();
  7629. }
  7630. }
  7631. // rewrite
  7632. if (this.scheme == "https:") {
  7633. newURL += "https/" + this.server + ((this.port != "443" && this.port != "") ? ":" + this.port : "");
  7634. }
  7635. else {
  7636. newURL += "http/" + this.server + ((this.port != "80" && this.port != "") ? ":" + this.port : "");
  7637. }
  7638. // add the slash portion in ANY case
  7639. newURL += "/";
  7640. if (this.path != "") {
  7641. newURL += com.ibm.mm.enabler.utils.Misc.encodePath(this.path);
  7642. }
  7643. if (!com.ibm.mm.enabler.utils.Misc.isEmpty(this.parameters)) {
  7644. newURL += "?" + dojo.objectToQuery(this.parameters);
  7645. }
  7646. if (this.anchor != "") {
  7647. newURL += "#" + this.anchor;
  7648. }
  7649. return newURL;
  7650. },
  7651. toString: function(decoded){
  7652. if (this.pocurl) {
  7653. return this.pocurl;
  7654. }
  7655. var str = "";
  7656. //safari doesn't support url normalization on xhr request
  7657. if (this.server != "") {
  7658. str += this.scheme + "//" + this.server;
  7659. if (this.port != "") {
  7660. if (this.scheme == "http:" && this.port == "80") {
  7661. str += "";
  7662. }
  7663. else
  7664. if (this.scheme == "https:" && this.port == "443") {
  7665. str += "";
  7666. }
  7667. else {
  7668. str += ":" + this.port;
  7669. }
  7670. }
  7671. }
  7672. // add the slash portion in ANY case
  7673. str += "/";
  7674. if (this.path != "") {
  7675. str += com.ibm.mm.enabler.utils.Misc.encodePath(this.path, decoded);
  7676. }
  7677. if (!com.ibm.mm.enabler.utils.Misc.isEmpty(this.parameters)) {
  7678. str += "?" + (decoded ? this._parametersToQuery(this.parameters) : dojo.objectToQuery(this.parameters));
  7679. }
  7680. if (this.anchor != "") {
  7681. str += "#" + this.anchor;
  7682. }
  7683. return str;
  7684. },
  7685. _parametersToQuery: function(params){
  7686. var str = "";
  7687. // concatenation function (defined outside of the for-loop)
  7688. var fn = function(value){
  7689. str += k + "=" + value + "&";
  7690. };
  7691. for (var k in params) {
  7692. // concatenate parameters
  7693. if (dojo.isArray(params[k])) {
  7694. dojo.forEach(params[k], fn);
  7695. }
  7696. else {
  7697. fn(params[k]);
  7698. }
  7699. }
  7700. // remove trailing ampersand
  7701. if (str.lastIndexOf('&') === str.length - 1) {
  7702. str = str.substr(0, str.length - 1);
  7703. }
  7704. return str;
  7705. },
  7706. _isAbsolute: function(){
  7707. return this._absoluteURL;
  7708. },
  7709. _extractScheme: function(/*String*/urlString){
  7710. // important check as :// may appear as query parameter and then below logic doesn't work in case it is a relative URL
  7711. var isRelative = urlString.indexOf("/") === 0;
  7712. if (isRelative) {
  7713. return window.location.protocol; // location.protocol returns the protocol like http: or https:
  7714. }
  7715. var indexOfScheme = urlString.indexOf("://");
  7716. if (indexOfScheme == -1) {
  7717. this._absoluteURL = false;
  7718. return window.location.protocol; // location.protocol returns the protocol like http: or https:
  7719. }
  7720. this._absoluteURL = true;
  7721. return urlString.substring(0, indexOfScheme + 1);
  7722. },
  7723. _extractServer: function(/*String*/urlString){
  7724. var indexOfScheme = urlString.indexOf(this.scheme);
  7725. var retVal = "";
  7726. if (indexOfScheme === 0) {
  7727. var serverAndPort;
  7728. var indexOfSlash = urlString.indexOf("/", indexOfScheme + this.scheme.length + 2);
  7729. if (indexOfSlash != -1) {
  7730. serverAndPort = urlString.substring(indexOfScheme + this.scheme.length + 2, indexOfSlash);
  7731. }
  7732. else {
  7733. serverAndPort = urlString.substring(indexOfScheme + this.scheme.length + 2);
  7734. }
  7735. retVal = serverAndPort.split(":")[0];
  7736. }
  7737. else {
  7738. var hostname = window.location.hostname;
  7739. retVal = this._isIPv6(hostname) ? "[" + hostname + "]" : hostname;
  7740. }
  7741. return retVal;
  7742. },
  7743. _extractPort: function(/*String*/urlString){
  7744. var indexOfServer = urlString.indexOf(this.server);
  7745. var retVal = "";
  7746. if (indexOfServer >= 0) {
  7747. var serverAndPort;
  7748. var indexOfSlash = urlString.indexOf("/", indexOfServer);
  7749. if (indexOfSlash != -1) {
  7750. serverAndPort = urlString.substring(indexOfServer, indexOfSlash);
  7751. }
  7752. else {
  7753. serverAndPort = urlString.substring(indexOfServer);
  7754. }
  7755. var serverAndPortParts = serverAndPort.split(":");
  7756. if (serverAndPortParts.length > 1) {
  7757. retVal = serverAndPortParts[1];
  7758. }
  7759. }
  7760. if (retVal == "") {
  7761. if (urlString.indexOf("/") === 0) {
  7762. retVal = window.location.port;
  7763. }
  7764. else {
  7765. retVal = "";
  7766. }
  7767. }
  7768. return retVal;
  7769. },
  7770. _extractPath: function( /*String*/urlString){
  7771. var indexOfScheme = urlString.indexOf(this.scheme);
  7772. var startIndex = 0;
  7773. if (indexOfScheme === 0) {
  7774. startIndex = this.scheme.length + 2;
  7775. }
  7776. var retVal = "";
  7777. var indexOfSlash = urlString.indexOf("/", startIndex);
  7778. var indexOfQuery = urlString.indexOf("?");
  7779. var indexOfHash = urlString.lastIndexOf("#");
  7780. if (indexOfQuery >= 0) {
  7781. retVal = urlString.substring(indexOfSlash + 1, indexOfQuery);
  7782. }
  7783. else {
  7784. if (indexOfHash >= 0 && indexOfSlash != -1) {
  7785. retVal = urlString.substring(indexOfSlash + 1, indexOfHash);
  7786. }
  7787. else
  7788. if (indexOfSlash != -1) {
  7789. retVal = urlString.substring(indexOfSlash + 1);
  7790. }
  7791. }
  7792. return retVal;
  7793. },
  7794. _extractQuery: function( /*String*/urlString){
  7795. var retVal = {};
  7796. var urlParts = urlString.split("?");
  7797. if (urlParts.length > 1) {
  7798. retVal = dojo.queryToObject(urlParts[1].split("#")[0]);
  7799. }
  7800. return retVal;
  7801. },
  7802. _extractAnchor: function( /*String*/urlString){
  7803. var retVal = "";
  7804. var urlParts = urlString.split("#");
  7805. if (urlParts.length > 1) {
  7806. retVal = urlParts[urlParts.length - 1];
  7807. }
  7808. return retVal;
  7809. },
  7810. _isIPv6: function(hostname){
  7811. // only IPv6 addresses contain colons
  7812. // note: the input hostname MUST NOT contain a port
  7813. return hostname.indexOf(":") != -1;
  7814. },
  7815. _equalsServer: function(hostname){
  7816. // consider square brackets in IPv6 case
  7817. return this.server == (this._isIPv6(hostname) ? "[" + hostname + "]" : hostname);
  7818. }
  7819. });
  7820. }
  7821. if(!dojo._hasResource["com.ibm.mm.enabler.utils.URLHelper"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7822. dojo._hasResource["com.ibm.mm.enabler.utils.URLHelper"] = true;
  7823. dojo.provide("com.ibm.mm.enabler.utils.URLHelper");
  7824. dojo.declare("com.ibm.mm.enabler.utils.URLHelperImpl", com.ibm.mashups.enabler.utils.URLHelper, {
  7825. rewriteURL: function(targetUrl){
  7826. var _targetURL = new com.ibm.mm.enabler.utils.HttpUrl(targetUrl);
  7827. return _targetURL.toProxifiedString();
  7828. }
  7829. });
  7830. com.ibm.mashups.enabler.utils.URLHelper = new com.ibm.mm.enabler.utils.URLHelperImpl();
  7831. com.ibm.mm.enabler.utils.URLHelper = com.ibm.mashups.enabler.utils.URLHelper;
  7832. }
  7833. if(!dojo._hasResource["com.ibm.mashups.enabler.utils.URLHelper"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7834. dojo._hasResource["com.ibm.mashups.enabler.utils.URLHelper"] = true;
  7835. dojo.provide("com.ibm.mashups.enabler.utils.URLHelper");
  7836. }
  7837. if(!dojo._hasResource["com.ibm.mm.enabler.services.ConfigObjectExtendedImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7838. dojo._hasResource["com.ibm.mm.enabler.services.ConfigObjectExtendedImpl"] = true;
  7839. dojo.provide("com.ibm.mm.enabler.services.ConfigObjectExtendedImpl");
  7840. /*
  7841. * This is injected on the fly and not fetched through an API. Therefore we need to define the @ibm-module so that the build process is picking it up
  7842. * @ibm-module Base
  7843. *
  7844. * This value defines the order in which the packages should be printed out into the dojo profile. Default is 100.
  7845. * Any number that is smaller causes this class to be written out before any other with a higher number
  7846. * @ibm-dojo-profile-level 40
  7847. */
  7848. dojo.declare("com.ibm.mm.enabler.services.ConfigObjectExtendedImpl", [com.ibm.mm.enabler.services.ConfigObjectDefaultImpl], {
  7849. constructor: function(provider, configService) {
  7850. this.valuesArray = null;
  7851. this.provider = provider;
  7852. this.configService = configService;
  7853. },
  7854. _getValue: function(/*string*/provider, /*string*/ name) {
  7855. if (!this.valuesArray) {
  7856. this._loadConfigData(provider);
  7857. }
  7858. return this.valuesArray[name];
  7859. },
  7860. _getValueDeferred: function(/*string*/provider, /*string*/ name) {
  7861. return new com.ibm.mm.enabler.DeferredImpl(this, function(deferred, sync, name) {
  7862. var callBack = deferred.getFinishedCallback();
  7863. if (!this.valuesArray) {
  7864. // lazy load, to support dojo layer build
  7865. dojo["require"]("com.ibm.mashups.enabler.xml.XPath"); // JSLINT-IGNORE: This needs to be done to allow modularization and not break the layer build
  7866. dojo["require"]("com.ibm.mashups.enabler.model.url.ModelUrlFactory"); // JSLINT-IGNORE: This needs to be done to allow modularization and not break the layer build
  7867. dojo["require"]("com.ibm.mm.enabler.services.ModelRestServiceRequest"); // JSLINT-IGNORE: This needs to be done to allow modularization and not break the layer build
  7868. var providerCheck = "ConfigProvider." + provider;
  7869. var provider2 = ibmConfig[providerCheck];
  7870. if ((typeof provider2 != "undefined") || (provider2 !== null)) {
  7871. provider = provider2;
  7872. }
  7873. var myUrl = com.ibm.mashups.enabler.model.url.ModelUrlFactory.createModelURL(com.ibm.mashups.enabler.model.url.ModelUrlFactory.CONFIG_URL, this);
  7874. myUrl.setSchemeSpecificPart("/" + provider + "/*");
  7875. var serviceReq = new com.ibm.mm.enabler.services.ModelRestServiceRequest(myUrl, null, null, false, sync);
  7876. var me = this;
  7877. serviceReq.read(function(type, data, xhr, args) {
  7878. if(!me.valuesArray) {
  7879. me.valuesArray = {};
  7880. }
  7881. var configXmls = com.ibm.mashups.enabler.xml.XPath.evaluateXPath("//atom:entry/atom:content/preferences/root/node/map/*", data, me.ns);
  7882. if (configXmls && configXmls.length > 0) {
  7883. for (var i = 0, l = configXmls.length; i < l; i++) {
  7884. var key = configXmls[i].getAttribute("key");
  7885. var value = configXmls[i].getAttribute("value");
  7886. me.valuesArray[key] = value;
  7887. }
  7888. }
  7889. if (me.valuesArray[name] && callBack) {
  7890. callBack(me.valuesArray[name], com.ibm.mm.enabler.model.HttpStatusCodes.HTTP_OK, deferred.getFinishedCallbackParameters());
  7891. }
  7892. });
  7893. }
  7894. else if (this.valuesArray[name] && callBack) {
  7895. callBack(this.valuesArray[name], com.ibm.mm.enabler.model.HttpStatusCodes.HTTP_OK, deferred.getFinishedCallbackParameters());
  7896. }
  7897. return this.valuesArray && this.valuesArray[name];
  7898. }, name);
  7899. },
  7900. _loadConfigData: function(/*string*/provider) {
  7901. // lazy load, to support dojo layer build
  7902. dojo["require"]("com.ibm.mashups.enabler.xml.XPath"); // JSLINT-IGNORE: This needs to be done to allow modularization and not break the layer build
  7903. dojo["require"]("com.ibm.mashups.enabler.model.url.ModelUrlFactory"); // JSLINT-IGNORE: This needs to be done to allow modularization and not break the layer build
  7904. dojo["require"]("com.ibm.mm.enabler.services.ModelRestServiceRequest"); // JSLINT-IGNORE: This needs to be done to allow modularization and not break the layer build
  7905. var providerCheck = "ConfigProvider." + provider;
  7906. var provider2 = ibmConfig[providerCheck];
  7907. if ((typeof provider2 != "undefined") || (provider2 !== null)) {
  7908. provider = provider2;
  7909. }
  7910. var ret = {};
  7911. var myUrl = com.ibm.mashups.enabler.model.url.ModelUrlFactory.createModelURL(com.ibm.mashups.enabler.model.url.ModelUrlFactory.CONFIG_URL, this);
  7912. myUrl.setSchemeSpecificPart("/" + provider + "/*");
  7913. var serviceReq = new com.ibm.mm.enabler.services.ModelRestServiceRequest(myUrl, null, null, false, true);
  7914. var me = this;
  7915. serviceReq.read(function(type, data, xhr, args) {
  7916. var configXmls = com.ibm.mashups.enabler.xml.XPath.evaluateXPath("//atom:entry/atom:content/preferences/root/node/map/*", data, me.ns);
  7917. if (configXmls && configXmls.length > 0) {
  7918. for (var i = 0; i < configXmls.length; i++) {
  7919. var name = configXmls[i].getAttribute("key");
  7920. var value = configXmls[i].getAttribute("value");
  7921. ret[name] = value;
  7922. }
  7923. }
  7924. });
  7925. this.valuesArray = ret;
  7926. }
  7927. });
  7928. }
  7929. if(!dojo._hasResource["com.ibm.mashups.enabler.strategy.Strategy"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7930. dojo._hasResource["com.ibm.mashups.enabler.strategy.Strategy"] = true;
  7931. dojo.provide("com.ibm.mashups.enabler.strategy.Strategy");
  7932. /**
  7933. * Interface that acts as base interface for all strategies. It can be set on
  7934. * models to define the behavior of the model, i.e. how resources are loaded
  7935. * from the server.
  7936. * @ibm-api
  7937. * @ibm-module Base
  7938. */
  7939. dojo.declare("com.ibm.mashups.enabler.strategy.Strategy", null, {});
  7940. }
  7941. if(!dojo._hasResource["com.ibm.mashups.enabler.model.Model_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7942. dojo._hasResource["com.ibm.mashups.enabler.model.Model_API"] = true;
  7943. dojo.provide("com.ibm.mashups.enabler.model.Model_API");
  7944. dojo.provide("com.ibm.mashups.enabler.model.Model");
  7945. /**
  7946. * Base class for all models
  7947. *
  7948. * @ibm-api
  7949. * @ibm-module Base
  7950. */
  7951. dojo.declare("com.ibm.mashups.enabler.model.Model", null, {
  7952. /**
  7953. * Sets the specified array of strategies or in case none has been
  7954. * defined falls back to the default strategy
  7955. * @param {com.ibm.mashups.enabler.strategy.Strategy[]} strategy array of strategies to set;
  7956. * may be <code>null</code>
  7957. * @type void
  7958. */
  7959. setStrategy : function(strategy) {
  7960. },
  7961. /**
  7962. * Returns the array of strategies which are in use
  7963. * @return {com.ibm.mashups.enabler.strategy.Strategy[]} array of strategies in use, <code>null</code> if no
  7964. * strategies are in use
  7965. */
  7966. getStrategies : function() {
  7967. },
  7968. /**
  7969. * Returns the specified strategy
  7970. * @param {strategy} strategy class name or array index of strategy
  7971. * @return {com.ibm.mashups.enabler.strategy.Strategy} strategy in use, <code>null</code> if no
  7972. * strategy with the specified type is in use
  7973. * @ibm-spi
  7974. */
  7975. getStrategy : function(strategy) {
  7976. },
  7977. /**
  7978. * Adds a strategy to the strategies array
  7979. * @param {com.ibm.mashups.enabler.strategy.Strategy} strategy strategy to add; must not be <code>null</code>
  7980. * @return {int} index where the strategy was added in the strategies array
  7981. */
  7982. addStrategy : function(strategy) {
  7983. },
  7984. /**
  7985. * Removes the specified strategy
  7986. * @param {strategy} strategy class name or array index of the strategy; must not be
  7987. * <code>null</code>
  7988. * @type void
  7989. */
  7990. removeStrategy : function(strategy) {
  7991. }
  7992. });
  7993. }
  7994. if(!dojo._hasResource["com.ibm.mashups.enabler.model.Model"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7995. dojo._hasResource["com.ibm.mashups.enabler.model.Model"] = true;
  7996. dojo.provide("com.ibm.mashups.enabler.model.Model");
  7997. }
  7998. if(!dojo._hasResource["com.ibm.mashups.enabler.strategy.NoCacheStrategy"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7999. dojo._hasResource["com.ibm.mashups.enabler.strategy.NoCacheStrategy"] = true;
  8000. dojo.provide("com.ibm.mashups.enabler.strategy.NoCacheStrategy");
  8001. /**
  8002. * Interface to control, if caching is used for obtaining model artifacts
  8003. *
  8004. * @since 3.0
  8005. *
  8006. * @ibm-spi
  8007. * @ibm-module Base
  8008. */
  8009. dojo.declare("com.ibm.mashups.enabler.strategy.NoCacheStrategy", com.ibm.mashups.enabler.strategy.Strategy, {
  8010. /**
  8011. * @private
  8012. */
  8013. _apply: function(restRequest) {
  8014. // this is the spec way, but nobody cares. Try it yourself: http://www.mnot.net/javascript/xmlhttprequest/cache.html
  8015. restRequest.setHeader("Pragma", "no-cache");
  8016. restRequest.setHeader("Cache-Control", "no-cache");
  8017. // This works on all major browsers even though it is not the spec way
  8018. restRequest.setHeader("If-Modified-Since", "Thu, 1 Jan 1970 00:00:00 GMT");
  8019. // the only other solution is to use the existing parameter solution (pragma=no-cache) or something like dojo with a random parameter
  8020. }
  8021. });
  8022. }
  8023. if(!dojo._hasResource["com.ibm.mm.enabler.model.ModelImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  8024. dojo._hasResource["com.ibm.mm.enabler.model.ModelImpl"] = true;
  8025. dojo.provide("com.ibm.mm.enabler.model.ModelImpl");
  8026. dojo.declare("com.ibm.mm.enabler.model.ModelImpl", com.ibm.mashups.enabler.model.Model, {
  8027. /**
  8028. * @private
  8029. */
  8030. // FIXME: use _strategies
  8031. strategy: null,
  8032. constructor: function() {
  8033. // messages
  8034. this.modelMessages = dojo.i18n.getLocalization("com.ibm.mm.enabler", "modelMessages");
  8035. },
  8036. setStrategy: function(strategy) {
  8037. if (strategy === null || typeof strategy == 'undefined') {
  8038. this.strategy = null;
  8039. }
  8040. else if (com.ibm.mm.enabler.utils.Misc.isInstanceOf(strategy, Array)) {
  8041. if (strategy.length > 0) {
  8042. this.strategy = [];
  8043. dojo.forEach(strategy, function(item, idx, arr) {
  8044. this.strategy.push(item);
  8045. this._preprocessStrategy(item);
  8046. }, this);
  8047. }
  8048. }
  8049. else {
  8050. this.strategy = [strategy];
  8051. this._preprocessStrategy(strategy);
  8052. }
  8053. },
  8054. getStrategies: function() {
  8055. // FIXME: expose copy of array
  8056. return this.strategy || [];
  8057. },
  8058. addStrategy: function(strategy) {
  8059. if (strategy === null || typeof strategy == 'undefined') {
  8060. throw new Error(this.modelMessages.E_PARAM_ISNULL_0);
  8061. }
  8062. if (null === this.strategy) {
  8063. // null strategy array
  8064. this.strategy = [];
  8065. }
  8066. // do preprocessing of strategies
  8067. this._preprocessStrategy(strategy);
  8068. // potentially replace existing strategy of same type
  8069. for (var i = 0, l = this.strategy.length; i < l; i++) {
  8070. // only dojo objects have declaredClass
  8071. if (this.strategy[i].declaredClass) {
  8072. if (strategy instanceof (dojo.getObject(this.strategy[i].declaredClass))) {
  8073. this.strategy[i] = strategy;
  8074. return i;
  8075. }
  8076. }
  8077. }
  8078. return (this.strategy.push(strategy) - 1);
  8079. },
  8080. removeStrategy: function(s) {
  8081. if (s === null || typeof s == 'undefined') {
  8082. throw new Error(this.modelMessages.E_PARAM_ISNULL_0);
  8083. }
  8084. if (!this.strategy) {
  8085. return;
  8086. }
  8087. else if (dojo.isString(s)) {
  8088. s = this._getIndexOfStrategyByType(s);
  8089. }
  8090. if (!isNaN(s) && (s < this.strategy.length) && (s >= 0)) {
  8091. this.strategy.splice(s, 1 + s);
  8092. }
  8093. },
  8094. getStrategy: function(s) {
  8095. if (!this.strategy) {
  8096. return null;
  8097. }
  8098. else if (dojo.isString(s)) {
  8099. return this._findStrategyByType(s);
  8100. }
  8101. else {
  8102. if (!isNaN(s) && (s < this.strategy.length) && (s >= 0)) {
  8103. return this.strategy[s];
  8104. }
  8105. else {
  8106. return null;
  8107. }
  8108. }
  8109. },
  8110. _findStrategyByType: function(type) {
  8111. var i = this._getIndexOfStrategyByType(type);
  8112. return i >= 0 ? this.strategy[i] : null;
  8113. },
  8114. _getIndexOfStrategyByType: function(type) {
  8115. if (this.strategy) {
  8116. for (var i = 0, l = this.strategy.length; i < l; i++) {
  8117. // only dojo objects have declaredClass
  8118. if (this.strategy[i].declaredClass) {
  8119. if (type == this.strategy[i].declaredClass) {
  8120. return i;
  8121. }
  8122. }
  8123. }
  8124. }
  8125. return -1;
  8126. },
  8127. _preprocessStrategy: function(s) {
  8128. if (com.ibm.mm.enabler.utils.Misc.isInstanceOf(s, com.ibm.mashups.enabler.strategy.NoCacheStrategy)) {
  8129. if (dojo.isFunction(this.invalidate)) {
  8130. this.invalidate();
  8131. }
  8132. }
  8133. }
  8134. });
  8135. }
  8136. if(!dojo._hasResource["com.ibm.mm.enabler.services.ModelRestServiceRequest"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  8137. dojo._hasResource["com.ibm.mm.enabler.services.ModelRestServiceRequest"] = true;
  8138. dojo.provide("com.ibm.mm.enabler.services.ModelRestServiceRequest");
  8139. /*
  8140. * This is injected on the fly and not fetched through an API. Therefore we need
  8141. * to define the @ibm-module so that the build process is picking it up
  8142. * @ibm-module Base
  8143. *
  8144. * This value defines the order in which the packages should be printed out into
  8145. * the dojo profile. Default is 100. Any number that is smaller causes this
  8146. * class to be written out before any other with a higher number
  8147. * @ibm-dojo-profile-level 50
  8148. */
  8149. dojo.declare("com.ibm.mm.enabler.services.ModelRestServiceRequest", null, {
  8150. REQUEST_METHOD_POST: "POST",
  8151. REQUEST_METHOD_PUT: "PUT",
  8152. REQUEST_METHOD_DELETE: "DELETE",
  8153. POST_ACTION_HEADER: "X-Method-Override",
  8154. MODIFICATION_COOKIE: "modified.id",
  8155. constructor: function( /* HttpUrl */feedlocation, /* HTMLFormElement? */ formNode, /* Function? */ formFilter, /* boolean? */ textOnly, /* boolean? */ sync) {
  8156. if (com.ibm.mm.enabler.services.ModelRestServiceRequestStatic.getXRequestDigest()) {
  8157. feedlocation.setParameter("digest", com.ibm.mm.enabler.services.ModelRestServiceRequestStatic.getXRequestDigest());
  8158. }
  8159. this._feedURI = feedlocation.toProxifiedString();
  8160. this._textOnly = textOnly;
  8161. if (textOnly) {
  8162. this._handleAs = "text";
  8163. } else {
  8164. this._handleAs = "xml";
  8165. }
  8166. this._sync = sync;
  8167. this._formNode = formNode;
  8168. this._formFilter = formFilter;
  8169. this._config = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);
  8170. this._headers = {};
  8171. this.logoutVerificationForRaw = false;
  8172. // Make sure this isn't undefined.
  8173. if (!this._sync) {
  8174. this._sync = false;
  8175. }
  8176. },
  8177. setHandleAs: function(handleAs) {
  8178. if (handleAs == "atom") {
  8179. this._handleAs = "xml";
  8180. } else {
  8181. this._handleAs = handleAs;
  8182. }
  8183. },
  8184. setHeader: function(name, value) {
  8185. this._headers[name] = value;
  8186. },
  8187. enableLogoutVerificationForRawRetrieval: function() {
  8188. this.logoutVerificationForRaw = true;
  8189. },
  8190. // summary: Sends a request to one of the Portal REST Services and handles
  8191. // the response.
  8192. // description: Create a new instance of this object for every REST service
  8193. // request that is
  8194. // sent. The URL is passed in to the constructor. If a form node and form
  8195. // filter is
  8196. // passed into the constructor, the REST service request is handled as a
  8197. // form submit.
  8198. // The request can also be executed synchronously if TRUE is passed into the
  8199. // constructor.
  8200. // In general, only the model implementations should send these requests.
  8201. create: function( /* ibm.atom.Feed */feed, /* Function */ callbackfn, /* Object? */ addtlCallbackFnArguments) {
  8202. // summary: Creates an entry in a feed.
  8203. // description: Creates an entry in a feed. This operation is not
  8204. // implemented in this
  8205. // class. It should be overridden by subclasses and properly implemented
  8206. // if
  8207. // the REST service supports the create operation.
  8208. // feed: the ATOM feed object
  8209. // entry: the ATOM entry to create
  8210. // callbackfn: the function to call when the operation is complete
  8211. this._updateCookie();
  8212. var me = this;
  8213. var args = {
  8214. url: this._feedURI,
  8215. headers: {
  8216. // "If-Modified-Since": "Thu, 1 Jan 1970 00:00:00 GMT",
  8217. "Content-Type": "application/atom+xml; charset=utf-8"
  8218. }, // temporary to force the browser to ignore cached requests
  8219. load: function(response, ioArgs) {
  8220. var xhr = ioArgs.xhr;
  8221. var data = response;
  8222. var xrd = xhr.getResponseHeader("X-Request-Digest");
  8223. if (xrd !== null) {
  8224. com.ibm.mm.enabler.services.ModelRestServiceRequestStatic.setXRequestDigest(xrd);
  8225. }
  8226. var contentType = xhr.getResponseHeader("Content-Type");
  8227. if (typeof contentType != "undefined" && contentType !== null && contentType.indexOf("text/html") >= 0) {
  8228. me._doLogin();
  8229. return;
  8230. }
  8231. if (dojo.isIE) {
  8232. data = dojox.xml.parser.parse(xhr.responseText);
  8233. }
  8234. callbackfn(com.ibm.mm.enabler.services.ModelRestServiceRequest.XHR_STATUS_LOAD, data, xhr, addtlCallbackFnArguments);
  8235. },
  8236. error: function(response, ioArgs) {
  8237. var xhr = ioArgs.xhr;
  8238. var status = xhr.status;
  8239. // Check whether we are having an authorization problem
  8240. if (status == 401) {
  8241. me._doLogin();
  8242. return;
  8243. }
  8244. callbackfn(com.ibm.mm.enabler.services.ModelRestServiceRequest.XHR_STATUS_ERROR, null, xhr, addtlCallbackFnArguments);
  8245. },
  8246. sync: this._sync,
  8247. postData: feed.toString(),
  8248. handleAs: this._handleAs
  8249. };
  8250. dojo.rawXhrPost(args);
  8251. },
  8252. read: function( /* Function? */callbackfn, /* Object? */ addtlCallbackFnArguments) {
  8253. // summary: Read the ATOM feed provided by the REST service.
  8254. // description: If textOnly is set to true, the ATOM feed is returned as
  8255. // text and
  8256. // passed in as a single argument to the specified callback function.
  8257. // Otherwise, the ATOM feed is parsed into an {@link ibm.atom.Feed}
  8258. // object
  8259. // and passed into the callback function along with the original XML
  8260. // Document
  8261. // Object Model object.
  8262. // callbackfn: the function to call when the operation is complete (only
  8263. // valid if
  8264. // sync is false)
  8265. // addtlCallbackFnArguments: any arguments to pass through to the
  8266. // callback function
  8267. if (this._textOnly) {
  8268. this._retrieveRawFeed(callbackfn, addtlCallbackFnArguments);
  8269. }
  8270. else {
  8271. this._retrieve(callbackfn, addtlCallbackFnArguments);
  8272. }
  8273. },
  8274. update: function( /* ibm.atom.Feed */feed, /* Function */ callbackfn, /* Object? */ addtlCallbackFnArguments) {
  8275. // summary: Updates an entry in a feed.
  8276. // description: Updates an entry in a feed. This operation is not
  8277. // implemented in this
  8278. // class. It should be overridden by subclasses and properly implemented
  8279. // if the
  8280. // REST service supports the update operation.
  8281. // feed: the ATOM feed object
  8282. // entry: the ATOM entry to create
  8283. // callbackfn: the function to call when the operation is complete
  8284. this._updateCookie();
  8285. var me = this;
  8286. var args = {
  8287. url: this._feedURI,
  8288. load: function(response, ioArgs) {
  8289. var xhr = ioArgs.xhr;
  8290. var xrd = xhr.getResponseHeader("X-Request-Digest");
  8291. if (xrd !== null) {
  8292. com.ibm.mm.enabler.services.ModelRestServiceRequestStatic.setXRequestDigest(xrd);
  8293. }
  8294. var contentType = xhr.getResponseHeader("Content-Type");
  8295. if (typeof contentType != "undefined" && contentType !== null && contentType.indexOf("text/html") >= 0) {
  8296. me._doLogin();
  8297. return;
  8298. }
  8299. // this seems to be fixed with dojo 1.4.1 ... WTF ? Seems or IS ???
  8300. // if (dojo.isIE < 7) {
  8301. // data = dojox.xml.parser.parse(xhr.responseText,"application/xml");
  8302. // }
  8303. dojo.partial(callbackfn)(com.ibm.mm.enabler.services.ModelRestServiceRequest.XHR_STATUS_LOAD, response, xhr, addtlCallbackFnArguments);
  8304. },
  8305. error: function(response, ioArgs) {
  8306. var xhr = ioArgs.xhr;
  8307. var status = xhr.status;
  8308. // Check whether we are having an authorization problem
  8309. if (status == 401) {
  8310. me._doLogin();
  8311. return;
  8312. }
  8313. dojo.partial(callbackfn)(com.ibm.mm.enabler.services.ModelRestServiceRequest.XHR_STATUS_ERROR, null, xhr, addtlCallbackFnArguments);
  8314. },
  8315. sync: this._sync,
  8316. handleAs: this._handleAs
  8317. };
  8318. var requestHeaders = {
  8319. // "If-Modified-Since": "Thu, 1 Jan 1970 00:00:00 GMT",
  8320. "Content-Type": "application/atom+xml; charset=utf-8"
  8321. };
  8322. var mpHandler = com.ibm.mashups.enabler.io.XHRMultipartFactory.create();
  8323. var inTrans = mpHandler.isTransaction();
  8324. // we verify for sync here as well because we know that the transactions
  8325. // gets aborted by the multipart processing and hence we can do the PUT
  8326. // right away
  8327. if (com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME).getValue(com.ibm.mashups.enabler.services.ConfigConstants.TUNNEL_MODE) === true && (!inTrans || this._sync)) {
  8328. requestHeaders[this.POST_ACTION_HEADER] = this.REQUEST_METHOD_PUT;
  8329. args.headers = requestHeaders;
  8330. args.postData = feed;
  8331. dojo.rawXhrPost(args);
  8332. }
  8333. else {
  8334. args.putData = feed;
  8335. args.headers = requestHeaders;
  8336. dojo.rawXhrPut(args);
  8337. }
  8338. },
  8339. remove: function(/* Function */callbackfn, /* Object? */ addtlCallbackFnArguments) {
  8340. // summary: Removes an entry from a feed.
  8341. // description: Removes an entry from a feed. This operation is not
  8342. // implemented in this
  8343. // class. It should be overridden by subclasses and properly implemented
  8344. // if the
  8345. // REST service supports the remove operation.
  8346. // feed: the ATOM feed object
  8347. // entry: the ATOM entry to create
  8348. // callbackfn: the function to call when the operation is complete
  8349. this._updateCookie();
  8350. var me = this;
  8351. var args = {
  8352. url: this._feedURI,
  8353. load: function(response, ioArgs) {
  8354. var type = com.ibm.mm.enabler.services.ModelRestServiceRequest.XHR_STATUS_LOAD;
  8355. var data = response;
  8356. var xhr = ioArgs.xhr;
  8357. var xrd = xhr.getResponseHeader("X-Request-Digest");
  8358. if (xrd !== null) {
  8359. com.ibm.mm.enabler.services.ModelRestServiceRequestStatic.setXRequestDigest(xrd);
  8360. }
  8361. var contentType = xhr.getResponseHeader("Content-Type");
  8362. if (typeof contentType != "undefined" && contentType !== null && contentType.indexOf("text/html") >= 0) {
  8363. me._doLogin();
  8364. return;
  8365. }
  8366. if (dojo.isIE) {
  8367. data = dojox.xml.parser.parse(xhr.responseText);
  8368. }
  8369. callbackfn(type, data, xhr, addtlCallbackFnArguments);
  8370. },
  8371. error: function(response, ioArgs) {
  8372. var xhr = ioArgs.xhr;
  8373. var status = xhr.status;
  8374. // Check whether we are having an authorization problem
  8375. if (status == 401) {
  8376. me._doLogin();
  8377. return;
  8378. }
  8379. callbackfn(com.ibm.mm.enabler.services.ModelRestServiceRequest.XHR_STATUS_ERROR, null, xhr, addtlCallbackFnArguments);
  8380. },
  8381. sync: this._sync,
  8382. handleAs: this._handleAs
  8383. };
  8384. var requestHeaders = {
  8385. // "If-Modified-Since": "Thu, 1 Jan 1970 00:00:00 GMT",
  8386. "Content-Type": "application/atom+xml"
  8387. };
  8388. if (com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME).getValue(com.ibm.mashups.enabler.services.ConfigConstants.TUNNEL_MODE) === true) {
  8389. requestHeaders[this.POST_ACTION_HEADER] = this.REQUEST_METHOD_DELETE;
  8390. args.headers = requestHeaders;
  8391. dojo.rawXhrPost(args);
  8392. }
  8393. else {
  8394. args.headers = requestHeaders;
  8395. dojo.xhrDelete(args);
  8396. }
  8397. },
  8398. _retrieveRawFeed: function(callbackfn, callbackargs) {
  8399. var me = this;
  8400. dojo.xhrGet({
  8401. url: this._feedURI,
  8402. headers: this._headers,
  8403. load: function(data, ioArgs) {
  8404. var xhr = ioArgs.xhr;
  8405. var xrd = xhr.getResponseHeader("X-Request-Digest");
  8406. if (xrd !== null) {
  8407. com.ibm.mm.enabler.services.ModelRestServiceRequestStatic.setXRequestDigest(xrd);
  8408. }
  8409. if (me.logoutVerificationForRaw) {
  8410. // in this case we assume that a X-Request-Digest is always returned from the resolver
  8411. // if it is not coming back it had to be due to a login challange
  8412. if (!xrd) {
  8413. me._doLogin();
  8414. return;
  8415. }
  8416. }
  8417. callbackfn(com.ibm.mm.enabler.services.ModelRestServiceRequest.XHR_STATUS_LOAD, data, ioArgs.xhr, callbackargs);
  8418. },
  8419. error: function(data, ioArgs) {
  8420. var xhr = ioArgs.xhr;
  8421. var status = xhr.status;
  8422. // Check whether we are having an authorization problem
  8423. if (status == 401) {
  8424. me._doLogin();
  8425. return;
  8426. }
  8427. callbackfn(com.ibm.mm.enabler.services.ModelRestServiceRequest.XHR_STATUS_ERROR, data, ioArgs.xhr, callbackargs);
  8428. },
  8429. sync: this._sync,
  8430. handleAs: this._handleAs
  8431. });
  8432. },
  8433. _retrieve: function(callbackfn, callbackargs, formNode, formFilter) {
  8434. var content = {};
  8435. // temp my ass
  8436. var mt = "xml"; // temp
  8437. if (dojo.isIE) {
  8438. // content = { "com.ibm.wps.web2.contenttype": "text/xml" };
  8439. mt = "text"; // temp
  8440. }
  8441. var me = this;
  8442. var args = {
  8443. url: this._feedURI,
  8444. content: content,
  8445. headers: this._headers,
  8446. load: function(response, ioArgs) {
  8447. var data = response;
  8448. var xhr = ioArgs.xhr;
  8449. var xrd = xhr.getResponseHeader("X-Request-Digest");
  8450. if (xrd !== null) {
  8451. com.ibm.mm.enabler.services.ModelRestServiceRequestStatic.setXRequestDigest(xrd);
  8452. }
  8453. var contentType = xhr.getResponseHeader("Content-Type");
  8454. // If the HTML content is returned, this is probably another
  8455. // re-direction so we need to
  8456. // force a full-page refresh.
  8457. if (typeof contentType != "undefined" && contentType !== null && contentType.indexOf("text/html") >= 0) {
  8458. me._doLogin();
  8459. return;
  8460. }
  8461. if (dojo.isIE) {
  8462. var doc = com.ibm.mm.enabler.utils.Dom.createDocument(data);
  8463. callbackfn(com.ibm.mm.enabler.services.ModelRestServiceRequest.XHR_STATUS_LOAD, doc, xhr, callbackargs);
  8464. }
  8465. else {
  8466. callbackfn(com.ibm.mm.enabler.services.ModelRestServiceRequest.XHR_STATUS_LOAD, data, xhr, callbackargs);
  8467. }
  8468. },
  8469. error: function(response, ioArgs) {
  8470. var data = response;
  8471. var xhr = ioArgs.xhr;
  8472. var status = xhr.status;
  8473. // Check whether we are having an authorization problem
  8474. if (status == 401) {
  8475. me._doLogin();
  8476. return;
  8477. }
  8478. if (dojo.isIE) {
  8479. var doc = null;
  8480. try {
  8481. if (data) {
  8482. doc = com.ibm.mm.enabler.utils.Dom.createDocument(data);
  8483. }
  8484. }
  8485. catch (e) {
  8486. }
  8487. callbackfn(com.ibm.mm.enabler.services.ModelRestServiceRequest.XHR_STATUS_ERROR, doc, xhr, callbackargs);
  8488. }
  8489. else {
  8490. callbackfn(com.ibm.mm.enabler.services.ModelRestServiceRequest.XHR_STATUS_ERROR, data, xhr, callbackargs);
  8491. }
  8492. },
  8493. sync: this._sync,
  8494. handleAs: mt
  8495. };
  8496. var method = "Get";
  8497. if (this._formNode) {
  8498. args.form = this._formNode;
  8499. method = "Post";
  8500. }
  8501. if (this._formFilter) {
  8502. args.formFilter = this._formFilter;
  8503. }
  8504. dojo["xhr" + method](args);
  8505. },
  8506. _updateCookie: function() {
  8507. var dt = new Date();
  8508. var properties = {};
  8509. properties.path = this._config.getValue(com.ibm.mashups.enabler.services.ConfigConstants.CONTEXT_ROOT);
  8510. dojo.cookie(this.MODIFICATION_COOKIE, dt.getTime(), properties);
  8511. },
  8512. _doLogin: function() {
  8513. // lazy load, to support dojo layer build
  8514. dojo["require"]("com.ibm.mashups.enabler.model.state.NavigationStateModelFactory"); // JSLINT-IGNORE:
  8515. // This
  8516. // needs
  8517. // to
  8518. // be
  8519. // done
  8520. // to
  8521. // allow
  8522. // modularization
  8523. // and
  8524. // not
  8525. // break
  8526. // the
  8527. // layer
  8528. // build
  8529. dojo["require"]("com.ibm.mashups.enabler.model.state.UrlGeneratorFactory"); // JSLINT-IGNORE:
  8530. // This
  8531. // needs
  8532. // to
  8533. // be
  8534. // done
  8535. // to
  8536. // allow
  8537. // modularization
  8538. // and
  8539. // not
  8540. // break
  8541. // the
  8542. // layer
  8543. // build
  8544. var pid = null;
  8545. var url = document.location.href;
  8546. // get full page refresh redirect url
  8547. var cb = function(url) {
  8548. if (url) {
  8549. top.location.href = url;
  8550. }
  8551. };
  8552. var navStateModel = com.ibm.mashups.enabler.model.state.NavigationStateModelFactory.getNavigationStateModel();
  8553. com.ibm.mashups.enabler.model.state.UrlGeneratorFactory.getURLGenerator().getUrl(navStateModel, cb, {
  8554. nohash: "true"
  8555. });
  8556. },
  8557. toString: function() {
  8558. return this._feedURI;
  8559. }
  8560. });
  8561. com.ibm.mm.enabler.services.ModelRestServiceRequestStatic = {
  8562. xRequestDigest : null,
  8563. getXRequestDigest: function() {
  8564. if ((null === this.xRequestDigest) && (ibmConfig["com.ibm.resolver.digest"])) {
  8565. this.xRequestDigest = ibmConfig["com.ibm.resolver.digest"];
  8566. }
  8567. return this.xRequestDigest;
  8568. },
  8569. setXRequestDigest: function(digest) {
  8570. this.xRequestDigest = digest;
  8571. },
  8572. invalidateXRequestDigest: function() {
  8573. // update digest
  8574. var dt = new Date();
  8575. var digest = dt.getTime();
  8576. this.setXRequestDigest(digest);
  8577. // update cookie
  8578. var properties = {};
  8579. var cs = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);
  8580. properties.path = cs.getValue(com.ibm.mashups.enabler.services.ConfigConstants.CONTEXT_ROOT);
  8581. dojo.cookie("modified.id", digest, properties);
  8582. }
  8583. };
  8584. // constants
  8585. com.ibm.mm.enabler.services.ModelRestServiceRequest.XHR_STATUS_LOAD = "load";
  8586. com.ibm.mm.enabler.services.ModelRestServiceRequest.XHR_STATUS_ERROR = "error";
  8587. dojo.declare("com.ibm.mm.enabler.services.XHRModelHeaderExtensionImpl", null, {
  8588. constructor: function() {
  8589. this.originalDojoXHR = dojo.xhr;
  8590. dojo.xhr = dojo.hitch(this, function(/* String */method, /* dojo.__XhrArgs */ args, /* Boolean */ hasBody) {
  8591. if (!args.headers) {
  8592. args.headers = {};
  8593. }
  8594. args.headers["X-IBM-XHR"] = "true";
  8595. var ret = this.originalDojoXHR(method, args, hasBody);
  8596. return ret;
  8597. });
  8598. }
  8599. });
  8600. com.ibm.mm.enabler.services.XHRModelHeaderExtension = new com.ibm.mm.enabler.services.XHRModelHeaderExtensionImpl();
  8601. }
  8602. if(!dojo._hasResource["com.ibm.mm.enabler.endpoints.XHREndpointExtensionImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  8603. dojo._hasResource["com.ibm.mm.enabler.endpoints.XHREndpointExtensionImpl"] = true;
  8604. dojo.provide("com.ibm.mm.enabler.endpoints.XHREndpointExtensionImpl");
  8605. dojo.declare("com.ibm.mm.enabler.endpoints.XHREndpointExtensionImpl", null, {
  8606. constructor: function(){
  8607. this.originalDojoXHR = dojo.xhr;
  8608. dojo.xhr = dojo.hitch(this, function(/* String */ method, /* dojo.__XhrArgs */ args, /* Boolean */ hasBody) {
  8609. var url = args.url;
  8610. var url2 = com.ibm.mm.enabler.EndpointUtils.checkForEndpoints(url);
  8611. url2 = url2 || null;
  8612. if (url2 !== null) {
  8613. args.url = url2;
  8614. }
  8615. var ret = this.originalDojoXHR(method, args, hasBody);
  8616. return ret;
  8617. });
  8618. }
  8619. });
  8620. com.ibm.mm.enabler.endpoints.XHREndpointExtension = new com.ibm.mm.enabler.endpoints.XHREndpointExtensionImpl();
  8621. }
  8622. if(!dojo._hasResource["com.ibm.mm.enabler.services.ConfigServiceExtendedImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  8623. dojo._hasResource["com.ibm.mm.enabler.services.ConfigServiceExtendedImpl"] = true;
  8624. dojo.provide("com.ibm.mm.enabler.services.ConfigServiceExtendedImpl");
  8625. /*
  8626. * This is injected on the fly and not fetched through an API. Therefore we need to define the @ibm-module so that the build process is picking it up
  8627. * @ibm-module Base
  8628. *
  8629. * This value defines the order in which the packages should be printed out into the dojo profile. Default is 100.
  8630. * Any number that is smaller causes this class to be written out before any other with a higher number
  8631. * @ibm-dojo-profile-level 40
  8632. */
  8633. // inject this service into the ServiceManager at the end. Therefore we have to require the implementation
  8634. dojo.declare("com.ibm.mm.enabler.services.ConfigServiceExtendedImpl", [com.ibm.mm.enabler.services.ConfigServiceDefaultImpl], {
  8635. constructor: function() {
  8636. },
  8637. _getConfigObject: function(/*string*/configProvider) {
  8638. if (!ibmConfig["CO_" + configProvider]) {
  8639. var co = new com.ibm.mm.enabler.services.ConfigObjectExtendedImpl(configProvider, this);
  8640. ibmConfig["CO_" + configProvider] = co;
  8641. }
  8642. return ibmConfig["CO_" + configProvider];
  8643. },
  8644. _getConfigProviderNames: function() {
  8645. // lazy load, to support dojo layer build
  8646. dojo["require"]("com.ibm.mashups.enabler.model.url.ModelUrlFactory"); // JSLINT-IGNORE: This needs to be done to allow modularization and not break the layer build
  8647. var ret = [];
  8648. ret.push("all");
  8649. var myUrl = com.ibm.mashups.enabler.model.url.ModelUrlFactory.createModelURL(com.ibm.mashups.enabler.model.url.ModelUrlFactory.CONFIG_URL, this);
  8650. myUrl.setSchemeSpecificPart("/*");
  8651. myUrl.setParameter("rep", "compact");
  8652. var serviceReq = new com.ibm.mm.enabler.services.ModelRestServiceRequest(myUrl, null, null, false, true);
  8653. var me = this;
  8654. serviceReq.read(function(type, data, xhr, args) {
  8655. var configXmls = com.ibm.mashups.enabler.xml.XPath.evaluateXPath("//atom:entry/atom:id", data, me.ns);
  8656. if (configXmls && configXmls.length > 0) {
  8657. for (var i = 0, l = configXmls.length; i < l; i++) {
  8658. var configXml = com.ibm.mm.enabler.utils.Dom.textContent(configXmls[i]);
  8659. var lastSlash = configXml.indexOf("/", 9);
  8660. configXml = configXml.substring(8, lastSlash).trim();
  8661. for (var config in ibmConfig) {
  8662. if (ibmConfig[config] === configXml) {
  8663. configXml = config.substring(15);
  8664. }
  8665. }
  8666. ret.push(configXml);
  8667. }
  8668. }
  8669. });
  8670. return ret;
  8671. }
  8672. });
  8673. com.ibm.mashups.services.ServiceManager.setService("configService", "com.ibm.mm.enabler.services.ConfigServiceExtendedImpl");
  8674. }
  8675. if(!dojo._hasResource["com.ibm.mashups.enabler.model.ServiceDocumentModel_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  8676. dojo._hasResource["com.ibm.mashups.enabler.model.ServiceDocumentModel_API"] = true;
  8677. dojo.provide("com.ibm.mashups.enabler.model.ServiceDocumentModel_API");
  8678. dojo.provide("com.ibm.mashups.enabler.model.ServiceDocumentModel");
  8679. /**
  8680. * An singleton that represents the Service Document
  8681. *
  8682. * @ibm-spi
  8683. * @ibm-module Base
  8684. *
  8685. * This value defines the order in which the packages should be printed out into the dojo profile. Default is 100.
  8686. * Any number that is smaller causes this class to be written out before any other with a higher number
  8687. * @ibm-dojo-profile-level 50
  8688. */
  8689. dojo.declare("com.ibm.mashups.enabler.model.ServiceDocumentModel", null,
  8690. {
  8691. /**
  8692. * Constant representing the navigation service
  8693. * @type {String}
  8694. */
  8695. SERVICE_NAVIGATION: "navigation",
  8696. /**
  8697. * Constant representing the space navigation service
  8698. * @type {String}
  8699. */
  8700. SERVICE_SPACE_NAVIGATION: "space-navigation",
  8701. /**
  8702. * Constant representing the shared navigation service
  8703. * @type {String}
  8704. */
  8705. SERVICE_SHARED_NAVIGATION: "shared-navigation",
  8706. /**
  8707. * Constant representing the content service
  8708. * @type {String}
  8709. */
  8710. SERVICE_CONTENT: "content",
  8711. /**
  8712. * Constant representing the catalog service
  8713. * @type {String}
  8714. */
  8715. SERVICE_CATALOG: "catalog",
  8716. /**
  8717. * Constant representing the resource service
  8718. * @type {String}
  8719. */
  8720. SERVICE_RESOURCE: "resource",
  8721. /**
  8722. * Constant representing the widget service
  8723. * @type {String}
  8724. */
  8725. SERVICE_WIDGET: "widget",
  8726. /**
  8727. * Constant representing the theme service
  8728. * @type {String}
  8729. */
  8730. SERVICE_THEME: "theme",
  8731. /**
  8732. * Constant representing the user service
  8733. * @type {String}
  8734. */
  8735. SERVICE_USER: "user",
  8736. /**
  8737. * Constant representing generic model services
  8738. * @type {String}
  8739. */
  8740. SERVICE_MODEL: "model",
  8741. /**
  8742. * Constant representing multipart services
  8743. * @type {String}
  8744. */
  8745. SERVICE_MULTIPART: "multipart",
  8746. /**
  8747. * Constant representing the huffman encoding of multipart services
  8748. * @type {String}
  8749. */
  8750. SERVICE_HUFFMAN: "huffman",
  8751. /**
  8752. * Constant representing the sitemap encoding of multipart services
  8753. * @type {String}
  8754. */
  8755. SERVICE_SITEMAP: "sitemap",
  8756. /**
  8757. * Constant representing the commit handler sitemap encoding of multipart services
  8758. * @type {String}
  8759. */
  8760. SERVICE_SITEMAP_COMMITHANDLER: "commit-handler",
  8761. /**
  8762. * Constant representing the composite application service
  8763. * @type {String}
  8764. */
  8765. SERVICE_COMPOSITE: "composite-applications",
  8766. /**
  8767. * Constant representing the space service
  8768. * @type {String}
  8769. */
  8770. SERVICE_SPACE: "application",
  8771. /**
  8772. * Constant representing the space favorites service
  8773. * @type {String}
  8774. */
  8775. SERVICE_SPACE_FAVORITE: "application-favorite",
  8776. /**
  8777. * Constant representing the template service
  8778. * @type {String}
  8779. */
  8780. SERVICE_TEMPLATE: "template",
  8781. /**
  8782. * Constant representing the config service
  8783. * @type {String}
  8784. */
  8785. SERVICE_CONFIG: "config",
  8786. /**
  8787. * Constant representing the webdav filestore
  8788. * @type {String}
  8789. */
  8790. SERVICE_FILESTORE: "filestore",
  8791. /**
  8792. * Constant representing generic webdav services
  8793. * @type {String}
  8794. */
  8795. SERVICE_WEBDAV: "webdav",
  8796. /**
  8797. * Invalidates the Service Document Model in order for it to be re-initialized again.
  8798. *
  8799. * @type void
  8800. */
  8801. invalidate: function() {
  8802. },
  8803. /**
  8804. * Returns a two-dimensional array of IDs representing services which are attached to a specific endpoint namespace.
  8805. * The IDs in the second dimension are required to lookup the service data.<br/>
  8806. * Example: [["webdav"],["filestore"]]<br/>
  8807. * Only the combination of both IDs make the service unique and must be used to lookup the service data
  8808. *
  8809. * @Returns {String[][]} A two-dimensional array with the second dimension being a list of IDs which represent the service.
  8810. */
  8811. getModelCollections: function() {
  8812. },
  8813. /**
  8814. * Returns a two-dimensional array of IDs representing services which are attached to mashups specifically.
  8815. * The IDs in the second dimension are required to lookup the service data.<br/>
  8816. * Example: [["webdav"],["filestore"]]<br/>
  8817. * Only the combination of both IDs make the service unique and must be used to lookup the service data
  8818. *
  8819. * @return {String[][]} A two-dimensional array with the second dimension being a list of IDs which represent the service.
  8820. */
  8821. getMashupsCollections: function() {
  8822. },
  8823. /**
  8824. * Returns a JSON object for a given collection link in the service document. Not all elements are mandatory.<br/>
  8825. * JSON format<br/>
  8826. * { id: "the id array",<br/>
  8827. * url :"the url",<br/>
  8828. * template :"the template",<br/>
  8829. * idprefix: "id|oid",<br/>
  8830. * namespaces : { "base" : "base-url", "model" : "model-url", "ext" : "ext-url", "creation-context" : "creation-context-url" },<br/>
  8831. * accept: "accept MIME type",<br/>
  8832. * version: "major.minor"<br/>
  8833. * }<br/>
  8834. * @param {String[]} idArray The ID Array to lookup the service for.
  8835. * @type Object
  8836. * @return {Object} Returns a JSON object for a given collection link in the service document
  8837. */
  8838. getCollectionData: function(idArray) {
  8839. }
  8840. }
  8841. );
  8842. }
  8843. if(!dojo._hasResource["com.ibm.mm.enabler.model.ServiceDocumentModel"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  8844. dojo._hasResource["com.ibm.mm.enabler.model.ServiceDocumentModel"] = true;
  8845. dojo.provide("com.ibm.mm.enabler.model.ServiceDocumentModel");
  8846. dojo.declare("com.ibm.mm.enabler.model.ServiceDocumentModelImpl", com.ibm.mashups.enabler.model.ServiceDocumentModel,
  8847. {
  8848. SERVICE_NAVIGATION: "navigation",
  8849. SERVICE_SPACE_NAVIGATION: "space-navigation",
  8850. SERVICE_SHARED_NAVIGATION: "shared-navigation",
  8851. SERVICE_CONTENT: "content",
  8852. SERVICE_CATALOG: "catalog",
  8853. SERVICE_RESOURCE: "resource",
  8854. SERVICE_WIDGET: "widget",
  8855. SERVICE_THEME: "theme",
  8856. SERVICE_USER: "user",
  8857. SERVICE_MODEL: "model",
  8858. SERVICE_MULTIPART: "multipart",
  8859. SERVICE_HUFFMAN: "huffman",
  8860. SERVICE_SITEMAP: "sitemap",
  8861. SERVICE_SITEMAP_COMMITHANDLER: "commit-handler",
  8862. SERVICE_COMPOSITE: "composite-applications",
  8863. SERVICE_SPACE: "application",
  8864. SERVICE_SPACE_FAVORITE: "application-favorite",
  8865. SERVICE_TEMPLATE: "template",
  8866. SERVICE_CONFIG: "config",
  8867. SERVICE_FILESTORE: "filestore",
  8868. SERVICE_WEBDAV: "webdav",
  8869. constructor: function () {
  8870. this.prefix = "service";
  8871. this.ns = { "atom" : "http://www.w3.org/2005/Atom",
  8872. "app" : "http://www.w3.org/2007/app",
  8873. "service" : "http://www.ibm.com/xmlns/prod/sw/model/service/1.0"};
  8874. this.xmlData = null;
  8875. this.xmlDataAsString = null;
  8876. this.max_version = null;
  8877. this.cache = [];
  8878. },
  8879. getInstance: function() {
  8880. var instance = com.ibm.mm.enabler.model.ServiceDocumentModelImpl._instance;
  8881. return instance ? instance : (com.ibm.mm.enabler.model.ServiceDocumentModelImpl._instance = new com.ibm.mm.enabler.model.ServiceDocumentModelImpl());
  8882. },
  8883. invalidate: function() {
  8884. this.xmlData = null;
  8885. this.max_version = null;
  8886. },
  8887. _loadAhead: function() {
  8888. // lazy load, to support dojo layer build
  8889. dojo["require"]("com.ibm.mashups.enabler.model.url.ModelUrlFactory"); // JSLINT-IGNORE: This needs to be done to allow modularization and not break the layer build
  8890. if (ibmConfig.servicedocument) {
  8891. if (this.xmlDataAsString != ibmConfig.servicedocument) {
  8892. this.xmlData = null;
  8893. }
  8894. }
  8895. if (this.xmlData) {
  8896. return;
  8897. }
  8898. if (ibmConfig.servicedocument) {
  8899. this.xmlData = dojox.xml.parser.parse( ibmConfig.servicedocument );
  8900. this.xmlDataAsString = ibmConfig.servicedocument;
  8901. } else {
  8902. var myUrl;
  8903. if (ibmConfig.serviceDocumentUrl) {
  8904. myUrl = new com.ibm.mm.enabler.utils.HttpUrl(ibmConfig.serviceDocumentUrl);
  8905. } else {
  8906. myUrl = com.ibm.mashups.enabler.model.url.ModelUrlFactory.createModelURL("service", null);
  8907. myUrl.setNodes([{
  8908. value: "collection",
  8909. isID: false
  8910. }]);
  8911. }
  8912. var serviceReq = new com.ibm.mm.enabler.services.ModelRestServiceRequest(myUrl, null, null, false, true);
  8913. serviceReq.read(
  8914. dojo.hitch(this,
  8915. function (type, data, xhr, args) {
  8916. if (type == com.ibm.mm.enabler.services.ModelRestServiceRequest.XHR_STATUS_LOAD) {
  8917. this.xmlData = data;
  8918. } else if (type == com.ibm.mm.enabler.services.ModelRestServiceRequest.XHR_STATUS_ERROR) {
  8919. // TODO
  8920. }
  8921. }
  8922. )
  8923. );
  8924. }
  8925. this._fillCache();
  8926. },
  8927. _fillCache: function() {
  8928. this.max_version = null;
  8929. if (ibmConfig.servicedocument_version_max) {
  8930. this.max_version = parseInt(ibmConfig.servicedocument_version_max.replace(/\./g, ""),10);
  8931. }
  8932. var matches = [];
  8933. var i, l, found;
  8934. var expr = "//app:collection";
  8935. var nodes = com.ibm.mashups.enabler.xml.XPath.evaluateXPath(expr, this.xmlData, this.ns);
  8936. for (i=0, l = nodes.length; i<l; ++i) {
  8937. found = this._processCollection(i, nodes[i]);
  8938. if (found) {
  8939. this.cache[this.cache.length] = found;
  8940. }
  8941. }
  8942. expr = "//service:collection";
  8943. nodes = com.ibm.mashups.enabler.xml.XPath.evaluateXPath(expr, this.xmlData, this.ns);
  8944. for (i=0, l = nodes.length; i<l; ++i) {
  8945. found = this._processCollection(i, nodes[i]);
  8946. if (found) {
  8947. this.cache[this.cache.length] = found;
  8948. }
  8949. }
  8950. },
  8951. /**
  8952. Returns an array of available model ids which are compatible for the enabler runtime
  8953. */
  8954. getModelCollections: function() {
  8955. this._loadAhead();
  8956. var ret = [];
  8957. var count = 0;
  8958. var expr = "//atom:category[@term='enabler-ns-base']";
  8959. var nodes = com.ibm.mashups.enabler.xml.XPath.evaluateXPath(expr, this.xmlData, this.ns);
  8960. for (var i=0, l = nodes.length; i<l; ++i) {
  8961. var parent = nodes[i].parentNode;
  8962. var expr2 = "//atom:category[not (@term='enabler-ns-base' or @term='enabler-ns-model' or @term='enabler-ns-ext' or @term='enabler-ns-creationcontext' or @term='mashups')]";
  8963. var nodes2 = com.ibm.mashups.enabler.xml.XPath.evaluateXPath(expr2, parent, this.ns);
  8964. if (nodes2 && nodes2.length>0) {
  8965. var terms = [];
  8966. for (var ii=0, ll = nodes2.length; ii<ll; ++ii) {
  8967. if (nodes2[ii].parentNode==parent) {
  8968. terms.push(nodes2[ii].getAttribute("term"));
  8969. }
  8970. }
  8971. terms.sort();
  8972. // verify if already exists(e.g. due to another version)
  8973. var dup = this._isDuplicate(ret, terms);
  8974. if (!dup) {
  8975. ret[count] = terms;
  8976. count++;
  8977. }
  8978. }
  8979. }
  8980. return ret;
  8981. },
  8982. _isDuplicate: function(array, newterm) {
  8983. var dup = false;
  8984. for (var ii=0; ii<array.length; ii++) {
  8985. if (array[ii].length==newterm.length) {
  8986. var equal = true;
  8987. for (var c=0; c<newterm.length; c++) {
  8988. if (array[ii][c]!=newterm[c]) {
  8989. equal = false;
  8990. break;
  8991. }
  8992. }
  8993. if (equal) {
  8994. dup = true;
  8995. break;
  8996. }
  8997. }
  8998. }
  8999. return dup;
  9000. },
  9001. /**
  9002. Returns an array of available model ids which are compatible for the enabler runtime
  9003. */
  9004. getMashupsCollections: function() {
  9005. this._loadAhead();
  9006. var ret = [];
  9007. var count = 0;
  9008. var expr = "//atom:category[@term='mashups']";
  9009. var nodes = com.ibm.mashups.enabler.xml.XPath.evaluateXPath(expr, this.xmlData, this.ns);
  9010. for (var i=0, l = nodes.length; i<l; ++i) {
  9011. var parent = nodes[i].parentNode;
  9012. var expr2 = "//atom:category[not (@term='enabler-ns-base' or @term='enabler-ns-model' or @term='enabler-ns-ext' or @term='enabler-ns-creationcontext' or @term='mashups')]";
  9013. var nodes2 = com.ibm.mashups.enabler.xml.XPath.evaluateXPath(expr2, parent, this.ns);
  9014. if (nodes2 && nodes2.length>0) {
  9015. var terms = [];
  9016. for (var ii=0,ll=nodes2.length; ii<ll; ++ii) {
  9017. if (nodes2[ii].parentNode==parent) {
  9018. terms.push(nodes2[ii].getAttribute("term"));
  9019. }
  9020. }
  9021. terms.sort();
  9022. // verify if already exists(e.g. due to another version)
  9023. var dup = this._isDuplicate(ret, terms);
  9024. if (!dup) {
  9025. ret[count] = terms;
  9026. count++;
  9027. }
  9028. }
  9029. }
  9030. return ret;
  9031. },
  9032. /**
  9033. Returns a JSON object for a given collection link in the service document. Not all elements are mandatory
  9034. JSON format
  9035. { id: "the id array",
  9036. url :"the url",
  9037. template :"the template",
  9038. idprefix: "id|oid",
  9039. namespaces : { "base" : "base-url", "model" : "model-url", "ext" : "ext-url", "creation-context" : "creation-context-url" },
  9040. accept: "accept MIME type",
  9041. version: "major.minor"
  9042. };
  9043. @param {Array} idArray
  9044. @type Object
  9045. @return {Object} Returns a JSON object for a given collection link in the service document
  9046. */
  9047. getCollectionData: function(idArray) {
  9048. this._loadAhead();
  9049. var ret = {};
  9050. this.xmlData = this.xmlData || null;
  9051. if (!this.xmlData) {
  9052. return ret;
  9053. }
  9054. var ids = [];
  9055. if (dojo.isArray(idArray)) {
  9056. ids = idArray;
  9057. }
  9058. else {
  9059. ids = [idArray];
  9060. }
  9061. ret = this._getCachedValue(ids);
  9062. return ret;
  9063. },
  9064. _getCachedValue: function(ids)
  9065. {
  9066. // try the best match
  9067. var scoreCard = [];
  9068. var i, cl, lo, m, l, scl;
  9069. for (i = 0, cl = this.cache.length; i < cl; i++) {
  9070. var matchIds = this.cache[i].id;
  9071. var score = 0;
  9072. for (j = 0, lo = matchIds.length; j < lo; j++) {
  9073. if (matchIds[j] == "mashups") {
  9074. // we prefer the mashups link. therefore we give score for it
  9075. score += 500;
  9076. }
  9077. for (m = 0, l = ids.length; m < l; m++) {
  9078. if (matchIds[j] == ids[m]) {
  9079. score += 1000;
  9080. }
  9081. }
  9082. }
  9083. var intVersion = parseInt(this.cache[i].version.replace(/\./g, ""),10);
  9084. score += intVersion;
  9085. if (this.max_version && (intVersion>this.max_version)) {
  9086. score = -1000; // disregard;
  9087. }
  9088. scoreCard[i] = score;
  9089. }
  9090. // see who won
  9091. var winner = -1;
  9092. var winningScore = 1000; // we need at least one matched item, therefore the minimum is 1000 points
  9093. for (i = 0, scl = scoreCard.length; i < scl; i++) {
  9094. if (scoreCard[i] > winningScore) {
  9095. winner = i;
  9096. winningScore = scoreCard[i];
  9097. }
  9098. }
  9099. if (winner == -1) {
  9100. return null;
  9101. }
  9102. return this.cache[winner];
  9103. },
  9104. _processCollection: function(i, node)
  9105. {
  9106. var ret = {};
  9107. // we found a match
  9108. var expr3 = "app:categories//atom:category[@term]";
  9109. var nodes3 = com.ibm.mashups.enabler.xml.XPath.evaluateXPath(expr3, node, this.ns);
  9110. var nodeIDs = [];
  9111. if (nodes3) {
  9112. for (var jj = 0, ll = nodes3.length; jj < ll; jj++) {
  9113. var term = nodes3[jj].getAttribute('term');
  9114. if (term.indexOf("enabler-ns-")===0) {
  9115. continue;
  9116. }
  9117. nodeIDs.push(term);
  9118. }
  9119. }
  9120. ret.id = nodeIDs;
  9121. ret.url = node.getAttribute("href");
  9122. ret.version = com.ibm.mm.enabler.utils.Dom.getAttributeWithNS(
  9123. node,"service:version","version",this.ns.service);
  9124. if (!ret.version) {
  9125. ret.version = "1.0";
  9126. }
  9127. ret.template = com.ibm.mm.enabler.utils.Dom.getAttributeWithNS(
  9128. node,"service:template","template",this.ns.service);
  9129. ret.idprefix = "id";
  9130. var ns = {};
  9131. expr3 = "app:categories/atom:category[@term='enabler-ns-base']";
  9132. nodes3 = com.ibm.mashups.enabler.xml.XPath.evaluateEntry(expr3, node, this.ns);
  9133. if (nodes3) {
  9134. ns.base = nodes3.getAttribute("scheme");
  9135. if (ns.base.indexOf("/mashups/")==-1) {
  9136. ret.idprefix = "oid";
  9137. }
  9138. }
  9139. expr3 = "app:categories/atom:category[@term='enabler-ns-model']";
  9140. nodes3 = com.ibm.mashups.enabler.xml.XPath.evaluateEntry(expr3, node, this.ns);
  9141. if (nodes3) {
  9142. ns.model = nodes3.getAttribute("scheme");
  9143. }
  9144. expr3 = "app:categories/atom:category[@term='enabler-ns-ext']";
  9145. nodes3 = com.ibm.mashups.enabler.xml.XPath.evaluateEntry(expr3, node, this.ns);
  9146. if (nodes3) {
  9147. ns.ext = nodes3.getAttribute("scheme");
  9148. }
  9149. expr3 = "app:categories/atom:category[@term='enabler-ns-creationcontext']";
  9150. nodes3 = com.ibm.mashups.enabler.xml.XPath.evaluateEntry(expr3, node, this.ns);
  9151. if (nodes3) {
  9152. ns["creation-context"] = nodes3.getAttribute("scheme");
  9153. }
  9154. ret.namespaces = ns;
  9155. expr3 = "app:accept";
  9156. nodes3 = com.ibm.mashups.enabler.xml.XPath.evaluateEntry(expr3, node, this.ns);
  9157. if (nodes3) {
  9158. ret.accept = nodes3.firstChild.nodeValue;
  9159. }
  9160. return ret;
  9161. }
  9162. }
  9163. );
  9164. com.ibm.mm.enabler.model.ServiceDocumentModel = com.ibm.mm.enabler.model.ServiceDocumentModelImpl.prototype.getInstance();
  9165. com.ibm.mashups.enabler.model.ServiceDocumentModel = com.ibm.mm.enabler.model.ServiceDocumentModel;
  9166. }
  9167. if(!dojo._hasResource["com.ibm.mashups.enabler.model.ServiceDocumentModel"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  9168. dojo._hasResource["com.ibm.mashups.enabler.model.ServiceDocumentModel"] = true;
  9169. dojo.provide("com.ibm.mashups.enabler.model.ServiceDocumentModel");
  9170. }
  9171. if(!dojo._hasResource["com.ibm.mashups.enabler.Commitable"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  9172. dojo._hasResource["com.ibm.mashups.enabler.Commitable"] = true;
  9173. dojo.provide("com.ibm.mashups.enabler.Commitable");
  9174. /**
  9175. * An interface that adds methods for checking for changes and appyling them.
  9176. * @since 2.4
  9177. * @ibm-api
  9178. * @ibm-module Base
  9179. */
  9180. dojo.declare("com.ibm.mashups.enabler.Commitable", null, {
  9181. /**
  9182. * States whether this object is &quot;dirty&quot;, meaning changes where done on this object.
  9183. * @return {boolean} <tt>true</tt> if changes where made to the object, <tt>false</tt> otherwise.
  9184. */
  9185. isDirty: function(){
  9186. return false;
  9187. },
  9188. /**
  9189. * Commits the modifications applied to this object.<br>
  9190. * @return {DeferredOperation} a deferred object used to start this operation.
  9191. * The return value when executed through the deferred object is <code>null</null>
  9192. */
  9193. commit: function(){
  9194. }
  9195. });
  9196. }
  9197. if(!dojo._hasResource["com.ibm.mashups.enabler.DefaultLocalized"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  9198. dojo._hasResource["com.ibm.mashups.enabler.DefaultLocalized"] = true;
  9199. dojo.provide("com.ibm.mashups.enabler.DefaultLocalized");
  9200. /**
  9201. * Read-Only interface providing methods to obtain default title, description,
  9202. * and locale
  9203. * @ibm-spi
  9204. * @ibm-module Base
  9205. */
  9206. dojo.declare("com.ibm.mashups.enabler.DefaultLocalized", null, {
  9207. /**
  9208. * Returns the default locale.<br>
  9209. * <br>
  9210. * @return {String} the default locale; may be <code>null</code>.
  9211. */
  9212. getDefaultLocale: function(){
  9213. },
  9214. /**
  9215. * Returns the default title.
  9216. * @return {String} the default title of this node; may be <code>null</code>.
  9217. */
  9218. getDefaultTitle: function(){
  9219. },
  9220. /**
  9221. * Returns the default description of this object.
  9222. * @return {String} the default description; may be <code>null</code>.
  9223. */
  9224. getDefaultDescription: function(){
  9225. }
  9226. });
  9227. }
  9228. if(!dojo._hasResource["com.ibm.mashups.enabler.Iterator"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  9229. dojo._hasResource["com.ibm.mashups.enabler.Iterator"] = true;
  9230. dojo.provide("com.ibm.mashups.enabler.Iterator");
  9231. /**
  9232. * Extended iterator interface, which allows iterating over elements
  9233. * in a sequentiell order. It allows to set the starting point of the
  9234. * iteration and exposes the number of elements in the iteration.
  9235. *
  9236. * @ibm-api
  9237. * @ibm-module Base
  9238. */
  9239. dojo.declare("com.ibm.mashups.enabler.Iterator", null, {
  9240. /**
  9241. * Returns <tt>true</tt> if the iteration has more elements.
  9242. * @return {Boolean} <tt>true</tt> if the iterator has more elements,
  9243. * otherwise <tt>false</tt>.
  9244. */
  9245. hasNext: function(){
  9246. },
  9247. /**
  9248. * Returns the next element in the iteration. Calling this method
  9249. * repeatedly until the hasNext() method returns false will return
  9250. * each element in the underlying collection exactly once.
  9251. * The cursor position is increased by one. if no element is available
  9252. * at the specified position, <code>null</code> is returned and the
  9253. * position is not changed
  9254. *
  9255. * @returns {Object} the next element in the iteration
  9256. */
  9257. next: function(){
  9258. },
  9259. /**
  9260. * Returns the number of elements in this iterator.
  9261. *
  9262. * @return {com.ibm.mashups.enabler.Deferred} a deferred object used to start this operation. The
  9263. * return value when executed through the deferred object
  9264. * is the number of elements in this iterator
  9265. */
  9266. size: function(){
  9267. },
  9268. /**
  9269. * Sets the zero-based position of the cursor, i.e the last
  9270. * element is addressed through size()-1.
  9271. * A position which is out of the bounds of the current iteration
  9272. * is ignored and in this case the position is set to the nearest
  9273. * possible value within valid bounds.
  9274. *
  9275. * @param {int} position position of the cursor. Defaults to zero
  9276. * @type void
  9277. */
  9278. setCursorPosition: function(position){
  9279. },
  9280. /**
  9281. * Returns the zero-based position of the cursor, i.e. zero for the first element
  9282. *
  9283. * @return {int} the position of the cursor
  9284. */
  9285. getCursorPosition: function(){
  9286. }
  9287. });
  9288. }
  9289. if(!dojo._hasResource["com.ibm.mashups.enabler.DeferredIterator_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  9290. dojo._hasResource["com.ibm.mashups.enabler.DeferredIterator_API"] = true;
  9291. dojo.provide("com.ibm.mashups.enabler.DeferredIterator_API");
  9292. dojo.provide("com.ibm.mashups.enabler.DeferredIterator");
  9293. /**
  9294. * The DeferredIterator can be used to iterate over a list of objects
  9295. * in an asynchronous fashion. The callback handler is called as
  9296. * soon as the next object has been loaded.
  9297. * The start method is only used for the asynchronous aspect of
  9298. * the deferred iterator. For the synchronous aspect the methods
  9299. * such as hasNext() can be called directly.
  9300. * @ibm-api
  9301. * @ibm-module Base
  9302. */
  9303. dojo.declare("com.ibm.mashups.enabler.DeferredIterator", [com.ibm.mashups.enabler.Deferred, com.ibm.mashups.enabler.Iterator], {
  9304. /**
  9305. * Sets the handler of the deferred action. It is called when the
  9306. * next object in the list has been loaded and is ready to be processed.
  9307. * @param {Object} callback the callback funtion in the format of <code>Function(object nextElement, Object[] params)</code>. Must not be <code>null</code><br>
  9308. * &nbsp;&nbsp;&nbsp;&nbsp;<b>Callbackparameters</b><br/>
  9309. * &nbsp;&nbsp;&nbsp;&nbsp;<code>nextElement</code> - the next
  9310. * object in the list<br/>
  9311. * &nbsp;&nbsp;&nbsp;&nbsp;<code>params</code> - the parameters
  9312. * passed into the addForEachCallback
  9313. * @param {Object[]} parameters optional array of parameters to be
  9314. * passed on to the callback function
  9315. * @return {com.ibm.mashups.enabler.DeferredIterator} the deferred object
  9316. */
  9317. setForEachCallback: function(callback, parameters){
  9318. }
  9319. });
  9320. }
  9321. if(!dojo._hasResource["com.ibm.mm.enabler.DeferredIteratorImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  9322. dojo._hasResource["com.ibm.mm.enabler.DeferredIteratorImpl"] = true;
  9323. dojo.provide("com.ibm.mm.enabler.DeferredIteratorImpl");
  9324. // iterator
  9325. dojo.declare("com.ibm.mm.enabler.DeferredIteratorImpl", [com.ibm.mashups.enabler.DeferredIterator, com.ibm.mm.enabler.DeferredImpl], {
  9326. setForEachCallback: function(callback, parameters){
  9327. this.foreachCallback = callback;
  9328. this.foreachCallbackParameters = parameters;
  9329. return this;
  9330. },
  9331. /**
  9332. * there's a typo in this one, keeping it around for backwards compat
  9333. *
  9334. * @param {Object} callback
  9335. * @param {Object} parameters
  9336. */
  9337. setForeachCallback: function(callback, parameters){
  9338. return this.setForEachCallback(callback, parameters);
  9339. },
  9340. getForeachCallback: function(){
  9341. return this.foreachCallback;
  9342. },
  9343. getForeachCallbackParameters: function(){
  9344. return this.foreachCallbackParameters;
  9345. },
  9346. nextFinish: function(entry) {
  9347. if(dojo.isFunction(this.getForeachCallback())) {
  9348. // call callback
  9349. dojo.partial(this.getForeachCallback())(entry, this.getForeachCallbackParameters());
  9350. }
  9351. },
  9352. start: function(sync){
  9353. while (this.hasNext(this, sync)) {
  9354. this.next(this, sync);
  9355. }
  9356. }
  9357. });
  9358. }
  9359. if(!dojo._hasResource["com.ibm.mashups.enabler.DeferredIterator"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  9360. dojo._hasResource["com.ibm.mashups.enabler.DeferredIterator"] = true;
  9361. dojo.provide("com.ibm.mashups.enabler.DeferredIterator");
  9362. }
  9363. if(!dojo._hasResource["com.ibm.mashups.enabler.DeferredOperation_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  9364. dojo._hasResource["com.ibm.mashups.enabler.DeferredOperation_API"] = true;
  9365. dojo.provide("com.ibm.mashups.enabler.DeferredOperation_API");
  9366. dojo.provide("com.ibm.mashups.enabler.DeferredOperation");
  9367. /**
  9368. * In addition to the Deferred interface, which allows to trigger callbacks after the
  9369. * entire action has finished, the DeferredOperation interface allows to trigger a
  9370. * callback for each involved operation.
  9371. * @ibm-api
  9372. * @ibm-module Base
  9373. */
  9374. dojo.declare( "com.ibm.mashups.enabler.DeferredOperation", [com.ibm.mashups.enabler.Deferred], {
  9375. /**
  9376. * Mode of operation: retrieving a resource
  9377. * @type String
  9378. */
  9379. OPERATION_GET: "GET",
  9380. /**
  9381. * Mode of operation: creating a resource
  9382. * @type String
  9383. */
  9384. OPERATION_CREATE: "CREATE",
  9385. /**
  9386. * Mode of operation: modifying a resource
  9387. * @type String
  9388. */
  9389. OPERATION_MODIFY: "MODIFY",
  9390. /**
  9391. * Mode of operation: deleting a resource
  9392. * @type String
  9393. */
  9394. OPERATION_DELETE: "DELETE",
  9395. /**
  9396. * Sets the handler of the deferred action. The handler is called for each
  9397. * operation the action involves.
  9398. * @param {Object} callback the callback funtion in the format of <code>Function(Object node, string mode, int statusCode, Object[] params)</code>. Must not be <code>null</code><br/>
  9399. * &nbsp;&nbsp;&nbsp;&nbsp;<b>Callbackparameters</b><br/>
  9400. * &nbsp;&nbsp;&nbsp;&nbsp;<code>node</code> - resource object or string id of the
  9401. * related resource, depending on the operation. For example, when a resource is created, the
  9402. * resource itself is returned. In case of a delete operation, the id is returned
  9403. * instead.<br/>
  9404. * &nbsp;&nbsp;&nbsp;&nbsp;<code>mode</code> - the mode of the operation.
  9405. * May be one of <code>OPERATION_GET</code>, <code>OPERATION_CREATE</code>,
  9406. * <code>OPERATION_MODIFY</code>, or <code>OPERATION_DELETE</code>.<br/>
  9407. * &nbsp;&nbsp;&nbsp;&nbsp;<code>statusCode</code> - the overall HTTP status code
  9408. * of the operation.<br/>
  9409. * &nbsp;&nbsp;&nbsp;&nbsp;<code>params</code> - the parameters
  9410. * passed into the callback
  9411. * @param {Object[]} parameters optional array of parameters to be
  9412. * passed on to the callback function. May be <code>null</code>
  9413. * @return {com.ibm.mashups.enabler.DeferredOperation} the deferred object
  9414. */
  9415. setOperationCallback: function(callback, parameters) {
  9416. }
  9417. });
  9418. com.ibm.mashups.enabler.DeferredOperation.OPERATION_GET = "GET";
  9419. com.ibm.mashups.enabler.DeferredOperation.OPERATION_CREATE = "CREATE";
  9420. com.ibm.mashups.enabler.DeferredOperation.OPERATION_MODIFY = "MODIFY";
  9421. com.ibm.mashups.enabler.DeferredOperation.OPERATION_DELETE = "DELETE";
  9422. }
  9423. if(!dojo._hasResource["com.ibm.mm.enabler.model.HttpStatusCodes"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  9424. dojo._hasResource["com.ibm.mm.enabler.model.HttpStatusCodes"] = true;
  9425. dojo.provide("com.ibm.mm.enabler.model.HttpStatusCodes");
  9426. dojo.provide("com.ibm.mm.enabler.model.HttpStatusCodesImpl");
  9427. dojo.declare("com.ibm.mm.enabler.model.HttpStatusCodesImpl", null, {
  9428. HTTP_CONTINUE: "100",
  9429. HTTP_SWITCHING_PROTOCOLS: "101",
  9430. HTTP_OK: "200",
  9431. HTTP_CREATED: "201",
  9432. HTTP_BAD_REQUEST: "400",
  9433. HTTP_NOT_FOUND: "404",
  9434. HTTP_REQUEST_TIMEOUT: "408",
  9435. HTTP_INTERNAL_SERVER_ERROR: "500",
  9436. HTTP_SERVICE_UNAVAILABLE: "503"
  9437. });
  9438. com.ibm.mm.enabler.model.HttpStatusCodes = new com.ibm.mm.enabler.model.HttpStatusCodesImpl();
  9439. }
  9440. if(!dojo._hasResource["com.ibm.mm.enabler.DeferredOperationImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  9441. dojo._hasResource["com.ibm.mm.enabler.DeferredOperationImpl"] = true;
  9442. dojo.provide("com.ibm.mm.enabler.DeferredOperationImpl");
  9443. // operation
  9444. dojo.declare("com.ibm.mm.enabler.DeferredOperationImpl", [com.ibm.mashups.enabler.DeferredOperation, com.ibm.mm.enabler.DeferredImpl], {
  9445. operationCallback: null,
  9446. operationCallbackParameters: null,
  9447. setOperationCallback: function(callback, parameters){
  9448. this.operationCallback = callback;
  9449. this.operationCallbackParameters = parameters;
  9450. return this;
  9451. },
  9452. getOperationCallback: function(){
  9453. return this.operationCallback;
  9454. },
  9455. getOperationCallbackParameters: function(){
  9456. return this.operationCallbackParameters;
  9457. },
  9458. finishOperation: function(result, operation, status) {
  9459. if(dojo.isFunction(this.getOperationCallback())) {
  9460. // call callback
  9461. if(dojo.isOpera && status === 0) {
  9462. status = com.ibm.mm.enabler.model.HttpStatusCodes.HTTP_NOT_FOUND;
  9463. }
  9464. dojo.partial(this.getOperationCallback())(result, operation, status, this.getOperationCallbackParameters());
  9465. }
  9466. }
  9467. });
  9468. }
  9469. if(!dojo._hasResource["com.ibm.mashups.enabler.DeferredOperation"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  9470. dojo._hasResource["com.ibm.mashups.enabler.DeferredOperation"] = true;
  9471. dojo.provide("com.ibm.mashups.enabler.DeferredOperation");
  9472. }
  9473. if(!dojo._hasResource["com.ibm.mashups.enabler.DirtyFlagProvider_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  9474. dojo._hasResource["com.ibm.mashups.enabler.DirtyFlagProvider_API"] = true;
  9475. dojo.provide("com.ibm.mashups.enabler.DirtyFlagProvider_API");
  9476. dojo.provide("com.ibm.mashups.enabler.DirtyFlagProvider");
  9477. /**
  9478. * Base interface that allows to track whether a node or model has been modified (i.e. became dirty).
  9479. *
  9480. * @since 3.0.0.1
  9481. * @ibm-spi
  9482. * @ibm-module Base
  9483. */
  9484. dojo.declare("com.ibm.mashups.enabler.DirtyFlagProvider", null, {
  9485. /**
  9486. * Tests whether the instance is dirty. Instances that have been modified, or newly created return true.
  9487. *
  9488. * @return {Boolean} true if the instance is dirty, otherwise false.
  9489. */
  9490. isDirty: function() {},
  9491. /**
  9492. * Marks this instance as dirty.
  9493. */
  9494. setDirty: function() {},
  9495. /**
  9496. * Marks this instance as not dirty, i.e. clean.
  9497. */
  9498. setClean: function() {},
  9499. /**
  9500. * Adds a callback handler to be called when the instance changes its state.
  9501. *
  9502. * @param {Object} ctx The context in which to run the callback handler
  9503. * Must not be <code>null</code>
  9504. * @param {Object} callback the callback funtion in the format of <code>Function(Object[] passed in with addDirtyCallback)</code>.
  9505. * Must not be <code>null</code>
  9506. * @param {Object[]} parameters optional array of parameters to be
  9507. * passed on to the callback function. May be <code>null</code>
  9508. * @param {Boolean} alwaysFire Specifies whether to only fire when clean->dirty (set flag to false) or also fire when dirty->dirty (set flag to true)
  9509. */
  9510. addDirtyCallback: function(ctx, callback, parameters, alwaysFire) {
  9511. },
  9512. /**
  9513. * Removes a callback handler previously added
  9514. *
  9515. * @param {Object} callback the callback funtion to be removed.
  9516. * Must not be <code>null</code>
  9517. */
  9518. removeDirtyCallback: function(fn){
  9519. }
  9520. });
  9521. }
  9522. if(!dojo._hasResource["com.ibm.mm.enabler.DirtyFlagProviderImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  9523. dojo._hasResource["com.ibm.mm.enabler.DirtyFlagProviderImpl"] = true;
  9524. dojo.provide("com.ibm.mm.enabler.DirtyFlagProviderImpl");
  9525. dojo.declare("com.ibm.mm.enabler.DirtyFlagProviderImpl", com.ibm.mashups.enabler.DirtyFlagProvider, {
  9526. _dirty: false,
  9527. setDirty: function() {
  9528. this._setDirty();
  9529. },
  9530. _setDirty: function() {
  9531. var wasFalse = this._dirty === false;
  9532. this._dirty = true;
  9533. if (this._dirtyCallbacks) {
  9534. dojo.forEach(this._dirtyCallbacks, function(cb) {
  9535. if ((wasFalse || cb.alwaysFire) && dojo.isFunction(cb.fn)) {
  9536. dojo.hitch(cb.ctx || null, cb.fn)(cb.args);
  9537. }
  9538. }, this);
  9539. }
  9540. },
  9541. setClean: function() {
  9542. this._setClean();
  9543. },
  9544. _setClean: function() {
  9545. this._dirty = false;
  9546. },
  9547. isDirty: function() {
  9548. return this._dirty;
  9549. },
  9550. _isDirty: function() {
  9551. return this._dirty;
  9552. },
  9553. addDirtyCallback: function(ctx, fn, args, alwaysFire) {
  9554. this._addDirtyCallback(ctx, fn, args, alwaysFire);
  9555. },
  9556. /**
  9557. * ctx = context
  9558. * fn = function to call
  9559. * args = arguments to that function
  9560. * alwaysFire (boolean) = whether to only fire when clean->dirty (set flag to false) or also fire when dirty->dirty (set flag to true)
  9561. */
  9562. _addDirtyCallback: function(ctx, fn, args, alwaysFire) {
  9563. if (!this._dirtyCallbacks) {
  9564. this._dirtyCallbacks = [];
  9565. }
  9566. this._dirtyCallbacks.push({
  9567. ctx: ctx,
  9568. fn: fn,
  9569. args: args,
  9570. alwaysFire: !!alwaysFire
  9571. });
  9572. },
  9573. removeDirtyCallback: function(fn) {
  9574. this._removeDirtyCallback(fn);
  9575. },
  9576. _removeDirtyCallback: function(fn) {
  9577. if (this._dirtyCallbacks) {
  9578. for (var i = this._dirtyCallbacks.length; i > 0; i--) {
  9579. if (fn === this._dirtyCallbacks[i - 1].fn) {
  9580. this._dirtyCallbacks.splice(i - 1, 1);
  9581. break;
  9582. }
  9583. }
  9584. }
  9585. }
  9586. });
  9587. }
  9588. if(!dojo._hasResource["com.ibm.mashups.enabler.DirtyFlagProvider"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  9589. dojo._hasResource["com.ibm.mashups.enabler.DirtyFlagProvider"] = true;
  9590. dojo.provide("com.ibm.mashups.enabler.DirtyFlagProvider");
  9591. }
  9592. if(!dojo._hasResource["com.ibm.mashups.enabler.Discardable_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  9593. dojo._hasResource["com.ibm.mashups.enabler.Discardable_API"] = true;
  9594. dojo.provide("com.ibm.mashups.enabler.Discardable_API");
  9595. dojo.provide("com.ibm.mashups.enabler.Discardable");
  9596. /**
  9597. * Discardable interface, which allows to discard artifacts or the whole
  9598. * model.
  9599. *
  9600. * @since 2.4
  9601. *
  9602. * @ibm-api
  9603. * @ibm-module Base
  9604. */
  9605. dojo.declare("com.ibm.mashups.enabler.Discardable", null, {
  9606. /**
  9607. * Discards the specified node, or the whole model if no node is specified.
  9608. * @parameter {Object} node node to discard, must not be <code>null</code>; optional
  9609. * @type void
  9610. */
  9611. discard : function(node) {
  9612. }
  9613. });
  9614. }
  9615. if(!dojo._hasResource["com.ibm.mashups.enabler.Discardable"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  9616. dojo._hasResource["com.ibm.mashups.enabler.Discardable"] = true;
  9617. dojo.provide("com.ibm.mashups.enabler.Discardable");
  9618. }
  9619. if(!dojo._hasResource["com.ibm.mashups.enabler.Identifiable"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  9620. dojo._hasResource["com.ibm.mashups.enabler.Identifiable"] = true;
  9621. dojo.provide("com.ibm.mashups.enabler.Identifiable");
  9622. /**
  9623. * Interface for any resource in the system that can be identified
  9624. * @ibm-api
  9625. * @ibm-module Base
  9626. */
  9627. dojo.declare("com.ibm.mashups.enabler.Identifiable", null, {
  9628. /**
  9629. * Returns the ID of the resource that implements the <code>Identifiable</code> interface.
  9630. * @return {String} the identifier; never <code>null</code>
  9631. */
  9632. getID: function(){
  9633. },
  9634. /**
  9635. * Returns the unique name of the resource that implements the <code>Identifiable</code> interface.
  9636. * @return {String} the unique name; never <code>null</code>
  9637. * @private
  9638. */
  9639. getUniqueName: function(){
  9640. }
  9641. });
  9642. }
  9643. if(!dojo._hasResource["com.ibm.mashups.enabler.Invalidatable_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  9644. dojo._hasResource["com.ibm.mashups.enabler.Invalidatable_API"] = true;
  9645. dojo.provide("com.ibm.mashups.enabler.Invalidatable_API");
  9646. dojo.provide("com.ibm.mashups.enabler.Invalidatable");
  9647. /**
  9648. * Invalidatable interface, which allows to invalidate artifacts or the whole
  9649. * model.
  9650. *
  9651. * @since 2.4
  9652. *
  9653. * @ibm-api
  9654. * @ibm-module Base
  9655. */
  9656. dojo.declare("com.ibm.mashups.enabler.Invalidatable", null, {
  9657. /**
  9658. * Invalidates the specified node, or the whole model if no node is specified.
  9659. *
  9660. * @param {Object} node node to invalidate, must not be <code>null</code>; optional
  9661. * @type void
  9662. */
  9663. invalidate : function(node) {
  9664. }
  9665. });
  9666. }
  9667. if(!dojo._hasResource["com.ibm.mashups.enabler.Invalidatable"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  9668. dojo._hasResource["com.ibm.mashups.enabler.Invalidatable"] = true;
  9669. dojo.provide("com.ibm.mashups.enabler.Invalidatable");
  9670. }
  9671. if(!dojo._hasResource["com.ibm.mashups.enabler.Locator"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  9672. dojo._hasResource["com.ibm.mashups.enabler.Locator"] = true;
  9673. dojo.provide( "com.ibm.mashups.enabler.Locator");
  9674. /**
  9675. * This interface defines search methods that allow locating resources in a model.
  9676. * A resource is identified by its ID (mandatory). This interface is the base for all locators;
  9677. * other locators allow a more specific search in the context they are offered in,
  9678. * e.g. a search for a node with certain properties in a model.<br>
  9679. * A <code>Locator</code> is usually obtained using the <code>getLocator()</code> method .
  9680. * <pre>
  9681. * var treeModel model = ...;
  9682. * var locator = model.getLocator();
  9683. * var node = locator.find(...);
  9684. * </pre>
  9685. * This locator returns an {@code Object} which is part of some model.
  9686. * What exact kind of object is returned depends on the locator.
  9687. * Please refer to individual JavaScriptDoc for the locator used.
  9688. * The result object can be expected to be an element of the model
  9689. * the locator is used on unless specified otherwise.
  9690. * @ibm-api
  9691. * @ibm-module Base
  9692. */
  9693. dojo.declare( "com.ibm.mashups.enabler.Locator", null, {
  9694. /**
  9695. * Returns an element of a model with the given ID.
  9696. * @param {com.ibm.mashups.enabler.Identifiable} id identifiable or string id of the object to find;
  9697. * must not be <code>null</code>.
  9698. * @return {com.ibm.mashups.enabler.Deferred} a deferred object used to start this operation.
  9699. * The return value when executed through the deferred object is
  9700. * the element with the given ID or <code>null</code> if the element cannot be found.
  9701. */
  9702. find: function (id) {
  9703. }
  9704. });
  9705. }
  9706. if(!dojo._hasResource["com.ibm.mashups.enabler.ListModel"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  9707. dojo._hasResource["com.ibm.mashups.enabler.ListModel"] = true;
  9708. dojo.provide("com.ibm.mashups.enabler.ListModel");
  9709. /**
  9710. * A read-only model representing a list. Acting as a base class for all concrete list models.
  9711. * @ibm-api
  9712. * @ibm-module Base
  9713. */
  9714. dojo.declare("com.ibm.mashups.enabler.ListModel", [com.ibm.mashups.enabler.model.Model, com.ibm.mashups.enabler.Locator], {
  9715. /**
  9716. * Returns an iterator over elements of the list.
  9717. *
  9718. * @return {com.ibm.mashups.enabler.DeferredIterator} a deferred iterator
  9719. */
  9720. iterator: function(){
  9721. }
  9722. });
  9723. }
  9724. if(!dojo._hasResource["com.ibm.mashups.enabler.ListModelController"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  9725. dojo._hasResource["com.ibm.mashups.enabler.ListModelController"] = true;
  9726. dojo.provide("com.ibm.mashups.enabler.ListModelController");
  9727. /**
  9728. * A modifiable model representing a list. Acting as a base class for all concrete list models.
  9729. * @ibm-api
  9730. * @ibm-module Base
  9731. */
  9732. dojo.declare("com.ibm.mashups.enabler.ListModelController", com.ibm.mashups.enabler.ListModel, {
  9733. /**
  9734. * Creates a new model object. The created node can be inserted
  9735. * into the model using an appropriate <code>insert</code> method defined
  9736. * on a subinterface of this interface. The node will not appear in the model
  9737. * unless it is inserted.
  9738. * @param {JSON} context array of predefined information
  9739. * used for the creation of the node. May be <code>null</code>. Accepted
  9740. * names are defined in the appropriate subinterfaces
  9741. * @type Object
  9742. * @return the created node
  9743. */
  9744. create: function(context){
  9745. },
  9746. /**
  9747. * Confirms whether creating the node is possible.
  9748. * @param {JSON} context array of predefined information
  9749. * used for the creation of the node. May be <code>null</code>. Accepted
  9750. * names are defined in the appropriate subinterfaces
  9751. * @return {Boolean} true if the node can be created, otherwise false.
  9752. */
  9753. confirmCreate: function(context){
  9754. },
  9755. /**
  9756. * Inserts the specified node into the list model at the specified
  9757. * position; the node must be created with the create method of the
  9758. * concrete ListModel
  9759. *
  9760. * @param {Object} node node or node uri (without any scope) to
  9761. * insert into the list model. Must not be
  9762. * <code>null</code>
  9763. * @param {Object} nextNode node object or node uri (without any scope) of
  9764. * the successor node before which the node
  9765. * is to be inserted;
  9766. * if <code>null</code> is specified, the
  9767. * node is appended at the end of the existing nodes
  9768. * @type void
  9769. */
  9770. insert: function(node, nextNode){
  9771. },
  9772. /**
  9773. * Confirms whether inserting the node is possible.
  9774. * @param {Object} node node or node uri (without any scope) to
  9775. * insert into the list model. Must not be
  9776. * <code>null</code>
  9777. * @param {Object} nextNode node object or node uri (without any scope) of
  9778. * the successor node before which the node
  9779. * is to be inserted;
  9780. * if <code>null</code> is specified, the
  9781. * node is appended at the end of the existing nodes
  9782. * @return {Boolean} true if the node can be inserted, otherwise false.
  9783. */
  9784. confirmInsert: function(node, nextNode){
  9785. },
  9786. /**
  9787. * Removes the specified node from the list model
  9788. *
  9789. * @param{Object} node node object or node uri (without any scope).
  9790. * Must not be <code>null</code>
  9791. * @type void
  9792. */
  9793. remove: function(node){
  9794. },
  9795. /**
  9796. * Confirms whether removing the node is possible.
  9797. * @param{Object} node node object or node uri (without any scope).
  9798. * Must not be <code>null</code>
  9799. * @return {Boolean} true if the node can be removed, otherwise false.
  9800. */
  9801. confirmRemove: function(node){
  9802. }
  9803. });
  9804. }
  9805. if(!dojo._hasResource["com.ibm.mashups.enabler.Localized_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  9806. dojo._hasResource["com.ibm.mashups.enabler.Localized_API"] = true;
  9807. dojo.provide("com.ibm.mashups.enabler.Localized_API");
  9808. dojo.provide("com.ibm.mashups.enabler.Localized");
  9809. /**
  9810. * Read-Only interface providing methods to obtain title and description of a
  9811. * resource. Please note that title or description are only returned if they
  9812. * are available in the requested locale. No fallback for locales is performed.
  9813. * @ibm-api
  9814. * @ibm-module Base
  9815. */
  9816. dojo.declare("com.ibm.mashups.enabler.Localized", null, {
  9817. /**
  9818. * Returns an array containing the locales that are supported by this
  9819. * object. The presence of a locale in this list does not mean that a title
  9820. * <b>and</b> description is available, but rather that either one or both
  9821. * are available in that locale.<br>
  9822. * <br>
  9823. * <b>Note:</b> Modifying the array does not change the supported locales.
  9824. * @return {String[]} a list of locales defined for this object, returns an
  9825. * empty array if no locales are supported. Can never be <code>null</code>.
  9826. */
  9827. getLocales: function(){
  9828. },
  9829. /**
  9830. * Returns the title of this object in the given locale.
  9831. * @param {String} locale the locale for which to retrieve the title,
  9832. * must not be <code>null</code>.
  9833. * @return {String} the title of this node in the given locale. If a title is not
  9834. * available in the given locale, this method will return <code>null</code>.
  9835. * It is up to the invoker of the method to implement an appropriate fallback mechanism.
  9836. */
  9837. getTitle: function(locale){
  9838. },
  9839. /**
  9840. * Returns the titles of this object in a map (key: locale, value: title).
  9841. *
  9842. * @param {String} locale (optional) the locale for which to retrieve the titles, can be <code>null</code>. If locale is null/omitted, all are returned.
  9843. * @return {Object} the titles of this node in a locale<->title map. If a locale was given, the result will be a map containing only those locales with country specific matches (e.g. if you give a locale "pt", you might also get brazilian portugese ("pt-BR") - if you give a locale "zh-TW", you won't get "zh"). If there are no titles (matching the given locale), an empty object will be returned.
  9844. *
  9845. * @since 3.0
  9846. */
  9847. getTitles: function(){
  9848. },
  9849. /**
  9850. * Returns the description of this object in the given locale.
  9851. * @param {String} locale the locale for which to retrieve the
  9852. * description, must not be <code>null</code>.
  9853. * @return {String} the description of this node in the given locale. If a
  9854. * description is not available in the given locale, this method
  9855. * will return <code>null</code>. It is up to the invoker of the
  9856. * method to implement an appropriate fallback mechanism.
  9857. */
  9858. getDescription: function(locale){
  9859. },
  9860. /**
  9861. * Returns the descriptions of this object in a map (key: locale, value: description).
  9862. *
  9863. * @param {String} locale (optional) the locale for which to retrieve the descriptions, can be <code>null</code>. If locale is null/omitted, all are returned.
  9864. * @return {Object} the descriptions of this node in a locale<->description map. If a locale was given, the result will be a map containing only those locales with country specific matches (e.g. if you give a locale "pt", you might also get brazilian portugese ("pt-BR") - if you give a locale "zh-TW", you won't get "zh"). If there are no descriptions (matching the given locale), an empty object will be returned.
  9865. *
  9866. * @since 3.0
  9867. */
  9868. getDescriptions: function(locale){
  9869. }
  9870. });
  9871. }
  9872. if(!dojo._hasResource["com.ibm.mashups.enabler.ModifiableLocalized"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  9873. dojo._hasResource["com.ibm.mashups.enabler.ModifiableLocalized"] = true;
  9874. dojo.provide("com.ibm.mashups.enabler.ModifiableLocalized");
  9875. /**
  9876. * Modifiable interface providing methods to set title and description of a
  9877. * resource.
  9878. * @ibm-api
  9879. * @ibm-module Base
  9880. */
  9881. dojo.declare("com.ibm.mashups.enabler.ModifiableLocalized", com.ibm.mashups.enabler.Localized, {
  9882. /**
  9883. * Sets the title for the given locale.
  9884. * @param {String} title title to set; must not be <code>null</code>
  9885. * @param {String} locale locale to set the title for; must not be <code>null</code>
  9886. * @return {String} the former title; if none existed, <code>null</code> is returned
  9887. */
  9888. setTitle: function(title, locale){
  9889. },
  9890. /**
  9891. * Confirms whether setting the title for the given locale is possible.
  9892. * @param {String} title title to set; must not be <code>null</code>
  9893. * @param {String} locale locale to set the title for; must not be <code>null</code>
  9894. * @return {Boolean} true if the value can be set, otherwise false.
  9895. */
  9896. confirmSetTitle: function(title, locale){
  9897. },
  9898. /**
  9899. * Removes the title for the given locale.
  9900. * @param {String} locale locale of the title to remove; must not be <code>null</code>
  9901. * @type void
  9902. */
  9903. removeTitle: function(locale){
  9904. },
  9905. /**
  9906. * Indicates if the title for the specified locale may be removed.
  9907. * @param {String} locale locale for which to indicate if the title may be removed; must not be <code>null</code>
  9908. * @return {Boolean} <code>true</code> if the title can be removed, otherwise <code>false</code>.
  9909. */
  9910. confirmRemoveTitle: function(locale){
  9911. },
  9912. /**
  9913. * Removes all titles.
  9914. * @type void
  9915. */
  9916. removeTitles: function(){
  9917. },
  9918. /**
  9919. * Indicates if the titles for all locales may be removed.
  9920. * @return {Boolean} <code>true</code> if all titles can be removed, otherwise
  9921. * <code>false</code>.
  9922. */
  9923. confirmRemoveTitles: function(){
  9924. },
  9925. /**
  9926. * Sets the description for the given locale.
  9927. * @param {String} desc description to set; must not be <code>null</code>
  9928. * @param {String} locale locale to set the description for; must not be <code>null</code>
  9929. * @return {String} the former description; if none existed, <code>null</code> is returned
  9930. */
  9931. setDescription: function(desc, locale){
  9932. },
  9933. /**
  9934. * Confirms whether setting the description for the given locale is possible.
  9935. * @param {String} desc description to set; must not be <code>null</code>
  9936. * @param {String} locale locale to set the description for; must not be <code>null</code>
  9937. * @return {Boolean} true if the value can be set, otherwise false.
  9938. */
  9939. confirmSetDescription: function(desc, locale){
  9940. },
  9941. /**
  9942. * Removes the description for the given locale.
  9943. * @param {String} locale locale of the description to remove; must not be <code>null</code>
  9944. * @type void
  9945. */
  9946. removeDescription: function(locale){
  9947. },
  9948. /**
  9949. * Indicates if the description for the specified locale may be removed.
  9950. * @param {String} locale locale for which to indicate if the description may be removed; must not be <code>null</code>
  9951. * @return {Boolean} <code>true</code> if the description can be removed, otherwise <code>false</code>.
  9952. */
  9953. confirmRemoveDescription: function(locale){
  9954. },
  9955. /**
  9956. * Removes all description.
  9957. * @type void
  9958. */
  9959. removeDescriptions: function(){
  9960. },
  9961. /**
  9962. * Indicates if the description for all locales may be removed.
  9963. * @return {Boolean} <code>true</code> if all descriptions can be removed, otherwise
  9964. * <code>false</code>.
  9965. */
  9966. confirmRemoveDescriptions: function(){
  9967. }
  9968. });
  9969. }
  9970. if(!dojo._hasResource["com.ibm.mashups.enabler.Localized"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  9971. dojo._hasResource["com.ibm.mashups.enabler.Localized"] = true;
  9972. dojo.provide("com.ibm.mashups.enabler.Localized");
  9973. }
  9974. if(!dojo._hasResource["com.ibm.mashups.enabler.Representation_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  9975. dojo._hasResource["com.ibm.mashups.enabler.Representation_API"] = true;
  9976. dojo.provide("com.ibm.mashups.enabler.Representation_API");
  9977. dojo.provide("com.ibm.mashups.enabler.Representation");
  9978. /**
  9979. * An interface that allows retrieving a URL and mime type representing the resource.
  9980. * @ibm-api
  9981. * @ibm-module Base
  9982. */
  9983. dojo.declare("com.ibm.mashups.enabler.Representation", com.ibm.mashups.enabler.Identifiable, {
  9984. /**
  9985. * Returns the mimetype of the representation.
  9986. * @return {String} the identifier; never <code>null</code>
  9987. */
  9988. getID: function(){
  9989. },
  9990. /**
  9991. * Returns a full or absolute URL pointing to the resource in another representation.
  9992. * @return {String} the URL pointing to the other representation; never <code>null</code>
  9993. */
  9994. getURL: function(){
  9995. },
  9996. /**
  9997. * Returns the mimetype of the content to which the URL is pointing to.
  9998. * @return {String} the mimetype; never <code>null</code>
  9999. */
  10000. getMimeType: function(){
  10001. }
  10002. });
  10003. }
  10004. if(!dojo._hasResource["com.ibm.mm.enabler.RepresentationImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  10005. dojo._hasResource["com.ibm.mm.enabler.RepresentationImpl"] = true;
  10006. dojo.provide( "com.ibm.mm.enabler.RepresentationImpl");
  10007. // representation
  10008. dojo.declare( "com.ibm.mm.enabler.RepresentationImpl", com.ibm.mashups.enabler.Representation,
  10009. {
  10010. constructor:function (url, type) {
  10011. this.url = url;
  10012. this.type = type;
  10013. },
  10014. getID: function() {
  10015. return this.type;
  10016. },
  10017. getURL: function() {
  10018. return this.url;
  10019. },
  10020. getMimeType: function() {
  10021. return this.type;
  10022. }
  10023. }
  10024. );
  10025. }
  10026. if(!dojo._hasResource["com.ibm.mashups.enabler.Representation"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  10027. dojo._hasResource["com.ibm.mashups.enabler.Representation"] = true;
  10028. dojo.provide("com.ibm.mashups.enabler.Representation");
  10029. }
  10030. if(!dojo._hasResource["com.ibm.mashups.enabler.RepresentationProvider_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  10031. dojo._hasResource["com.ibm.mashups.enabler.RepresentationProvider_API"] = true;
  10032. dojo.provide("com.ibm.mashups.enabler.RepresentationProvider_API");
  10033. dojo.provide("com.ibm.mashups.enabler.RepresentationProvider");
  10034. /**
  10035. * An interface that allows to retrieve information about different representations of the resource.
  10036. * @ibm-api
  10037. * @ibm-module Base
  10038. */
  10039. dojo.declare("com.ibm.mashups.enabler.RepresentationProvider", null, {
  10040. /**
  10041. * Returns a ListModel containing information about the alternate representations available. The model contains <code>Representation</code> objects .
  10042. * @see com.ibm.mashups.enabler.Representation
  10043. * @return {com.ibm.mashups.enabler.ListModel} ListModel containing alternate representations of the resource; never <code>null</code>
  10044. */
  10045. getAlternateModel: function(){
  10046. }
  10047. });
  10048. }
  10049. if(!dojo._hasResource["com.ibm.mm.enabler.RepresentationModelImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  10050. dojo._hasResource["com.ibm.mm.enabler.RepresentationModelImpl"] = true;
  10051. dojo.provide("com.ibm.mm.enabler.RepresentationModelImpl");
  10052. // alternate representation list model
  10053. dojo.declare("com.ibm.mm.enabler.RepresentationModelImpl", [com.ibm.mashups.enabler.ListModel, com.ibm.mm.enabler.DeferredIteratorImpl], {
  10054. constructor: function(nodes) {
  10055. this.loadedNodes = {};
  10056. this.entries = [];
  10057. this.cursor = 0;
  10058. this.size = null;
  10059. this.start = null;
  10060. this.num = null;
  10061. this.strategy = null;
  10062. // now fill in loadedNodes and entries
  10063. if (nodes && nodes.length > 0) {
  10064. this.size = nodes.length;
  10065. for (var i = 0; i < nodes.length; i++) {
  10066. var link = nodes[i];
  10067. var url = link.getAttribute("href");
  10068. var mimetype = link.getAttribute("type");
  10069. // create a new representation node
  10070. var uri = mimetype;
  10071. var node = new com.ibm.mm.enabler.RepresentationImpl(url, mimetype);
  10072. // setup the internal objects
  10073. this.entries[i] = uri;
  10074. this.loadedNodes[uri] = node;
  10075. }
  10076. }
  10077. },
  10078. find: function(uri) {
  10079. return new com.ibm.mm.enabler.DeferredImpl(this, this._find, uri);
  10080. },
  10081. _find: function(deferred, sync, uri) {
  10082. return this._load(uri, deferred, sync);
  10083. },
  10084. start: function(sync) {
  10085. while (this._hasNext(this, sync)) {
  10086. if (this._next(this, sync)) {
  10087. continue;
  10088. }
  10089. else {
  10090. break;
  10091. }
  10092. }
  10093. },
  10094. hasNext: function() {
  10095. return this._hasNext(null, true);
  10096. },
  10097. _hasNext: function(deferred, sync) {
  10098. if (this.start === null || this.cursor < this.start || (this.cursor >= (this.start + this.num) && (this.size > this.cursor))) {
  10099. this._loadAhead(deferred, sync);
  10100. }
  10101. return (this.size > this.cursor);
  10102. },
  10103. next: function() {
  10104. return this._next(null, true);
  10105. },
  10106. _next: function(deferred, sync) {
  10107. return this._hasNext(deferred, sync) ? this.loadedNodes[this.entries[this.cursor++]] : null;
  10108. },
  10109. size: function() {
  10110. return this.size;
  10111. },
  10112. setCursorPosition: function(position) {
  10113. this.cursor = position;
  10114. },
  10115. getCursorPosition: function() {
  10116. return this.cursor;
  10117. },
  10118. setStrategy: function(strategy) {
  10119. if (com.ibm.mm.enabler.utils.Misc.isInstanceOf(strategy, Array)) {
  10120. // evaluate the first strategy only
  10121. this.strategy = strategy[0];
  10122. }
  10123. else {
  10124. // backwards compatibility
  10125. this.strategy = strategy;
  10126. }
  10127. },
  10128. _load: function(uri, deferred, sync) {
  10129. if (uri in this.loadedNodes) {
  10130. // fetch node from cache
  10131. if(deferred) { deferred.finish(this.loadedNodes[uri], com.ibm.mm.enabler.model.HttpStatusCodes.HTTP_OK); }
  10132. }
  10133. return this.loadedNodes[uri];
  10134. },
  10135. _loadAhead: function(deferred, sync) {
  10136. // noop
  10137. }
  10138. });
  10139. }
  10140. if(!dojo._hasResource["com.ibm.mm.enabler.RepresentationProviderImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  10141. dojo._hasResource["com.ibm.mm.enabler.RepresentationProviderImpl"] = true;
  10142. dojo.provide("com.ibm.mm.enabler.RepresentationProviderImpl");
  10143. // representation provider
  10144. dojo.declare("com.ibm.mm.enabler.RepresentationProviderImpl", com.ibm.mashups.enabler.RepresentationProvider, {
  10145. constructor: function() {
  10146. // service document and initialization
  10147. this.serviceJson = com.ibm.mm.enabler.model.ServiceDocumentModel.getCollectionData(com.ibm.mm.enabler.model.ServiceDocumentModel.SERVICE_NAVIGATION);
  10148. var nsf = com.ibm.mm.enabler.model.NameSpaceFactory;
  10149. this.r_ns = dojo.delegate(this.serviceJson.namespaces, nsf.getNameSpaces([nsf.NS_ATOM, nsf.NS_XML]));
  10150. this.XPATH = "atom:link";
  10151. },
  10152. getAlternateModel: function() {
  10153. var validLinks = [];
  10154. var md = com.ibm.mashups.enabler.xml.XPath.evaluateXPath(this.XPATH, this.xmlData, this.r_ns);
  10155. if (md && md.length > 0) {
  10156. for (var i = 0, l = md.length; i < l; i++) {
  10157. var link = md[i];
  10158. var rel = link.getAttribute("rel");
  10159. var extrel = com.ibm.mm.enabler.utils.Dom.getAttributeWithNS(link, "ext:rel", "rel", this.r_ns.ext);
  10160. if (extrel == "") {
  10161. extrel = null;
  10162. }
  10163. if (((!rel) || (rel == 'alternate')) && (!extrel)) {
  10164. validLinks[validLinks.length] = link;
  10165. }
  10166. }
  10167. }
  10168. var model = new com.ibm.mm.enabler.RepresentationModelImpl(validLinks);
  10169. return model;
  10170. }
  10171. });
  10172. }
  10173. if(!dojo._hasResource["com.ibm.mashups.enabler.RepresentationProvider"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  10174. dojo._hasResource["com.ibm.mashups.enabler.RepresentationProvider"] = true;
  10175. dojo.provide("com.ibm.mashups.enabler.RepresentationProvider");
  10176. }
  10177. if(!dojo._hasResource["com.ibm.mashups.enabler.ResourceLocator"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  10178. dojo._hasResource["com.ibm.mashups.enabler.ResourceLocator"] = true;
  10179. dojo.provide("com.ibm.mashups.enabler.ResourceLocator");
  10180. /**
  10181. * Interface for finding resources within a model.
  10182. * @ibm-api
  10183. * @ibm-module Base
  10184. */
  10185. dojo.declare("com.ibm.mashups.enabler.ResourceLocator", com.ibm.mashups.enabler.Locator, {
  10186. /**
  10187. * Returns the URL of the resource to be located, or <code>null</code> if the resource cannot be found.
  10188. * @param {Object} node A node of the model this locator is implemented on. Must not be <code>null</code>.
  10189. * @param {String} name The name of the resource to be located within the given model. The name can also contain a directory path relative to the model. Must not be <code>null</code>.
  10190. * @return {String} The URL that can be used to fetch the resource, or <code>null</code> if the resource cannot be found.
  10191. * @deprecated Use findResourceURL instead.
  10192. */
  10193. findResourceUrl: function(node, name){
  10194. },
  10195. /**
  10196. * Returns the URL of the resource to be located, or <code>null</code> if the resource cannot be found.
  10197. * @param {Object} node A node of the model this locator is implemented on. Must not be <code>null</code>.
  10198. * @param {String} name The name of the resource to be located within the given model. The name can also contain a directory path relative to the model. Must not be <code>null</code>.
  10199. * @return {String} The URL that can be used to fetch the resource, or <code>null</code> if the resource cannot be found.
  10200. */
  10201. findResourceURL: function(node, name){
  10202. }
  10203. });
  10204. }
  10205. if(!dojo._hasResource["com.ibm.mashups.enabler.SubmittableForm_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  10206. dojo._hasResource["com.ibm.mashups.enabler.SubmittableForm_API"] = true;
  10207. dojo.provide("com.ibm.mashups.enabler.SubmittableForm_API");
  10208. dojo.provide("com.ibm.mashups.enabler.SubmittableForm");
  10209. /**
  10210. * An interface representing a submittable form. Submittable forms can be used
  10211. * to import resources of models, which implement the SubmittableFormProvider
  10212. * interface, for example spaces or templates. The provider of submittable forms
  10213. * automatically set the necessary URL parameters, such as enctype, action and method.
  10214. * To submit a submittable form, you invoke the submit()-method, which in turn
  10215. * imports the resource using an appropriate xhr request.<br><br>
  10216. * Example:<br>
  10217. * <code>
  10218. * var form = spaceModel.getSubmittableImportForm(spaceId);<br>
  10219. * form.submit().start();<br>
  10220. * </code>
  10221. * @ibm-api
  10222. * @ibm-module Base
  10223. */
  10224. dojo.declare("com.ibm.mashups.enabler.SubmittableForm", com.ibm.mashups.enabler.Identifiable, {
  10225. /**
  10226. * Returns the URL this form is submitted to. Used to fill in the action attribute in the form.
  10227. * @return {String} the URL this form is submitted to; never <code>null</code>
  10228. */
  10229. getURL: function(){
  10230. },
  10231. /**
  10232. * Returns the HTTP method used to submit this form. Used to fill in the method attribute in the form.
  10233. * @return {String} the method; never <code>null</code>
  10234. */
  10235. getMethod: function(){
  10236. },
  10237. /**
  10238. * Submits the form
  10239. * @return {com.ibm.mashups.enabler.Deferred} a deferred object used to start this operation.
  10240. */
  10241. submit: function(){
  10242. }
  10243. });
  10244. }
  10245. if(!dojo._hasResource["com.ibm.mm.enabler.SubmittableFormImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  10246. dojo._hasResource["com.ibm.mm.enabler.SubmittableFormImpl"] = true;
  10247. dojo.provide("com.ibm.mm.enabler.SubmittableFormImpl");
  10248. dojo.declare("com.ibm.mm.enabler.SubmittableFormImpl", com.ibm.mashups.enabler.SubmittableForm, {
  10249. constructor: function(url, method, formId){
  10250. this.url = url;
  10251. this.method = method;
  10252. this.formId = formId;
  10253. },
  10254. /**
  10255. * Returns the URL this form is submitted to. Used to fill in the action attribute in the form.
  10256. * @return {String} the URL this form is submitted to; never <code>null</code>
  10257. */
  10258. getURL: function(){
  10259. return this.url;
  10260. },
  10261. /**
  10262. * Returns the HTTP method used to submit this form. Used to fill in the method attribute in the form.
  10263. * @return {String} the method; never <code>null</code>
  10264. */
  10265. getMethod: function(){
  10266. return this.method;
  10267. },
  10268. /**
  10269. * Submits the form
  10270. * @return {com.ibm.mashups.enabler.Deferred} a deferred object used to start this operation.
  10271. */
  10272. submit: function(){
  10273. return new com.ibm.mm.enabler.DeferredImpl(this, this._submit);
  10274. },
  10275. /**
  10276. * Submits the form
  10277. * @return {com.ibm.mashups.enabler.Deferred} a deferred object used to start this operation.
  10278. */
  10279. _submit: function(deferred){
  10280. dojo.io.iframe.send({
  10281. url: this.url,
  10282. method: this.method,
  10283. handleAs: "text",
  10284. // For IE issue
  10285. form: document.getElementsByName(this.formId)[0],
  10286. load: function(data, ioArgs){
  10287. if(deferred) { deferred.finish(data, com.ibm.mm.enabler.model.HttpStatusCodes.HTTP_CREATED); }
  10288. },
  10289. error: function(data, ioArgs){
  10290. if(deferred) { deferred.finish(data, com.ibm.mm.enabler.model.HttpStatusCodes.HTTP_NOT_FOUND); }
  10291. }
  10292. });
  10293. }
  10294. });
  10295. }
  10296. if(!dojo._hasResource["com.ibm.mashups.enabler.SubmittableForm"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  10297. dojo._hasResource["com.ibm.mashups.enabler.SubmittableForm"] = true;
  10298. dojo.provide("com.ibm.mashups.enabler.SubmittableForm");
  10299. }
  10300. if(!dojo._hasResource["com.ibm.mashups.enabler.SubmittableFormProvider_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  10301. dojo._hasResource["com.ibm.mashups.enabler.SubmittableFormProvider_API"] = true;
  10302. dojo.provide("com.ibm.mashups.enabler.SubmittableFormProvider_API");
  10303. dojo.provide("com.ibm.mashups.enabler.SubmittableFormProvider");
  10304. /**
  10305. * An interface that allows to retieve submittable form
  10306. * @ibm-api
  10307. * @ibm-module Base
  10308. */
  10309. dojo.declare("com.ibm.mashups.enabler.SubmittableFormProvider", null, {
  10310. /**
  10311. * Returns a SubmittableForm object associated with the given id.
  10312. * @param {String} id the id of the html form this object is associated with
  10313. * @return {com.ibm.mashups.enabler.SubmittableForm} SubmittableForm object, maybe <code>null</code>
  10314. */
  10315. getSubmittableForm: function(id){
  10316. }
  10317. });
  10318. }
  10319. if(!dojo._hasResource["com.ibm.mashups.enabler.model.url.ModelUrl_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  10320. dojo._hasResource["com.ibm.mashups.enabler.model.url.ModelUrl_API"] = true;
  10321. dojo.provide("com.ibm.mashups.enabler.model.url.ModelUrl_API");
  10322. dojo.provide("com.ibm.mashups.enabler.model.url.ModelUrl");
  10323. /**
  10324. * Interface representing a model URL. This class should be used by the specific model
  10325. * API's in order to generate a valid model URL. The low level classes like ModelRestServiceRequest
  10326. * expect a request to be made with an implementation of the interface. It also allows an easy way
  10327. * to handle URIs. e.g. <br/>
  10328. * <code>&lt;scheme&gt;:&lt;primaryNode&gt;@&lt;secondaryNode&gt;</code><bt/>
  10329. * <code>scheme-specific part = &lt;primaryNode&gt;@&lt;secondaryNode&gt;
  10330. *
  10331. * @ibm-spi
  10332. * @ibm-module Base
  10333. */
  10334. dojo.declare("com.ibm.mashups.enabler.model.url.ModelUrl", null, {
  10335. /**
  10336. * @private
  10337. */
  10338. constructor: function () {
  10339. },
  10340. /**
  10341. * Sets the nodes of the scheme-specific part.
  10342. * @param {JSONArray} nodes an array containing the nodes of the scheme-specific part in a JSON notation way.<br/>
  10343. * The ordering of the array elements specifies the position of the node, meaning
  10344. * the array element 0 will become node 1 and so on and so forth.<br/><br/>
  10345. * valid JSON attributes are: <br/>
  10346. * <ul>
  10347. * <li>value <i>{String} [mandatory]</i></li>
  10348. * <li>isID <i>{boolean} [optional, default: true]</i></li>
  10349. * <li>subModel <i>{String} [optional]</i></li>
  10350. * </ul><br/>
  10351. * example for &quot;nodes&quot;: <br/>
  10352. * <code>
  10353. * [ {<br/>
  10354. * value: &quot;100&quot;,<br/>
  10355. * isID: false,<br/>
  10356. * subModel: &quot;member&quot;<br/>
  10357. * } ]
  10358. * </code>
  10359. * @type {void}
  10360. */
  10361. setNodes: function(nodes) {
  10362. },
  10363. /**
  10364. * Sets the scheme-specific part of the unerlying URI.
  10365. * @param {String} value the value for the scheme-specifc part. (Must not be <code>null</code>)
  10366. * @type {void}
  10367. */
  10368. setSchemeSpecificPart: function (value) {
  10369. },
  10370. /**
  10371. * Returns the scheme-specific part of the underlying URI.
  10372. * @type {String}
  10373. * @return the scheme-specific part. If a scheme-specific part was set through <code>setSchemeSpecificPart</code>
  10374. * the raw value will be returned. If the SSP was set by using <code>setNodes</code>,
  10375. * the converted part will be returned. If neither a node nor the raw SSP was set,
  10376. * this method returns <code>null</code>.
  10377. */
  10378. getSchemeSpecificPart: function() {
  10379. return null;
  10380. },
  10381. /**
  10382. * Adds the value of the specified parameter.
  10383. * @param {String} name the name of the parameter; must not be <code>null</code>.
  10384. * @param {String} value the value of the parameter. Valid is only a single String. (Must not be <code>null</code>)
  10385. * @type {void}
  10386. */
  10387. addParameter: function (name, value) {
  10388. },
  10389. /**
  10390. * Sets the value(s) of the specified parameter.
  10391. * @param {String} name the name of the parameter; must not be <code>null</code>.
  10392. * @param {String} value the value of the parameter. Valid are either a single String or a String array. (Must not be <code>null</code>)
  10393. * @type {void}
  10394. */
  10395. setParameter: function (name, value) {
  10396. },
  10397. /**
  10398. * Returns the value(s) of the specified parameter.
  10399. * @param {String} name the name of the parameter; must not be <code>null</code>.
  10400. * @type {String}
  10401. * @return the value(s) of the specified parameter or <code>null</code> if the specified parameter wasn't found. In case the parameter has one value
  10402. * the return type is String. For multiple values a String array is returned.
  10403. */
  10404. getParameter: function (name) {
  10405. return null;
  10406. },
  10407. /**
  10408. * Returns the parameters as an object. <b>Note: this must be used read-only</b>
  10409. * @type {JSON}
  10410. * @return an object containing all parameters in the format { &lt;name&gt;: [&lt;value&gt;, &lt;value&gt;, ... ], ... }
  10411. */
  10412. getParameters: function() {
  10413. return null;
  10414. },
  10415. /**
  10416. * Returns the absolute URL of this object.
  10417. * @type {String}
  10418. * @return the absolute URL of this object. e.g. <code>http://myhost/contenthandler?uri=acme:id:myid</code>
  10419. * or <code>/contenthandler?uri=acme:id:myid</code>
  10420. */
  10421. getAbsoluteURL: function () {
  10422. return null;
  10423. },
  10424. /**
  10425. * The same as <code>getAbsoluteURL</code> with the difference that this URL is (if needed) converted to a proxified URL
  10426. * @type {String}
  10427. * @return the proxified absolute URL. e.g. <code>http://acme.com/proxy/http/myhost/contenthandler?uri=acme:id:myid</code>
  10428. */
  10429. getProxifiedAbsoluteURL: function () {
  10430. return null;
  10431. },
  10432. /**
  10433. * Returns the model URI of this object. If the complete link is e.g. <code>/mum/contenthandler?uri=acme:id:myid</code>,
  10434. * this method will return <code>acme:id:myid</code>.
  10435. * @type {String}
  10436. * @return the URI portion of this Model URL.
  10437. */
  10438. getModelURI: function () {
  10439. return null;
  10440. }
  10441. }
  10442. );
  10443. }
  10444. if(!dojo._hasResource["com.ibm.mashups.enabler.model.url.ModelUrl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  10445. dojo._hasResource["com.ibm.mashups.enabler.model.url.ModelUrl"] = true;
  10446. dojo.provide("com.ibm.mashups.enabler.model.url.ModelUrl");
  10447. }
  10448. if(!dojo._hasResource["com.ibm.mashups.enabler.model.url.ModelUrlFactory_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  10449. dojo._hasResource["com.ibm.mashups.enabler.model.url.ModelUrlFactory_API"] = true;
  10450. dojo.provide("com.ibm.mashups.enabler.model.url.ModelUrlFactory_API");
  10451. dojo.provide("com.ibm.mashups.enabler.model.url.ModelUrlFactory");
  10452. /**
  10453. * Interface for a ModelUrl Factory that allows to generate ModelUrl's a comfortable way.
  10454. * This class should not be instantiated directly, but should be used through it's defined singleton
  10455. * (<code>com.ibm.mashups.enabler.model.url.ModelUrlFactory</code>).
  10456. * @ibm-spi
  10457. * @ibm-module Base
  10458. */
  10459. dojo.declare( "com.ibm.mashups.enabler.model.url.ModelUrlFactory", null,
  10460. {
  10461. /**
  10462. * Constant for creation of a navigation URL
  10463. * @type {String}
  10464. */
  10465. NAVIGATION_URL: "nav",
  10466. /**
  10467. * Constant for creation of a layout URL
  10468. * @type {String}
  10469. */
  10470. LAYOUT_URL: "layout",
  10471. /**
  10472. * Constant for creation of a shared navigation URL
  10473. * @type {String}
  10474. */
  10475. SHARED_NAVIGATION_URL: "sharednav",
  10476. /**
  10477. * Constant for creation of a fragment URL
  10478. * @type {String}
  10479. */
  10480. FRAGMENT_URL: "fragment",
  10481. /**
  10482. * Constant for creation of a fragment-media URL
  10483. * @type {String}
  10484. */
  10485. FRAGMENT_MEDIA_URL: "fragment-media",
  10486. /**
  10487. * Constant for creation of a user URL
  10488. * @type {String}
  10489. */
  10490. USER_URL: "user",
  10491. /**
  10492. * Constant for creation of a theme URL
  10493. * @type {String}
  10494. */
  10495. THEME_URL: "theme",
  10496. /**
  10497. * Constant for creation of a theme-media URL
  10498. * @type {String}
  10499. */
  10500. THEME_MEDIA_URL: "theme-media",
  10501. /**
  10502. * Constant for creation of a catalog URL
  10503. * @type {String}
  10504. */
  10505. CATALOG_URL: "cat",
  10506. /**
  10507. * Constant for creation of a config URL
  10508. * @type {String}
  10509. */
  10510. CONFIG_URL: "config",
  10511. /**
  10512. * Constant for creation of a space URL
  10513. * @type {String}
  10514. */
  10515. SPACE_URL: "space",
  10516. /**
  10517. * Constant for creation of a space-favorite URL
  10518. * @type {String}
  10519. */
  10520. SPACE_FAVORITE_URL: "space-favorite",
  10521. /**
  10522. * Constant for creation of a ac URL
  10523. * @type {String}
  10524. */
  10525. AC_URL: "ac",
  10526. /**
  10527. * Constant for creation of a ac URL
  10528. * @type {String}
  10529. */
  10530. AI_URL: "ai",
  10531. /**
  10532. * Constant for creation of a template URL
  10533. * @type {String}
  10534. */
  10535. TEMPLATE_URL: "template",
  10536. /**
  10537. * Constant for widget model
  10538. * @type {String}
  10539. */
  10540. WIDGET_URL: "widget",
  10541. /**
  10542. * Constant for event model
  10543. * @type {String}
  10544. */
  10545. EVENT_URL: "event",
  10546. /**
  10547. * Constant for member sub model
  10548. * @type {String}
  10549. */
  10550. SUBMODEL_MEMBER: "member",
  10551. /**
  10552. * Constant for role sub model
  10553. * @type {String}
  10554. */
  10555. SUBMODEL_ROLE: "role",
  10556. /**
  10557. * Constant for allowed-access sub model
  10558. * @type {String}
  10559. */
  10560. SUBMODEL_ACCESS: "access",
  10561. /**
  10562. * Constant for resource sub model
  10563. * @type {String}
  10564. */
  10565. SUBMODEL_RESOURCE: "resource",
  10566. RESOURCE_URL: "resource-service",
  10567. /**
  10568. * @private
  10569. **/
  10570. constructor:function () {
  10571. },
  10572. /**
  10573. * Create a ModelUrl based on the specified urlType. Afterwards parameters and scheme
  10574. * specific parts can be changed.<br />
  10575. * Sample:
  10576. * <pre>var myURL = com.ibm.mashups.enabler.model.url.ModelUrlFactory.createModelURL(com.ibm.mashups.enabler.model.url.ModelUrlFactory.NAVIGATION_URL, this);</pre>
  10577. * @param {String} urlType the type of ModelUrl that should be created. You should use the URL constants that are defined in this interface. (Must not be <code>null</code>)
  10578. * @param {com.ibm.mashups.enabler.model.Model} model the model used to create this ModelUrl object for. (Might be <code>null</code>)
  10579. * @type {com.ibm.mashups.enabler.model.url.ModelUrl}
  10580. * @return the created <code>ModelUrl</code>. Returns <code>null</code> if the specified urlType is not known.
  10581. * @deprecated Use createModelURL instead.
  10582. */
  10583. createModelUrl: function (urlType, model) {
  10584. return new com.ibm.mashups.enabler.model.url.ModelUrl(urlType, model);
  10585. },
  10586. /**
  10587. * Create a ModelUrl based on the specified urlType. Afterwards parameters and scheme
  10588. * specific parts can be changed.<br />
  10589. * Sample:
  10590. * <pre>var myURL = com.ibm.mashups.enabler.model.url.ModelUrlFactory.createModelURL(com.ibm.mashups.enabler.model.url.ModelUrlFactory.NAVIGATION_URL, this);</pre>
  10591. * @param {String} urlType the type of ModelUrl that should be created. You should use the URL constants that are defined in this interface. (Must not be <code>null</code>)
  10592. * @param {com.ibm.mashups.enabler.model.Model} model the model used to create this ModelUrl object for. (Might be <code>null</code>)
  10593. * @type {com.ibm.mashups.enabler.model.url.ModelUrl}
  10594. * @return the created <code>ModelUrl</code>. Returns <code>null</code> if the specified urlType is not known.
  10595. */
  10596. createModelURL: function (urlType, model) {
  10597. return new com.ibm.mashups.enabler.model.url.ModelUrl(urlType, model);
  10598. },
  10599. /**
  10600. * Create a ModelUrl based on the specified URL. Afterwards parameters and scheme specific parts can be changed.
  10601. * @param {String} url the URL that should be used to create a <code>ModelUrl</code>. (Must not be <code>null</code>)
  10602. * @param {com.ibm.mashups.enabler.model.Model} model the model used to create this ModelUrl object for. (Might be <code>null</code>)
  10603. * @type {com.ibm.mashups.enabler.model.url.ModelUrl}
  10604. * @return the created <code>ModelUrl</code> (Must not be <code>null</code>).
  10605. * @deprecated Use getModelURL instead.
  10606. */
  10607. getModelUrl: function (url, model) {
  10608. return new com.ibm.mashups.enabler.model.url.ModelUrl(url, model);
  10609. },
  10610. /**
  10611. * Create a ModelUrl based on the specified URL. Afterwards parameters and scheme specific parts can be changed.
  10612. * @param {String} url the URL that should be used to create a <code>ModelUrl</code>. (Must not be <code>null</code>)
  10613. * @param {com.ibm.mashups.enabler.model.Model} model the model used to create this ModelUrl object for. (Might be <code>null</code>)
  10614. * @type {com.ibm.mashups.enabler.model.url.ModelUrl}
  10615. * @return the created <code>ModelUrl</code> (Must not be <code>null</code>).
  10616. */
  10617. getModelURL: function (url, model) {
  10618. return new com.ibm.mashups.enabler.model.url.ModelUrl(url, model);
  10619. }
  10620. }
  10621. );
  10622. }
  10623. if(!dojo._hasResource["com.ibm.mm.enabler.model.url.BaseModelUrl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  10624. dojo._hasResource["com.ibm.mm.enabler.model.url.BaseModelUrl"] = true;
  10625. dojo.provide("com.ibm.mm.enabler.model.url.BaseModelUrl");
  10626. dojo.declare("com.ibm.mm.enabler.model.url.BaseModelUrl", [com.ibm.mashups.enabler.model.url.ModelUrl], {
  10627. modelSchema: null,
  10628. schemeSpecific: null,
  10629. isMediaUrl: false,
  10630. httpUrl: null,
  10631. VALUE: "value",
  10632. IS_ID: "isID",
  10633. SUBMODEL: "submodel",
  10634. constructor: function() {
  10635. this.nodes = [];
  10636. this.prefix = null;
  10637. this.subModelSchemeMap = {};
  10638. this.subModelSchemeMap[com.ibm.mashups.enabler.model.url.ModelUrlFactory.SUBMODEL_RESOURCE] = "resource";
  10639. this.subModelSchemeMap[com.ibm.mashups.enabler.model.url.ModelUrlFactory.SUBMODEL_ROLE] = "role";
  10640. this.subModelSchemeMap[com.ibm.mashups.enabler.model.url.ModelUrlFactory.SUBMODEL_MEMBER] = "member";
  10641. this.subModelSchemeMap[com.ibm.mashups.enabler.model.url.ModelUrlFactory.SUBMODEL_ACCESS] = "access";
  10642. },
  10643. _loadPrefix: function() {
  10644. if (!this.prefix) {
  10645. // service document and initialization
  10646. this.serviceJson = com.ibm.mm.enabler.model.ServiceDocumentModel.getCollectionData(com.ibm.mm.enabler.model.ServiceDocumentModel.SERVICE_NAVIGATION);
  10647. this.prefix = this.serviceJson.idprefix;
  10648. }
  10649. },
  10650. setPrimaryNode: function(value, isID, subModel) {
  10651. var primary = {};
  10652. primary.value = value;
  10653. primary.isID = (isID === false) ? isID : true;
  10654. primary.subModel = subModel;
  10655. this.nodes[0] = primary;
  10656. this._updateURI();
  10657. },
  10658. setSecondaryNode: function(value, isID, subModel) {
  10659. var secondary = {};
  10660. secondary.value = value;
  10661. secondary.isID = (isID === false) ? isID : true;
  10662. secondary.subModel = subModel;
  10663. this.nodes[1] = secondary;
  10664. this._updateURI();
  10665. },
  10666. setNodes: function(nodes) {
  10667. this.nodes = nodes;
  10668. for (var i = 0; i < nodes.length; i++) {
  10669. nodes[i].isID = (nodes[i].isID === false) ? nodes[i].isID : true;
  10670. }
  10671. this._updateURI();
  10672. },
  10673. setSchemeSpecificPart: function(value) {
  10674. this.nodes = [];
  10675. this.schemeSpecific = value;
  10676. this._updateURI();
  10677. },
  10678. getSchemeSpecificPart: function() {
  10679. if (this.schemeSpecific) {
  10680. return this.schemeSpecific;
  10681. }
  10682. var tempSSP = "";
  10683. if (this.isMediaUrl) {
  10684. tempSSP = "/";
  10685. }
  10686. if (!this.nodes) {
  10687. return tempSSP;
  10688. }
  10689. var i, node;
  10690. if (this.isMediaUrl) {
  10691. for (i = 0; i < this.nodes.length; i++) {
  10692. node = this.nodes[i];
  10693. // the prefix MUST only be loaded if the prefix is needed, since the
  10694. // loading method uses this function as well which would causea infinite loop
  10695. if (node.isID && !this.prefix) {
  10696. this._loadPrefix();
  10697. }
  10698. if (i > 0) {
  10699. if (i < this.nodes.length - 1) {
  10700. tempSSP += "@";
  10701. }
  10702. else {
  10703. tempSSP += "/";
  10704. }
  10705. }
  10706. tempSSP += node.value;
  10707. }
  10708. }
  10709. else {
  10710. for (i = 0; i < this.nodes.length; i++) {
  10711. node = this.nodes[i];
  10712. // the prefix MUST only be loaded if the prefix is needed, since the
  10713. // loading method uses this function as well which would causea infinite loop
  10714. if (node.isID && !this.prefix) {
  10715. this._loadPrefix();
  10716. }
  10717. if (tempSSP != "") {
  10718. tempSSP += "@";
  10719. }
  10720. if (node.subModel) {
  10721. tempSSP += this.subModelSchemeMap[node.subModel] + ":";
  10722. }
  10723. if (node.isID) {
  10724. tempSSP += this.prefix + ":";
  10725. }
  10726. tempSSP += node.value;
  10727. }
  10728. }
  10729. return tempSSP;
  10730. },
  10731. _updateURI: function() {
  10732. var uri = this.modelSchema + ":" + this.getSchemeSpecificPart();
  10733. this.httpUrl.setParameter("uri", uri);
  10734. },
  10735. addParameter: function(name, value) {
  10736. this.httpUrl.addParameter(name, value);
  10737. },
  10738. setParameter: function(name, value) {
  10739. this.httpUrl.setParameter(name, value);
  10740. },
  10741. getParameter: function(name) {
  10742. return this.httpUrl.getParameter(name);
  10743. },
  10744. getParameters: function() {
  10745. return this.httpUrl.getParameters();
  10746. },
  10747. getAbsoluteURL: function() {
  10748. return this.httpUrl.toString();
  10749. },
  10750. getProxifiedAbsoluteURL: function() {
  10751. return this.httpUrl.toProxifiedString();
  10752. },
  10753. getModelURI: function() {
  10754. return this.httpUrl.getParameter("uri");
  10755. },
  10756. toProxifiedString: function() {
  10757. // TBD: REMOVE AFTER FULL SWITCH
  10758. return this.httpUrl.toProxifiedString();
  10759. }
  10760. });
  10761. }
  10762. if(!dojo._hasResource["com.ibm.mm.enabler.model.url.SchemeBasedModelUrlImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  10763. dojo._hasResource["com.ibm.mm.enabler.model.url.SchemeBasedModelUrlImpl"] = true;
  10764. dojo.provide("com.ibm.mm.enabler.model.url.SchemeBasedModelUrlImpl");
  10765. dojo.declare("com.ibm.mm.enabler.model.url.SchemeBasedModelUrlImpl", [com.ibm.mm.enabler.model.url.BaseModelUrl], {
  10766. constructor: function(modelSchema, model) {
  10767. this.modelSchema = modelSchema;
  10768. this.model = model;
  10769. var configService = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);
  10770. var url = "";
  10771. // add the contextroot
  10772. url += configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.CONTEXT_ROOT);
  10773. // add the public contenthandler url
  10774. var anonymousUser = configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.ANONYMOUS_USER);
  10775. var contenthandlerPath;
  10776. if (anonymousUser) {
  10777. contenthandlerPath = configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.CONTENTHANDLER_PUBLIC);
  10778. }
  10779. else {
  10780. contenthandlerPath = configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.CONTENTHANDLER_PRIVATE);
  10781. }
  10782. url += contenthandlerPath;
  10783. this.httpUrl = new com.ibm.mm.enabler.utils.HttpUrl(url);
  10784. this.httpUrl.setParameter("uri", this.modelSchema); // first initialization
  10785. }
  10786. });
  10787. }
  10788. if(!dojo._hasResource["com.ibm.mm.enabler.model.url.SchemeBasedModelMediaUrlImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  10789. dojo._hasResource["com.ibm.mm.enabler.model.url.SchemeBasedModelMediaUrlImpl"] = true;
  10790. dojo.provide("com.ibm.mm.enabler.model.url.SchemeBasedModelMediaUrlImpl");
  10791. dojo.declare("com.ibm.mm.enabler.model.url.SchemeBasedModelMediaUrlImpl", [com.ibm.mm.enabler.model.url.SchemeBasedModelUrlImpl], {
  10792. constructor: function(modelSchema, model) {
  10793. this.isMediaUrl = true;
  10794. }
  10795. });
  10796. }
  10797. if(!dojo._hasResource["com.ibm.mm.enabler.model.url.ThemeResourceUrlImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  10798. dojo._hasResource["com.ibm.mm.enabler.model.url.ThemeResourceUrlImpl"] = true;
  10799. dojo.provide("com.ibm.mm.enabler.model.url.ThemeResourceUrlImpl");
  10800. dojo.declare("com.ibm.mm.enabler.model.url.ThemeResourceUrlImpl", [com.ibm.mm.enabler.model.url.BaseModelUrl],
  10801. {
  10802. constructor: function (modelSchema, model) {
  10803. this.modelSchema = modelSchema;
  10804. this.model = model;
  10805. this.httpUrl = new com.ibm.mm.enabler.utils.HttpUrl("/");
  10806. this.httpUrl.setParameter("uri", this.modelSchema); // first initialization
  10807. },
  10808. _updateURI: function() {
  10809. // at this point we know it must be a theme or skin resource we try to fetch
  10810. var resource, url;
  10811. if (this.nodes.length==2) { // theme
  10812. var themeId = this.nodes[0].value;
  10813. resource = this.nodes[1].value;
  10814. var themeNode = this.model.find(themeId).start();
  10815. url = themeNode._getBaseUrl();
  10816. this.httpUrl = new com.ibm.mm.enabler.utils.HttpUrl(url+resource);
  10817. }
  10818. else if (this.nodes.length==3) { // skin
  10819. var skinId = this.nodes[0].value;
  10820. //var themeId = this.nodes[1].value;
  10821. resource = this.nodes[2].value;
  10822. var skinNode = this.model.find(skinId).start();
  10823. url = skinNode._getBaseUrl();
  10824. this.httpUrl = new com.ibm.mm.enabler.utils.HttpUrl(url+resource);
  10825. }
  10826. else {
  10827. this.httpUrl = new com.ibm.mm.enabler.utils.HttpUrl("/");
  10828. }
  10829. }
  10830. }
  10831. );
  10832. }
  10833. if(!dojo._hasResource["com.ibm.mm.enabler.model.url.StringBasedModelUrlImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  10834. dojo._hasResource["com.ibm.mm.enabler.model.url.StringBasedModelUrlImpl"] = true;
  10835. dojo.provide("com.ibm.mm.enabler.model.url.StringBasedModelUrlImpl");
  10836. dojo.declare("com.ibm.mm.enabler.model.url.StringBasedModelUrlImpl", [com.ibm.mm.enabler.model.url.BaseModelUrl], {
  10837. constructor: function(url, model) {
  10838. if (!com.ibm.mm.enabler.model.url.StringBasedModelUrlImpl.CONTEXT_ROOT) {
  10839. com.ibm.mm.enabler.model.url.StringBasedModelUrlImpl.CONTEXT_ROOT = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME).getValue(com.ibm.mashups.enabler.services.ConfigConstants.CONTEXT_ROOT);
  10840. com.ibm.mm.enabler.model.url.StringBasedModelUrlImpl.PRIVATE_HANDLER = com.ibm.mm.enabler.model.url.StringBasedModelUrlImpl.CONTEXT_ROOT +
  10841. com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME).getValue(com.ibm.mashups.enabler.services.ConfigConstants.CONTENTHANDLER_PRIVATE);
  10842. com.ibm.mm.enabler.model.url.StringBasedModelUrlImpl.PUBLIC_HANDLER = com.ibm.mm.enabler.model.url.StringBasedModelUrlImpl.CONTEXT_ROOT +
  10843. com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME).getValue(com.ibm.mashups.enabler.services.ConfigConstants.CONTENTHANDLER_PUBLIC);
  10844. }
  10845. if (url.indexOf("?") === 0) {
  10846. // add the public contenthandler url
  10847. var anonymousUser = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME).getValue(com.ibm.mashups.enabler.services.ConfigConstants.ANONYMOUS_USER);
  10848. var contenthandlerPath;
  10849. if (anonymousUser) {
  10850. contenthandlerPath = com.ibm.mm.enabler.model.url.StringBasedModelUrlImpl.PUBLIC_HANDLER;
  10851. }
  10852. else {
  10853. contenthandlerPath = com.ibm.mm.enabler.model.url.StringBasedModelUrlImpl.PRIVATE_HANDLER;
  10854. }
  10855. var newURL = "";
  10856. // add contenthandlerPath
  10857. newURL += contenthandlerPath;
  10858. url = newURL + url;
  10859. }
  10860. this.httpUrl = new com.ibm.mm.enabler.utils.HttpUrl(url);
  10861. }
  10862. });
  10863. }
  10864. if(!dojo._hasResource["com.ibm.mm.enabler.model.url.ModelUrlFactoryImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  10865. dojo._hasResource["com.ibm.mm.enabler.model.url.ModelUrlFactoryImpl"] = true;
  10866. dojo.provide("com.ibm.mm.enabler.model.url.ModelUrlFactoryImpl");
  10867. dojo.declare("com.ibm.mm.enabler.model.url.ModelUrlFactoryImpl", [com.ibm.mashups.enabler.model.url.ModelUrlFactory], {
  10868. WEBDAV_URL: "webdav",
  10869. /**
  10870. * @private
  10871. **/
  10872. constructor: function() {
  10873. this.schemeMap = {};
  10874. this.schemeMap[this.NAVIGATION_URL] = "nm";
  10875. this.schemeMap[this.SHARED_NAVIGATION_URL] = "snm";
  10876. this.schemeMap[this.FRAGMENT_URL] = "fragment";
  10877. this.schemeMap[this.FRAGMENT_MEDIA_URL] = "fragment-media";
  10878. this.schemeMap[this.USER_URL] = "um";
  10879. this.schemeMap[this.THEME_URL] = "theme";
  10880. this.schemeMap[this.THEME_MEDIA_URL] = "theme-media";
  10881. this.schemeMap[this.CATALOG_URL] = "catalog";
  10882. this.schemeMap[this.CONFIG_URL] = "config";
  10883. this.schemeMap[this.SPACE_URL] = "space";
  10884. this.schemeMap[this.SPACE_FAVORITE_URL] = "space-favorite";
  10885. this.schemeMap[this.AC_URL] = "ac";
  10886. this.schemeMap[this.AI_URL] = "ai";
  10887. this.schemeMap[this.TEMPLATE_URL] = "template";
  10888. this.schemeMap[this.LAYOUT_URL] = "lm";
  10889. // internal, not exposed
  10890. this.schemeMap.service = "service";
  10891. this.schemeMap[this.WEBDAV_URL] = "dav:mmdav";
  10892. this.schemeMap[this.WIDGET_URL] = "wm";
  10893. this.schemeMap[this.EVENT_URL] = "ce";
  10894. this.schemeMap[this.RESOURCE_URL] = "resource-service";
  10895. },
  10896. // @deprecated
  10897. createModelUrl: function(urlType, model) {
  10898. return this.createModelURL(urlType, model);
  10899. },
  10900. createModelURL: function(urlType, model) {
  10901. var modelSchema = com.ibm.mashups.enabler.model.url.ModelUrlFactory.schemeMap[urlType];
  10902. if (!modelSchema) {
  10903. return null;
  10904. }
  10905. var urlImpl;
  10906. if (urlType == this.THEME_MEDIA_URL) {
  10907. urlImpl = new com.ibm.mm.enabler.model.url.ThemeResourceUrlImpl(modelSchema, model);
  10908. }
  10909. else if (urlType == this.FRAGMENT_MEDIA_URL) {
  10910. urlImpl = new com.ibm.mm.enabler.model.url.SchemeBasedModelMediaUrlImpl(modelSchema, model);
  10911. }
  10912. else {
  10913. urlImpl = new com.ibm.mm.enabler.model.url.SchemeBasedModelUrlImpl(modelSchema, model);
  10914. }
  10915. return urlImpl;
  10916. },
  10917. // @deprecated
  10918. getModelUrl: function(url, model) {
  10919. return this.getModelURL(url, model);
  10920. },
  10921. getModelURL: function(url, model) {
  10922. return new com.ibm.mm.enabler.model.url.StringBasedModelUrlImpl(url, model);
  10923. }
  10924. });
  10925. // legacy
  10926. com.ibm.mm.enabler.model.UrlFactory = new com.ibm.mm.enabler.model.url.ModelUrlFactoryImpl();
  10927. // define public factory
  10928. com.ibm.mashups.enabler.model.url.ModelUrlFactory = com.ibm.mm.enabler.model.UrlFactory;
  10929. }
  10930. if(!dojo._hasResource["com.ibm.mashups.enabler.model.url.ModelUrlFactory"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  10931. dojo._hasResource["com.ibm.mashups.enabler.model.url.ModelUrlFactory"] = true;
  10932. dojo.provide("com.ibm.mashups.enabler.model.url.ModelUrlFactory");
  10933. }
  10934. if(!dojo._hasResource["com.ibm.mm.enabler.SubmittableFormProviderImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  10935. dojo._hasResource["com.ibm.mm.enabler.SubmittableFormProviderImpl"] = true;
  10936. dojo.provide("com.ibm.mm.enabler.SubmittableFormProviderImpl");
  10937. // submittable form provider
  10938. dojo.declare("com.ibm.mm.enabler.SubmittableFormProviderImpl", com.ibm.mashups.enabler.SubmittableFormProvider, {
  10939. constructor: function(){
  10940. },
  10941. /**
  10942. * Returns a SubmittableForm object associated with the given id.
  10943. * @param {String} id the id of the html form this object is associated with
  10944. * @return {SubmittableForm} SubmittableForm object, maybe <code>null</code>
  10945. */
  10946. getSubmittableForm: function(id){
  10947. var model = null;
  10948. var url;
  10949. if (id == "spaceForm") {
  10950. url = new com.ibm.mashups.enabler.model.url.ModelUrlFactory.createModelURL(com.ibm.mashups.enabler.model.url.ModelUrlFactory.SPACE_URL, null);
  10951. url.setNodes([{
  10952. value: "collection",
  10953. isID: false
  10954. }]);
  10955. url.setParameter("mode", "import");
  10956. url.setParameter("mime-type", "text/html");
  10957. url = url.toProxifiedString();
  10958. /*"/mum/mycontenthandler?uri=space:collection&mode=import"*/
  10959. model = new com.ibm.mm.enabler.SubmittableFormImpl(url, "post", id);
  10960. }
  10961. else
  10962. if (id == "pageForm") {
  10963. var serviceJson = com.ibm.mm.enabler.model.ServiceDocumentModel.getCollectionData(com.ibm.mm.enabler.model.ServiceDocumentModel.SERVICE_RESOURCE);
  10964. url = new com.ibm.mashups.enabler.model.url.ModelUrlFactory.getModelURL(serviceJson.url, this);
  10965. url.setParameter("mode", "import");
  10966. url.setParameter("mime-type", "text/html");
  10967. // post the spaceId to server.
  10968. if (arguments[1]) {
  10969. url.setParameter("spaceId", arguments[1]);
  10970. }
  10971. url = url.toProxifiedString();
  10972. /*"/mum/mycontenthandler?uri=resource:collection&mode=import"*/
  10973. model = new com.ibm.mm.enabler.SubmittableFormImpl(url, "post", id);
  10974. }
  10975. else
  10976. if (id == "spacePageForm") {
  10977. url = new com.ibm.mashups.enabler.model.url.ModelUrlFactory.createModelURL(com.ibm.mashups.enabler.model.url.ModelUrlFactory.SPACE_URL, null);
  10978. url.setNodes([{
  10979. value: "collection",
  10980. isID: false
  10981. }]);
  10982. url.setParameter("mode", "import");
  10983. url.setParameter("mime-type", "text/html");
  10984. // When we import page .data file came from old BSpace data, we should use the import space rest api, and post spaceId to server.
  10985. if (arguments[1]) {
  10986. url.setParameter("spaceId", arguments[1]);
  10987. }
  10988. // The form id is come from the arguments[2]
  10989. var postForm = null;
  10990. if (arguments[2]) {
  10991. postForm = arguments[2];
  10992. }
  10993. url = url.toProxifiedString();
  10994. /*"/mum/mycontenthandler?uri=space:collection&mode=import"*/
  10995. model = new com.ibm.mm.enabler.SubmittableFormImpl(url, "post", postForm);
  10996. }
  10997. return model;
  10998. }
  10999. });
  11000. }
  11001. if(!dojo._hasResource["com.ibm.mashups.enabler.SubmittableFormProvider"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  11002. dojo._hasResource["com.ibm.mashups.enabler.SubmittableFormProvider"] = true;
  11003. dojo.provide("com.ibm.mashups.enabler.SubmittableFormProvider");
  11004. }
  11005. if(!dojo._hasResource["com.ibm.mashups.enabler.TimeStamped_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  11006. dojo._hasResource["com.ibm.mashups.enabler.TimeStamped_API"] = true;
  11007. dojo.provide("com.ibm.mashups.enabler.TimeStamped_API");
  11008. dojo.provide("com.ibm.mashups.enabler.TimeStamped");
  11009. /**
  11010. * Model interface for specific date access properties: This is information such as the
  11011. * creation date or the last modification date of a resource.
  11012. * @ibm-api
  11013. * @ibm-module Base
  11014. */
  11015. dojo.declare( "com.ibm.mashups.enabler.TimeStamped", null, {
  11016. /**
  11017. * Returns the creation date of the resource.
  11018. * @return {Date} the creation date, never <code>null</code>.
  11019. */
  11020. getCreated: function () {
  11021. },
  11022. /**
  11023. * Returns the modification date of the resource.
  11024. * @return {Date} the modification date, never <code>null</code>.
  11025. */
  11026. getLastModified: function () {
  11027. }
  11028. });
  11029. }
  11030. if(!dojo._hasResource["com.ibm.mashups.enabler.TimeStamped"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  11031. dojo._hasResource["com.ibm.mashups.enabler.TimeStamped"] = true;
  11032. dojo.provide( "com.ibm.mashups.enabler.TimeStamped" );
  11033. }
  11034. if(!dojo._hasResource["com.ibm.mashups.enabler.Transformable_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  11035. dojo._hasResource["com.ibm.mashups.enabler.Transformable_API"] = true;
  11036. dojo.provide("com.ibm.mashups.enabler.Transformable_API");
  11037. dojo.provide("com.ibm.mashups.enabler.Transformable");
  11038. /**
  11039. * Interface for resources in the system that can be transformed
  11040. * @ibm-spi
  11041. * @ibm-module Base
  11042. */
  11043. dojo.declare("com.ibm.mashups.enabler.Transformable", null, {
  11044. /**
  11045. * Returns the xml representation of the resource. It may be modified,
  11046. * e.g. with an xsl transformation.
  11047. * WARNING: Please note that you must change the xml representation
  11048. * of the resource in a compatible way only, since the Enabler API
  11049. * operates on this representation. Otherwise the Enabler API may
  11050. * function incorrectly or break.
  11051. * @return {Object} the xml representation; never <code>null</code>
  11052. */
  11053. getXml: function() {
  11054. },
  11055. /**
  11056. * Sets the specified xml of the resource.
  11057. * WARNING: Please note that you must set a valid xml representation
  11058. * of the resource, since the Enabler API operates on this representation.
  11059. * Otherwise the Enabler API may function incorrectly or break.
  11060. * @param {Object} xml the xml representation to set for the resource
  11061. */
  11062. setXml: function(xml) {
  11063. }
  11064. });
  11065. }
  11066. if(!dojo._hasResource["com.ibm.mm.enabler.TransformableImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  11067. dojo._hasResource["com.ibm.mm.enabler.TransformableImpl"] = true;
  11068. dojo.provide("com.ibm.mm.enabler.TransformableImpl");
  11069. // transformable
  11070. dojo.declare("com.ibm.mm.enabler.TransformableImpl", [com.ibm.mashups.enabler.Transformable, com.ibm.mm.enabler.DirtyFlagProviderImpl], {
  11071. constructor: function() {
  11072. },
  11073. getXml: function() {
  11074. return this.xmlData;
  11075. },
  11076. setXml: function(xml, keepClean) {
  11077. this.xmlData = xml;
  11078. if (this._resetCachedRawID) {
  11079. // if this also implements the IdentifiableXml aspect we need to clean out any cached raw id at this point
  11080. this._resetCachedRawID();
  11081. }
  11082. if (!keepClean) {
  11083. this._setDirty();
  11084. }
  11085. }
  11086. });
  11087. }
  11088. if(!dojo._hasResource["com.ibm.mashups.enabler.Transformable"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  11089. dojo._hasResource["com.ibm.mashups.enabler.Transformable"] = true;
  11090. dojo.provide("com.ibm.mashups.enabler.Transformable");
  11091. }
  11092. if(!dojo._hasResource["com.ibm.mashups.enabler.TreeModel"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  11093. dojo._hasResource["com.ibm.mashups.enabler.TreeModel"] = true;
  11094. dojo.provide("com.ibm.mashups.enabler.TreeModel");
  11095. /**
  11096. * This interface provides a generic tree model acting as a base class
  11097. * for all concrete tree models
  11098. * @ibm-api
  11099. * @ibm-module Base
  11100. */
  11101. dojo.declare("com.ibm.mashups.enabler.TreeModel", [com.ibm.mashups.enabler.model.Model, com.ibm.mashups.enabler.Locator], {
  11102. /**
  11103. * Returns the root node of the model; may return <code>null</code>
  11104. * if the concrete tree model supports for empty models
  11105. *
  11106. * @type Deferred
  11107. * @return a deferred object used to start this operation. The
  11108. * return value when executed through the deferred object
  11109. * is the root object of the tree model
  11110. */
  11111. getRoot: function(){
  11112. },
  11113. /**
  11114. * Returns whether or not the given node has children. Please pay
  11115. * attention to the documentation of the return value; it is not
  11116. * guaranteed that children are present if the method returns
  11117. * <code>true</code> - the iterator might be empty.
  11118. *
  11119. * @param {Object} node node object or node uri (without any scope)
  11120. * for which to check if it has children. Must
  11121. * not be <code>null</code>.
  11122. * @return {Boolean} <tt>true</tt> if the specified node has children, <tt>false</tt> otherwise
  11123. */
  11124. hasChildren: function(node){
  11125. },
  11126. /**
  11127. * Returns an iterator over the child elements for the given node.
  11128. *
  11129. * @param {Object} node node object or node uri (without any scope)
  11130. * for which to return its children. Must not
  11131. * be <code>null</code>.
  11132. * @return {com.ibm.mashups.enabler.DeferredIterator} deferred iterator for the children of the given node.
  11133. * Never <code>null</code>
  11134. */
  11135. getChildren: function(node){
  11136. },
  11137. /**
  11138. * Returns the parent of a given node.
  11139. * @param {Object} node node object or node uri (without any scope)
  11140. * for which to return its parent. Must not
  11141. * be <code>null</code>.
  11142. * @return {com.ibm.mashups.enabler.Deferred} a deferred object used to start this operation. The
  11143. * return value when executed through the deferred object
  11144. * is the parent of the given node, or <code>null</code>
  11145. * if the node has no parent
  11146. */
  11147. getParent: function(node){
  11148. }
  11149. });
  11150. }
  11151. if(!dojo._hasResource["com.ibm.mashups.enabler.TreeModelController"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  11152. dojo._hasResource["com.ibm.mashups.enabler.TreeModelController"] = true;
  11153. dojo.provide("com.ibm.mashups.enabler.TreeModelController");
  11154. /**
  11155. * This modifiable interface provides a generic tree model acting as a base class
  11156. * for all concrete tree models
  11157. * @ibm-api
  11158. * @ibm-module Base
  11159. */
  11160. dojo.declare("com.ibm.mashups.enabler.TreeModelController", com.ibm.mashups.enabler.TreeModel, {
  11161. /**
  11162. * creates a new model object. The created node can be inserted
  11163. * into the model using an appropriate <code>insert</code> method defined
  11164. * on a subinterface of this interface. The node will not appear in the model
  11165. * unless it is inserted.
  11166. * @param {JSON} context array of predefined information
  11167. * used for the creation of the node. May be <code>null</code>. Accepted
  11168. * names are defined in the appropriate subinterfaces
  11169. * @type Object
  11170. * @return the created node
  11171. */
  11172. create: function(context){
  11173. },
  11174. /**
  11175. * Confirms whether creating the node is possible.
  11176. * @param {JSON} context array of predefined information
  11177. * used for the creation of the node. May be <code>null</code>. Accepted
  11178. * names are defined in the appropriate subinterfaces
  11179. * @return {Boolean} true if the node can be created, otherwise false.
  11180. */
  11181. confirmCreate: function(context){
  11182. },
  11183. /**
  11184. * Inserts a node into the tree model at the specified location;
  11185. * the node must either be created with the create method of the
  11186. * concrete tree model before, or must exist in the tree model;
  11187. * in this case the existing node is moved to the specified location
  11188. *
  11189. * @param {Object} node node to insert or move. Must not be
  11190. * <code>null</code>.
  11191. * @param {Object} parentNode node object or node uri (without any
  11192. * scope) of the parent node. The given
  11193. * node is inserted/moved underneath the
  11194. * parent node; must not be <code>null</code>.
  11195. * @param {Object} nextNode node object or node uri (without any
  11196. * scope) of the successor node before
  11197. * which the node is to be inserted;
  11198. * if <code>null</code> is specified,
  11199. * the node is appended at the end of
  11200. * the existing nodes
  11201. * @type void
  11202. */
  11203. insert: function(node, parentNode, nextNode){
  11204. },
  11205. /**
  11206. * Confirms whether inserting the node is possible.
  11207. * @param {Object} node node to insert or move. Must not be
  11208. * <code>null</code>.
  11209. * @param {Object} parentNode node object or node uri (without any
  11210. * scope) of the parent node. The given
  11211. * node is inserted/moved underneath the
  11212. * parent node; must not be <code>null</code>.
  11213. * @param {Object} nextNode node object or node uri (without any
  11214. * scope) of the successor node before
  11215. * which the node is to be inserted;
  11216. * if <code>null</code> is specified,
  11217. * the node is appended at the end of
  11218. * the existing nodes
  11219. * @return {Boolean} true if the node can be inserted, otherwise false.
  11220. */
  11221. confirmInsert: function(node, parentNode, nextNode){
  11222. },
  11223. /**
  11224. * Deletes a node from the model. All its children are deleted as well.
  11225. *
  11226. * @param {Object} node node object or node uri (without any scope)
  11227. * to delete from the model. Must not be <code>null</code>.
  11228. * @type void
  11229. */
  11230. remove: function(node){
  11231. },
  11232. /**
  11233. * Confirms whether removing the node is possible.
  11234. * @param{Object} node node object or node uri (without any scope).
  11235. * Must not be <code>null</code>
  11236. * @return {Boolean} true if the node can be removed, otherwise false.
  11237. */
  11238. confirmRemove: function(node){
  11239. }
  11240. });
  11241. }
  11242. if(!dojo._hasResource["com.ibm.mashups.enabler.io.DynamicResolver_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  11243. dojo._hasResource["com.ibm.mashups.enabler.io.DynamicResolver_API"] = true;
  11244. dojo.provide("com.ibm.mashups.enabler.io.DynamicResolver_API");
  11245. dojo.provide("com.ibm.mashups.enabler.io.DynamicResolver");
  11246. /**
  11247. * This provides a system plugin point where extensions can be registered
  11248. * to provide immediate resolution of IO requests for data that can be
  11249. * retrieved from the client. It allows circumvention of remote requests
  11250. * to serve data that is already available in the system. It also allows
  11251. * an completely extensible URL naming system such that URLs passed to
  11252. * IO requests can take on formats besides typical ones such as http or https.
  11253. * Extension formats and schemes can be handled by custom plugins to allow
  11254. * an arbitrary mapping of resources on the client to URLs that can be serviced
  11255. * through normal IO requests.
  11256. * The service can be retrieved using the following code: <br>
  11257. * <code>var dynamicResolver = com.ibm.mashups.services.ServiceManager.getService(<br/>
  11258. * &nbsp;&nbsp;&nbsp;&nbsp;com.ibm.mashups.enabler.io.DynamicResolver.SERVICE_NAME);</code><br/>
  11259. * @ibm-spi
  11260. * @ibm-module Base
  11261. */
  11262. dojo.declare("com.ibm.mashups.enabler.io.DynamicResolver", null, {
  11263. /**
  11264. * The service name to be used to fetch the service from the ServiceManager
  11265. * @type String
  11266. */
  11267. SERVICE_NAME: "dynamicResolver",
  11268. /**
  11269. * Registers a plugin for immediate request resolution.
  11270. * @param {String} id the id of the plugin
  11271. * @param {Function} matcher the function that returns a validation result
  11272. * to verify if the plugin can resolve the current request. Function format:
  11273. * <code>Function(String url)</code>.<br>
  11274. * This function must return a "truthy" value to indicate that it can resolve
  11275. * this request, or a "falsy" value if it cannot. Whatever this function returns
  11276. * will be passed into the plugin's resolver function as the second argument.
  11277. * @param {Function} resolver the function that resolves the current request
  11278. * and passes the response data back to the caller. Function format:
  11279. * <code>Function(String url, Anything validationResult)</code>.<br>
  11280. * This function must return the data for the response.
  11281. * @param {Boolean} first optional argument to specify if this plugin should
  11282. * take precedence over all existing plugins if set to true. If it is false
  11283. * the plugin will take lowest precedence of existing plugins. Default is false.
  11284. * @type void
  11285. */
  11286. register: function(/*String*/ id, /*Function*/matcher, /*Function*/resolver, /*Boolean?*/first) {
  11287. },
  11288. /**
  11289. * Unregisters a plugin by its registered id.
  11290. * @param {String} id the id of the plugin to unregister
  11291. * @type void
  11292. */
  11293. unregister: function(/*String*/id) {
  11294. }
  11295. });
  11296. com.ibm.mashups.enabler.io.DynamicResolver.SERVICE_NAME = "dynamicResolver";
  11297. }
  11298. if(!dojo._hasResource["com.ibm.mm.enabler.io.XHRWrapper"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  11299. dojo._hasResource["com.ibm.mm.enabler.io.XHRWrapper"] = true;
  11300. dojo.provide("com.ibm.mm.enabler.io.XHRWrapper");
  11301. dojo.declare("com.ibm.mm.enabler.io.XHRWrapper", null, {
  11302. constructor: function(ioArgs, partString, statusCode, contentType, partHeaders) {
  11303. this.ioArgs = ioArgs;
  11304. this.xhr = ioArgs.xhr;
  11305. this.readyState = ioArgs.xhr.readyState;
  11306. this.responseText = partString;
  11307. this.responseXML = ioArgs.xhr.responseXML;
  11308. this.status = statusCode;
  11309. this.statusText = ioArgs.xhr.statusText;
  11310. this.contentType = contentType;
  11311. this.partHeaders = partHeaders;
  11312. },
  11313. getAllResponseHeaders: function() {
  11314. return this.xhr.getAllResponseHeaders();
  11315. },
  11316. getInterface: function() {
  11317. return this.xhr.getInterface();
  11318. },
  11319. getResponseHeader: function(header) {
  11320. var headerString = header + '';
  11321. if (this.partHeaders[headerString]) {
  11322. return this.partHeaders[headerString];
  11323. } else if (headerString.toLowerCase() == "content-type") {
  11324. return (this.contentType);
  11325. }
  11326. return this.xhr.getResponseHeader(header);
  11327. }
  11328. });
  11329. }
  11330. if(!dojo._hasResource["com.ibm.mm.enabler.io.DynamicResolver"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  11331. dojo._hasResource["com.ibm.mm.enabler.io.DynamicResolver"] = true;
  11332. dojo.provide("com.ibm.mm.enabler.io.DynamicResolver");
  11333. dojo.declare("com.ibm.mm.enabler.io.DynamicResolver", com.ibm.mashups.enabler.io.DynamicResolver, {
  11334. constructor: function(){
  11335. this._plugins = []; // each plugin has format -> [id,matchFn,resolveFn]
  11336. // Wrap dojo.xhr; if a resolver is found, use it, otherwise delegate to unwrapped dojo.xhr
  11337. var me = this, origXhr = dojo.xhr;
  11338. dojo.xhr = function(){
  11339. var fn = me.getResolver.apply(me, arguments) || origXhr;
  11340. return fn.apply(this, arguments);
  11341. };
  11342. },
  11343. _buildDfdFn: function(fname, obj, ioArgs){
  11344. var func = obj[fname];
  11345. return func ? function(val){
  11346. return func.call(obj, val, ioArgs);
  11347. }
  11348. : null;
  11349. },
  11350. resolve: function(/*Function*/resolver, /*Object*/ validationResult, /* String */ method, /* dojo.__XhrArgs */ args, /* Boolean */ hasBody){
  11351. // called in scope of original xhr call, not in DynamicResolver instance scope
  11352. var data = null, isErr = false, dfd = new dojo.Deferred(), ioArgs = { // dojo.__IoCallbackArgs
  11353. args: args,
  11354. url: com.ibm.mm.enabler.EndpointUtils.checkForEndpoints(args.url) || args.url, // check for endpoint URLs
  11355. handleAs: args.handleAs || "text",
  11356. xhr: { // need this stubbed out for XHRWrapper
  11357. readyState: 4,
  11358. responseXML: null,
  11359. statusText: ""
  11360. }
  11361. };
  11362. dfd.addCallback(this._buildDfdFn("load", args, ioArgs)).addErrback(this._buildDfdFn("error", args, ioArgs)).addBoth(this._buildDfdFn("handle", args, ioArgs));
  11363. ioArgs.xhr = new com.ibm.mm.enabler.io.XHRWrapper(ioArgs, "", 200, "text", {});
  11364. try {
  11365. data = resolver(ioArgs.url, validationResult); // use potentially endpoint-resolved URL
  11366. ioArgs.xhr.status = 200;
  11367. if (data) {
  11368. ioArgs.xhr.responseText = data;
  11369. if (args.handleAs === "xml" && typeof data === "string") {
  11370. // create document object from text string
  11371. ioArgs.xhr.responseXML = com.ibm.mm.enabler.utils.Dom.createDocument(data);
  11372. }
  11373. }
  11374. }
  11375. catch (err) {
  11376. ioArgs.xhr.status = 500;
  11377. data = err;
  11378. ioArgs.xhr.responseText = err.toString();
  11379. isErr = true;
  11380. }
  11381. dfd[isErr ? "errback" : "callback"](data);
  11382. return dfd; // dojo.Deferred
  11383. },
  11384. _embedValidation: function(fn, vResult){
  11385. var me = this;
  11386. return function(method, args, hasBody){
  11387. return me.resolve(fn, vResult, method, args, hasBody);
  11388. };
  11389. },
  11390. getResolver: function(/* String */method, /* dojo.__XhrArgs */ args, /* Boolean */ hasBody){
  11391. if (method && method.toLowerCase() == "get") {
  11392. for (var i = 0; i < this._plugins.length; i++) {
  11393. var plg = this._plugins[i];
  11394. var ret = plg[1](args.url);
  11395. if (ret) {
  11396. // escape closure around the unnecessaries
  11397. return this._embedValidation(plg[2], ret);
  11398. }
  11399. }
  11400. }
  11401. return null;
  11402. },
  11403. register: function(/*String*/id, /*Function*/ plgMatcher, /*Function*/ plgResolver, /*Boolean?*/ first){
  11404. this._plugins[first ? "unshift" : "push"]([id, plgMatcher, plgResolver]);
  11405. },
  11406. unregister: function(/*String*/id){
  11407. for (var i = 0; i < this._plugins.length; i++) {
  11408. if (id === this._plugins[i][0]) {
  11409. this._plugins.splice(i, 1);
  11410. return;
  11411. }
  11412. }
  11413. }
  11414. });
  11415. com.ibm.mashups.services.ServiceManager.setService(com.ibm.mashups.enabler.io.DynamicResolver.SERVICE_NAME, "com.ibm.mm.enabler.io.DynamicResolver");
  11416. }
  11417. if(!dojo._hasResource["com.ibm.mashups.enabler.io.DynamicResolver"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  11418. dojo._hasResource["com.ibm.mashups.enabler.io.DynamicResolver"] = true;
  11419. dojo.provide("com.ibm.mashups.enabler.io.DynamicResolver");
  11420. }
  11421. if(!dojo._hasResource["com.ibm.mashups.enabler.io.XHRMultipart_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  11422. dojo._hasResource["com.ibm.mashups.enabler.io.XHRMultipart_API"] = true;
  11423. dojo.provide("com.ibm.mashups.enabler.io.XHRMultipart_API");
  11424. dojo.provide("com.ibm.mashups.enabler.io.XHRMultipart");
  11425. /**
  11426. * Provides Dojo XHR support. Requests are batched together via a transaction
  11427. * concept - Dojo XHR requests which are made between the start and end
  11428. * transaction calls will be batched. This would include any Dojo API's which would
  11429. * use Dojo XHR. If the com.ibm.mashups.multipart.correlatehosts
  11430. * Configuration Service property is set to true, multipart requests will be
  11431. * split by hostname.
  11432. * @ibm-api
  11433. * @ibm-module Base
  11434. */
  11435. dojo.declare("com.ibm.mashups.enabler.io.XHRMultipart", null, {
  11436. /**
  11437. * @private
  11438. */
  11439. constructor: function() {
  11440. },
  11441. /**
  11442. * Begins a multipart transaction. If the com.ibm.mashups.multipart.enabled
  11443. * property is set to false, this method simply returns.
  11444. * @type void
  11445. */
  11446. startTransaction: function() {
  11447. },
  11448. /**
  11449. * Ends a multipart transaction and submits the multipart request to
  11450. * the server. If the com.ibm.mashups.multipart.enabled
  11451. * property is set to false, this method simply returns.
  11452. * @return {DeferredOperation} a deferred object used to start this operation.
  11453. * The return value when executed through the deferred object is <code>null</null>
  11454. */
  11455. endTransactionDeferred: function() {
  11456. },
  11457. /**
  11458. * Ends a multipart transaction and submits the multipart request to
  11459. * the server. If the com.ibm.mashups.multipart.enabled
  11460. * property is set to false, this method simply returns.
  11461. * @param {Object} callback the callback funtion in the format of <code>Function(Object[] params)</code>. May be <code>null</code><br>
  11462. * &nbsp;&nbsp;&nbsp;&nbsp;<b>Callbackparameters</b><br>
  11463. * &nbsp;&nbsp;&nbsp;&nbsp;<code>params</code> - the parameters
  11464. * passed into the callback
  11465. * @param {Object[]} parameters optional array of parameters to be
  11466. * passed on to the callback function. May be <code>null</code>
  11467. * @type void
  11468. * @deprecated Use endTransactionDeferred instead.
  11469. */
  11470. endTransaction: function(callback, parameters) {
  11471. },
  11472. /**
  11473. * Suspends a mulitpart transaction, allowing normal XHR requests
  11474. * to be made. If the com.ibm.mashups.multipart.enabled
  11475. * property is set to false, this method simply returns.
  11476. * @type void
  11477. */
  11478. suspendTransaction: function() {
  11479. },
  11480. /**
  11481. * Resumes a mulitpart transaction. If the com.ibm.mashups.multipart.enabled
  11482. * property is set to false, this method simply returns.
  11483. * @type void
  11484. */
  11485. resumeTransaction: function() {
  11486. },
  11487. /**
  11488. * Returns if there is an active multipart transaction
  11489. * @return {Boolean} <code>true</code> if there is an active multipart
  11490. * transaction, <code>false</code> otherwise
  11491. */
  11492. isTransaction: function() {
  11493. return false;
  11494. }
  11495. });
  11496. }
  11497. if(!dojo._hasResource["com.ibm.mm.enabler.ServiceDocConsumer"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  11498. dojo._hasResource["com.ibm.mm.enabler.ServiceDocConsumer"] = true;
  11499. dojo.provide("com.ibm.mm.enabler.ServiceDocConsumer");
  11500. dojo.declare("com.ibm.mm.enabler.ServiceDocConsumer",null,{
  11501. _noop: function(){},
  11502. _initServiceDoc: function() {
  11503. this._initServiceDoc = this._noop; // turns this init into a noop for this object
  11504. }
  11505. });
  11506. }
  11507. if(!dojo._hasResource["com.ibm.mm.enabler.encode.huffman.ZEncoder"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  11508. dojo._hasResource["com.ibm.mm.enabler.encode.huffman.ZEncoder"] = true;
  11509. dojo.provide("com.ibm.mm.enabler.encode.huffman.ZEncoder");
  11510. dojo.declare("com.ibm.mm.enabler.encode.huffman.ZEncoder", null, {
  11511. HEX_CHARS: ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"],
  11512. UNSAFE_CHARS: "$&+,/:;=?@ <>#%{}|\\^~[]`\"Z",
  11513. constructor: function() {
  11514. },
  11515. isUnsafeChar: function(testChar) {
  11516. if (this.UNSAFE_CHARS.indexOf(testChar) > -1 || testChar.charCodeAt(0) <= 32 || testChar.charCodeAt(0) >= 123) {
  11517. return true;
  11518. }
  11519. return false;
  11520. },
  11521. zEncode: function(value) {
  11522. var retVal = "";
  11523. for (var i = 0; i < value.length; ++i) {
  11524. var currentChar = value.charAt(i);
  11525. if (!this.isUnsafeChar(currentChar)) {
  11526. retVal += currentChar;
  11527. continue;
  11528. }
  11529. retVal += this.zEncodeChar(currentChar);
  11530. }
  11531. return retVal;
  11532. },
  11533. zEncodeChar: function(plainChar) {
  11534. var magicChar = "Z";
  11535. return magicChar + this.byteToHex(plainChar.charCodeAt(0));
  11536. },
  11537. byteToHex: function(byteValue) {
  11538. var upper = Math.floor(byteValue / 16);
  11539. var lower = byteValue % 16;
  11540. return this.HEX_CHARS[upper] + this.HEX_CHARS[lower];
  11541. },
  11542. zDecode: function(value) {
  11543. var retVal = "";
  11544. var magicChar = "Z";
  11545. if (value.indexOf(magicChar) != -1) {
  11546. for (var i = 0, l = value.length; i < l; i++) {
  11547. var charX = value.charAt(i);
  11548. if (charX == magicChar) {
  11549. var hex = "0x" + value.substr(i + 1, 2);
  11550. i = i + 2;
  11551. try {
  11552. var charCode = parseInt(hex,16);
  11553. retVal = retVal.concat(String.fromCharCode(charCode));
  11554. }
  11555. catch (e) {
  11556. continue;
  11557. }
  11558. }
  11559. else {
  11560. retVal = retVal.concat(value.substr(i, 1)); //concat character
  11561. }
  11562. }
  11563. }
  11564. else {
  11565. retVal = value;
  11566. }
  11567. return retVal;
  11568. }
  11569. });
  11570. com.ibm.mm.enabler.encode.huffman.ZEncoder = new com.ibm.mm.enabler.encode.huffman.ZEncoder();
  11571. }
  11572. if(!dojo._hasResource["com.ibm.mm.enabler.encode.huffman.HuffmanURL"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  11573. dojo._hasResource["com.ibm.mm.enabler.encode.huffman.HuffmanURL"] = true;
  11574. dojo.provide("com.ibm.mm.enabler.encode.huffman.HuffmanURL");
  11575. dojo.declare("com.ibm.mm.enabler.encode.huffman.HuffmanURL", null, {
  11576. // alphabet used for base64 encoding, this is NOT the default base64 alphabet but an alphabet that only contains URL safe characters
  11577. URL_ALPHABET: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_!",
  11578. constructor: function() {
  11579. },
  11580. /** Encodes the huffman codes of the tokens in the alphabet into a stream
  11581. * @param the target stream
  11582. * @param the map between token and prefix
  11583. * @param the array of tokens to encode
  11584. */
  11585. _encodeTokens: function(stream, nodes, tokens) {
  11586. // iterate over all tokens
  11587. var len = tokens.length;
  11588. for (var i = 0; i < len; ++i) {
  11589. // add the code for the token
  11590. this._addBits(stream, nodes[tokens[i]].prefix);
  11591. }
  11592. // return the stream
  11593. return this._encodeStream(stream);
  11594. },
  11595. /** Encodes the dwords in the stream into a base64 encoded string
  11596. *
  11597. * @param stream stream to encode
  11598. * @return a string of the base64 encoded dwords
  11599. */
  11600. _encodeStream: function(stream) {
  11601. // number of bytes to encode
  11602. var len = stream.dwords.length * 4;
  11603. // push the last dword
  11604. if (stream.bits > 0) {
  11605. // add the last dword
  11606. stream.dwords.push(stream.dword);
  11607. // update the length
  11608. len += ((stream.bits + 0x07) >> 0x03);
  11609. stream.bits = 0;
  11610. }
  11611. // compute the number of bytes and encode
  11612. return this._encodeBase64(stream.dwords, 0, len);
  11613. },
  11614. /* Initializes the stream object
  11615. * @param stream the stream to be initialized
  11616. * @return the actual stream
  11617. */
  11618. _initStream: function(stream) {
  11619. // reset the masks and the current dword
  11620. stream.dword = 0;
  11621. stream.mask = 1;
  11622. stream.bits = 0;
  11623. // start with an empty array of encoded dwords
  11624. stream.dwords = [];
  11625. // the stream
  11626. return stream;
  11627. },
  11628. /* Encode an array of 0/1 values that are stored in the data array into a sequence of 32 bit values stored
  11629. * in the stream.
  11630. *
  11631. * @param stream target stream that contains a dword array
  11632. * @param data the data array of 0/1 values to be encoded
  11633. */
  11634. _addBits: function(stream, data) {
  11635. // cache the data in local variables and save it back to the stream object at the end
  11636. var mask = stream.mask, dword = stream.dword, bits = stream.bits;
  11637. // add all bits sequentially
  11638. var len = data.length, off = 0;
  11639. while (len > 0) {
  11640. // check how many bits we can add in a batch
  11641. var copy = Math.min(len, 0x20 - bits);
  11642. for (var i = 0; i < copy; ++i) {
  11643. // add the bit
  11644. if (data[off + i] == 1) {
  11645. dword |= mask;
  11646. }
  11647. mask <<= 1;
  11648. }
  11649. // update
  11650. bits += copy;
  11651. len -= copy;
  11652. off += copy;
  11653. // check for an overflow
  11654. if (bits == 0x20) {
  11655. // add the new word
  11656. stream.dwords.push(dword);
  11657. bits = 0;
  11658. mask = 1;
  11659. dword = 0;
  11660. }
  11661. }
  11662. // update the object
  11663. stream.mask = mask;
  11664. stream.bits = bits;
  11665. stream.dword = dword;
  11666. },
  11667. /* Adds a single bit (0/1) to the the stream
  11668. * @param stream target stream that contains a dword array
  11669. * @param bit to be encoded, must be 1 or 0
  11670. */
  11671. _addBit: function(stream, bit) {
  11672. // add to the dword
  11673. if (bit == 1) {
  11674. stream.dword |= stream.mask;
  11675. }
  11676. stream.mask <<= 1;
  11677. stream.bits++;
  11678. // check for the max mask
  11679. if (stream.bits == 0x20) {
  11680. // add the dword to the list
  11681. stream.dwords.push(stream.dword);
  11682. stream.dword = 0;
  11683. stream.mask = 1;
  11684. stream.bits = 0;
  11685. }
  11686. },
  11687. /** encodes the data into base64 format, the data is packed in 32bit integer values in little endian notation.
  11688. * Offset and length refer to the actual bytes, not the dwords. */
  11689. _encodeBase64: function(data, off, len) {
  11690. // cache the alphabet
  11691. var ab = this.URL_ALPHABET;
  11692. // starting dword and offset of the byte inside the dword
  11693. var srcIdx = off >> 0x02;
  11694. var shift = off & 0x03;
  11695. // the current dword and a place holder for the next (wrapping) dword
  11696. var value = data[srcIdx++], newValue;
  11697. // the four 6-bit numbers that we decode from three consequtive bytes
  11698. var c1, c2, c3, c4;
  11699. // the resulting base64 encoding
  11700. var result = "";
  11701. // iterate over the range of bytes in three-byte tuples
  11702. for (var i = len; i > 0; i -= 3) {
  11703. /** get the next three bytes. We use direct bit operations based on the packing.
  11704. */
  11705. switch (shift) {
  11706. case 0:
  11707. // all bytes are available inside the dword
  11708. c1 = ((value >> 0x02) & 0x3f);
  11709. c2 = ((value << 0x04) & 0x30) | ((value >> 0x0c) & 0x0f);
  11710. c3 = ((value >> 0x06) & 0x3c) | ((value >> 0x16) & 0x03);
  11711. c4 = ((value >> 0x10) & 0x3f);
  11712. // next shift
  11713. shift = 3;
  11714. break;
  11715. case 1:
  11716. // all bytes are available inside the dword
  11717. c1 = ((value >> 0x0a) & 0x3f);
  11718. c2 = ((value >> 0x04) & 0x30) | ((value >> 0x14) & 0x0f);
  11719. c3 = ((value >> 0x0e) & 0x3c) | ((value >> 0x1e) & 0x03);
  11720. c4 = ((value >> 0x18) & 0x3f);
  11721. // next shift
  11722. shift = 0;
  11723. value = data[srcIdx++];
  11724. break;
  11725. case 2:
  11726. // wrap around to the next dword
  11727. newValue = data[srcIdx++];
  11728. c1 = ((value >> 0x12) & 0x3f);
  11729. c2 = ((value >> 0x0c) & 0x30) | ((value >> 0x1c) & 0x0f);
  11730. c3 = ((value >> 0x16) & 0x3c) | ((newValue >> 0x06) & 0x03);
  11731. c4 = (newValue & 0x3f);
  11732. // next shift
  11733. value = newValue;
  11734. shift = 1;
  11735. break;
  11736. case 3:
  11737. // wrap around to the next dword
  11738. newValue = data[srcIdx++];
  11739. c1 = ((value >> 0x1A) & 0x3f);
  11740. c2 = ((value >> 0x14) & 0x30) | ((newValue >> 0x04) & 0x0f);
  11741. c3 = ((newValue << 0x02) & 0x3c) | ((newValue >> 0x0e) & 0x03);
  11742. c4 = ((newValue >> 0x08) & 0x3f);
  11743. // next shift
  11744. value = newValue;
  11745. shift = 2;
  11746. break;
  11747. }
  11748. // padding
  11749. switch (i) {
  11750. case 1:
  11751. c3 = 0x40;
  11752. c4 = 0x40;
  11753. break;
  11754. case 2:
  11755. c4 = 0x40;
  11756. break;
  11757. }
  11758. // construct the 4-character tuple
  11759. result += ab.charAt(c1);
  11760. result += ab.charAt(c2);
  11761. result += ab.charAt(c3);
  11762. result += ab.charAt(c4);
  11763. }
  11764. // return the result of the encoding process
  11765. return result;
  11766. },
  11767. //decode encoded string
  11768. //conver 4 byte into 3
  11769. //return an array of charcode
  11770. //first item in the array should be the right most in bit stream...
  11771. _decodeBase64: function(encodedStr) {
  11772. var ab = this.URL_ALPHABET;
  11773. var len = encodedStr.length / 4;
  11774. var i = 0;
  11775. var array = []; //each array item contains 3 char
  11776. for (var j = 0; j < len; j++) {
  11777. var padding = 0;
  11778. indexC1 = ab.indexOf(encodedStr.charAt(i++));
  11779. indexC2 = ab.indexOf(encodedStr.charAt(i++));
  11780. indexC3 = ab.indexOf(encodedStr.charAt(i++));
  11781. if (indexC3 == 64) {
  11782. padding++;
  11783. }
  11784. indexC4 = ab.indexOf(encodedStr.charAt(i++));
  11785. if (indexC4 == 64) {
  11786. padding++;
  11787. }
  11788. c1 = (indexC1 << 2) | (indexC2 >> 4); //this is the last byte (from right)
  11789. c2 = ((indexC2 & 15) << 4) | (indexC3 >> 2); //this is the middle byte
  11790. c3 = ((indexC3 & 3) << 6) | indexC4; //this is the byte on the left
  11791. array.push(c1);
  11792. switch (padding) {
  11793. case 0:
  11794. array.push(c2);
  11795. array.push(c3);
  11796. break;
  11797. case 1:
  11798. array.push(c2);
  11799. break;
  11800. case 2:
  11801. break;
  11802. }
  11803. }
  11804. return array;
  11805. },
  11806. /** Callback used by the sort method to compare nodes by frequency
  11807. */
  11808. _frequencyCompare: function(n1, n2) {
  11809. return n1.frequency - n2.frequency;
  11810. },
  11811. /** Initializes the encoding and the prefixes of the huffman tree. The
  11812. * method writes the tree structure as a bit sequence into the stream and
  11813. * initializes the node prefixes with the huffman code.
  11814. *
  11815. * @param stream the stream that contains the tree structure and the sequence of the node names
  11816. * @param node the current node in the tree to encode
  11817. * @param prefix the huffman prefix of the parent node, an array that contains 0/1 bits
  11818. */
  11819. _initTree: function(stream, node, prefix) {
  11820. // iterate into the children
  11821. if (node.left && node.right) {
  11822. // add to the stream
  11823. this._addBit(stream, 1);
  11824. // recurse the left and right branch
  11825. this._initTree(stream, node.left, prefix.concat(0));
  11826. this._initTree(stream, node.right, prefix.concat(1));
  11827. }
  11828. else {
  11829. // add to the stream
  11830. this._addBit(stream, 0);
  11831. // this is our huffman code!
  11832. node.prefix = prefix;
  11833. // add this node
  11834. stream.tokens.push(node.name);
  11835. }
  11836. // ok
  11837. return stream;
  11838. },
  11839. _dumpTokens: function(tree, nodes) {
  11840. },
  11841. /** Constructs the huffman tree from the token sequence
  11842. *
  11843. * @param array of tokens
  11844. * @return the URL that encodes the tokens
  11845. */
  11846. _buildTree: function(tokens) {
  11847. // build a list of token frequencies
  11848. var nodes = {};
  11849. // iterate and fill the node map
  11850. var len = tokens.length;
  11851. var node, i;
  11852. for (i = len - 1; i >= 0; --i) {
  11853. // do we know the node?
  11854. var token = tokens[i];
  11855. node = nodes[token];
  11856. if (node) {
  11857. // increment the frequency of the node
  11858. node.frequency++;
  11859. }
  11860. else {
  11861. // construct the new token
  11862. node = {
  11863. frequency: 1,
  11864. name: token
  11865. };
  11866. // add the node
  11867. nodes[token] = node;
  11868. }
  11869. }
  11870. // produce a sorted list based on the frequencies
  11871. var queue = [];
  11872. for (node in nodes) {
  11873. if (Object.prototype.hasOwnProperty.call(nodes,node)) {
  11874. queue.push(nodes[node]);
  11875. }
  11876. }
  11877. queue.sort(this._frequencyCompare);
  11878. // build the huffman tree
  11879. while (queue.length > 1) {
  11880. // remove the smallest items
  11881. var left = queue.shift(), right = queue.shift();
  11882. // construct the new, combined node
  11883. queue.push({
  11884. frequency: left.frequency + right.frequency,
  11885. left: left,
  11886. right: right
  11887. });
  11888. queue.sort(this._frequencyCompare);
  11889. }
  11890. // now, we have the tree, initialize its huffman codes
  11891. var root = queue[0];
  11892. var tree = this._initTree(this._initStream({
  11893. tokens: []
  11894. }), queue.shift(), []);
  11895. this._dumpTokens(tree, nodes);
  11896. // serialize the tree into a prefix
  11897. var url = this._encodeStream(tree);
  11898. // append the tokens
  11899. len = tree.tokens.length;
  11900. for (i = 0; i < len; ++i) {
  11901. url += "/" + com.ibm.mm.enabler.encode.huffman.ZEncoder.zEncode(tree.tokens[i]);
  11902. }
  11903. // serialize the huffman codes
  11904. url += "/" + this._encodeTokens(this._initStream({}), nodes, tokens);
  11905. // return the url
  11906. return url;
  11907. },
  11908. /** Constructs the huffman tree from a data string an a regular expression that splits
  11909. * the string into tokens. The delimiters are considered part of the tokens.
  11910. * @param data the data string to split
  11911. * @param regexStrg the regular expression string, e.g. "[\/\.<>]"
  11912. *
  11913. * @return the encoded URL
  11914. */
  11915. _buildTreeFromRegex: function(data, regexStrg) {
  11916. // compile the regex
  11917. var regex = new RegExp(regexStrg, "g");
  11918. // record the split positions
  11919. var pos = [];
  11920. var result;
  11921. while ((result = regex.exec(data))) {
  11922. pos.push(result.index);
  11923. }
  11924. // padding
  11925. if (pos[0]) {
  11926. pos.unshift(0);
  11927. }
  11928. if (pos[pos.length - 1] != data.length) {
  11929. pos.push(data.length);
  11930. }
  11931. // split
  11932. var tokens = [];
  11933. for (result = 1; result < pos.length; ++result) {
  11934. tokens.push(data.substring(pos[result - 1], pos[result]));
  11935. }
  11936. // construct the URL
  11937. return this._buildTree(tokens);
  11938. },
  11939. /** Constructs the huffman tree from the token sequence
  11940. *
  11941. * @param array of tokens
  11942. * @return the URL that encodes the tokens
  11943. */
  11944. createRawSchemeSpecificPartFromTokens: function(tokens) {
  11945. return this._buildTree(tokens);
  11946. },
  11947. /** Constructs the huffman tree from a data string an a regular expression that splits
  11948. * the string into tokens. The delimiters are considered part of the tokens.
  11949. * @param data the data string to split
  11950. * @param regexStrg the regular expression string, e.g. "[\/\.<>]"
  11951. *
  11952. * @return the encoded URL
  11953. */
  11954. createRawSchemeSpecificPartFromRegex: function(data, regexStrg) {
  11955. return this._buildTreeFromRegex(data, regexStrg);
  11956. },
  11957. /** Restores data from the encoded huffman tree based on the token sequence
  11958. * @param url encoded data
  11959. * @return the data string that's decoded from huffman tree
  11960. */
  11961. getDataFromHuffmanTree: function(tree) {
  11962. return this._restoreData(tree);
  11963. },
  11964. _restoreData: function(tree) {
  11965. if (!tree) {
  11966. return null;
  11967. }
  11968. var i0 = tree.indexOf("/");
  11969. var i1 = tree.lastIndexOf("/");
  11970. if ((i0 >= 0) && (i1 >= 0)) {
  11971. var treeStream = this._decodeBase64(tree.substring(0, i0));
  11972. var encodedToken = tree.substring(i0 + 1, i1).split("/");
  11973. var codeStream = this._decodeBase64(tree.substring(i1 + 1));
  11974. //array of decoded tokens
  11975. encodedTokens = this._decodeTokens(encodedToken);
  11976. //build tree with token
  11977. var root = this._readStructure(this._convertBitToChar(treeStream), encodedTokens);
  11978. var bitArr = this._convertBitToChar(codeStream);
  11979. var retVal = "";
  11980. while (bitArr.length > 0) {
  11981. retVal = this._buildData(retVal, bitArr, root);
  11982. }
  11983. return retVal;
  11984. }
  11985. return null;
  11986. },
  11987. _buildData: function(retVal, bitArr, root) {
  11988. var found = false;
  11989. var node = null;
  11990. while (!found) {
  11991. var bit = bitArr.shift();
  11992. if (typeof bit == "undefined") {
  11993. node = null;
  11994. break;
  11995. }
  11996. node = this._getNode(bit, root);
  11997. if (node && node.token && node.token) {
  11998. found = true;
  11999. }
  12000. else if (!node) {
  12001. found = true;
  12002. }
  12003. root = node;
  12004. }
  12005. if (found && node) {
  12006. retVal = retVal.concat(node.token);
  12007. }
  12008. return retVal;
  12009. },
  12010. _getNode: function(bit, parent) {
  12011. //0 --left, 1--right
  12012. var node = null;
  12013. node = (bit == 1) ? parent.right : parent.left;
  12014. if (!node) {
  12015. return null;
  12016. }
  12017. return node;
  12018. },
  12019. _convertBitToChar: function(charCodeArr) {
  12020. var arr = [];
  12021. var mask = 0x01;
  12022. var bit = 0;
  12023. for (var i = 0; i < charCodeArr.length; i++) {
  12024. var charCode = charCodeArr[i];
  12025. for (var j = 0; j < 8; j++) {
  12026. bit = charCode & mask;
  12027. arr.push(bit);
  12028. charCode = (charCode >> 1); //remove 1 bit
  12029. }
  12030. }
  12031. return arr;
  12032. },
  12033. _readStructure: function(charArr, encodedTokens) {
  12034. var bit = charArr.shift();
  12035. var node = {};
  12036. if (bit == 1) { // internal node
  12037. node.left = this._readStructure(charArr, encodedTokens);
  12038. node.right = this._readStructure(charArr, encodedTokens);
  12039. }
  12040. else { //leaf node
  12041. var token = encodedTokens.shift();
  12042. node.token = token;
  12043. }
  12044. return node;
  12045. },
  12046. // an array of tokens try to zDecode it
  12047. _decodeTokens: function(encodedToken) {
  12048. var arr = [];
  12049. for (var i in encodedToken) {
  12050. if (Object.prototype.hasOwnProperty.call(encodedToken,i)) {
  12051. arr.push(com.ibm.mm.enabler.encode.huffman.ZEncoder.zDecode(encodedToken[i]));
  12052. }
  12053. }
  12054. return arr;
  12055. }
  12056. });
  12057. com.ibm.mm.enabler.encode.huffman.HuffmanURL = new com.ibm.mm.enabler.encode.huffman.HuffmanURL();
  12058. }
  12059. if(!dojo._hasResource["com.ibm.mm.enabler.ArrayMap"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  12060. dojo._hasResource["com.ibm.mm.enabler.ArrayMap"] = true;
  12061. dojo.provide("com.ibm.mm.enabler.ArrayMap");
  12062. dojo.declare("com.ibm.mm.enabler.ArrayMap", null, {
  12063. constructor: function(){
  12064. this.entries = [];
  12065. this.keys = {};
  12066. },
  12067. values: function(){
  12068. return this.entries;
  12069. },
  12070. put: function(/*String*/key,/*object*/ value){
  12071. var index = this.keys[key];
  12072. if (typeof index != 'undefined' && index !== null) {
  12073. this.entries[index] = value;
  12074. }
  12075. else {
  12076. index = this.entries.length;
  12077. this.entries.push(value);
  12078. this.keys[key] = index;
  12079. }
  12080. },
  12081. getKey: function(index){
  12082. if (index < this.entries.length) {
  12083. for (var key in this.keys) {
  12084. if(Object.prototype.hasOwnProperty.call(this.keys,key)) {
  12085. var temp = this.keys[key];
  12086. if (temp !== null && temp == index) {
  12087. return temp;
  12088. }
  12089. }
  12090. }
  12091. }
  12092. else {
  12093. return null;
  12094. }
  12095. },
  12096. getValue: function(index){
  12097. return (index < this.entries.length) ? this.entries[index] : null;
  12098. },
  12099. get: function(key){
  12100. var index = this.keys[key];
  12101. if (typeof index != 'undefined' && index !== null) {
  12102. var value = this.entries[index];
  12103. return value;
  12104. }
  12105. return null;
  12106. },
  12107. remove: function(key){
  12108. var index = this.keys[key];
  12109. if (typeof index != 'undefined' && index !== null) {
  12110. this.entries.splice(index, 1);
  12111. this.keys[key] = null;
  12112. }
  12113. return index;
  12114. },
  12115. size: function(){
  12116. return this.entries.length;
  12117. },
  12118. keySet: function(){
  12119. var arr = [];
  12120. com.ibm.mm.enabler.utils.Misc.forIn(this.keys,function(value,key) {
  12121. arr.push(key);
  12122. });
  12123. return arr;
  12124. }
  12125. });
  12126. }
  12127. if(!dojo._hasResource["com.ibm.mm.enabler.io.XHRMultipartImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  12128. dojo._hasResource["com.ibm.mm.enabler.io.XHRMultipartImpl"] = true;
  12129. dojo.provide("com.ibm.mm.enabler.io.XHRMultipartImpl");
  12130. dojo.declare("com.ibm.mm.enabler.io.XHRMultipartImpl", [com.ibm.mashups.enabler.io.XHRMultipart, com.ibm.mm.enabler.ServiceDocConsumer], {
  12131. DYN_RES: com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.io.DynamicResolver.SERVICE_NAME),
  12132. statics: {
  12133. semaphore: 0,
  12134. digest: null,
  12135. suspendedXhr: null
  12136. },
  12137. constructor: function() {
  12138. this.method = "POST";
  12139. this.partsArray = null;
  12140. var configService = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);
  12141. this.correlateHosts = configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.MULTIPART_CORRELATE_HOSTS);
  12142. this.correlatedHosts = null;
  12143. this.cacheQueries = false;
  12144. var cacheQueriesConfig = configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.MULTIPART_CACHE_QUERIES);
  12145. if (typeof(cacheQueriesConfig) !== "undefined" && cacheQueriesConfig !== null && cacheQueriesConfig === true) {
  12146. this.cacheQueries = true;
  12147. }
  12148. this.privateUrl = configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.CONTEXT_ROOT) +
  12149. configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.CONTENTHANDLER_PRIVATE);
  12150. this.publicUrl = configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.CONTEXT_ROOT) +
  12151. configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.CONTENTHANDLER_PUBLIC);
  12152. this.doSiteMap = true;
  12153. this.urlMaxLength = 2000;
  12154. // unique (arbitrary) boundary
  12155. this.boundary = "{EB2F8DA2-5B2C-F66A-CDD0-A2D42143F5AC}";
  12156. this.newL = "\r\n";
  12157. this.sep = "--";
  12158. this.startB = this.newL + this.sep + this.boundary + this.newL;
  12159. this.endB = this.sep + this.boundary + this.sep + this.newL;
  12160. // used to capture the header
  12161. //this.headerRegx = /\r\n\s*([^\r]*)\s*/mg;
  12162. this.headerRegx = new RegExp(this.newL + "\s*([^\r]*)\s*", "mg");// JSLINT-IGNORE: Enabler Team decided to keep this paradigma from dojo in tact
  12163. this.headerPartsRegx = /\s*([^:]*):\s*(.+)/;
  12164. // used to find the boundary
  12165. this.boundaryRegx = /boundary\s*=\s*\"?([^\"]*)\"?/;
  12166. this.multipartParts = false;
  12167. this.replaceDigest = false;
  12168. this.digest = null;
  12169. },
  12170. _initServiceDoc: function() {
  12171. this.inherited("_initServiceDoc", arguments);
  12172. this.doMultipart = com.ibm.mashups.enabler.io.XHRMultipartFactory.isMultipartEnabled();
  12173. if(this.doMultipart) {
  12174. this.serviceMPJson = com.ibm.mm.enabler.model.ServiceDocumentModel.getCollectionData([com.ibm.mm.enabler.model.ServiceDocumentModel.SERVICE_MODEL, com.ibm.mm.enabler.model.ServiceDocumentModel.SERVICE_MULTIPART]);
  12175. this.serviceSMJson = com.ibm.mm.enabler.model.ServiceDocumentModel.getCollectionData([com.ibm.mm.enabler.model.ServiceDocumentModel.SERVICE_MODEL, com.ibm.mm.enabler.model.ServiceDocumentModel.SERVICE_HUFFMAN]);
  12176. this.serviceCHJson = com.ibm.mm.enabler.model.ServiceDocumentModel.getCollectionData([com.ibm.mm.enabler.model.ServiceDocumentModel.SERVICE_MODEL, com.ibm.mm.enabler.model.ServiceDocumentModel.SERVICE_SITEMAP_COMMITHANDLER]);
  12177. }
  12178. },
  12179. _partHandler: function(partArgs, responsePart, ioArgs, partHeaders) {
  12180. var work = dojo.hitch(partArgs, function() {
  12181. try {
  12182. if (com.ibm.mm.enabler.utils.Misc.isInstanceOf(responsePart, Error)) {
  12183. if (this.error) {
  12184. this.error(responsePart, ioArgs, partHeaders);
  12185. }
  12186. }
  12187. else if (ioArgs.xhr.status >= 400) {
  12188. if (this.error) {
  12189. this.error(new Error(ioArgs.xhr.status + ": " + partHeaders.URI), ioArgs, partHeaders);
  12190. }
  12191. }
  12192. else {
  12193. if (this.load) {
  12194. this.load(responsePart, ioArgs, partHeaders);
  12195. }
  12196. }
  12197. // always call the handle function if it exists
  12198. if (this.handle) {
  12199. this.handle(responsePart, ioArgs, partHeaders);
  12200. }
  12201. }
  12202. catch (err) {
  12203. // make one attempt to call the error handler
  12204. try {
  12205. if (this.error) {
  12206. this.error(responsePart, ioArgs, partHeaders);
  12207. }
  12208. }
  12209. catch (err2) {
  12210. //noop
  12211. }
  12212. }
  12213. }); // JSLINT-IGNORE: Enabler Team decided to keep this paradigma from dojo in tact
  12214. work();
  12215. },
  12216. _handleMultiPartResponse: function(parts, multipartParts, scope, response, ioArgs) {
  12217. // Getting the Content-Type header from the response, and extract
  12218. // the boundary string
  12219. var contentType = ioArgs.xhr.getResponseHeader("Content-Type");
  12220. var boundMatch = contentType.match(scope.boundaryRegx);
  12221. if (!boundMatch) {
  12222. throw new Error("No boundary specified in Content-Type response header");
  12223. }
  12224. var bound = boundMatch[1];
  12225. var stripPossibleCharSetIndex = bound.indexOf(";");
  12226. if (stripPossibleCharSetIndex!=-1) {
  12227. bound = bound.substring(0,stripPossibleCharSetIndex);
  12228. }
  12229. // build a regx from the response boundary string used to split the parts
  12230. var splitterRegx = new RegExp(scope.newL + scope.sep + bound, "mg");
  12231. var respParts = response.split(splitterRegx);
  12232. // if handleAs is xml, it comes as text so build it using the domUtilities
  12233. // iterate through the response parts, handling the callbacks for each
  12234. var mpHandler = null;
  12235. if (multipartParts) {
  12236. mpHandler = new com.ibm.mm.enabler.io.XHRMultipartImpl();
  12237. mpHandler.startTransaction();
  12238. }
  12239. var i = 1;
  12240. for (var current in parts) {
  12241. if (Object.prototype.hasOwnProperty.call(parts, current)) {
  12242. var partArgs = parts[current];
  12243. for (var x = 0, l = partArgs.length; x<l; x++) {
  12244. var requestArgs = partArgs[x];
  12245. var part = respParts[i++];
  12246. var partHeaders = {};
  12247. var header = null;
  12248. var statusCodeText = null;
  12249. var contentType = null;
  12250. scope.headerRegx.lastIndex = 0;
  12251. // extract the headers for this part, stopping at the blank line
  12252. while ((header = scope.headerRegx.exec(part)) !== null && (header[1].length > 0)) {
  12253. // ensure bad headers are not allowed through
  12254. if (-1 == header[1].indexOf(":")) {
  12255. continue;
  12256. }
  12257. if (-1 == header[1].indexOf("digest=")) {
  12258. var headerParts = header[1].match(scope.headerPartsRegx);
  12259. partHeaders[headerParts[1]] = headerParts[2];
  12260. if (headerParts[1] == "X-Status-Code") {
  12261. statusCodeText = headerParts[2];
  12262. }
  12263. else if (headerParts[1] == "Content-Type") {
  12264. contentType = headerParts[2];
  12265. }
  12266. }
  12267. }
  12268. part = dojo.string.trim(part.substr(scope.headerRegx.lastIndex + scope.newL.length));
  12269. var partString = part;
  12270. if (requestArgs.handleAs == "xml") {
  12271. // create document object from text string
  12272. part = com.ibm.mm.enabler.utils.Dom.createDocument(part);
  12273. }
  12274. else {
  12275. // call the appropriate content handler for this part
  12276. // dojo.contentHandlers is public since Dojo 1.4
  12277. part = dojo.contentHandlers[requestArgs.handleAs]({
  12278. responseText: part
  12279. });
  12280. }
  12281. // Set the appropriate status code
  12282. var statusCode = parseInt(statusCodeText, 10);
  12283. var xhrWrapper = new com.ibm.mm.enabler.io.XHRWrapper(ioArgs, partString, statusCode, contentType, partHeaders);
  12284. var xhr = ioArgs.xhr;
  12285. ioArgs.xhr = xhrWrapper;
  12286. scope._partHandler(requestArgs, part, ioArgs, partHeaders);
  12287. ioArgs.xhr = xhr;
  12288. }
  12289. }
  12290. }
  12291. if (multipartParts) {
  12292. mpHandler.endTransactionDeferred().start();
  12293. }
  12294. },
  12295. _multiPartXhr: function( /*String*/method, /*dojo.__XhrArgs*/ args, /*Array*/ parts, /*boolean*/ multipartParts) {
  12296. // summary: Sends a request with a multi-part body (and content type) to
  12297. // the server. Uses dojo.xhr functions under the covers, so the args
  12298. // object has the same structure as what those functions expect.
  12299. // The main difference is that this function builds the raw post or put
  12300. // data automatically from the parts array. Each item in the parts array
  12301. // is an object which is a subset of the dojo.__XhrArgs type. The callbacks
  12302. // should be specified per part as this function will provide a general
  12303. // callback that parses the multi-part response and calls the callback
  12304. // associated with that response part provided in the parts array.
  12305. // method: String specifying the HTTP method used. Must be either POST or PUT.
  12306. // Default is POST.
  12307. // args: dojo.__XhrArgs specifying how this XHR should be handled. The following
  12308. // properties are not used since they do not make sense in this context -
  12309. // [form, handle, load, content, handleAs]
  12310. // parts: Array the multiple parts to use to build the multi-part request body.
  12311. // Each item in the array should be an object with these properties -
  12312. // {
  12313. // headers: Object key-value map which is used to write out a
  12314. // section at the top of this part in the form key: value.
  12315. // Example could be Content-Type of this part of the multi-part
  12316. // request.
  12317. // data: String text to write out the body of this part
  12318. // load: function(response, ioArgs){} callback called where
  12319. // the response body is the body of the part associated this
  12320. // request part
  12321. // error: function(response, ioArgs){} callback called when
  12322. // a failure occurs either in the transmission or from the
  12323. // server
  12324. // handle: function(response, ioArgs){} callback called at the
  12325. // end of this request with either the response or an error
  12326. // if one occured
  12327. // handleAs: String value indicating how the response body of this
  12328. // part should be handled
  12329. // }
  12330. // returns: Deferred object which can be used to attach additional callbacks to
  12331. var body = "";
  12332. var headersStr = null;
  12333. for (var current in parts) {
  12334. if (Object.prototype.hasOwnProperty.call(parts, current)) {
  12335. for (var entry in parts[current]) {
  12336. if (Object.prototype.hasOwnProperty.call(parts[current], entry)) {
  12337. var part = parts[current][entry];
  12338. part.handleAs = part.handleAs ? part.handleAs.toLowerCase() : "text";
  12339. headersStr = "";
  12340. for (var x in part.headers) {
  12341. if (Object.prototype.hasOwnProperty.call(part.headers, x)) {
  12342. headersStr += x + ": " + part.headers[x] + this.newL;
  12343. }
  12344. }
  12345. body += this.startB + headersStr + this.newL;
  12346. if (part.data && part.data.length > 1) {
  12347. body += part.data + this.newL;
  12348. }
  12349. else if (part.postData && part.postData.length > 1) {
  12350. body += part.postData + this.newL;
  12351. }
  12352. else if (part.putData && part.putData.length > 1) {
  12353. body += part.putData + this.newL;
  12354. }
  12355. }
  12356. }
  12357. }
  12358. }
  12359. body += this.endB;
  12360. // if method is PUT, leave it be; otherwise set it to POST
  12361. if (method.toUpperCase() != "PUT") {
  12362. method = "POST";
  12363. }
  12364. var me = this;
  12365. var status;
  12366. var xhrArgs = dojo.mixin({}, args, {
  12367. load: function(response, ioArgs) {
  12368. me._handleMultiPartResponse(parts, multipartParts, me, response, ioArgs);
  12369. status = ioArgs.xhr.status;
  12370. },
  12371. error: function(response, ioArgs) {
  12372. dojo.forEach(parts, function(part) {
  12373. for (var x = 0, l = part.length; x<l; x++) {
  12374. var requestArgs = part[x];
  12375. me._partHandler(requestArgs, response, ioArgs, null);
  12376. }
  12377. });
  12378. status = ioArgs.xhr.status;
  12379. },
  12380. headers: {
  12381. "Content-type": 'multipart/mixed; boundary="' + me.boundary + '"'
  12382. },
  12383. handleAs: "text",
  12384. form: null,
  12385. content: null,
  12386. postData: null,
  12387. putData: null
  12388. });
  12389. xhrArgs[method.toLowerCase() + "Data"] = body;
  12390. dojo.xhr(method, xhrArgs, true);
  12391. return status;
  12392. },
  12393. suspendTransaction: function() {
  12394. if (0 === this.statics.semaphore) {
  12395. return;
  12396. }
  12397. if (this.statics.suspendedXhr) {
  12398. return;
  12399. }
  12400. this.statics.suspendedXhr = dojo.xhr;
  12401. dojo.xhr = this.statics.oldXhr;
  12402. },
  12403. resumeTransaction: function() {
  12404. if (0 === this.statics.semaphore) {
  12405. return;
  12406. }
  12407. if (!this.statics.suspendedXhr) {
  12408. return;
  12409. }
  12410. dojo.xhr = this.statics.suspendedXhr;
  12411. this.statics.suspendedXhr = null;
  12412. },
  12413. startTransaction: function() {
  12414. this._initServiceDoc();
  12415. if (!this.doMultipart) {
  12416. return;
  12417. }
  12418. this._acquire();
  12419. // return if another handler is in use
  12420. if (1 < this.statics.semaphore) {
  12421. return;
  12422. }
  12423. if (this.correlateHosts) {
  12424. this.correlatedHosts = new com.ibm.mm.enabler.ArrayMap();
  12425. }
  12426. else {
  12427. this.partsArray = [];
  12428. }
  12429. this.statics.oldXhr = dojo.xhr;
  12430. dojo.xhr = dojo.hitch(this, function(/* String */method, /* dojo.__XhrArgs */ args, /* Boolean */ hasBody) {
  12431. var dfd;
  12432. // DynamicResolver will catch this underneath
  12433. if (args.sync) {
  12434. dfd = this.statics.oldXhr(method, args, hasBody);
  12435. return dfd;
  12436. }
  12437. // explicit DynamicResolver support since we may circumvent its
  12438. // wrapped dojo.xhr
  12439. var res = this.DYN_RES.getResolver.apply(this.DYN_RES, arguments);
  12440. if(res) {
  12441. dfd = res.apply(this, arguments);
  12442. return dfd;
  12443. }
  12444. // Create a header for our method
  12445. var _targetURL = new com.ibm.mm.enabler.utils.HttpUrl(args.url);
  12446. var contentIdHeader = _targetURL.getParameter("uri");
  12447. if (this.doSiteMap && method != "GET") {
  12448. this.doSiteMap = false;
  12449. }
  12450. else if (this.doSiteMap && (!this.cacheQueries) && (method == "GET") &&
  12451. (contentIdHeader) &&
  12452. (null !== contentIdHeader)) {
  12453. this.doSiteMap = false;
  12454. }
  12455. args.method = method;
  12456. if (this.correlateHosts) {
  12457. var proxyURL = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME).getValue(com.ibm.mashups.enabler.services.ConfigConstants.PROXY_URL);
  12458. var server = _targetURL.server;
  12459. if (null !== proxyURL) {
  12460. proxyURL += "/";
  12461. if (args.url.indexOf(proxyURL) === 0) {
  12462. var index = args.url.indexOf("/", proxyURL.length);
  12463. server = args.url.substring(0, index);
  12464. }
  12465. }
  12466. var _partsArray = this.correlatedHosts.get(server);
  12467. if (!_partsArray) {
  12468. _partsArray = [];
  12469. this.correlatedHosts.put(server, _partsArray);
  12470. }
  12471. this._addToPartsArray(_partsArray, args);
  12472. }
  12473. else {
  12474. this._addToPartsArray(this.partsArray, args);
  12475. }
  12476. });
  12477. },
  12478. isTransaction: function() {
  12479. return (0 < this.statics.semaphore);
  12480. },
  12481. _encodeUrl: function(url, escapeExclamations) {
  12482. if (escapeExclamations) {
  12483. return escape(url).replace(/\+/g, '%2B').replace(/%20/g, '+').replace(/\*/g, '%2A').replace(/\//g, '%2F').replace(/@/g, '%40').replace(/%21/g, '!');
  12484. }
  12485. return escape(url).replace(/\+/g, '%2B').replace(/%20/g, '+').replace(/\*/g, '%2A').replace(/\//g, '%2F').replace(/@/g, '%40');
  12486. },
  12487. _createHuffmanUrl: function(parts) {
  12488. var cxml = this._createSiteMap(parts);
  12489. cxml = com.ibm.mm.enabler.encode.huffman.HuffmanURL.createRawSchemeSpecificPartFromRegex(cxml, "[/ ]");
  12490. // encode appropriately
  12491. var url;
  12492. this._initServiceDoc();
  12493. if (this.serviceSMJson.template.indexOf('{uri_code}') != -1) {
  12494. cxml = this._encodeUrl(cxml, true);
  12495. url = this.serviceSMJson.template.replace(/\{uri_code\}/, cxml);
  12496. }
  12497. else {
  12498. url = this.serviceSMJson.template.replace(/\{code\}/, cxml);
  12499. }
  12500. // Add/Replace digest
  12501. url = this._updateDigest(url);
  12502. return url;
  12503. },
  12504. _loadResources: function(parts) {
  12505. var status;
  12506. if (this.doSiteMap) {
  12507. var url = this._createHuffmanUrl(parts);
  12508. if (url.length > this.urlMaxLength) {
  12509. // fall back
  12510. status = this._doMultipartPOSTRequest(this.method, parts, this.multipartParts);
  12511. }
  12512. else {
  12513. var me = this;
  12514. xhrArgs = {
  12515. url: url,
  12516. load: function(response, ioArgs) {
  12517. me._handleMultiPartResponse(parts, me.multipartParts, me, response, ioArgs);
  12518. status = ioArgs.xhr.status;
  12519. }, // JSLINT-IGNORE: Enabler Team decided to keep this paradigma from dojo in tact
  12520. error: function(response, ioArgs) {
  12521. dojo.forEach(parts, function(part) {
  12522. for (var x = 0, l = part.length; x<l; x++) {
  12523. var requestArgs = part[x];
  12524. me._partHandler(requestArgs, response, ioArgs, null);
  12525. }
  12526. });
  12527. status = ioArgs.xhr.status;
  12528. }, // JSLINT-IGNORE: Enabler Team decided to keep this paradigma from dojo in tact
  12529. handleAs: "text",
  12530. sync: true
  12531. };
  12532. dojo.xhrGet(xhrArgs);
  12533. }
  12534. }
  12535. else {
  12536. status = this._doMultipartPOSTRequest(this.method, parts, this.multipartParts);
  12537. }
  12538. return status;
  12539. },
  12540. // deprecated
  12541. endTransaction: function(multipartParts, callback, parameters) {
  12542. if (!this.doMultipart) {
  12543. return;
  12544. }
  12545. this._release();
  12546. // return if another handler is in use
  12547. if (0 < this.statics.semaphore) {
  12548. return;
  12549. }
  12550. dojo.xhr = this.statics.oldXhr;
  12551. var doMultipartParts = false;
  12552. if (multipartParts !== undefined) {
  12553. doMultipartParts = multipartParts;
  12554. }
  12555. var url;
  12556. var xhrArgs;
  12557. var me = this;
  12558. if (this.correlateHosts) {
  12559. var _correlatedHosts = this.correlatedHosts.values();
  12560. for (var i in _correlatedHosts) {
  12561. if (Object.prototype.hasOwnProperty.call(_correlatedHosts, i)) {
  12562. this._loadResources(_correlatedHosts[i]);
  12563. }
  12564. }
  12565. }
  12566. else {
  12567. // nothing in the parts array
  12568. if (0 === this._assocArraySize(this.partsArray)) {
  12569. return;
  12570. }
  12571. this._loadResources(this.partsArray);
  12572. }
  12573. if (callback) {
  12574. callback(parameters);
  12575. }
  12576. },
  12577. endTransactionDeferred: function(multipartParts) {
  12578. if (typeof multipartParts !== "undefined" && true === multipartParts) {
  12579. this.multipartParts = true;
  12580. }
  12581. return new com.ibm.mm.enabler.DeferredOperationImpl(this, this._endTransaction);
  12582. },
  12583. _endTransaction: function(deferred, sync) {
  12584. if (!this.doMultipart) {
  12585. return;
  12586. }
  12587. this._release();
  12588. // return if another handler is in use
  12589. if (0 < this.statics.semaphore) {
  12590. return;
  12591. }
  12592. dojo.xhr = this.statics.oldXhr;
  12593. var url;
  12594. var xhrArgs;
  12595. var me = this;
  12596. var status;
  12597. if (this.correlateHosts) {
  12598. var _correlatedHosts = this.correlatedHosts.values();
  12599. for (var i in _correlatedHosts) {
  12600. if (Object.prototype.hasOwnProperty.call(_correlatedHosts, i)) {
  12601. status = this._loadResources(_correlatedHosts[i]);
  12602. }
  12603. }
  12604. }
  12605. else {
  12606. // nothing in the parts array
  12607. if (0 === this._assocArraySize(this.partsArray)) {
  12608. return;
  12609. }
  12610. status = this._loadResources(this.partsArray);
  12611. }
  12612. if (deferred) {
  12613. var callBack = deferred.getOperationCallback();
  12614. if (callBack) {
  12615. callBack(id, com.ibm.mashups.enabler.DeferredOperation.OPERATION_GET, xhr.status, myDeferred.getOperationCallbackParameters());
  12616. }
  12617. }
  12618. },
  12619. _doMultipartPOSTRequest: function(method, partsArray, doMultipartParts) {
  12620. var useCommitHandler = this._processMultipartBody(partsArray);
  12621. this._initServiceDoc();
  12622. var rawMPArgs;
  12623. if (useCommitHandler) {
  12624. rawMPArgs = {
  12625. url: this.serviceCHJson.url,
  12626. sync: true
  12627. };
  12628. } else {
  12629. rawMPArgs = {
  12630. url: this.serviceMPJson.url,
  12631. sync: true
  12632. };
  12633. }
  12634. var status = this._multiPartXhr(method, rawMPArgs, partsArray, doMultipartParts);
  12635. return status;
  12636. },
  12637. _assocArraySize: function(tempArray) {
  12638. var size = 0;
  12639. for (var x in tempArray) {
  12640. if (Object.prototype.hasOwnProperty.call(tempArray, x)) {
  12641. size++;
  12642. }
  12643. }
  12644. return size;
  12645. },
  12646. _addToPartsArray: function(partsArray, args) {
  12647. var existing = partsArray[args.url];
  12648. if (!existing) {
  12649. partsArray[args.url] = [];
  12650. partsArray[args.url][0] = args;
  12651. }
  12652. else {
  12653. existing[existing.length] = args;
  12654. }
  12655. },
  12656. // acquire semaphore
  12657. _acquire: function() {
  12658. this.statics.semaphore++;
  12659. },
  12660. // release semaphore
  12661. _release: function(deferred, statusCode) {
  12662. this.statics.semaphore--;
  12663. },
  12664. _createPocURI: function(args) {
  12665. var url = args.url;
  12666. // OR added de-proxyfication since this is not needed for resolver uri's
  12667. var proxyPrefix = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME).getValue(com.ibm.mashups.enabler.services.ConfigConstants.PROXY_URL);
  12668. proxyPrefix += "/http/"; // e.g. /mum/proxy/http/
  12669. if (url.indexOf(proxyPrefix) === 0) {
  12670. var newUrl = "http://";
  12671. var slashPos = url.indexOf("/", proxyPrefix.length + 1); // skip /http/ to find next /
  12672. // need to decode the authority part in order to have a valid URI
  12673. if (slashPos > -1) {
  12674. newUrl += unescape(url.substring(proxyPrefix.length, slashPos));
  12675. newUrl += url.substring(slashPos);
  12676. }
  12677. else {
  12678. newUrl = "http://" + url.substring(proxyPrefix.length);
  12679. }
  12680. url = newUrl;
  12681. }
  12682. // OR changed url to be HttpURL and get files by res:/
  12683. var httpUrl = new com.ibm.mm.enabler.utils.HttpUrl(url);
  12684. // extract the digest
  12685. var digest = this._extractDigest(httpUrl, url);
  12686. if (digest) {
  12687. if (null === this.digest && false === this.replaceDigest) {
  12688. this.replaceDigest = true;
  12689. } else if (digest !== this.digest) {
  12690. this.replaceDigest = false;
  12691. }
  12692. this.digest = digest;
  12693. } else {
  12694. this.digest = "";
  12695. this.replaceDigest = false;
  12696. }
  12697. // add any dojo.xhr content parameters
  12698. if (args.content) {
  12699. for (var name in args.content) {
  12700. if (Object.prototype.hasOwnProperty.call(args.content, name)) {
  12701. var value = args.content[name];
  12702. httpUrl.addParameter(name, value);
  12703. }
  12704. }
  12705. }
  12706. var uri = "";
  12707. var isProxyNeeded = httpUrl.isProxyNeeded();
  12708. if (isProxyNeeded) {
  12709. uri = httpUrl.toString(); // the URI is the true url
  12710. }
  12711. else {
  12712. // FIXME: currently the server/resolver can't handle res URIs for a data sink
  12713. var method = (args.method) ? args.method.toLowerCase() : null;
  12714. if (method && (method == "post" || method == "put" || method == "delete")) {
  12715. uri = httpUrl.getParameter("uri");
  12716. } else {
  12717. uri = "res:" + httpUrl.toServerRelativeString(); // need to prefix res: before the server relative url
  12718. }
  12719. }
  12720. return uri;
  12721. },
  12722. _processMultipartBody: function(parts) {
  12723. var useCommitHandler = false;
  12724. for (var w in parts) {
  12725. if (Object.prototype.hasOwnProperty.call(parts, w)) {
  12726. for (var x in parts[w]) {
  12727. if (Object.prototype.hasOwnProperty.call(parts[w], x)) {
  12728. // Create a header for our method
  12729. var args = parts[w][x];
  12730. var uri = this._createPocURI(args);
  12731. var contentIdHeader = uri;
  12732. args.headers = dojo.mixin({}, args.headers, {
  12733. "X-Method-Override": args.method,
  12734. "Content-ID": contentIdHeader
  12735. });
  12736. if ("GET" !== args.method) {
  12737. useCommitHandler = true;
  12738. }
  12739. }
  12740. }
  12741. }
  12742. }
  12743. return useCommitHandler;
  12744. },
  12745. _createSiteMap: function(parts) {
  12746. var cxml = '<mashup:sitemap xmlns:mashup="http://www.ibm.com/xmlns/prod/websphere/portal/v6.0.2/mashup-sitemap">';
  12747. for (var w in parts) {
  12748. if (Object.prototype.hasOwnProperty.call(parts, w)) {
  12749. // Create a header for our method
  12750. var args = parts[w][0];
  12751. args.handleAs = args.handleAs ? args.handleAs.toLowerCase() : "text";
  12752. var uri = this._createPocURI(args).replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/&/g, "&amp;");
  12753. cxml += '<mashup:entry uri="' + uri + '" mode="download"/>';
  12754. }
  12755. }
  12756. cxml += '</mashup:sitemap>';
  12757. return cxml;
  12758. },
  12759. _extractDigest: function(httpUrl, url) {
  12760. // check for a normal parameter
  12761. var digest;
  12762. var tempDigest = httpUrl.getParameter("digest");
  12763. if (!tempDigest) {
  12764. // potentially portal style:
  12765. // /wps/mycontenthandler/!ut/p/digest!YYKwv4D5SWBlr5MXQwCujg/res//mccbuilder/widget-catalog/breadcrumbWidget.xml?pragma=cache&max-age=1209600&cache-scope=public&vary=none&user-context=false?cache-scope=public&vary=none&user-context=false&max-age=1209600
  12766. var start = url.indexOf("digest!");
  12767. if (0 < start) {
  12768. start += 7;
  12769. var end = url.indexOf("/", start);
  12770. digest = url.substring(start, end);
  12771. }
  12772. } else {
  12773. digest = tempDigest;
  12774. }
  12775. return digest;
  12776. },
  12777. _updateDigest: function(url) {
  12778. if (!this.replaceDigest) {
  12779. return url;
  12780. }
  12781. // potentially portal style:
  12782. // /wps/mycontenthandler/!ut/p/digest!YYKwv4D5SWBlr5MXQwCujg/res//mccbuilder/widget-catalog/breadcrumbWidget.xml?pragma=cache&max-age=1209600&cache-scope=public&vary=none&user-context=false?cache-scope=public&vary=none&user-context=false&max-age=1209600
  12783. var digest;
  12784. var end;
  12785. var start = url.indexOf("digest!");
  12786. if (0 < start) {
  12787. start += 7;
  12788. end = url.indexOf("/", start);
  12789. digest = url.substring(start, end);
  12790. } else if (!digest) {
  12791. // url parameter
  12792. start = url.indexOf("digest=");
  12793. if (0 < start) {
  12794. start += 7;
  12795. end = url.indexOf("&", start);
  12796. if (-1 === end) {
  12797. digest = url.substring(start);
  12798. } else {
  12799. digest = url.substring (start, end);
  12800. }
  12801. }
  12802. }
  12803. var retval = url;
  12804. if (digest) {
  12805. retval = url.replace(digest, this.digest);
  12806. }
  12807. return retval;
  12808. }
  12809. });
  12810. }
  12811. if(!dojo._hasResource["com.ibm.mashups.enabler.io.XHRMultipart"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  12812. dojo._hasResource["com.ibm.mashups.enabler.io.XHRMultipart"] = true;
  12813. dojo.provide("com.ibm.mashups.enabler.io.XHRMultipart");
  12814. }
  12815. if(!dojo._hasResource["com.ibm.mashups.enabler.io.XHRMultipartFactory_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  12816. dojo._hasResource["com.ibm.mashups.enabler.io.XHRMultipartFactory_API"] = true;
  12817. dojo.provide("com.ibm.mashups.enabler.io.XHRMultipartFactory_API");
  12818. dojo.provide("com.ibm.mashups.enabler.io.XHRMultipartFactory");
  12819. /**
  12820. * Interface representing the XHR multipart handler factory
  12821. * @ibm-api
  12822. * @ibm-module Base
  12823. */
  12824. dojo.declare("com.ibm.mashups.enabler.io.XHRMultipartFactory", null, {
  12825. /**
  12826. * Returns a new XHR multipart handler
  12827. *
  12828. * @return {com.ibm.mashups.enabler.io.XHRMultipart} a new multipart
  12829. * handler, never <code>null</code>
  12830. */
  12831. create: function(){
  12832. },
  12833. /**
  12834. * Returns if multipart is enabled on the server
  12835. * @return {Boolean} <code>true</code> if multipart is
  12836. * enabled, <code>false</code> otherwise
  12837. */
  12838. isMultipartEnabled: function(){
  12839. },
  12840. /**
  12841. * Returns if application widgets should be fetched in multipart requests
  12842. * @return {Boolean} <code>true</code> if application widgets should be
  12843. * fetched in multipart requests, <code>false</code> otherwise
  12844. */
  12845. isMultipartApplicationWidgets: function(){
  12846. }
  12847. });
  12848. }
  12849. if(!dojo._hasResource["com.ibm.mm.enabler.io.XHRMultipartFactoryImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  12850. dojo._hasResource["com.ibm.mm.enabler.io.XHRMultipartFactoryImpl"] = true;
  12851. dojo.provide("com.ibm.mm.enabler.io.XHRMultipartFactoryImpl");
  12852. // public factory
  12853. dojo.declare("com.ibm.mm.enabler.io.XHRMultipartFactoryImpl", [com.ibm.mashups.enabler.io.XHRMultipartFactory, com.ibm.mm.enabler.ServiceDocConsumer], {
  12854. constructor: function() {
  12855. this._init = false;
  12856. this.serviceMPJson = null;
  12857. this.doMultipart = false;
  12858. var configService = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);
  12859. var pageLoadOptAppWidgets = configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.PAGE_LOAD_OPTIMIZATION_APP_WIDGETS);
  12860. this.multipartAppWidgets = false;
  12861. if (typeof(pageLoadOptAppWidgets) == "undefined" || pageLoadOptAppWidgets === null || pageLoadOptAppWidgets === true) {
  12862. this.multipartAppWidgets = true;
  12863. }
  12864. },
  12865. _initServiceDoc: function() {
  12866. this.inherited("_initServiceDoc", arguments);
  12867. // service document and initialization
  12868. if (dojo.exists("com.ibm.mm.enabler.model.ServiceDocumentModel")) {
  12869. this.serviceMPJson = com.ibm.mm.enabler.model.ServiceDocumentModel.getCollectionData([com.ibm.mm.enabler.model.ServiceDocumentModel.SERVICE_MODEL, com.ibm.mm.enabler.model.ServiceDocumentModel.SERVICE_MULTIPART]);
  12870. }
  12871. if(this.serviceMPJson && this.serviceMPJson.url) {
  12872. this.doMultipart = true;
  12873. }
  12874. },
  12875. create: function() {
  12876. return new com.ibm.mm.enabler.io.XHRMultipartImpl();
  12877. },
  12878. isMultipartEnabled: function() {
  12879. if(!this._init) {
  12880. this._init = true;
  12881. var configService = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);
  12882. var multipartConfig = configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.MULTIPART_ENABLED);
  12883. // disable on IE6
  12884. if (dojo.isIE != 6 && multipartConfig) {
  12885. this._initServiceDoc();
  12886. }
  12887. }
  12888. return this.doMultipart;
  12889. },
  12890. isMultipartApplicationWidgets: function() {
  12891. return this.multipartAppWidgets;
  12892. }
  12893. });
  12894. // public factory
  12895. com.ibm.mashups.enabler.io.XHRMultipartFactory = new com.ibm.mm.enabler.io.XHRMultipartFactoryImpl();
  12896. }
  12897. if(!dojo._hasResource["com.ibm.mashups.enabler.io.XHRMultipartFactory"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  12898. dojo._hasResource["com.ibm.mashups.enabler.io.XHRMultipartFactory"] = true;
  12899. dojo.provide("com.ibm.mashups.enabler.io.XHRMultipartFactory");
  12900. dojo.require( "com.ibm.mm.enabler.io.XHRMultipartFactoryImpl" );
  12901. }
  12902. if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.Accessor"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  12903. dojo._hasResource["com.ibm.mashups.enabler.model.state.Accessor"] = true;
  12904. dojo.provide("com.ibm.mashups.enabler.model.state.Accessor");
  12905. /**
  12906. * Interface representing an Accessor.
  12907. *
  12908. * @ibm-spi
  12909. * @ibm-module Base
  12910. */
  12911. dojo.declare("com.ibm.mashups.enabler.model.state.Accessor", null, {});
  12912. }
  12913. if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.PageAccessor_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  12914. dojo._hasResource["com.ibm.mashups.enabler.model.state.PageAccessor_API"] = true;
  12915. dojo.provide("com.ibm.mashups.enabler.model.state.PageAccessor_API");
  12916. dojo.provide("com.ibm.mashups.enabler.model.state.PageAccessor");
  12917. /**
  12918. * Interface representing an PageAccessor.
  12919. * @ibm-spi
  12920. * @ibm-module Base
  12921. */
  12922. dojo.declare( "com.ibm.mashups.enabler.model.state.PageAccessor", [com.ibm.mashups.enabler.model.state.Accessor] , {
  12923. /**
  12924. * Returns the of the page within a space.
  12925. * @type String
  12926. * @return {String} The page id of provided space
  12927. */
  12928. getPageID:function() {
  12929. },
  12930. /**
  12931. * Sets the page of the space
  12932. * @param {String} pageId id of page
  12933. * @type void
  12934. */
  12935. setPageID:function(pageId) {
  12936. },
  12937. /**
  12938. * Confirms if it's possible to set a new page id
  12939. * @param {String} pageId id of page
  12940. * @type Boolean
  12941. * @return{Boolean} return true if it's possible to set a new page id
  12942. */
  12943. confirmSetPageID:function(pageId) {
  12944. return true;
  12945. }
  12946. });
  12947. }
  12948. if(!dojo._hasResource["com.ibm.mm.enabler.model.state.PageAccessorImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  12949. dojo._hasResource["com.ibm.mm.enabler.model.state.PageAccessorImpl"] = true;
  12950. dojo.provide("com.ibm.mm.enabler.model.state.PageAccessorImpl");
  12951. dojo.declare("com.ibm.mm.enabler.model.state.PageAccessorImpl", [com.ibm.mashups.enabler.model.state.PageAccessor], {
  12952. constructor: function(navStateModel, spaceid) {
  12953. this.navStateModel = navStateModel;
  12954. if (spaceid) {
  12955. this.spaceid = spaceid;
  12956. }
  12957. },
  12958. getPageID: function() {
  12959. var state = this.navStateModel._state;
  12960. var rc = null;
  12961. if (!state) {
  12962. return null;
  12963. }
  12964. if (!this.spaceid) {
  12965. if (state.pid) {
  12966. return state.pid.value;
  12967. }
  12968. return null;
  12969. }
  12970. else {
  12971. if (state.pageselection && state.pageselection[this.spaceid]) {
  12972. return state.pageselection[this.spaceid].value;
  12973. }
  12974. return null;
  12975. }
  12976. return null;
  12977. },
  12978. setPageID: function(pageId) {
  12979. var state = this.navStateModel._state;
  12980. if (!state) {
  12981. this.navStateModel._state = {};
  12982. state = this.navStateModel._state;
  12983. }
  12984. if (!pageId) {
  12985. state.pid = null;
  12986. if (this.spaceid) {
  12987. if (state.pageselection && state.pageselection[this.spaceid]) {
  12988. state.pageselection[this.spaceid] = null;
  12989. }
  12990. }
  12991. this.navStateModel.setDirty(true, "pid");
  12992. return;
  12993. }
  12994. var lm = new Date().getTime();
  12995. state.pid = state.pid ? state.pid : {};
  12996. state.pid.value = pageId;
  12997. state.pid.params = state.pid.params ? state.pid.params : {};
  12998. state.pid.params.lm = lm;
  12999. if (this.spaceid) {
  13000. if (!state.pageselection) {
  13001. state.pageselection = {};
  13002. }
  13003. if (!state.pageselection[this.spaceid]) {
  13004. state.pageselection[this.spaceid] = {};
  13005. }
  13006. state.pageselection[this.spaceid].value = pageId;
  13007. state.pageselection[this.spaceid].params = state.pageselection[this.spaceid].params ? state.pageselection[this.spaceid].params : {};
  13008. state.pageselection[this.spaceid].params.lm = lm;
  13009. }
  13010. this.navStateModel.setDirty(true, "pid");
  13011. }
  13012. });
  13013. }
  13014. if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.PageAccessor"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  13015. dojo._hasResource["com.ibm.mashups.enabler.model.state.PageAccessor"] = true;
  13016. dojo.provide("com.ibm.mashups.enabler.model.state.PageAccessor");
  13017. }
  13018. if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.SpaceAccessor_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  13019. dojo._hasResource["com.ibm.mashups.enabler.model.state.SpaceAccessor_API"] = true;
  13020. dojo.provide("com.ibm.mashups.enabler.model.state.SpaceAccessor_API");
  13021. dojo.provide("com.ibm.mashups.enabler.model.state.SpaceAccessor");
  13022. /**
  13023. * Interface representing a SpaceAccessor.
  13024. * @ibm-spi
  13025. * @ibm-module Base
  13026. */
  13027. dojo.declare( "com.ibm.mashups.enabler.model.state.SpaceAccessor", [com.ibm.mashups.enabler.model.state.Accessor], {
  13028. /**
  13029. * Returns the of the currently selected space.
  13030. * @type String
  13031. * @return {String} The spaceid
  13032. */
  13033. getSpaceID:function() {
  13034. },
  13035. /**
  13036. * Sets the space
  13037. * @param {String} spaceId id of space
  13038. * @type void
  13039. */
  13040. setSpaceID:function(spaceId) {
  13041. },
  13042. /**
  13043. * Confirms if it's possible ot set the space id
  13044. * @param {String} spaceId id of space
  13045. * @type Boolean
  13046. * @return{Boolean} return true if it's possible to set the new space id
  13047. */
  13048. confirmSetSpaceID:function(spaceId) {
  13049. return true;
  13050. }
  13051. });
  13052. }
  13053. if(!dojo._hasResource["com.ibm.mm.enabler.model.state.SpaceAccessorImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  13054. dojo._hasResource["com.ibm.mm.enabler.model.state.SpaceAccessorImpl"] = true;
  13055. dojo.provide("com.ibm.mm.enabler.model.state.SpaceAccessorImpl");
  13056. dojo.declare("com.ibm.mm.enabler.model.state.SpaceAccessorImpl", [com.ibm.mashups.enabler.model.state.SpaceAccessor], {
  13057. constructor: function(navStateModel) {
  13058. this.navStateModel = navStateModel;
  13059. },
  13060. getSpaceID: function() {
  13061. var state = this.navStateModel._state;
  13062. if (!state) {
  13063. return null;
  13064. }
  13065. if (state.sid && state.sid.value) {
  13066. return state.sid.value;
  13067. }
  13068. return null;
  13069. },
  13070. _setSpaceIDInternal: function(spaceId) {
  13071. var state = this.navStateModel._state;
  13072. if (!state) {
  13073. this.navStateModel._state = {};
  13074. state = this.navStateModel._state;
  13075. }
  13076. var lm = new Date().getTime(); //todo
  13077. if (typeof spaceId == "undefined") {
  13078. state.sid = {};
  13079. }
  13080. else {
  13081. state.sid = state.sid ? state.sid : {};
  13082. state.sid.value = spaceId;
  13083. state.sid.params = state.sid.params ? state.sid.params : {};
  13084. state.sid.params.lm = lm;
  13085. }
  13086. if (state.pid) {
  13087. state.pid = null;
  13088. }
  13089. },
  13090. setSpaceID: function(spaceId) {
  13091. this._setSpaceIDInternal(spaceId);
  13092. this.navStateModel.setDirty(true, "sid");
  13093. }
  13094. });
  13095. }
  13096. if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.SpaceAccessor"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  13097. dojo._hasResource["com.ibm.mashups.enabler.model.state.SpaceAccessor"] = true;
  13098. dojo.provide("com.ibm.mashups.enabler.model.state.SpaceAccessor");
  13099. }
  13100. if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.WidgetAccessor_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  13101. dojo._hasResource["com.ibm.mashups.enabler.model.state.WidgetAccessor_API"] = true;
  13102. dojo.provide("com.ibm.mashups.enabler.model.state.WidgetAccessor_API");
  13103. dojo.provide("com.ibm.mashups.enabler.model.state.WidgetAccessor");
  13104. /**
  13105. * Interface representing a WidgetAccessor. Reserved Widget Paramers:
  13106. * "cp" : the reserved paremeter for widget customized state.
  13107. * "h" : the reserved paremeter for widget height.
  13108. * "w" : the reserved paremeter for widget width.
  13109. * "st" : the reserved paremeter for widget window state.
  13110. * "md" : the reserved paremeter for widget mode.
  13111. * @ibm-spi
  13112. * @ibm-module Base
  13113. */
  13114. dojo.declare( "com.ibm.mashups.enabler.model.state.WidgetAccessor", [com.ibm.mashups.enabler.model.state.Accessor], {
  13115. /**
  13116. * @private
  13117. */
  13118. constructor:function (navStateModel, id) {
  13119. },
  13120. /**
  13121. * Returns the widget id of the Widget
  13122. * @type String
  13123. * @return {String} ID of required Widget
  13124. */
  13125. getWidgetID:function() {
  13126. },
  13127. /**
  13128. * Returns the values of the required widget state parameter. If state has only one value, this method returns a single array with a length of 1.
  13129. *
  13130. * @since 2.4
  13131. * @param {String} key The name of the required parameter of Widget Navigation State
  13132. * "cp" is the reserved parameter for widget customized state.
  13133. * @type String
  13134. * @return {String[]} Values of required parameter
  13135. */
  13136. getWidgetStateValues:function(key) {
  13137. },
  13138. /**
  13139. * Returns the state of the required widget state parameter
  13140. * @param {String} key The name of the required parameter of Widget Navigation State
  13141. * "cp" is the reserved parameter for widget customized state.
  13142. * @type String
  13143. * @return {String} Value of required parameter
  13144. */
  13145. getWidgetState:function(key) {
  13146. },
  13147. /**
  13148. * Set the value of a widget state parameter
  13149. *
  13150. * @since 2.4
  13151. * @param {String} key The name of the required parameter
  13152. * @param {String[]} values The values of the required parameter
  13153. * @type WidgetAccessor
  13154. * @return{WidgetAccessor} return an handle of WidgetAccessor upon successful, <code>null</code> upon failure.
  13155. */
  13156. setWidgetState:function(key,values){
  13157. },
  13158. /**
  13159. * Confirms whether setting the values for the given widget state parameter is possible.
  13160. *
  13161. * @since 2.4
  13162. * @param {String} key The name of the required parameter
  13163. * @param {String[]} values The values of the required parameter
  13164. * @type Boolean
  13165. * @return {Boolean} true if the values can be set, otherwise false.
  13166. */
  13167. confirmSetWidgetState:function(key,values){
  13168. return true;
  13169. },
  13170. /**
  13171. * Set the value of a widget state parameter
  13172. *
  13173. * @since 2.4
  13174. * @param {String} key The name of the required parameter
  13175. * @param {String} value The value of the required parameter
  13176. * @type WidgetAccessor
  13177. * @return{WidgetAccessor} return an handle of WidgetAccessor upon successful, <code>null</code> upon failure.
  13178. */
  13179. setWidgetState:function(key,value){ // JSLINT-IGNORE: in Java functions with the same name but different signatures are allowed - this is only used for generating JavaDoc
  13180. },
  13181. /**
  13182. * Confirms whether setting the value for the given widget state parameter is possible.
  13183. *
  13184. * @since 2.4
  13185. * @param {String} key The name of the required parameter
  13186. * @param {String} value The value of the required parameter
  13187. * @type Boolean
  13188. * @return {Boolean} true if the value can be set, otherwise false.
  13189. */
  13190. confirmSetWidgetState:function(key,value){// JSLINT-IGNORE: in Java functions with the same name but different signatures are allowed - this is only used for generating JavaDoc
  13191. return true;
  13192. },
  13193. /**
  13194. * Remove a widget state parameter
  13195. * @param {String} key The name of the required parameter
  13196. * @type WidgetAccessor
  13197. * @return{WidgetAccessor} return an handle of WidgetAccessor upon successful, <code>null</code> upon failure.
  13198. */
  13199. removeWidgetState:function(key){
  13200. },
  13201. /**
  13202. * Confirms whether removing a widget state parameter is possible
  13203. *
  13204. * @since 2.4
  13205. * @param {String} key The name of the required parameter
  13206. * @type Boolean
  13207. * @return{Boolean} return true if the required parameter can be removed
  13208. */
  13209. confirmRemoveWidgetState:function(key){
  13210. return true;
  13211. },
  13212. /**
  13213. * Returns the names of custimized widget state
  13214. * @type String[]
  13215. * @return {String[]} an array of customized widget state names
  13216. */
  13217. getWidgetStateNames:function(){
  13218. },
  13219. /**
  13220. * Returns the mode of the required widget
  13221. * @type String
  13222. * @return {String} The mode of the required widget and <code>null</code> if no mode is set yet.
  13223. */
  13224. getWidgetMode:function() {
  13225. },
  13226. /**
  13227. * Set the mode of a widget
  13228. * @param {String} mode of the required widget
  13229. * @type WidgetAccessor
  13230. * @return{WidgetAccessor} return an handle of WidgetAccessor upon successful, <code>null</code> upon failure.
  13231. */
  13232. setWidgetMode:function(mode) {
  13233. },
  13234. /**
  13235. * Confirms whether it's possible or not to set the widget to a new mode
  13236. * @param {String} mode of the required widget
  13237. * @type Boolean
  13238. * @return{Boolean} return true if it's possible to set widget to the new model
  13239. */
  13240. confirmSetWidgetMode:function(mode) {
  13241. return true;
  13242. },
  13243. /**
  13244. * Returns the window state of the required widget
  13245. * @type String
  13246. * @return {String} The window state of the required widget following states are allowed: "normal","minimize","maximize". It returns <code>null</code> if no windowstate is set yet.
  13247. */
  13248. getWindowState:function() {
  13249. },
  13250. /**
  13251. * Set the window state of a widget
  13252. * @param {String} windowState The window state of the required widget
  13253. * @type WidgetAccessor
  13254. * @return{WidgetAccessor} return an handle of WidgetAccessor upon successful, <code>null</code> upon failure.
  13255. */
  13256. setWindowState:function(windowState) {
  13257. },
  13258. /**
  13259. * Confirms whether it's possible or not to set the widget to a new window state
  13260. * @param {String} windowState The window state of the required widget
  13261. * @type Boolean
  13262. * @return{Boolean} return true if it's possible to set widget to the new window state
  13263. */
  13264. confirmSetWindowState:function(windowState) {
  13265. return true;
  13266. },
  13267. /**
  13268. * Returns the size of the required widget
  13269. * @type Object
  13270. * @return {Object} A JSON object representing the widget width/height, for example: <code>{w:"200",h:"400"}</code>
  13271. */
  13272. getSize:function() {
  13273. },
  13274. /**
  13275. * Set the size of a widget
  13276. * @param {String} width The width of the widget
  13277. * @param {String} height The height of the widget
  13278. * @type WidgetAccessor
  13279. * @return{WidgetAccessor} return an handle of WidgetAccessor upon successful, <code>null</code> upon failure.
  13280. */
  13281. setSize:function(width, height) {
  13282. },
  13283. /**
  13284. * Confirms whether it's possible or not to set the widget to the new width and height
  13285. * @param {String} width The width of the widget
  13286. * @param {String} height The height of the widget
  13287. * @type Boolean
  13288. * @return{Boolean} return true if it's possible to set widget to the new width and height
  13289. */
  13290. confirmSetSize:function(width,height) {
  13291. return true;
  13292. },
  13293. /**
  13294. * "minimize" window state supported by enabler
  13295. * @type String
  13296. */
  13297. MIN: "minimize",
  13298. /**
  13299. * "maximize" window state supported by enabler
  13300. * @type String
  13301. */
  13302. MAX: "maximize",
  13303. /**
  13304. * "normal" window state supported by enabler
  13305. * @type String
  13306. */
  13307. NORMAL: "normal"
  13308. });
  13309. }
  13310. if(!dojo._hasResource["com.ibm.mm.enabler.model.state.WidgetAccessorImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  13311. dojo._hasResource["com.ibm.mm.enabler.model.state.WidgetAccessorImpl"] = true;
  13312. dojo.provide("com.ibm.mm.enabler.model.state.WidgetAccessorImpl");
  13313. dojo.declare("com.ibm.mm.enabler.model.state.WidgetAccessorImpl", [com.ibm.mashups.enabler.model.state.WidgetAccessor], {
  13314. constructor: function(navStateModel, id){
  13315. this.navStateModel = navStateModel;
  13316. this.wid = id;
  13317. this.uniqueWid = this._getUniqueWid();
  13318. this.widgetNavStateNode = navStateModel._find(this.WIDGET_PREFIX + this.navStateModel.DELIMITER + this.uniqueWid);
  13319. if (this.wid != this.uniqueWid && !this.widgetNavStateNode) {
  13320. this.widgetNavStateNodeFallback = navStateModel._find(this.WIDGET_PREFIX + this.navStateModel.DELIMITER + this.wid);
  13321. }
  13322. },
  13323. WIDGET_PREFIX: "wparams",
  13324. WIDTH: "w",
  13325. HEIGHT: "h",
  13326. WINDOWSTATE: "st",
  13327. SYSTEMSTATE: "rp",
  13328. CUSTOMSTATE: "cp",
  13329. VALUE: "value",
  13330. PARAMS: "params",
  13331. MODE: "md",
  13332. RP: {
  13333. w: "w",
  13334. h: "h",
  13335. st: "st",
  13336. md: "md"
  13337. },
  13338. VIEW: "view",
  13339. getWidgetID: function(){
  13340. return this.wid;
  13341. },
  13342. _getUniqueWid: function(){
  13343. return this.navStateModel._getUniqueWid(this.wid);
  13344. },
  13345. getWidgetStateSet: function(){
  13346. var value = null;
  13347. if (!this.widgetNavStateNode && !this.widgetNavStateNodeFallback) {
  13348. return null;
  13349. }
  13350. var widgetNavStateNode = this.widgetNavStateNode;
  13351. if (!widgetNavStateNode) {
  13352. widgetNavStateNode = this.widgetNavStateNodeFallback;
  13353. }
  13354. var data = widgetNavStateNode.getRef();
  13355. if (data && data[this.VALUE]) {
  13356. if (data[this.VALUE][this.CUSTOMSTATE]) {
  13357. value = data[this.VALUE][this.CUSTOMSTATE];
  13358. }
  13359. }
  13360. if (value && !dojo.isString(value)) {
  13361. value = dojo.toJson(value);
  13362. }
  13363. return value; //always return string as defined by the spec
  13364. },
  13365. _createWidgetNavStateNode: function(){
  13366. var aNode = this.navStateModel.create({
  13367. key: this.uniqueWid
  13368. });
  13369. var parentNode = this.navStateModel._find(this.WIDGET_PREFIX);
  13370. if (!parentNode) {
  13371. var temp = this.navStateModel.create({
  13372. key: this.WIDGET_PREFIX
  13373. });
  13374. this.navStateModel.insert(temp, this.navStateModel._getRoot());
  13375. parentNode = this.navStateModel._find(this.WIDGET_PREFIX);
  13376. }
  13377. this.navStateModel.insert(aNode, parentNode);
  13378. aNode = this.navStateModel._find(this.WIDGET_PREFIX + this.navStateModel.DELIMITER + this.uniqueWid);
  13379. return aNode;
  13380. },
  13381. setWidgetStateSet: function(object){
  13382. //it should be a simple String,save as an object internally
  13383. var value = null;
  13384. //need to support both string or object
  13385. //save as object for portal CSA2 support
  13386. if (dojo.isString(object)) {
  13387. try {
  13388. object = dojo.fromJson(object);
  13389. } catch (e) {
  13390. // just use the string
  13391. }
  13392. }
  13393. if (!this.widgetNavStateNode) {
  13394. //create this.widgetNavStateNode
  13395. this.widgetNavStateNode = this._createWidgetNavStateNode();
  13396. }
  13397. var data = this.widgetNavStateNode.getRef();
  13398. data.params = data.params ? data.params : {};
  13399. data.params.lm = new Date().getTime(); //todo
  13400. if (data && data[this.VALUE]) {
  13401. if (data[this.VALUE][this.CUSTOMSTATE]) {
  13402. value = dojo.clone(data[this.VALUE][this.CUSTOMSTATE]);
  13403. }
  13404. }
  13405. data[this.VALUE] = data[this.VALUE] ? data[this.VALUE] : {};
  13406. var obj = object;
  13407. if (value && !dojo.isString(value) && !dojo.isString(object)) {
  13408. obj = dojo.mixin(value, object); //mixin behaviour
  13409. }
  13410. data[this.VALUE][this.CUSTOMSTATE] = obj;
  13411. this.navStateModel.setDirty(true);
  13412. return this;
  13413. },
  13414. _getWidgetSystemState: function(key){
  13415. var value = null;
  13416. if (!this.widgetNavStateNode && !this.widgetNavStateNodeFallback) {
  13417. return null;
  13418. }
  13419. var widgetNavStateNode = this.widgetNavStateNode;
  13420. if (!widgetNavStateNode) {
  13421. widgetNavStateNode = this.widgetNavStateNodeFallback;
  13422. }
  13423. var data = widgetNavStateNode.getRef();
  13424. if (data && data[this.VALUE]) {
  13425. if (data[this.VALUE][this.SYSTEMSTATE]) {
  13426. data = data[this.VALUE][this.SYSTEMSTATE];
  13427. if (data && data[key]) {
  13428. value = data[key];
  13429. }
  13430. }
  13431. }
  13432. return value;
  13433. },
  13434. _setWidgetSystemState: function(key, value){
  13435. //overwrite behaviour
  13436. if (!this.widgetNavStateNode) {
  13437. this.widgetNavStateNode = this._createWidgetNavStateNode();
  13438. }
  13439. var data = this.widgetNavStateNode.getRef();
  13440. data.params = data.params ? data.params : {};
  13441. data.params.lm = new Date().getTime(); //todo
  13442. var keyRef = null;
  13443. data[this.VALUE] = data[this.VALUE] ? data[this.VALUE] : {};
  13444. data[this.VALUE][this.SYSTEMSTATE] = data[this.VALUE][this.SYSTEMSTATE] ? data[this.VALUE][this.SYSTEMSTATE] : {};
  13445. keyRef = data[this.VALUE][this.SYSTEMSTATE];
  13446. keyRef[key] = value;
  13447. this.navStateModel.setDirty(true);
  13448. return this;
  13449. },
  13450. getWidgetState: function(key){
  13451. var rc = this._getWidgetStateValue(key) || null;
  13452. if (!rc) {
  13453. return null;
  13454. }
  13455. if (!dojo.isString(rc)) {
  13456. rc = dojo.toJson(rc);
  13457. }
  13458. return rc;
  13459. },
  13460. _getWidgetStateValue: function(key){
  13461. if (!key) {
  13462. return null;
  13463. }
  13464. if (key && key == "cp") {
  13465. return this.getWidgetStateSet();
  13466. }
  13467. if (this.RP[key]) {
  13468. return this._getWidgetSystemState(key);
  13469. }
  13470. var value = null;
  13471. if (!this.widgetNavStateNode && !this.widgetNavStateNodeFallback) {
  13472. return null;
  13473. }
  13474. var widgetNavStateNode = this.widgetNavStateNode;
  13475. if (!widgetNavStateNode) {
  13476. widgetNavStateNode = this.widgetNavStateNodeFallback;
  13477. }
  13478. var data = widgetNavStateNode.getRef();
  13479. if (data && data[this.VALUE]) {
  13480. if (data[this.VALUE][this.CUSTOMSTATE]) {
  13481. data = data[this.VALUE][this.CUSTOMSTATE];
  13482. if (dojo.isString(data)) {
  13483. return null;
  13484. }
  13485. if (data && data[key]) {
  13486. value = data[key];
  13487. }
  13488. }
  13489. }
  13490. return value;
  13491. },
  13492. getWidgetStateValues: function(key){
  13493. // TODO implement
  13494. var rc = this._getWidgetStateValue(key) || null;
  13495. if (!rc) {
  13496. return null;
  13497. }
  13498. if (dojo.isString(rc)) {
  13499. var arr = [];
  13500. arr.push(rc);
  13501. return arr;
  13502. }
  13503. return rc;
  13504. },
  13505. getWidgetStateNames: function(){
  13506. var names = [];
  13507. if (!this.widgetNavStateNode && !this.widgetNavStateNodeFallback) {
  13508. return null;
  13509. }
  13510. var widgetNavStateNode = this.widgetNavStateNode;
  13511. if (!widgetNavStateNode) {
  13512. widgetNavStateNode = this.widgetNavStateNodeFallback;
  13513. }
  13514. var data = widgetNavStateNode.getRef();
  13515. if (data && data[this.VALUE]) {
  13516. if (data[this.VALUE][this.CUSTOMSTATE]) {
  13517. data = data[this.VALUE][this.CUSTOMSTATE];
  13518. if (dojo.isString(data)) {
  13519. return null;
  13520. }
  13521. if (data) {
  13522. for (var i in data) {
  13523. if (Object.prototype.hasOwnProperty.call(data, i)) {
  13524. if (data[i]) { //if it's not deleted
  13525. names.push(i);
  13526. }
  13527. }
  13528. }
  13529. }
  13530. }
  13531. }
  13532. if (names.length === 0) {
  13533. return null;
  13534. }
  13535. return names;
  13536. },
  13537. setWidgetState: function(key, value){
  13538. if (!key || !value) {
  13539. return null;
  13540. }
  13541. if (key && key == "cp") {
  13542. return this.setWidgetStateSet(value);
  13543. }
  13544. var isValidValue = false;
  13545. if (dojo.isArray(value) && value.length >= 1) {
  13546. if (dojo.isString(value[0])) {
  13547. isValidValue = true;
  13548. }
  13549. }
  13550. if (!isValidValue) {
  13551. if (dojo.isString(value)) {
  13552. isValidValue = true;
  13553. }
  13554. }
  13555. if (!isValidValue) {
  13556. return null;
  13557. }
  13558. if (this.RP[key]) {
  13559. return this._setWidgetSystemState(key, value);
  13560. }
  13561. //overwrite behaviour
  13562. if (key && key == "cp") {
  13563. return this.setWidgetStateSet(value);
  13564. }
  13565. if (!this.widgetNavStateNode) {
  13566. this.widgetNavStateNode = this._createWidgetNavStateNode();
  13567. }
  13568. var data = this.widgetNavStateNode.getRef();
  13569. data.params = data.params ? data.params : {};
  13570. data.params.lm = new Date().getTime(); //todo
  13571. var keyRef = null;
  13572. data[this.VALUE] = data[this.VALUE] ? data[this.VALUE] : {};
  13573. data[this.VALUE][this.CUSTOMSTATE] = data[this.VALUE][this.CUSTOMSTATE] ? data[this.VALUE][this.CUSTOMSTATE] : {};
  13574. keyRef = data[this.VALUE][this.CUSTOMSTATE];
  13575. keyRef[key] = value;
  13576. this.navStateModel.setDirty(true);
  13577. return this;
  13578. },
  13579. removeWidgetState: function(key){
  13580. if (!key) {
  13581. return false;
  13582. }
  13583. if (this.RP[key]) {
  13584. return this._removeWidgetSystemState(key);
  13585. }
  13586. if (!this.widgetNavStateNode) {
  13587. return false;
  13588. }
  13589. var data = this.widgetNavStateNode.getRef();
  13590. data.params = data.params ? data.params : {};
  13591. data.params.lm = new Date().getTime(); //todo
  13592. if (key && key == "cp") {
  13593. if (data && data[this.VALUE] && data[this.VALUE][this.CUSTOMSTATE]) {
  13594. data[this.VALUE][this.CUSTOMSTATE] = null;
  13595. this.navStateModel.setDirty(true);
  13596. return true;
  13597. }
  13598. return false;
  13599. }
  13600. if (data && data[this.VALUE] && data[this.VALUE][this.CUSTOMSTATE]) {
  13601. var keyRef = data[this.VALUE][this.CUSTOMSTATE];
  13602. if (keyRef && keyRef[key]) {
  13603. keyRef[key] = null;
  13604. this.navStateModel.setDirty(true);
  13605. return true;
  13606. }
  13607. }
  13608. return false;
  13609. },
  13610. _removeWidgetSystemState: function(key){
  13611. if (!key) {
  13612. return false;
  13613. }
  13614. if (!this.widgetNavStateNode) {
  13615. return false;
  13616. }
  13617. var data = this.widgetNavStateNode.getRef();
  13618. data.params = data.params ? data.params : {};
  13619. data.params.lm = new Date().getTime(); //todo
  13620. if (data && data[this.VALUE] && data[this.VALUE][this.SYSTEMSTATE]) {
  13621. var keyRef = data[this.VALUE][this.SYSTEMSTATE];
  13622. if (keyRef && keyRef[key]) {
  13623. keyRef[key] = null;
  13624. this.navStateModel.setDirty(true);
  13625. return true;
  13626. }
  13627. }
  13628. return false;
  13629. },
  13630. getWindowState: function(){
  13631. rc = this._getWidgetSystemState(this.WINDOWSTATE);
  13632. //rc = rc ? rc : this.NORMAL;
  13633. return rc;
  13634. },
  13635. setWindowState: function(windowState){
  13636. if (windowState && (windowState == this.MIN || windowState == this.MAX || windowState == this.NORMAL)) {
  13637. this._setWidgetSystemState(this.WINDOWSTATE, windowState);
  13638. }
  13639. },
  13640. getWidgetMode: function(){
  13641. var rc = this._getWidgetSystemState(this.MODE);
  13642. //rc = rc ? rc : this.VIEW;
  13643. return rc;
  13644. },
  13645. setWidgetMode: function(aMode){
  13646. if (aMode) {
  13647. this._setWidgetSystemState(this.MODE, aMode);
  13648. return this;
  13649. }
  13650. return null;
  13651. },
  13652. getSize: function(){
  13653. var size = {};
  13654. var height = this._getWidgetSystemState(this.HEIGHT);
  13655. var width = this._getWidgetSystemState(this.WIDTH);
  13656. if (height) {
  13657. size[this.HEIGHT] = height;
  13658. }
  13659. if (width) {
  13660. size[this.WIDTH] = width;
  13661. }
  13662. if (!size[this.HEIGHT] && !size[this.WIDTH]) {
  13663. return null;
  13664. }
  13665. return size;
  13666. },
  13667. setSize: function(width, height){
  13668. if (width) {
  13669. this._setWidgetSystemState(this.WIDTH, width);
  13670. }
  13671. if (height) {
  13672. this._setWidgetSystemState(this.HEIGHT, height);
  13673. }
  13674. return this;
  13675. }
  13676. });
  13677. }
  13678. if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.WidgetAccessor"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  13679. dojo._hasResource["com.ibm.mashups.enabler.model.state.WidgetAccessor"] = true;
  13680. dojo.provide("com.ibm.mashups.enabler.model.state.WidgetAccessor");
  13681. }
  13682. if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.PageModeAccessor_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  13683. dojo._hasResource["com.ibm.mashups.enabler.model.state.PageModeAccessor_API"] = true;
  13684. dojo.provide("com.ibm.mashups.enabler.model.state.PageModeAccessor_API");
  13685. dojo.provide("com.ibm.mashups.enabler.model.state.PageModeAccessor");
  13686. /**
  13687. * Interface representing an PageModeAccessor.
  13688. * @ibm-spi
  13689. * @ibm-module Base
  13690. */
  13691. dojo.declare( "com.ibm.mashups.enabler.model.state.PageModeAccessor", [com.ibm.mashups.enabler.model.state.Accessor] , {
  13692. /**
  13693. * VIEW mode of page, can be used as com.ibm.mashups.enabler.model.state.PageModeAccessor.VIEW with "view" as the actual value</br>
  13694. * @type String
  13695. */
  13696. VIEW:"view",
  13697. /**
  13698. * EDIT mode of page, can be used as com.ibm.mashups.enabler.model.state.PageModeAccessor.EDIT with "edit" as the actual value</br>
  13699. * @type String
  13700. */
  13701. EDIT:"edit",
  13702. /**
  13703. * Returns the of the page mode of current page.
  13704. * @type String
  13705. * @return {String} The page mode of current page
  13706. */
  13707. getPageMode:function() {
  13708. },
  13709. /**
  13710. * Sets the page mode of the page
  13711. * @param {String} pageMode The mode of the page
  13712. * @type void
  13713. */
  13714. setPageMode:function(pageMode) {
  13715. },
  13716. /**
  13717. * Confirms if it's possible to set a new page mode
  13718. * @param {String} pageMode The mode of the page
  13719. * @type Boolean
  13720. * @return{Boolean} return true if it's possible to set a new page mode
  13721. */
  13722. confirmSetPageMode:function(pageMode) {
  13723. return true;
  13724. }
  13725. });
  13726. com.ibm.mashups.enabler.model.state.PageModeAccessor.VIEW = "view";
  13727. com.ibm.mashups.enabler.model.state.PageModeAccessor.EDIT = "edit";
  13728. }
  13729. if(!dojo._hasResource["com.ibm.mm.enabler.model.state.PageModeAccessorImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  13730. dojo._hasResource["com.ibm.mm.enabler.model.state.PageModeAccessorImpl"] = true;
  13731. dojo.provide("com.ibm.mm.enabler.model.state.PageModeAccessorImpl");
  13732. dojo.declare("com.ibm.mm.enabler.model.state.PageModeAccessorImpl", [com.ibm.mashups.enabler.model.state.PageModeAccessor], {
  13733. constructor: function(navStateModel) {
  13734. // it supports 3 modes: "view","edit","unload" -- unload is internal at this moment and used to indicate a page is being unloaded
  13735. this.navStateModel = navStateModel;
  13736. },
  13737. getPageMode: function() {
  13738. var pageMode = this.navStateModel._getPageMode();
  13739. if (!pageMode) {
  13740. return null;
  13741. }
  13742. return pageMode;
  13743. },
  13744. setPageMode: function(mode) {
  13745. if (mode) {
  13746. this.navStateModel._setPageMode(mode);
  13747. }
  13748. return;
  13749. }
  13750. });
  13751. }
  13752. if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.PageModeAccessor"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  13753. dojo._hasResource["com.ibm.mashups.enabler.model.state.PageModeAccessor"] = true;
  13754. dojo.provide("com.ibm.mashups.enabler.model.state.PageModeAccessor");
  13755. }
  13756. if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.ShareableParameterSetAccessor_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  13757. dojo._hasResource["com.ibm.mashups.enabler.model.state.ShareableParameterSetAccessor_API"] = true;
  13758. dojo.provide("com.ibm.mashups.enabler.model.state.ShareableParameterSetAccessor_API");
  13759. dojo.provide("com.ibm.mashups.enabler.model.state.ShareableParameterSetAccessor");
  13760. /**
  13761. * Interface representing a ShareableParameterSetAccessor.
  13762. * @ibm-spi
  13763. * @ibm-module Base
  13764. */
  13765. dojo.declare( "com.ibm.mashups.enabler.model.state.ShareableParameterSetAccessor", [com.ibm.mashups.enabler.model.state.Accessor], {
  13766. /**
  13767. * Returns the id of ShareableParamterSet
  13768. * @type String
  13769. * @return {String} name of ShareableParameterSet
  13770. */
  13771. getId:function() {
  13772. },
  13773. /**
  13774. * Returns the scope of ShareableParamterSet or null, if this accessor represents the global scope.
  13775. * @type String
  13776. * @return {String} name of the scope
  13777. */
  13778. getScope:function() {
  13779. },
  13780. /**
  13781. * Returns an array of all Shareable Parameter names within this Shareable Parameter Set
  13782. * @type String[]
  13783. * @return {String[]} array of all the ShareableParameterSet
  13784. */
  13785. getAllNames:function() {
  13786. },
  13787. /**
  13788. * Set the value of a required item. It will replace the old value. If the value is a serialized version of complex data type, it's recommended for the widget to get the original
  13789. * value, update the complex object and serialize again before calling this api.
  13790. * @param {String} itemName The name of the required parameter
  13791. * @param {String} value The value of the required parameter
  13792. * @type Boolean
  13793. * @return {Boolean} return true if item is updated or created successfully.
  13794. */
  13795. setItemValue:function(itemName,value){
  13796. },
  13797. /**
  13798. * Confirm if it's possible to set the value of a required item. It will replace the old value. If the value is a serialized version of complex data type, it's recommended for the widget to get the original
  13799. * value, update the complex object and serialize again before calling this api.
  13800. * @param {String} itemName The name of the required parameter
  13801. * @param {String} value The value of the required parameter
  13802. * @type Boolean
  13803. * @return {Boolean} return true if it's possible to set the value
  13804. */
  13805. confirmSetItemValue:function(itemName,value){
  13806. return true;
  13807. },
  13808. /**
  13809. * Remove the required item
  13810. * @param {String} itemName The name of the required parameter that needs to be removed
  13811. * @type Boolean
  13812. * @return {Boolean} return true if item is removed successfully.
  13813. */
  13814. removeItem:function(itemName){
  13815. },
  13816. /**
  13817. * confirm if it's possible to remove the required item
  13818. * @param {String} itemName The name of the required parameter that needs to be removed
  13819. * @type Boolean
  13820. * @return {Boolean} return true if it's possible to remove item
  13821. */
  13822. confirmRemoveItem:function(itemName){
  13823. return true;
  13824. },
  13825. /**
  13826. * Returns the value of required item name
  13827. * @param {String} itemName the name of the required parameter
  13828. * @type String
  13829. * @return {String} value of the required item
  13830. */
  13831. getItemValue:function(itemName) {
  13832. },
  13833. /**
  13834. * Register listener so listener will be notified when an item set is updated
  13835. * @param {Function} listener which is a js function that's already scoped properly.
  13836. * @return{String} listener id
  13837. */
  13838. registerListener:function(listener) {
  13839. },
  13840. /**
  13841. * Remove the listener given a listener id
  13842. * @param {String} listenerId id of the listener that will be removed.
  13843. * @type Boolean
  13844. * @return {Boolean} return true if listener is removed successfully
  13845. */
  13846. removeListener:function(listenerId) {
  13847. },
  13848. /**
  13849. * Confirm if it's possible to remove the listener given a listener id
  13850. * @param {String} listenerId id of the listener that will be removed.
  13851. * @type Boolean
  13852. * @return {Boolean} return true if it's possible to remove Listener
  13853. */
  13854. confirmRemoveListener:function(listenerId) {
  13855. return true;
  13856. }
  13857. });
  13858. }
  13859. if(!dojo._hasResource["com.ibm.mm.enabler.model.state.ShareableParameterSetAccessorImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  13860. dojo._hasResource["com.ibm.mm.enabler.model.state.ShareableParameterSetAccessorImpl"] = true;
  13861. dojo.provide("com.ibm.mm.enabler.model.state.ShareableParameterSetAccessorImpl");
  13862. dojo.declare("com.ibm.mm.enabler.model.state.ShareableParameterSetAccessorImpl", [com.ibm.mashups.enabler.model.state.ShareableParameterSetAccessor], {
  13863. /**
  13864. * @private
  13865. */
  13866. DELETE_TOKEN: "DELETE_TOKEN",
  13867. TYPE_NEW: "newItem",
  13868. TYPE_UPDATE: "changedValue",
  13869. TYPE_REMOVE: "removedItem",
  13870. constructor: function(navStateModel, name, scope) {
  13871. /*{
  13872. value:{//type: newItem/changedValue/removedItem
  13873. page:{value:"3",params:{_isDirty:true,_type:"changedValue",_oldVal:"4"}},
  13874. tablesize:{value:"10"}
  13875. }
  13876. params:{lm:{},_listener:{}}
  13877. }
  13878. */
  13879. if (!scope) {
  13880. this.scope = com.ibm.mm.enabler.model.state.ShareableParameterSetAccessorImpl.GLOBAL_SCOPE;
  13881. } else {
  13882. this.scope = scope;
  13883. }
  13884. this.name = name;
  13885. this.navStateModel = navStateModel;
  13886. this.navStateNode = navStateModel._find("sparams" + this.navStateModel.DELIMITER + name + this.navStateModel.DELIMITER + this.scope);
  13887. },
  13888. _createNavStateNode: function() {
  13889. var temp;
  13890. var parentNode = this.navStateModel._find("sparams");
  13891. if (!parentNode) {
  13892. temp = this.navStateModel.create({
  13893. key: "sparams"
  13894. });
  13895. this.navStateModel.insert(temp, this.navStateModel._getRoot());
  13896. parentNode = this.navStateModel._find("sparams");
  13897. }
  13898. var nameNode = this.navStateModel._find(this.name);
  13899. if (!nameNode) {
  13900. temp = this.navStateModel.create({
  13901. key: this.name
  13902. });
  13903. this.navStateModel.insert(temp, parentNode);
  13904. nameNode = this.navStateModel._find("sparams" + this.navStateModel.DELIMITER + this.name);
  13905. }
  13906. var scopeNode = this.navStateModel.create({
  13907. key: this.scope
  13908. });
  13909. this.navStateModel.insert(scopeNode, nameNode);
  13910. scopeNode = this.navStateModel._find("sparams" + this.navStateModel.DELIMITER + this.name + this.navStateModel.DELIMITER + this.scope);
  13911. return scopeNode;
  13912. },
  13913. getId: function() {
  13914. return this.name;
  13915. },
  13916. getScope: function() {
  13917. return this.scope;
  13918. },
  13919. getAllNames: function() {
  13920. if (!this.navStateNode) {
  13921. return null;
  13922. }
  13923. var arr = [];
  13924. var data = this.navStateNode.getRef();
  13925. if (data && data[this.navStateModel.VALUE]) {
  13926. for (var i in data[this.navStateModel.VALUE]) {
  13927. if (data[this.navStateModel.VALUE].hasOwnProperty(i)) {
  13928. var value = data[this.navStateModel.VALUE][i][this.navStateModel.VALUE];
  13929. if (value && value != this.DELETE_TOKEN) {
  13930. arr.push(i);
  13931. }
  13932. }
  13933. }
  13934. }
  13935. return arr;
  13936. },
  13937. setItemValue: function(itemName, value) {
  13938. if (!this.navStateNode) {
  13939. //create this.widgetNavStateNode
  13940. this.navStateNode = this._createNavStateNode();
  13941. }
  13942. var data = this.navStateNode.getRef();
  13943. data.params = data.params ? data.params : {};
  13944. data.params.lm = new Date().getTime(); //mark lm of itemset
  13945. data.value = data.value ? data.value : {};
  13946. var change = {};
  13947. if (!data.value[itemName]) {
  13948. //new item
  13949. data.value[itemName] = {};
  13950. data.value[itemName].value = value;
  13951. data.value[itemName].params = data.value[itemName].params ? data.value[itemName].params : {};
  13952. data.value[itemName].params._isDirty = true;
  13953. change.alias = itemName;
  13954. change.type = this.TYPE_NEW;
  13955. change.newVal = value;
  13956. data.value[itemName].params._change = change;
  13957. } else if (data.value[itemName]) {
  13958. var oldValue = dojo.clone(data.value[itemName].value);
  13959. data.value[itemName].value = value;
  13960. data.value[itemName].params = data.value[itemName].params ? data.value[itemName].params : {};
  13961. var isDirty = data.value[itemName].params._isDirty;
  13962. if (isDirty) {
  13963. //check various condition
  13964. change = data.value[itemName].params._change;
  13965. if (change.type == this.TYPE_NEW) {
  13966. change.newVal = value;
  13967. } else if (change.type == this.TYPE_UPDATE) {
  13968. change.newVal = value;
  13969. } else if (change.type == this.TYPE_REMOVE) {
  13970. if (change.oldVal) {
  13971. change.type = this.TYPE_UPDATE;
  13972. } else {
  13973. change.type = this.TYPE_NEW;
  13974. }
  13975. change.newVal = value;
  13976. }
  13977. } else {
  13978. change.type = this.TYPE_UPDATE;
  13979. change.oldVal = oldValue;
  13980. change.newVal = value;
  13981. change.alias = itemName;
  13982. data.value[itemName].params._change = change;
  13983. }
  13984. data.value[itemName].params._isDirty = true;
  13985. }
  13986. this.navStateModel.setDirty(true);
  13987. return true;
  13988. },
  13989. removeItem: function(itemName) {
  13990. if (!this.navStateNode) {
  13991. return false;
  13992. }
  13993. var data = this.navStateNode.getRef();
  13994. data.params = data.params ? data.params : {};
  13995. data.params.lm = new Date().getTime(); //mark lm of itemset
  13996. if (data && data[this.navStateModel.VALUE]) {
  13997. if (data[this.navStateModel.VALUE][itemName]) {
  13998. var anItem = data[this.navStateModel.VALUE][itemName];
  13999. var oldValue = dojo.clone(anItem.value);
  14000. anItem.value = this.DELETE_TOKEN;
  14001. anItem.params = anItem.params ? anItem.params : {};
  14002. var isDirty = anItem.params._isDirty;
  14003. var change = {};
  14004. if (isDirty) {
  14005. change = anItem.params._change;
  14006. if (change.type == this.TYPE_NEW) {
  14007. //completely remove this item
  14008. //data[this.navStateModel.VALUE][itemName];
  14009. delete data[this.navStateModel.VALUE][itemName];
  14010. } else if (change.type == this.TYPE_UPDATE) {
  14011. change.type = this.TYPE_REMOVE;
  14012. change.newVal = null;
  14013. delete change.oldVal;
  14014. } //don't do anything if it's remove
  14015. } else {
  14016. change.type = this.TYPE_REMOVE;
  14017. change.alias = itemName;
  14018. change.oldVal = oldValue;
  14019. anItem.params._change = change;
  14020. anItem.params._isDirty = true;
  14021. }
  14022. this.navStateModel.setDirty(true);
  14023. } else {
  14024. return false; //if item not found
  14025. }
  14026. }
  14027. return true;
  14028. },
  14029. getItemValue: function(itemName) {
  14030. if (!this.navStateNode) {
  14031. return null;
  14032. }
  14033. var data = this.navStateNode.getRef();
  14034. if (data && data[this.navStateModel.VALUE]) {
  14035. if (data[this.navStateModel.VALUE][itemName]) {
  14036. var anItemNode = data[this.navStateModel.VALUE][itemName];
  14037. var value = anItemNode[this.navStateModel.VALUE];
  14038. if (value && value != this.DELETE_TOKEN) {
  14039. return value;
  14040. }
  14041. }
  14042. }
  14043. return null;
  14044. },
  14045. registerListener: function(listener) {
  14046. if (!this.navStateNode) {
  14047. //create this.widgetNavStateNode
  14048. this.navStateNode = this._createNavStateNode();
  14049. }
  14050. var data = this.navStateNode.getRef();
  14051. var params = data[this.navStateModel.PARAMS];
  14052. if (!params) {
  14053. data[this.navStateModel.PARAMS] = {};
  14054. params = data[this.navStateModel.PARAMS];
  14055. }
  14056. if (!params._listeners) {
  14057. params._listeners = {};
  14058. }
  14059. var listenerId = this.navStateModel._generateListenerId();
  14060. params._listeners[listenerId] = listener; //save the function pointer here
  14061. return listenerId;
  14062. },
  14063. removeListener: function(listenerId) {
  14064. if (!this.navStateNode) {
  14065. return null;
  14066. }
  14067. var data = this.navStateNode.getRef();
  14068. var params = data[this.navStateModel.PARAMS];
  14069. if (params && params._listeners) {
  14070. var listeners = params._listeners;
  14071. if (listeners[listenerId]) {
  14072. listeners[listenerId] = null;
  14073. delete listeners[listenerId];
  14074. return true;
  14075. }
  14076. }
  14077. return false;
  14078. //listener not found
  14079. },
  14080. _setItems: function(changedItems) {
  14081. // add data to navigationstate
  14082. for (var i in changedItems) {
  14083. if (changedItems[i] && changedItems[i] == this.DELETE_TOKEN) {
  14084. this.removeItem(i);
  14085. } else if (changedItems[i]) {
  14086. this.setItemValue(i, changedItems[i]);
  14087. }
  14088. }
  14089. }
  14090. });
  14091. com.ibm.mm.enabler.model.state.ShareableParameterSetAccessorImpl.GLOBAL_SCOPE = "global";
  14092. }
  14093. if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.ShareableParameterSetAccessor"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  14094. dojo._hasResource["com.ibm.mashups.enabler.model.state.ShareableParameterSetAccessor"] = true;
  14095. dojo.provide("com.ibm.mashups.enabler.model.state.ShareableParameterSetAccessor");
  14096. }
  14097. if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.LayoutContainerAccessor_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  14098. dojo._hasResource["com.ibm.mashups.enabler.model.state.LayoutContainerAccessor_API"] = true;
  14099. dojo.provide("com.ibm.mashups.enabler.model.state.LayoutContainerAccessor_API");
  14100. dojo.provide("com.ibm.mashups.enabler.model.state.LayoutContainerAccessor");
  14101. /**
  14102. * Interface representing a LayoutContainerAccessor. Reserved layout container paramers:
  14103. * "w" : the reserved parameter for layout container width.
  14104. * @ibm-spi
  14105. * @ibm-module Base
  14106. */
  14107. dojo.declare( "com.ibm.mashups.enabler.model.state.LayoutContainerAccessor", [com.ibm.mashups.enabler.model.state.Accessor], {
  14108. /**
  14109. * @private
  14110. */
  14111. constructor:function (navStateModel, componentId, pageId) {
  14112. },
  14113. /**
  14114. * Returns the id of the layout container
  14115. * @type String
  14116. * @return {String} ID of required layout container
  14117. */
  14118. getID:function() {
  14119. },
  14120. /**
  14121. * Returns the size of the required layout container
  14122. * @type Object
  14123. * @return {Object} A JSON object representing the layout container width, for example: <code>{w:"70%"}</code>
  14124. */
  14125. getSize:function() {
  14126. },
  14127. /**
  14128. * Set the size of a layout container
  14129. * @param {String} width The width of the layout container
  14130. * @type LayoutContainerAccessor
  14131. * @return{LayoutContainerAccessor} return an handle of LayoutContainerAccessor upon successful, <code>null</code> upon failure.
  14132. */
  14133. setSize:function(width) {
  14134. },
  14135. /**
  14136. * Confirms whether it's possible or not to set the layout container to the new width and height
  14137. * @param {String} width The width of the layout container
  14138. * @type Boolean
  14139. * @return{Boolean} return true if it's possible to set layout container to the new width and height
  14140. */
  14141. confirmSetSize:function(width) {
  14142. return true;
  14143. }
  14144. });
  14145. }
  14146. if(!dojo._hasResource["com.ibm.mm.enabler.model.state.LayoutContainerAccessorImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  14147. dojo._hasResource["com.ibm.mm.enabler.model.state.LayoutContainerAccessorImpl"] = true;
  14148. dojo.provide("com.ibm.mm.enabler.model.state.LayoutContainerAccessorImpl");
  14149. dojo.declare("com.ibm.mm.enabler.model.state.LayoutContainerAccessorImpl", [com.ibm.mashups.enabler.model.state.LayoutContainerAccessor], {
  14150. constructor: function(navStateModel, containerId, pageId){
  14151. this.navStateModel = navStateModel;
  14152. this.cid = containerId;
  14153. this.pid = pageId;
  14154. var delim = this.navStateModel.DELIMITER;
  14155. var path = this.LAYOUT_PREFIX;
  14156. path += delim + this.pid;
  14157. this.layoutNavStateNode = navStateModel._find(path);
  14158. if (this.layoutNavStateNode) {
  14159. path += delim + this.VALUE + delim + this.cid;
  14160. this.layoutContainerNavStateNode = navStateModel._find(path);
  14161. }
  14162. else {
  14163. this.layoutContainerNavStateNode = null;
  14164. }
  14165. },
  14166. LAYOUT_PREFIX: "lcparams",
  14167. WIDTH: "w",
  14168. SYSTEMSTATE: "rp",
  14169. VALUE: "value",
  14170. PARAMS: "params",
  14171. MODE: "md",
  14172. RP: {
  14173. w: "w"
  14174. },
  14175. getID: function(){
  14176. return this.cid;
  14177. },
  14178. _getLayoutContainerSystemState: function(key){
  14179. var value = null;
  14180. if (!this.layoutContainerNavStateNode) {
  14181. return null;
  14182. }
  14183. var data = this.layoutContainerNavStateNode.getRef();
  14184. if (data && data[this.VALUE]) {
  14185. if (data[this.VALUE][this.SYSTEMSTATE]) {
  14186. data = data[this.VALUE][this.SYSTEMSTATE];
  14187. if (data && data[key]) {
  14188. value = data[key];
  14189. }
  14190. }
  14191. }
  14192. return value;
  14193. },
  14194. _setLayoutContainerSystemState: function(key, value){
  14195. var data;
  14196. //overwrite behavior
  14197. if (!this.layoutContainerNavStateNode) {
  14198. this.layoutContainerNavStateNode = this._createLayoutContainerNavStateNode();
  14199. }
  14200. data = this.layoutNavStateNode.getRef();
  14201. data.params = data.params ? data.params : {};
  14202. data.params.lm = new Date().getTime();
  14203. data = this.layoutContainerNavStateNode.getRef();
  14204. var keyRef = null;
  14205. data[this.VALUE] = data[this.VALUE] ? data[this.VALUE] : {};
  14206. data[this.VALUE][this.SYSTEMSTATE] = data[this.VALUE][this.SYSTEMSTATE] ? data[this.VALUE][this.SYSTEMSTATE] : {};
  14207. keyRef = data[this.VALUE][this.SYSTEMSTATE];
  14208. keyRef[key] = value;
  14209. this.navStateModel.setDirty(true);
  14210. return this;
  14211. },
  14212. _createLayoutNavStateNode: function(){
  14213. var aNode = this.navStateModel.create({
  14214. key: this.pid
  14215. });
  14216. var parentNode = this.navStateModel._find(this.LAYOUT_PREFIX);
  14217. if (!parentNode) {
  14218. var temp = this.navStateModel.create({
  14219. key: this.LAYOUT_PREFIX
  14220. });
  14221. this.navStateModel.insert(temp, this.navStateModel._getRoot());
  14222. parentNode = this.navStateModel._find(this.LAYOUT_PREFIX);
  14223. }
  14224. this.navStateModel.insert(aNode, parentNode);
  14225. aNode = this.navStateModel._find(this.LAYOUT_PREFIX + this.navStateModel.DELIMITER + this.pid);
  14226. return aNode;
  14227. },
  14228. _createLayoutContainerNavStateNode: function(){
  14229. //overwrite behaviour
  14230. if (!this.layoutNavStateNode) {
  14231. this.layoutNavStateNode = this._createLayoutNavStateNode();
  14232. }
  14233. var data = this.layoutNavStateNode.getRef();
  14234. data[this.VALUE] = data[this.VALUE] ? data[this.VALUE] : {};
  14235. var delim = this.navStateModel.DELIMITER;
  14236. var path = this.LAYOUT_PREFIX + delim + this.pid + delim + this.VALUE;
  14237. var aNode = this.navStateModel.create({
  14238. key: this.cid
  14239. });
  14240. var parentNode = this.navStateModel._find(path);
  14241. this.navStateModel.insert(aNode, parentNode);
  14242. aNode = this.navStateModel._find(path + delim + this.cid);
  14243. return aNode;
  14244. },
  14245. getSize: function(){
  14246. var size = {};
  14247. var width = this._getLayoutContainerSystemState(this.WIDTH);
  14248. if (width) {
  14249. size[this.WIDTH] = width;
  14250. return size;
  14251. }
  14252. else {
  14253. return null;
  14254. }
  14255. return size;
  14256. },
  14257. setSize: function(width){
  14258. if (width) {
  14259. this._setLayoutContainerSystemState(this.WIDTH, width);
  14260. }
  14261. return this;
  14262. }
  14263. });
  14264. }
  14265. if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.LayoutContainerAccessor"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  14266. dojo._hasResource["com.ibm.mashups.enabler.model.state.LayoutContainerAccessor"] = true;
  14267. dojo.provide("com.ibm.mashups.enabler.model.state.LayoutContainerAccessor");
  14268. }
  14269. if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.LayoutAccessor_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  14270. dojo._hasResource["com.ibm.mashups.enabler.model.state.LayoutAccessor_API"] = true;
  14271. dojo.provide("com.ibm.mashups.enabler.model.state.LayoutAccessor_API");
  14272. dojo.provide("com.ibm.mashups.enabler.model.state.LayoutAccessor");
  14273. /**
  14274. * Interface representing a LayoutAccessor. Reserved layout container parameters:
  14275. * "templateURL" : the reserved parameter for layout template URL.
  14276. * @ibm-spi
  14277. * @ibm-module Base
  14278. */
  14279. dojo.declare( "com.ibm.mashups.enabler.model.state.LayoutAccessor", [com.ibm.mashups.enabler.model.state.Accessor], {
  14280. /**
  14281. * @private
  14282. */
  14283. constructor:function (navStateModel, pageId) {
  14284. },
  14285. /**
  14286. * Returns the layout template URL (can be used to determine if the state layout is inconsistent with the page instance layout)
  14287. * @type String
  14288. * @return {String} A url to the layout's template. Uses dav: endpoint notation, e.g. "dav:filestore/layout-tempates/2ColumnEqual"
  14289. */
  14290. getTemplateURL:function() {
  14291. },
  14292. /**
  14293. * Sets the layout template URL
  14294. * @param {String} url The layout templateURL. Uses dav: endpoint notation, e.g. "dav:filestore/layout-tempates/2ColumnEqual"
  14295. * @type LayoutAccessor
  14296. * @return{com.ibm.mashups.enabler.model.state.LayoutAccessor} returns a LayoutAccessor upon success, <code>null</code> upon failure.
  14297. */
  14298. setTemplateURL:function(url) {
  14299. },
  14300. /**
  14301. * Returns the layout container accessor for the specified layout container id in this layout. (Note: Possibly non-intinutively Layout contains LayoutContainers.)
  14302. * @param {String} containerId The layout container id for the desired layout container.
  14303. * @type LayoutContainerAccessor
  14304. * @return {com.ibm.mashups.enabler.model.state.LayoutContainerAccessor} Returns the specified LayoutContainerAccessor upon success, <code>null</code> upon failure.
  14305. */
  14306. getContainerAccessor:function(containerId) {
  14307. },
  14308. /**
  14309. * Removes all layout containers and the template URL (can be used to remove obsolete layout's i.e. when the state layout is not the same as the page instance layout)
  14310. * @param {Array} pageWidgets Set of widgets on page that if in model should have their size removed. Optional parameter.
  14311. * @type LayoutContainerAccessor
  14312. * @return{com.ibm.mashups.enabler.model.state.LayoutAccessor} Returns a LayoutAccessor upon success, <code>null</code> upon failure.
  14313. */
  14314. removeAll:function(pageWidgets) {
  14315. }
  14316. });
  14317. }
  14318. if(!dojo._hasResource["com.ibm.mm.enabler.model.state.LayoutAccessorImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  14319. dojo._hasResource["com.ibm.mm.enabler.model.state.LayoutAccessorImpl"] = true;
  14320. dojo.provide("com.ibm.mm.enabler.model.state.LayoutAccessorImpl");
  14321. dojo.declare("com.ibm.mm.enabler.model.state.LayoutAccessorImpl", [com.ibm.mashups.enabler.model.state.LayoutAccessor], {
  14322. constructor: function(navStateModel, pageId){
  14323. this.navStateModel = navStateModel;
  14324. this.pid = pageId;
  14325. this.path = this.LAYOUT_PREFIX + this.navStateModel.DELIMITER + this.pid;
  14326. this.layoutNavStateNode = null;
  14327. },
  14328. LAYOUT_PREFIX: "lcparams",
  14329. WIDGET_PREFIX: "wparams",
  14330. VALUE: "value",
  14331. TEMPLATE_URL: "templateURL",
  14332. SYSTEMSTATE: "rp",
  14333. WIDTH: "w",
  14334. HEIGHT: "h",
  14335. _getLayoutState: function(key){
  14336. var value = null;
  14337. // we need to check if the layoutNavsState node exists for each call because
  14338. // layout containers can create this node too.
  14339. if (!this.layoutNavStateNode) {
  14340. this.layoutNavStateNode = this.navStateModel._find(this.path);
  14341. if (!this.layoutNavStateNode)
  14342. return null;
  14343. }
  14344. var data = this.layoutNavStateNode.getRef();
  14345. if (data && data[key])
  14346. value = data[key];
  14347. return value;
  14348. },
  14349. _setLayoutState: function(key, value){
  14350. var data;
  14351. //overwrite behavior
  14352. if (!this.layoutNavStateNode) {
  14353. this.layoutNavStateNode = this.navStateModel._find(this.path);
  14354. if (!this.layoutNavStateNode)
  14355. this.layoutNavStateNode = this._createLayoutNavStateNode();
  14356. }
  14357. data = this.layoutNavStateNode.getRef();
  14358. data.params = data.params ? data.params : {};
  14359. data.params.lm = new Date().getTime();
  14360. data[key] = value;
  14361. this.navStateModel.setDirty(true);
  14362. return this;
  14363. },
  14364. _createLayoutNavStateNode: function(){
  14365. var aNode = this.navStateModel.create({
  14366. key: this.pid
  14367. });
  14368. var parentNode = this.navStateModel._find(this.LAYOUT_PREFIX);
  14369. if (!parentNode) {
  14370. var temp = this.navStateModel.create({
  14371. key: this.LAYOUT_PREFIX
  14372. });
  14373. this.navStateModel.insert(temp, this.navStateModel._getRoot());
  14374. parentNode = this.navStateModel._find(this.LAYOUT_PREFIX);
  14375. }
  14376. this.navStateModel.insert(aNode, parentNode);
  14377. aNode = this.navStateModel._find(this.path);
  14378. return aNode;
  14379. },
  14380. getTemplateURL: function(){
  14381. return this._getLayoutState(this.TEMPLATE_URL);
  14382. },
  14383. setTemplateURL: function(url){
  14384. return this._setLayoutState(this.TEMPLATE_URL, url);
  14385. },
  14386. removeAll: function(pageWidgets) {
  14387. var delim = this.navStateModel.DELIMITER;
  14388. if (pageWidgets && this.navStateModel._find(this.WIDGET_PREFIX)) {
  14389. var i;
  14390. var systemState;
  14391. for (i = 0; i < pageWidgets.length; i++) {
  14392. systemState = this.navStateModel._find(this.WIDGET_PREFIX + delim + pageWidgets[i] + delim + this.VALUE + delim + this.SYSTEMSTATE);
  14393. if (systemState) {
  14394. systemState = systemState.getRef();
  14395. delete systemState[this.WIDTH];
  14396. delete systemState[this.HEIGHT];
  14397. this.navStateModel.setDirty(true);
  14398. }
  14399. }
  14400. }
  14401. if (this.layoutNavStateNode) {
  14402. this.navStateModel.remove(this.layoutNavStateNode);
  14403. this.navStateModel.setDirty(true);
  14404. delete this.layoutNavStateNode;
  14405. }
  14406. return this;
  14407. },
  14408. getContainerAccessor: function(containerId) {
  14409. return new com.ibm.mm.enabler.model.state.LayoutContainerAccessorImpl(this.navStateModel, containerId, this.pid);
  14410. }
  14411. });
  14412. }
  14413. if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.LayoutAccessor"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  14414. dojo._hasResource["com.ibm.mashups.enabler.model.state.LayoutAccessor"] = true;
  14415. dojo.provide("com.ibm.mashups.enabler.model.state.LayoutAccessor");
  14416. }
  14417. if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.AccessorFactory_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  14418. dojo._hasResource["com.ibm.mashups.enabler.model.state.AccessorFactory_API"] = true;
  14419. dojo.provide("com.ibm.mashups.enabler.model.state.AccessorFactory_API");
  14420. dojo.provide("com.ibm.mashups.enabler.model.state.AccessorFactory");
  14421. /**
  14422. * Interface representing an AccessorFactory. Accessor API should be used to read/write information from NavigationStateModel.
  14423. * @ibm-spi
  14424. * @ibm-module Base
  14425. */
  14426. dojo.declare( "com.ibm.mashups.enabler.model.state.AccessorFactory", null, {
  14427. /**
  14428. * Returns the Accessor to access Page selection in each Space
  14429. * @param {com.ibm.mashups.enabler.model.state.NavigationStateModel} navStateModel NavigationStateModel to get Space/Page Selection
  14430. * @param {String} spaceId spaceId to getPage Selection
  14431. * @type com.ibm.mashups.enabler.model.state.PageAccessor
  14432. * @return {com.ibm.mashups.enabler.model.state.PageAccessor} The PageAccessor of NavigationStateModel
  14433. */
  14434. getPageAccessor:function(navStateModel,spaceId) {
  14435. // look for node in model and instatiate the Page Accessor with Node
  14436. },
  14437. /**
  14438. * Returns the Accessor to access Space selection
  14439. * @param {com.ibm.mashups.enabler.model.state.NavigationStateModel} navStateModel NavigationStateModel to get Space Selection
  14440. * @type com.ibm.mashups.enabler.model.state.SpaceAccessor
  14441. * @return {com.ibm.mashups.enabler.model.state.SpaceAccessor} The SpaceAccessor of NavigationStateModel
  14442. */
  14443. getSpaceAccessor:function(navStateModel) {
  14444. },
  14445. /**
  14446. * Returns the Widget Accessor to access Widget state information
  14447. * @param {com.ibm.mashups.enabler.model.state.NavigationStateModel} navStateModel to Widget Navigation State
  14448. * @param {String} widgetId to Widget Navigation State
  14449. * @type com.ibm.mashups.enabler.model.state.WidgetAccessor
  14450. * @return {com.ibm.mashups.enabler.model.state.WidgetAccessor} The WidgetAccessor of NavigationStateModel
  14451. */
  14452. getWidgetAccessor:function(navStateModel, widgetId) {
  14453. },
  14454. /**
  14455. * Returns the Accessor to access Page mode of current page
  14456. * @param {com.ibm.mashups.enabler.model.state.NavigationStateModel} navStateModel NavigationStateModel to get Space/Page Selection
  14457. * @type com.ibm.mashups.enabler.model.state.PageModeAccessor
  14458. * @return {com.ibm.mashups.enabler.model.state.PageModeAccessor} The PageModeAccessor of NavigationStateModel
  14459. */
  14460. getPageModeAccessor:function(navStateModel) {
  14461. // look for node in model and instatiate the Page Accessor with Node
  14462. },
  14463. /**
  14464. * Returns the Accessor to access the sharable parameters
  14465. * @param {com.ibm.mashups.enabler.model.state.NavigationStateModel} navStateModel NavigationStateModel to get ShareableParameterSet
  14466. * @param {String} id id of ShareableParameterSet
  14467. * @param {String} scope optional scope for the sharable item set. If not provided or null, the global scope is returned.
  14468. * @type com.ibm.mashups.enabler.model.state.ShareableParameterSetAccessor
  14469. * @return {com.ibm.mashups.enabler.model.state.ShareableParameterSetAccessor} The ShareableParameterSetAccessor of NavigationStateModel
  14470. */
  14471. getShareableParameterSetAccessor:function(navStateModel,id,scope) {
  14472. // look for node in model and instatiate the Page Accessor with Node
  14473. },
  14474. /**
  14475. * Returns the Layout Accessor to access page layout state information
  14476. * @param {com.ibm.mashups.enabler.model.state.NavigationStateModel} navStateModel to Layout Navigation State
  14477. * @param {String} pageId of the page containing the Layout Container
  14478. * @type com.ibm.mashups.enabler.model.state.LayoutAccessor
  14479. * @return {com.ibm.mashups.enabler.model.state.LayoutAccessor} The LayoutAccessor of NavigationStateModel for the specified page
  14480. */
  14481. getLayoutAccessor:function(navStateModel, pageId){
  14482. }
  14483. });
  14484. }
  14485. if(!dojo._hasResource["com.ibm.mm.enabler.model.state.AccessorFactoryImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  14486. dojo._hasResource["com.ibm.mm.enabler.model.state.AccessorFactoryImpl"] = true;
  14487. dojo.provide("com.ibm.mm.enabler.model.state.AccessorFactoryImpl");
  14488. dojo.declare("com.ibm.mm.enabler.model.state.AccessorFactoryImpl", [com.ibm.mashups.enabler.model.state.AccessorFactory], {
  14489. constructor: function() {
  14490. },
  14491. getPageAccessor: function(navStateModel, spaceId) {
  14492. return new com.ibm.mm.enabler.model.state.PageAccessorImpl(navStateModel, spaceId);
  14493. },
  14494. getPageModeAccessor: function(navStateModel) {
  14495. return new com.ibm.mm.enabler.model.state.PageModeAccessorImpl(navStateModel);
  14496. },
  14497. getSpaceAccessor: function(navStateModel) {
  14498. return new com.ibm.mm.enabler.model.state.SpaceAccessorImpl(navStateModel);
  14499. },
  14500. getWidgetAccessor: function(navStateModel, widgetId) {
  14501. return new com.ibm.mm.enabler.model.state.WidgetAccessorImpl(navStateModel, widgetId);
  14502. },
  14503. getShareableParameterSetAccessor: function(navStateModel, name, scope) {
  14504. return new com.ibm.mm.enabler.model.state.ShareableParameterSetAccessorImpl(navStateModel, name, scope);
  14505. },
  14506. getLayoutAccessor:function(navStateModel, pageId){
  14507. return new com.ibm.mm.enabler.model.state.LayoutAccessorImpl(navStateModel, pageId);
  14508. }
  14509. });
  14510. com.ibm.mashups.enabler.model.state.AccessorFactory = new com.ibm.mm.enabler.model.state.AccessorFactoryImpl();
  14511. }
  14512. if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.AccessorFactory"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  14513. dojo._hasResource["com.ibm.mashups.enabler.model.state.AccessorFactory"] = true;
  14514. dojo.provide("com.ibm.mashups.enabler.model.state.AccessorFactory");
  14515. }
  14516. if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.NavigationStateModel_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  14517. dojo._hasResource["com.ibm.mashups.enabler.model.state.NavigationStateModel_API"] = true;
  14518. dojo.provide("com.ibm.mashups.enabler.model.state.NavigationStateModel_API");
  14519. dojo.provide("com.ibm.mashups.enabler.model.state.NavigationStateModel");
  14520. /**
  14521. * Interface for a Navigation state model.<br/>
  14522. * Navigation State API does not garantee that any modifications issued on the API have any further impact on the<br/>
  14523. * user experience of any widgets or components on the page. Widgets or components may choose to listen to changes on the Navigation</br>
  14524. * State Model and react properly upon those changes. However any user experience change cuased by those components are not part of</br>
  14525. * the contract of this API and therefore these UI behaviour may change going forward<br>
  14526. *
  14527. * AccessorFactory API should be used to read/write navigation state within NavigationStateModel.</code><br/>
  14528. * <code>var navStateModel=com.ibm.mashups.enabler.model.state.NavigationStateModelFactory.getNavigationStateModel();</code><br/>
  14529. * <code>var widgetAccessor = com.ibm.mashups.enabler.model.state.AccessorFactory.getWidgetAccessor(navStateModel);</code><br/>
  14530. * <code>widgetAccessor.setSize("200","300");</code><br/>
  14531. * <code>var deferred = navStateModel.commit();</code><br/>
  14532. * <code>deferred.setFinishedCallback(cb);</code><br/>
  14533. * <code>deferred.start();</code><br/>
  14534. *
  14535. * @ibm-spi
  14536. * @ibm-module Base
  14537. */
  14538. dojo.declare( "com.ibm.mashups.enabler.model.state.NavigationStateModel", null, {
  14539. /**
  14540. * The name of the event to handle to get NavState update notifications.
  14541. * @type String
  14542. */
  14543. ONNAVSTATEUPDATED:"com.ibm.mashups.enabler.model.state.onNavStateUpdated",
  14544. /**
  14545. * This method starts a global transaction for a NavigationStateModel object<br>
  14546. * @type void
  14547. */
  14548. startTransaction: function () {
  14549. return;
  14550. },
  14551. /**
  14552. * This method commits all changes done withing a global transaction for a NavigationStateModel object<br>
  14553. * @type void
  14554. */
  14555. commitTransaction: function () {
  14556. return;
  14557. },
  14558. /**
  14559. * This method discards all changes done within a transaction for a NavigationStateModel object and restores the original NavigationStateModel object.<br>
  14560. * @type void
  14561. */
  14562. discardTransaction: function () {
  14563. return;
  14564. },
  14565. /**
  14566. * This method starts a global transaction for a NavigationStateModel object<br>
  14567. * @return {boolean} Returns true if a transaction has been started, false otherwise.
  14568. */
  14569. isTransaction: function () {
  14570. return false;
  14571. },
  14572. /**
  14573. * Commits the modifications applied to this model and all dependent models.<br>
  14574. * @param {Object} additionalParams <i>Optional</i> JSON object to control various aspects while commiting <br>
  14575. * &nbsp;&nbsp;<b><code>addToHistory</code> (Boolean)</b> - <code>true</code> if the state should be added to the browser history, <code>false</code> otherwise <br>
  14576. * &nbsp;&nbsp;<b><code>allowRedirect</code> (Boolean)</b> - <code>true</code> if the page should be refreshed after the commit, <code>false</code> otherwise. Note, this parameter is ignored if the commit is synchronous <br>
  14577. * @return {DeferredOperation} a deferred object used to start this operation.
  14578. * The return value when executed through the deferred object is <code>null</code>
  14579. */
  14580. commit: function (additionalParams) {
  14581. return new com.ibm.mashups.enabler.Deferred();
  14582. },
  14583. /**
  14584. * Discards the modifications applied to this model. <br>
  14585. * @type void
  14586. */
  14587. discard: function () {
  14588. return;
  14589. },
  14590. /**
  14591. * Dispose this model completely all the navigation state will be destroyed. <br>
  14592. * @type void
  14593. */
  14594. dispose: function () {
  14595. return;
  14596. }
  14597. });
  14598. }
  14599. if(!dojo._hasResource["com.ibm.mashups.enabler.services.IdentificationService_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  14600. dojo._hasResource["com.ibm.mashups.enabler.services.IdentificationService_API"] = true;
  14601. dojo.provide("com.ibm.mashups.enabler.services.IdentificationService_API");
  14602. dojo.provide("com.ibm.mashups.enabler.services.IdentificationService");
  14603. /**
  14604. * Interface to work with client side ids.
  14605. * @ibm-spi
  14606. * @ibm-module Base
  14607. * @since 3.0
  14608. */
  14609. dojo.declare("com.ibm.mashups.enabler.services.IdentificationService", null, {
  14610. /**
  14611. * Returns a new client side ID.
  14612. * @return {String} client side id; never <code>null</code>.
  14613. */
  14614. createClientID: function() {
  14615. },
  14616. /**
  14617. * This method attaches a client side id to make it know to the service
  14618. * @param {Object} clientID client side id as string or Identifiable object
  14619. * @return {void}
  14620. * @since 3.0.0.1
  14621. */
  14622. attachClientID: function(clientID) {
  14623. },
  14624. /**
  14625. * Releases an earlier through <tt>getClientID</tt> loaded client id.
  14626. * @param {String} id the id to release
  14627. * @return {void}
  14628. */
  14629. releaseClientID: function(id) {
  14630. },
  14631. /**
  14632. * Checks whether the specified id is a client id of this IdentificationService
  14633. * @param {String} id the id to check for client id
  14634. * @return {boolean} <tt>true</tt> if the specified id is a client id <tt>false</tt> otherwise.
  14635. */
  14636. isClientID: function(id) {
  14637. },
  14638. /**
  14639. * Checks whether the specified id is a server id generated by the underling server implementation
  14640. * @param {String} id the id to check for server id
  14641. * @return {boolean} <tt>true</tt> if the specified id is a server id <tt>false</tt> otherwise.
  14642. */
  14643. isServerID: function(id) {
  14644. },
  14645. /**
  14646. * Checks whether the specified id is neither an client id nor an server id but is specified outside the mashup framework.
  14647. *
  14648. * @param {String} id the id to check for alien id
  14649. * @return {boolean} <tt>true</tt> if the specified id is a alien id <tt>false</tt> otherwise.
  14650. */
  14651. isAlienID: function(id) {
  14652. },
  14653. /**
  14654. * This method attaches a server side id to an existing client side id.
  14655. * @param {Object} clientID client side id as string or Identifiable object
  14656. * @param {Object} serverID server side id as string or Identifiable object
  14657. * @return {void}
  14658. */
  14659. attachServerID: function(clientID, serverID) {
  14660. },
  14661. /**
  14662. * Returns the attached server side id for any given client side id. Returns the
  14663. * specified id, if it cannot be resolved.
  14664. * @param {String} id the id to resolve
  14665. * @return {String} id the resolved id
  14666. */
  14667. resolveID: function(id) {
  14668. },
  14669. /**
  14670. * Returns the attached server side id for any given client side id. Returns the
  14671. * specified id, if it cannot be resolved.
  14672. * @param {String} id the id to resolve
  14673. * @return {com.ibm.mashups.enabler.Identifiable} id the resolved id
  14674. */
  14675. resolveIdentifiable: function(id) {
  14676. }
  14677. });
  14678. }
  14679. if(!dojo._hasResource["com.ibm.mm.enabler.utils.Utils"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  14680. dojo._hasResource["com.ibm.mm.enabler.utils.Utils"] = true;
  14681. /*WARNING: don't include this class in any iWidget2 modules,it should be exclusively used by Model related api*/
  14682. dojo.provide("com.ibm.mm.enabler.utils.Utils");
  14683. dojo.declare("com.ibm.mm.enabler.utils.UtilsImpl", null, {
  14684. constructor: function() {
  14685. // we do a lazy init
  14686. this.serviceJson = null;
  14687. },
  14688. _lazyInit: function() {
  14689. if (this.serviceJson) {
  14690. return;
  14691. }
  14692. this.xmlDom = com.ibm.mm.enabler.utils.Dom.createDocument();
  14693. // service document and initialization
  14694. this.serviceJson = com.ibm.mm.enabler.model.ServiceDocumentModel.getCollectionData(com.ibm.mm.enabler.model.ServiceDocumentModel.SERVICE_NAVIGATION);
  14695. this.prefix = this.serviceJson.idprefix;
  14696. var nsf = com.ibm.mm.enabler.model.NameSpaceFactory;
  14697. this.ns = dojo.delegate(this.serviceJson.namespaces, nsf.getNameSpaces([nsf.NS_ATOM]));
  14698. },
  14699. createNode: function(name, ns) {
  14700. this._lazyInit();
  14701. return com.ibm.mm.enabler.utils.Dom.createElement(this.xmlDom, name, ns);
  14702. },
  14703. createLinkNode: function(href, rel, ns) {
  14704. var linkNode = this.createNode("atom:link", ns);
  14705. linkNode.setAttribute("href", href);
  14706. linkNode.setAttribute("rel", rel);
  14707. return linkNode;
  14708. },
  14709. createExtLinkNode: function(href, rel, extrel) {
  14710. this._lazyInit();
  14711. var nsf = com.ibm.mm.enabler.model.NameSpaceFactory;
  14712. var linkNode = this.createNode("atom:link", this.ns[nsf.NS_ATOM]);
  14713. linkNode.setAttribute("href", href);
  14714. if (rel) {
  14715. linkNode.setAttribute("rel", rel);
  14716. }
  14717. com.ibm.mm.enabler.utils.Dom.setAttributeWithNS(this.xmlDom, linkNode, "ext:rel", "rel", this.ns.ext, extrel);
  14718. return linkNode;
  14719. },
  14720. getIdFromExtUri: function(prefix, node) {
  14721. this._lazyInit();
  14722. var id = null;
  14723. var uri = com.ibm.mm.enabler.utils.Dom.getAttributeWithNS(node, "ext:uri", "uri", this.ns.ext);
  14724. // remove model scope from id
  14725. if (uri) {
  14726. // check for associative id
  14727. var aPos = uri.indexOf("@");
  14728. if (aPos != -1) {
  14729. uri = uri.slice(0, aPos);
  14730. }
  14731. id = uri;
  14732. // remove model scope from id
  14733. var idPos = id.lastIndexOf(":");
  14734. if (idPos != -1) {
  14735. id = id.slice(idPos + 1);
  14736. }
  14737. idPos = id.toUpperCase().lastIndexOf("%3A");
  14738. if (idPos != -1) {
  14739. id = id.slice(idPos + 3);
  14740. }
  14741. idPos = id.lastIndexOf("/");
  14742. if (idPos != -1) {
  14743. id = id.slice(idPos + 1);
  14744. }
  14745. }
  14746. return id;
  14747. },
  14748. getHrefFromIdentifiable: function(identifiable) {
  14749. return (identifiable && (typeof identifiable._getParameters == "function")) ? identifiable._getParameters().href : null;
  14750. },
  14751. getIdFromIdentifiable: function(identifiable) {
  14752. if(com.ibm.mm.enabler.utils.Misc.isInstanceOf(identifiable, com.ibm.mashups.enabler.Identifiable)) {
  14753. return identifiable.getID();
  14754. } else if(dojo.isString(identifiable)) {
  14755. return dojo.string.trim(identifiable);
  14756. } else {
  14757. return identifiable;
  14758. }
  14759. },
  14760. setAttributeWithNS: function(element, attName, nsUri, value) {
  14761. this._lazyInit();
  14762. com.ibm.mm.enabler.utils.Dom.setAttributeWithNS(this.xmlDom, element, attName, null, nsUri, value);
  14763. },
  14764. createFeed: function(id, title, entry, namespaces) {
  14765. var ns = "";
  14766. for (var prefix in namespaces) {
  14767. if (Object.prototype.hasOwnProperty.call(namespaces,prefix)) {
  14768. ns += "xmlns:" + prefix + "=\"" + namespaces[prefix] + "\" ";
  14769. }
  14770. }
  14771. var time = new Date();
  14772. var feed = '<?xml version="1.0" encoding="UTF-8"?>\n' +
  14773. '<atom:feed ' +
  14774. ns +
  14775. ' >\n' +
  14776. '<atom:title>' +
  14777. title +
  14778. '</atom:title>\n' +
  14779. '<atom:id>' +
  14780. id +
  14781. '</atom:id>\n' +
  14782. '<atom:updated>' +
  14783. time.toGMTString() +
  14784. '</atom:updated>\n' +
  14785. entry +
  14786. '</atom:feed>';
  14787. return feed;
  14788. }
  14789. });
  14790. com.ibm.mm.enabler.utils.Utils = new com.ibm.mm.enabler.utils.UtilsImpl();
  14791. }
  14792. if(!dojo._hasResource["com.ibm.mm.enabler.IdentifiableHelper"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  14793. dojo._hasResource["com.ibm.mm.enabler.IdentifiableHelper"] = true;
  14794. dojo.provide("com.ibm.mm.enabler.IdentifiableHelper");
  14795. //com.ibm.mm.enabler.IdentifiableHelper.getID = function(id){
  14796. // // check for associative id
  14797. // var aPos = id.indexOf("@");
  14798. // if (aPos != -1) {
  14799. // id = id.slice(0, aPos);
  14800. // }
  14801. //
  14802. // // remove model scope from id
  14803. // var idPos = id.lastIndexOf(":");
  14804. // if (idPos != -1) {
  14805. // id = id.slice(idPos + 1);
  14806. // }
  14807. // idPos = id.toUpperCase().lastIndexOf("%3A");
  14808. // if (idPos != -1) {
  14809. // id = id.slice(idPos + 3);
  14810. // }
  14811. // idPos = id.lastIndexOf("/");
  14812. // if (idPos != -1) {
  14813. // id = id.slice(idPos + 1);
  14814. // }
  14815. //
  14816. // return id;
  14817. //};
  14818. com.ibm.mm.enabler.IdentifiableHelper.ID_MATCHER = /^(.*?)(%3a)?([ \.\w_\-]*)(@.*?)?$/i;
  14819. com.ibm.mm.enabler.IdentifiableHelper.getID = function(id) {
  14820. var matches = id.match(com.ibm.mm.enabler.IdentifiableHelper.ID_MATCHER);
  14821. return matches ? matches[3] : "";
  14822. };
  14823. //com.ibm.mm.enabler.IdentifiableHelper.replaceID = function(currentId, prefix, newId){
  14824. //
  14825. // // associative id (including '@')
  14826. // var aPos = currentId.indexOf("@");
  14827. // var association = (aPos != -1) ? currentId.slice(aPos) : "";
  14828. //
  14829. // // model schema
  14830. // var mPos = currentId.indexOf(prefix + ":");
  14831. // var model = (mPos > 0) ? currentId.slice(0, mPos) : "";
  14832. //
  14833. // // remove model scope and add 'newId:' from input newId if necessary
  14834. // var idPos = newId.indexOf(prefix + ":");
  14835. // var value = (idPos >= 0) ? newId.slice(idPos) : prefix + ":" + newId;
  14836. //
  14837. // return model + value + association;
  14838. //};
  14839. com.ibm.mm.enabler.IdentifiableHelper.replaceID = function(currentId, prefix, newId) {
  14840. var id = com.ibm.mm.enabler.IdentifiableHelper.getID(newId);
  14841. var matches = currentId.match(com.ibm.mm.enabler.IdentifiableHelper.ID_MATCHER);
  14842. return prefix + ":" + id + (matches ? (matches[4] || "") : "");
  14843. };
  14844. }
  14845. if(!dojo._hasResource["com.ibm.mm.enabler.utils.Atom"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  14846. dojo._hasResource["com.ibm.mm.enabler.utils.Atom"] = true;
  14847. dojo.provide("com.ibm.mm.enabler.utils.Atom");
  14848. com.ibm.mm.enabler.utils.Atom = {
  14849. // atom feed
  14850. _FEED: "atom:feed",
  14851. // atom entry
  14852. _ENTRY: "atom:entry",
  14853. // atom link
  14854. _LINK: "atom:link",
  14855. // atom id
  14856. _ID: "atom:id",
  14857. // next link
  14858. _NEXT_LINK: "atom:link[@rel='next']",
  14859. // edit link
  14860. _EDIT_LINK: "atom:link[@rel='edit']",
  14861. // replies link
  14862. _REPLIES_LINK: "atom:link[@rel='replies']",
  14863. // replies link href
  14864. _REPLIES_LINK_HREF: "atom:link[@rel='replies']/@href",
  14865. // in-reply-to link
  14866. _IN_REPLY_TO_LINK: "thr:in-reply-to",
  14867. // in-reply-to link href
  14868. _IN_REPLY_TO_LINK_HREF: "thr:in-reply-to/@href",
  14869. /**
  14870. * Creates an atom:entry with a title and an optional element for a specific model artifact.
  14871. *
  14872. * Example usage:
  14873. *
  14874. *
  14875. *
  14876. * var res = com.ibm.mm.enabler.utils.Misc._createAtomEntry("new navigation node", "model:navigation-node", namespace);
  14877. * var entry = res.entryElement; // reference to <atom:entry>
  14878. * var id = res.idElement; // reference to <atom:id>
  14879. * var model = res.modelElement; // reference to <model:navigation-node>
  14880. *
  14881. * @param {String} title title of the atom:entry
  14882. * @param {String} qname the qname of the model artifact to be created in the atom:content element
  14883. * @param {String} namespace corresponding name space
  14884. * @return {Object} object with properties "entryElement", "modelElement" (optional), and "idElement"
  14885. */
  14886. createEntry: function(title, qname, namespace){
  14887. var result = {};
  14888. // name spaces
  14889. var nsf = com.ibm.mm.enabler.model.NameSpaceFactory;
  14890. var ns = nsf.getNameSpaces([nsf.NS_ATOM]);
  14891. // atom:entry
  14892. var entry = com.ibm.mm.enabler.utils.Utils.createNode("atom:entry", ns.atom);
  14893. // atom:id
  14894. var idElem = com.ibm.mm.enabler.utils.Utils.createNode("atom:id", ns.atom);
  14895. entry.appendChild(idElem);
  14896. // atom:title
  14897. var titleElem = com.ibm.mm.enabler.utils.Utils.createNode("atom:title", ns.atom);
  14898. if (title) {
  14899. com.ibm.mm.enabler.utils.Dom.textContent(titleElem, title);
  14900. }
  14901. entry.appendChild(titleElem);
  14902. // atom:updated
  14903. var updated = com.ibm.mm.enabler.utils.Utils.createNode("atom:updated", ns.atom);
  14904. var time = new Date();
  14905. com.ibm.mm.enabler.utils.Dom.textContent(updated, time.toGMTString());
  14906. entry.appendChild(updated);
  14907. // atom:content
  14908. var content = com.ibm.mm.enabler.utils.Utils.createNode("atom:content", ns.atom);
  14909. content.setAttribute("type", "application/xml");
  14910. entry.appendChild(content);
  14911. if (qname && namespace) {
  14912. // add specified element
  14913. var elem = com.ibm.mm.enabler.utils.Utils.createNode(qname, namespace);
  14914. content.appendChild(elem);
  14915. result.modelElement = elem;
  14916. }
  14917. result.entryElement = entry;
  14918. result.idElement = idElem;
  14919. return result;
  14920. }
  14921. };
  14922. }
  14923. if(!dojo._hasResource["com.ibm.mm.enabler.persistence.xml.IdentifiableXmlImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  14924. dojo._hasResource["com.ibm.mm.enabler.persistence.xml.IdentifiableXmlImpl"] = true;
  14925. dojo.provide("com.ibm.mm.enabler.persistence.xml.IdentifiableXmlImpl");
  14926. // i18n
  14927. dojo.declare("com.ibm.mm.enabler.persistence.xml.IdentifiableXmlImpl", [com.ibm.mashups.enabler.Identifiable, com.ibm.mm.enabler.DirtyFlagProviderImpl, com.ibm.mm.enabler.ServiceDocConsumer], {
  14928. constructor: function(){
  14929. // messages
  14930. this.modelMessages = dojo.i18n.getLocalization("com.ibm.mm.enabler", "modelMessages");
  14931. this._resetCachedRawID();
  14932. this._addDirtyCallback(this, this._resetCachedRawID, null, true);
  14933. },
  14934. // class member - must NOT be an instance member
  14935. _cachedRawIdToken: {},
  14936. _resetCachedRawID: function(){
  14937. this._cachedRawID = this._cachedRawIdToken;
  14938. },
  14939. _cachedRawID: null,
  14940. _initServiceDoc: function(){
  14941. this.inherited("_initServiceDoc", arguments);
  14942. // service document and initialization
  14943. var serviceJson = com.ibm.mm.enabler.model.ServiceDocumentModel.getCollectionData(com.ibm.mm.enabler.model.ServiceDocumentModel.SERVICE_NAVIGATION);
  14944. var nsf = com.ibm.mm.enabler.model.NameSpaceFactory;
  14945. this.id_ns = dojo.delegate(serviceJson.namespaces, nsf.getNameSpaces([nsf.NS_ATOM, nsf.NS_THR, nsf.NS_XML, nsf.NS_OPENSEARCH, nsf.NS_XHTML, nsf.NS_APP]));
  14946. this.id_prefix = serviceJson.idprefix;
  14947. },
  14948. getID: function(){
  14949. var id = this._getRawID();
  14950. return id ? com.ibm.mm.enabler.IdentifiableHelper.getID(id) : id;
  14951. },
  14952. _getRawID: function(){
  14953. this._initServiceDoc();
  14954. if (this._cachedRawID === this._cachedRawIdToken) {
  14955. var result = null;
  14956. var node = com.ibm.mashups.enabler.xml.XPath.evaluateString(com.ibm.mm.enabler.utils.Atom._ID, this.xmlData, this.id_ns);
  14957. if (node) {
  14958. result = dojo.string.trim(node);
  14959. }
  14960. this._cachedRawID = result;
  14961. }
  14962. return this._cachedRawID;
  14963. },
  14964. equals: function(identifiable){
  14965. return com.ibm.mm.enabler.utils.Utils.getIdFromIdentifiable(this) == com.ibm.mm.enabler.utils.Utils.getIdFromIdentifiable(identifiable);
  14966. },
  14967. setID: function(id){
  14968. this._initServiceDoc();
  14969. var rawID = this._getRawID();
  14970. var newId = com.ibm.mm.enabler.IdentifiableHelper.replaceID(rawID || "", this.id_prefix, id);
  14971. if (newId != rawID) {
  14972. this._setRawID(newId);
  14973. }
  14974. },
  14975. _setRawID: function(id){
  14976. this._initServiceDoc();
  14977. id = id || "";
  14978. var node = com.ibm.mashups.enabler.xml.XPath.evaluateEntry(com.ibm.mm.enabler.utils.Atom._ID, this.xmlData, this.id_ns);
  14979. if (node) {
  14980. var currentId = this._getRawID();
  14981. if (id != currentId) {
  14982. com.ibm.mm.enabler.utils.Dom.textContent(node, id);
  14983. this._setDirty();
  14984. // populate cache
  14985. this._cachedRawID = dojo.string.trim(id);
  14986. }
  14987. }
  14988. else {
  14989. throw new Error(dojo.string.substitute(this.modelMessages.E_ELEMENT_NOT_FOUND_2, [com.ibm.mm.enabler.utils.Atom._ID, this.toString()]));
  14990. }
  14991. },
  14992. getUniqueName: function(){
  14993. this._initServiceDoc();
  14994. var name = null;
  14995. var res = com.ibm.mashups.enabler.xml.XPath.evaluateEntry(com.ibm.mm.enabler.utils.Atom._ID, this.xmlData, this.id_ns);
  14996. if (res) {
  14997. name = com.ibm.mm.enabler.utils.Dom.getAttributeWithNS(res, "ext:uniquename", "uniquename", this.id_ns.ext);
  14998. }
  14999. return name || "";
  15000. }
  15001. });
  15002. }
  15003. if(!dojo._hasResource["com.ibm.mm.enabler.IdentifierImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  15004. dojo._hasResource["com.ibm.mm.enabler.IdentifierImpl"] = true;
  15005. dojo.provide("com.ibm.mm.enabler.IdentifierImpl");
  15006. // identifier
  15007. dojo.declare("com.ibm.mm.enabler.IdentifierImpl", com.ibm.mm.enabler.persistence.xml.IdentifiableXmlImpl, {
  15008. _id: null,
  15009. _params: null,
  15010. constructor: function(id, params) {
  15011. if (dojo.isString(id)) {
  15012. this._id = id;
  15013. }
  15014. else {
  15015. this.xmlData = id;
  15016. }
  15017. this._params = params;
  15018. },
  15019. setID: function(id) {
  15020. if (this._id) {
  15021. this._id = id;
  15022. }
  15023. else {
  15024. this.inherited(arguments);
  15025. }
  15026. },
  15027. getID: function() {
  15028. return this._id ? com.ibm.mm.enabler.IdentifiableHelper.getID(this._id) : this.inherited(arguments);
  15029. },
  15030. _getParameters: function() {
  15031. return this._params;
  15032. },
  15033. /**
  15034. * This method returns the raw id like it is stored in the atom entry
  15035. */
  15036. _getRawID: function() {
  15037. return this._id ? this._id : this.inherited(arguments);
  15038. },
  15039. _setRawID: function(id) {
  15040. if (!this._id) {
  15041. var nodes = com.ibm.mashups.enabler.xml.XPath.evaluateEntry(com.ibm.mm.enabler.utils.Atom._ID, this.xmlData, this.id_ns);
  15042. if (nodes) {
  15043. com.ibm.mm.enabler.utils.Dom.textContent(nodes, id);
  15044. }
  15045. }
  15046. }
  15047. });
  15048. }
  15049. if(!dojo._hasResource["com.ibm.mm.enabler.services.IdentificationServiceImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  15050. dojo._hasResource["com.ibm.mm.enabler.services.IdentificationServiceImpl"] = true;
  15051. dojo.provide("com.ibm.mm.enabler.services.IdentificationServiceImpl");
  15052. dojo.declare("com.ibm.mm.enabler.services.IdentificationServiceImpl", [com.ibm.mashups.enabler.services.IdentificationService], {
  15053. constructor: function() {
  15054. // client ids
  15055. this.clientIds = {};
  15056. // client id map
  15057. this.clientServerMap = {};
  15058. var regexString = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME).getValue(com.ibm.mashups.enabler.services.ConfigConstants.SERVER_OBJECT_ID_FORMAT);
  15059. if (!regexString) {
  15060. regexString = "M[A-F0-9]+$";
  15061. }
  15062. // the regexp for the Server ID
  15063. this.serverOidRegExp = new RegExp(regexString);
  15064. },
  15065. createClientID: function() {
  15066. while (true) {
  15067. var id = dojox.uuid.generateRandomUuid().replace(/-/g, "_");
  15068. if (!(id in this.clientIds)) {
  15069. this.clientIds[id] = null;
  15070. return id;
  15071. }
  15072. }
  15073. // unreachable code
  15074. return null;
  15075. },
  15076. attachClientID: function(clientID) {
  15077. this.clientIds[clientID] = null;
  15078. },
  15079. releaseClientID: function(id) {
  15080. var cidString = com.ibm.mm.enabler.utils.Utils.getIdFromIdentifiable(id);
  15081. if (this.isClientID(cidString)) {
  15082. delete this.clientIds[cidString];
  15083. delete this.clientServerMap[cidString];
  15084. }
  15085. },
  15086. isClientID: function(id) {
  15087. return (id in this.clientIds);
  15088. },
  15089. isServerID: function(id) {
  15090. return this.serverOidRegExp.test(id);
  15091. },
  15092. isAlienID: function(id) {
  15093. return !this.isServerID(id) && !this.isClientID(id);
  15094. },
  15095. attachServerID: function(cid, sid) {
  15096. var cidString = com.ibm.mm.enabler.utils.Utils.getIdFromIdentifiable(cid);
  15097. var sidString = com.ibm.mm.enabler.utils.Utils.getIdFromIdentifiable(sid);
  15098. // create mapping
  15099. this.clientServerMap[cidString] = sidString;
  15100. },
  15101. resolveID: function(id) {
  15102. var cidString = com.ibm.mm.enabler.utils.Utils.getIdFromIdentifiable(id);
  15103. return (cidString in this.clientServerMap) ? this.clientServerMap[cidString] : cidString;
  15104. },
  15105. resolveIdentifiable: function(id) {
  15106. return new com.ibm.mm.enabler.IdentifierImpl(this.resolveID(id));
  15107. }
  15108. });
  15109. com.ibm.mashups.enabler.services.IdentificationService = new com.ibm.mm.enabler.services.IdentificationServiceImpl();
  15110. }
  15111. if(!dojo._hasResource["com.ibm.mashups.enabler.services.IdentificationService"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  15112. dojo._hasResource["com.ibm.mashups.enabler.services.IdentificationService"] = true;
  15113. dojo.provide("com.ibm.mashups.enabler.services.IdentificationService");
  15114. }
  15115. if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.NavigationStateProcessor_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  15116. dojo._hasResource["com.ibm.mashups.enabler.model.state.NavigationStateProcessor_API"] = true;
  15117. dojo.provide("com.ibm.mashups.enabler.model.state.NavigationStateProcessor_API");
  15118. dojo.provide("com.ibm.mashups.enabler.model.state.NavigationStateProcessor");
  15119. /**
  15120. * Interface representing NavigationStateProcessor.NavigationState is internally Represented as an JSON object.<br/>
  15121. * Paramters are predefined.<br/>
  15122. * <code>
  15123. * {<br/>
  15124. * sid:{<br/>
  15125. * &nbsp;&nbsp;value: &lt;sid>,<br/>
  15126. * &nbsp;&nbsp;params:{}<br/>
  15127. * },<br/>
  15128. * pid:{<br/>
  15129. * &nbsp;&nbsp;value: &lt;pid>,<br/>
  15130. * &nbsp;&nbsp;params:{}<br/>
  15131. * },<br/>
  15132. * pageselection:{<br/>
  15133. * &nbsp;&nbsp;&lt;spaceid>:{<br/>
  15134. * &nbsp;&nbsp;&nbsp;&nbsp;value: &lt;pageid>,<br/>
  15135. * &nbsp;&nbsp;&nbsp;&nbsp;params:{lm:&lt;timestamp>}<br/>
  15136. * &nbsp;&nbsp;},<br/>
  15137. * &nbsp;&nbsp;&lt;spaceid>:{<br/>
  15138. * &nbsp;&nbsp;&nbsp;&nbsp;value: &lt;pageid>,<br/>
  15139. * &nbsp;&nbsp;&nbsp;&nbsp;params:{lm:&lt;timestamp>}<br/>
  15140. * &nbsp;&nbsp;}<br/>
  15141. * },<br/>
  15142. * wparams:{<br/>
  15143. * &nbsp;&nbsp;&lt;wid>:{<br/>
  15144. * &nbsp;&nbsp;&nbsp;&nbsp;value: {<br/>
  15145. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rp:{w:&lt;"200">,h:&lt;"300">,st:&lt;"NORMAL">},<br/>
  15146. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cp:{&lt;page:"3">}<br/>
  15147. * &nbsp;&nbsp;&nbsp;&nbsp;},<br/>
  15148. * &nbsp;&nbsp;&nbsp;&nbsp;params:{lm:&lt;timestamp>}<br/>
  15149. * &nbsp;&nbsp;},<br/>
  15150. * &nbsp;&nbsp;&lt;wid>:{<br/>
  15151. * &nbsp;&nbsp;&nbsp;&nbsp;value: {<br/>
  15152. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rp:{w:&lt;"300">,h:&lt;"400">,st:&lt;"MAX">},<br/>
  15153. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cp:{&lt;page:"4">}<br/>
  15154. * &nbsp;&nbsp;&nbsp;&nbsp;},<br/>
  15155. * &nbsp;&nbsp;&nbsp;&nbsp;params:{lm:&lt;timestamp>}<br/>
  15156. * &nbsp;&nbsp;}<br/>
  15157. * },<br/>
  15158. * lcparams:{<br/>
  15159. * &nbsp;&nbsp;&lt;pid>:{<br/>
  15160. * &nbsp;&nbsp;templateURL: "&lt;dav:filestore/layout-templates/2ColumnEqual>",{<br/>
  15161. * &nbsp;&nbsp;&nbsp;&nbsp;value: {<br/>
  15162. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;lcid>:{<br/>
  15163. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value: {<br/>
  15164. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rp:{w:&lt;"70%">}<br/>
  15165. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>
  15166. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},<br/>
  15167. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;lcid>:{<br/>
  15168. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value: {<br/>
  15169. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rp:{w:&lt;"30%">}<br/>
  15170. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>
  15171. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>
  15172. * &nbsp;&nbsp;&nbsp;&nbsp;},<br/>
  15173. * &nbsp;&nbsp;&nbsp;&nbsp;params:{lm:&lt;timestamp>}<br/>
  15174. * &nbsp;&nbsp;},<br/>
  15175. * &nbsp;&nbsp;&lt;pid>:{<br/>
  15176. * &nbsp;&nbsp;templateURL: "&lt;dav:filestore/layout-templates/3ColumnEqual>",{<br/>
  15177. * &nbsp;&nbsp;&nbsp;&nbsp;value: {<br/>
  15178. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;lcid>:{<br/>
  15179. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value: {<br/>
  15180. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rp:{w:&lt;"30%">}<br/>
  15181. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>
  15182. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},<br/>
  15183. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;lcid>:{<br/>
  15184. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value: {<br/>
  15185. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rp:{w:&lt;"30%">}<br/>
  15186. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>
  15187. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},<br/>
  15188. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;lcid>:{<br/>
  15189. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value: {<br/>
  15190. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rp:{w:&lt;"40%">}<br/>
  15191. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>
  15192. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>
  15193. * &nbsp;&nbsp;&nbsp;&nbsp;},<br/>
  15194. * &nbsp;&nbsp;&nbsp;&nbsp;params:{lm:&lt;timestamp>}<br/>
  15195. * &nbsp;&nbsp;}<br/>
  15196. * },<br/>
  15197. * sparams:{<br/>
  15198. * &nbsp;&nbsp;&lt;id>:{<br/>
  15199. * &nbsp;&nbsp;&nbsp;&nbsp;global: {<br/>
  15200. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;params:{lm:&lt;timestamp>},<br/>
  15201. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value: {<br/>
  15202. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;name>:{<br/>
  15203. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value: &lt;value>,<br/>
  15204. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;params:{lm:&lt;timestamp>}<br/>
  15205. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},<br/>
  15206. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;name>:{<br/>
  15207. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value: &lt;value>,<br/>
  15208. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;params:{lm:&lt;timestamp>}<br/>
  15209. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>
  15210. * &nbsp;&nbsp;&nbsp;&nbsp;},<br/>
  15211. * &nbsp;&nbsp;&nbsp;&nbsp;&lt;scope-id>: {<br/>
  15212. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;params:{lm:&lt;timestamp>},<br/>
  15213. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value: {<br/>
  15214. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;name>:{<br/>
  15215. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value: &lt;value>,<br/>
  15216. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;params:{lm:&lt;timestamp>}<br/>
  15217. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},<br/>
  15218. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;name>:{<br/>
  15219. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value: &lt;value>,<br/>
  15220. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;params:{lm:&lt;timestamp>}<br/>
  15221. * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>
  15222. * &nbsp;&nbsp;}<br/>
  15223. * }<br/>
  15224. * }<br/>
  15225. * </code>
  15226. * <br/>
  15227. * Navigation State parameters will be written to url or persistence store upon configuration.<br/>
  15228. * Here's the default configuration:<br>
  15229. * <ul>
  15230. * <li>navstate.persistence.url = pid,cp,sparams</li>
  15231. * <li>persistence.pstore = w,h,st,pid,sid,pageselection</li>
  15232. * </ul>
  15233. * <br/>
  15234. * Following is the list of parameters that are configurable:<br/>
  15235. * <ul>
  15236. * <li>pid: page id </li>
  15237. * <li>sid: space id </li>
  15238. * <li>pageselection: page selections </li>
  15239. * <li>sparams: shareable parameter sets </li>
  15240. * <li>h: widget height </li>
  15241. * <li>w: widget width </li>
  15242. * <li>st: widget window state </li>
  15243. * <li>md: widget mode </li>
  15244. * <li>cp: widget customized state </li>
  15245. * </ul>
  15246. *
  15247. * Upon page loading or page refresh, navigationstatemodel is initialized with navigation state data from url or </br>
  15248. * persistence. "decode" will be used to load data from url and "preprocess" will be used to load data from persistence.</br>
  15249. * Upon commit on NavigationStateModel updates, navigation state data will be sent to url or sent to persistence.</br>
  15250. * "postprocess" will send the updates to persistence and "encode" will generate the new url fragment based on latest navigation state.</br>
  15251. *
  15252. *
  15253. * @ibm-spi
  15254. * @ibm-module Base
  15255. */
  15256. dojo.declare( "com.ibm.mashups.enabler.model.state.NavigationStateProcessor", null, {
  15257. /**
  15258. * Encodes the specified widget instance id.
  15259. * @param {String} wid widget instance id; different page may have same widget instance id.
  15260. * @param {com.ibm.mashups.enabler.model.state.NavigationStateModel} navigationStateModel
  15261. * @type String
  15262. * @return {String} unique id, representing a widget instance on a page
  15263. */
  15264. encodeWidgetIdentifier: function(wid, navigationStateModel){
  15265. },
  15266. /**
  15267. * Decodes a unique widget instance id.
  15268. * @param {String} wid unique widget instance id.
  15269. * @param {com.ibm.mashups.enabler.model.state.NavigationStateModel} navigationStateModel
  15270. * @type String
  15271. * @return {String} widget instance id
  15272. */
  15273. decodeWidgetIdentifier: function(wid, navigationStateModel){
  15274. },
  15275. /**
  15276. * Decode the url and store the state into a JSON Object. JSON object should be
  15277. * pass into Callback. If no callback is defined, navigation state is returned.<br/>
  15278. * <code>callback:function(state){};</code><br/>
  15279. * @param {String} url url string
  15280. * @param {Function} callback callback function
  15281. * @type Object
  15282. * @return {Object} navigation state object
  15283. */
  15284. decode:function(url,callback){
  15285. },
  15286. /**
  15287. * Encode state object and generate fragment. Fragment should be passed into callback function.<br/>
  15288. * <code>callback(fragment);</code>
  15289. * If no callback is defined, url fragment is returned.<br/>
  15290. * @param {Object} state JSON object representing Mashup state
  15291. * @param {Function} callback callback function which takes the following parameters:
  15292. * &nbsp;&nbsp;<b><code>additionalParams</code> (JSON)</b> - if the <code>additionalParams<code> was passed in to the encode
  15293. * function, then it must be passed back into the callback function <br>
  15294. * &nbsp;&nbsp;<b><code>responseParams</code> (JSON)</b> - <i>Optional</i> If <code>additionalParams.allowRedirect</code> is true and this is an asynchronous commit,
  15295. * then the implementation of this function may pass <code>responseParams.doRedirect</code> set to true to refresh the page after the commit is completed <br>
  15296. * @param {Object} oldState JSON object representing Mashup state before it gets updated
  15297. * @param {Object} additionalParams <i>Optional</i> JSON object to control various aspects of encoding or the registered callback
  15298. * @param {com.ibm.mashups.enabler.model.state.NavigationStateModel} navigationStateModel
  15299. * @type String
  15300. * @return {String} the url fragment that contains navigation state
  15301. */
  15302. encode:function(state,callback,oldState, additionalParams, navigationStateModel){
  15303. },
  15304. /**
  15305. * @deprecated Use generateURL instead.
  15306. *
  15307. * @param {Object} state
  15308. * @param {Function} callback
  15309. * @param {JSON} params
  15310. * @type String
  15311. */
  15312. generateUrl:function(state,callback,params){
  15313. },
  15314. /**
  15315. * Encode state object and generate full url. URL should be absolute URL. URL should be passed into callback function.
  15316. * If no callback, full url is returned.<br/>
  15317. * <code>callback:function(url){};</code><br/>
  15318. * Sample parameter: {nohash:"true"}<br/>
  15319. * if "nohash" is set to true,the returned url will not contain state in hash.<br/>
  15320. * By default Lotus Mashups only supports url that contains navigation state in hash. <br/>
  15321. * Extensions can be added to support additional parameter by using extension registry.<br/>
  15322. *
  15323. * @param {Object} state JSON object representing Mashup state
  15324. * @param {Function} callback callback function
  15325. * @param {JSON} params additional parameter in json format
  15326. * @type String
  15327. * @return {String} full url that contains navigation state
  15328. */
  15329. generateURL:function(state,callback,params){
  15330. },
  15331. /**
  15332. * Preprocess could be used to filter the original state. For example,
  15333. * pulling more state information that's cached in cookie.<br/>
  15334. * The final state should be passed into callback.<br/>
  15335. * <code>callback:function(state){};</code><br/>
  15336. * If no callback, state object will be returned.<br/>
  15337. * @param {Object} state JSON object representing Mashup state
  15338. * @param {Function} callback callback function
  15339. * @type Object
  15340. * @return {Object} object contains navigation state
  15341. */
  15342. preprocess:function(state,callback){
  15343. },
  15344. /**
  15345. * Dispose the any navigation state that's persisted. Callback is executed when dispose action is done. <br/>
  15346. * <code>callback:function(){};</code>
  15347. * @param {Function} callback callback function
  15348. * @type void
  15349. */
  15350. dispose:function(callback){
  15351. },
  15352. /**
  15353. * Postprocess could be used to filter the original state before url is generated.
  15354. * For example,some state information should be persisted into cookie.<br/>
  15355. * The final state should be passed into callback.<br/>
  15356. * <code>callback:function(state){};</code><br/>
  15357. * If no callback, state object will be returned.<br/>
  15358. * @param {Object} state JSON object representing Mashup state
  15359. * @param {Function} callback callback function
  15360. * @param {Object} oldState JSON object representing Mashup state before it gets updated
  15361. * @param {Object} additionalParams <i>Optional</i> JSON object to control various aspects of encoding or the registered callback.
  15362. * @type Object
  15363. * @return {Object} object contains navigation state
  15364. */
  15365. postprocess:function(state,callback,oldState, additionalParams){
  15366. }
  15367. });
  15368. }
  15369. if(!dojo._hasResource["com.ibm.mm.enabler.model.state.CookieManager"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  15370. dojo._hasResource["com.ibm.mm.enabler.model.state.CookieManager"] = true;
  15371. dojo.provide("com.ibm.mm.enabler.model.state.CookieManager");
  15372. dojo.declare("com.ibm.mm.enabler.model.state.CookieManager", null, {
  15373. //cookie limit is 4096byte(at least for IE)
  15374. //cookie is persisted per user, cookiename uid+"_state"
  15375. //need to split if we run into problems
  15376. /* {sid:{value:<sid>,params:{}},
  15377. * pid:{value:<pid>,params:{}},
  15378. * pageselection:{
  15379. * <spaceid>:{value:<pageid>,params:{lm:<timestamp>}},
  15380. * <spaceid>:{value:<pageid>,params:{lm:<timestamp>}}
  15381. * },
  15382. * wparams:{
  15383. * <wid>:{value:{rp:{w:<"200">,h:<"300">,st:<"NORMAL">}},params:{lm:<timestamp>}},
  15384. * <wid>:{value:{rp:{w:<"300">,h:<"400">,st:<"MAX">}},params:{lm:<timestamp>}}
  15385. * }
  15386. * }
  15387. */
  15388. constructor: function() {
  15389. this._dirty = false;
  15390. this.cookiePath = window.location.pathname;
  15391. },
  15392. COOKIE_PREFIX: "digest.ignore.state.",
  15393. disposeState: function() {
  15394. if (ibmConfig["com.ibm.mashups.embedding.isActive"]===true) {
  15395. // in case of embedding we are not allowed to write out a cookie
  15396. return;
  15397. }
  15398. var id = this._getCookieID();
  15399. if (id && dojo.cookie(id)) {
  15400. if (dojo.isIE) {
  15401. dojo.cookie(id, null, {
  15402. expires: -1
  15403. });
  15404. }
  15405. else {
  15406. dojo.cookie(id, null, {
  15407. expires: -1,
  15408. path: this.cookiePath
  15409. });
  15410. }
  15411. }
  15412. if (this._state) {
  15413. delete this._state;
  15414. }
  15415. this._dirty = false;
  15416. },
  15417. _getCookieID: function() {
  15418. //get user id
  15419. if (!this._cookieID) {
  15420. var configSvr = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);
  15421. var uid = configSvr.getValue(com.ibm.mashups.enabler.services.ConfigConstants.USER);
  15422. if (!uid || (uid && uid == "null")) {
  15423. return null;
  15424. }
  15425. //this._cookieID = uid+"_state";
  15426. this._cookieID = this.COOKIE_PREFIX + uid;
  15427. }
  15428. return this._cookieID;
  15429. },
  15430. _init: function() {
  15431. if (!this._getCookieID()) {
  15432. this._state = {};
  15433. return;
  15434. }
  15435. if (dojo.cookie.isSupported()) {
  15436. if (dojo.cookie(this._getCookieID()) && dojo.fromJson(dojo.cookie(this._getCookieID()))) {
  15437. this._state = dojo.fromJson(dojo.cookie(this._getCookieID()));
  15438. }
  15439. }
  15440. if (!this._state) {
  15441. this._state = {};
  15442. }
  15443. },
  15444. getState: function(id) {
  15445. //if id is not defined, return the whole state object
  15446. if (!this._state) {
  15447. this._init();
  15448. }
  15449. if (!id) {
  15450. return this._state;
  15451. }
  15452. if (this._state[id]) {
  15453. return this._state[id];
  15454. }
  15455. return null;
  15456. },
  15457. setState: function(id,/*object*/ value) {
  15458. //pid,sid,pageselection,wparams
  15459. if (!this._state) {
  15460. this._state = {};
  15461. }
  15462. this._state[id] = value; //create/overwrite
  15463. this._dirty = true;
  15464. },
  15465. removeState: function(id) {
  15466. if (this._state[id]) {
  15467. delete this._state[id];
  15468. this._dirty = true;
  15469. }
  15470. },
  15471. commit: function() {
  15472. if (ibmConfig["com.ibm.mashups.embedding.isActive"]===true) {
  15473. // in case of embedding we are not allowed to write out a cookie
  15474. return;
  15475. }
  15476. //cookie expiration?
  15477. if (this._dirty) {
  15478. if (!this._getCookieID()) {
  15479. this._dirty = false;
  15480. return;
  15481. }
  15482. if (dojo.cookie.isSupported()) {
  15483. if (dojo.isIE) {
  15484. dojo.cookie(this._getCookieID(), dojo.toJson(this._state), {
  15485. expires: 3652
  15486. });
  15487. }
  15488. else {
  15489. dojo.cookie(this._getCookieID(), dojo.toJson(this._state), {
  15490. expires: 3652,
  15491. path: this.cookiePath
  15492. });
  15493. }
  15494. }
  15495. this._dirty = false;
  15496. }
  15497. }
  15498. });
  15499. com.ibm.mashups.enabler.model.state.CookieManager = new com.ibm.mm.enabler.model.state.CookieManager();
  15500. }
  15501. if(!dojo._hasResource["com.ibm.mashups.iwidget.model.Factory_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  15502. dojo._hasResource["com.ibm.mashups.iwidget.model.Factory_API"] = true;
  15503. dojo.provide("com.ibm.mashups.iwidget.model.Factory_API");
  15504. dojo.provide("com.ibm.mashups.iwidget.model.Factory");
  15505. /**
  15506. * Interface represents iWidgetModelFactory
  15507. * @ibm-spi
  15508. * @ibm-module iWidget2
  15509. */
  15510. dojo.declare("com.ibm.mashups.iwidget.model.Factory", null, {
  15511. /**
  15512. * @private
  15513. */
  15514. constructor: function() {
  15515. },
  15516. /**
  15517. Returns global widget model.
  15518. @type com.ibm.mashups.iwidget.model.WidgetModel
  15519. @returns{com.ibm.mashups.iwidget.model.WidgetModel } Interface for WidgetModel.
  15520. */
  15521. getGlobalWidgetModel: function() {
  15522. }
  15523. });
  15524. }
  15525. if(!dojo._hasResource["com.ibm.mm.iwidget.Constants"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  15526. dojo._hasResource["com.ibm.mm.iwidget.Constants"] = true;
  15527. dojo.provide("com.ibm.mm.iwidget.Constants");
  15528. dojo.declare("com.ibm.mm.iwidget.Constants", null, {
  15529. constructor: function() {
  15530. },
  15531. WIDGETEVENT_PREFIX: "widgetevents.",
  15532. WILDCARD_PREFIX: "*.",
  15533. mode: {
  15534. VIEW:/*String*/ "view",//The generated markup fragment(s) should reflect normal interaction with the iWidget
  15535. EDIT:/*String*/ "edit",//The generated markup fragment(s) should reflect iWidget interactions for editing iWidget attributes scoped to this instance of iwidget, but applicable to all users
  15536. PERSONALIZE:/*String*/ "personalize",//The generated markup fragment(s) should reflect iWidget interactions for personalizing iwidget attributes scoped to this instance on the iWidget for this user
  15537. CONFIG:/*String*/ "config",//The generated markup fragment(s) should reflect iWidget interactions for editing iwidget attributes scoped to all instances of the iWidget for all users
  15538. HELP:/*String*/ "help"//The iWidget should generate markup fragment(s) to assist the user with interacting with the iWidget
  15539. },
  15540. mode_view: "view",
  15541. mode_edit: "edit",
  15542. mode_help: "help",
  15543. event: {
  15544. TITLE:/*String*/ "title",//Name for the Attribute holding event title
  15545. DESCRIPTION:/*String*/ "description"//Name for the Attribute holding event description
  15546. },
  15547. ATTRIBUTES:/*String*/ "attributes", //Name for the ManagedItemSet holding the customization attributes.
  15548. IDESCRIPTOR:/*String*/ "idescriptor", //Name for the ManagedItemSet holding the items describing the iWidget
  15549. USERPROFILE:/*String*/ "userprofile", //Name for the ManagedItemSet holding data about the user
  15550. windowstate: {
  15551. NORMAL:/*String*/ "normal",
  15552. MINIMIZE:/*String*/ "minimize",
  15553. MAXIMIZE:/*String*/ "maximize"
  15554. },
  15555. status: {
  15556. SUCCESS:/*int*/ 200,
  15557. TIMEOUT:/*int*/ 408,
  15558. NOTFOUND:/*int*/ 404,
  15559. INTERROR:/*int*/ 500,
  15560. OTHER:/*int*/ 303
  15561. },
  15562. changeType: {
  15563. CHANGEDVALUE:/*String*/ "changedValue",
  15564. NEWITEM:/*String*/ "newItem",
  15565. REMOVEDITEM:/*String*/ "removedItem"
  15566. },
  15567. iDescriptorItems: {
  15568. title: "title",
  15569. name: "name",
  15570. description: "description",
  15571. defaultHeight: "defaultHeight",
  15572. defaultWidth: "defaultWidth",
  15573. displayLocale: "displayLocale",
  15574. mode: "mode",
  15575. author: "author",
  15576. email: "email",
  15577. website: "website",
  15578. version: "version",
  15579. icon: "icon",
  15580. windowState: "windowState",
  15581. messageLocale:"messageLocale",
  15582. availableMessageLocales:"availableMessageLocales",
  15583. thumbnail:"thumbnail"
  15584. },
  15585. IW_PREFIX: "iw-",
  15586. IW_DEFINITION_TYPE: "iwidget",
  15587. OSGADGET_DEFINITION_TYPE: "os-gadget",
  15588. CSSCLASS_INSTANCE: {
  15589. iwWidget: "iWidget",
  15590. iwOSGadget: "OSGadget",
  15591. iwSandbox:"Sandbox",
  15592. iwDefinition: "Definition",
  15593. iwEventDescription:"EventDescription",
  15594. iwPayloadType:"PayloadType",
  15595. iwHandled: "Handled",
  15596. iwPublished: "Published",
  15597. iwDescription: "Description",
  15598. iwTitle:"Title",
  15599. iwEvent:"Event",
  15600. iwDescRef:"DescRef",
  15601. iwGlobalid:"Globalid",
  15602. iwHandler: "Handler",
  15603. iwNewWire: "NewWire",
  15604. iwRemoveWire: "RemoveWire",
  15605. iwReadOnly: "ReadOnly",
  15606. iwItemSet: "ItemSet",
  15607. iwItem: "Item",
  15608. iwValue: "Value",
  15609. iwContent: "Content",
  15610. iwReceivedEvent: "ReceivedEvent",
  15611. iwSourceEvent: "SourceEvent",
  15612. iwTargetEvent: "TargetEvent",
  15613. iwMappedName: "MappedName",
  15614. iwStandalone: "Standalone"
  15615. },
  15616. CSSCLASS_PREFIXED_INSTANCE: { /* filled at runtime */},
  15617. CSSCLASS_PERSONALIZED: "mm-Personalized",
  15618. RESOURCE: {
  15619. src: "src",
  15620. id: "id",
  15621. globalid: "globalid",
  15622. mimeType: "mimeType",
  15623. callback: "callback",
  15624. version: "version",
  15625. blockInit:"blockInit",
  15626. skipLoad:"skipLoad"
  15627. },
  15628. EVENTS: {
  15629. onLoad:/*String*/ "onLoad",
  15630. onUnLoad:/*String*/ "onUnload",
  15631. onModeChanged:/*String*/ "onModeChanged",
  15632. onItemSetChanged:/*String*/ "onItemSetChanged",
  15633. unloadWidget:/*String*/ "/enabler/unloadWidget",
  15634. unSubscribeWire:/*String*/ "/enabler/unSubscribeWire",
  15635. modeChanged:/*String*/ "modeChanged",
  15636. onSizeChanged:/*String*/ "onSizeChanged",
  15637. onNavStateChanged:/*String*/ "onNavStateChanged",
  15638. onAttributeSaved:/*String*/ "com.ibm.mashups.iwidget.onAttributeSaved",
  15639. onWindowStateChanged:/*String*/ "onWindowStateChanged",
  15640. onIncompleteEventDescription:/*String*/"onIncompleteEventDescription"
  15641. },
  15642. eventservice:{
  15643. type:{
  15644. MAIN:"MAIN",
  15645. IFRAME:"IFRAME"
  15646. }
  15647. }
  15648. });
  15649. com.ibm.mm.iwidget.Constants = new com.ibm.mm.iwidget.Constants();
  15650. (function() {
  15651. for(var key in com.ibm.mm.iwidget.Constants.CSSCLASS_INSTANCE) {
  15652. if(Object.prototype.hasOwnProperty.call(com.ibm.mm.iwidget.Constants.CSSCLASS_INSTANCE,key)) {
  15653. com.ibm.mm.iwidget.Constants.CSSCLASS_PREFIXED_INSTANCE[key] = com.ibm.mm.iwidget.Constants.IW_PREFIX + com.ibm.mm.iwidget.Constants.CSSCLASS_INSTANCE[key];
  15654. }
  15655. }
  15656. })();
  15657. // TODO: move to legacy layer
  15658. iwConstants = com.ibm.mm.iwidget.Constants;
  15659. }
  15660. if(!dojo._hasResource["com.ibm.mashups.iwidget.widget.WireProvider"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  15661. dojo._hasResource["com.ibm.mashups.iwidget.widget.WireProvider"] = true;
  15662. dojo.provide("com.ibm.mashups.iwidget.widget.WireProvider");
  15663. /**
  15664. * Interface defines functions to access handled or published event descriptions.
  15665. * @ibm-spi
  15666. * @ibm-module iWidget2
  15667. */
  15668. dojo.declare("com.ibm.mashups.iwidget.widget.WireProvider", null, {
  15669. /**
  15670. * @private
  15671. */
  15672. constructor: function(id) {
  15673. },
  15674. /**
  15675. This method returns an array of supported wires.
  15676. @type com.ibm.mashups.iwidget.widget.Wire[]
  15677. @returns{com.ibm.mashups.iwidget.widget.Wire[] } array of Wire this iWidget is wired as target .
  15678. */
  15679. getWires: function() {
  15680. }
  15681. });
  15682. }
  15683. if(!dojo._hasResource["com.ibm.mashups.iwidget.IEventDescription_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  15684. dojo._hasResource["com.ibm.mashups.iwidget.IEventDescription_API"] = true;
  15685. dojo.provide("com.ibm.mashups.iwidget.IEventDescription_API");
  15686. dojo.provide("com.ibm.mashups.iwidget.IEventDescription");
  15687. /**
  15688. * It contains various pieces of information describing an event.
  15689. *
  15690. * @ibm-api
  15691. * @ibm-module iWidget2
  15692. */
  15693. dojo.declare("com.ibm.mashups.iwidget.IEventDescription", null, {
  15694. constructor: function() {
  15695. /**
  15696. * @private
  15697. */
  15698. },
  15699. /**
  15700. The alias of the event.
  15701. @type String
  15702. */
  15703. alias:/*String*/ "",
  15704. /**
  15705. The name of the event.
  15706. @type String
  15707. */
  15708. name:/*String*/ "",
  15709. /**
  15710. The type of any payload. If this is set to null, no information is being provided.
  15711. @type String
  15712. */
  15713. type:/*String*/ "",
  15714. /**
  15715. This provides the name of a callback function with the following signature and no return value.
  15716. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code> function(ievent) </code>
  15717. @type String
  15718. */
  15719. handlingFn:/*String*/ "",
  15720. /**
  15721. it returns a user-oriented description (markup allowed) of the event in the requested locale. If no locale is supplied, the default locale of the iWidget is used (with "en" being the default iWidget locale). The description is likely to be displayed when a user is wiring event flow between iWidgets.
  15722. @param{String} locale required locale. Can be NULL. If no locale is supplied, the default locale of the iWidget is used (with "en" being the default iWidget locale).
  15723. @type String
  15724. @returns{String} Return the description of a given locale,if no locale is provided, then the default locale of the iWidget is used.
  15725. @deprecated please use getAttribute("description",locale) instead
  15726. @since Deprecated since Version 2.0
  15727. */
  15728. getDescription: function(/*String*/locale) {
  15729. return null;
  15730. },
  15731. /**
  15732. This provides the default language of all the localized attributes within this event description.
  15733. @type String
  15734. */
  15735. lang:/*String*/ "",
  15736. /**
  15737. This indicates if an event is a handled event or not. Default value is false.
  15738. @type Boolean
  15739. */
  15740. isHandled: false,
  15741. /**
  15742. This indicates if an event is a published event or not. Default value is false.
  15743. @type Boolean
  15744. */
  15745. isPublished: false,
  15746. /**
  15747. This method returns the asking value of an attribute of the event description. Each event description should have title and description . Normally title and description should be globalized, default locale should be specified by using the iso language code, if missing, the value for the default locale will be en. <br/>
  15748. @param{String} attributeName name of attribute. Can Not be NULL.
  15749. @param{String} locale required locale. Can be NULL. If no locale is supplied, the default locale of the iWidget is used (with "en" being the default iWidget locale).
  15750. @type String
  15751. @returns{String} Return the value of the required attribute,if locale is provided, it returns locale specific value.
  15752. */
  15753. getAttribute: function(/*String*/attributeName,/*String*/ locale) {
  15754. return null;
  15755. },
  15756. /**
  15757. The method set the value for a given event description attribute.It returns a handle of this eventdescription, return null upon failure. If the locale parameter is absent, then the given attribute won't be locale specific.
  15758. @param{String} attributeName name of attribute. Can Not be NULL.
  15759. @param{String} attributeValue value of attribute. Can Not be NULL.
  15760. @param{String} locale optional, locale. Can be NULL.
  15761. @type com.ibm.mashups.iwidget.IEventDescription
  15762. @returns{com.ibm.mashups.iwidget.IEventDescription} return a handle of this eventdescription, return null upon failure..
  15763. */
  15764. setAttribute: function(/*String*/attributeName, /* String*/ attributeValue, /*String*/ locale) {
  15765. }
  15766. });
  15767. }
  15768. if(!dojo._hasResource["com.ibm.mm.iwidget.IEventDescriptionImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  15769. dojo._hasResource["com.ibm.mm.iwidget.IEventDescriptionImpl"] = true;
  15770. dojo.provide("com.ibm.mm.iwidget.IEventDescriptionImpl");
  15771. dojo.declare("com.ibm.mm.iwidget.IEventDescriptionImpl", com.ibm.mashups.iwidget.IEventDescription, {
  15772. constructor: function(/*String*/name,/*function*/ handlingFn,/*String*/ type,/*String*/ description,/*String[]*/ aliases, defaultLang,/*[]*/ descriptions) {
  15773. if (dojo.isString(name)) {
  15774. /*backward compatibility, some widget are still trying to create iEventDescription by using this constuctor as is!*/
  15775. var obj = {};
  15776. obj.name = name;
  15777. handlingFn = handlingFn || null;
  15778. if (handlingFn) {
  15779. obj.handlingFn = handlingFn;
  15780. obj.isHandled = true;
  15781. obj.isPublished = false; //backward compatibility either isPublished or isHandled
  15782. }
  15783. else {
  15784. obj.isPublished = true;
  15785. }
  15786. type = type || null;
  15787. if (type) {
  15788. obj.type = type;
  15789. }
  15790. defaultLang = defaultLang || null;
  15791. if (defaultLang) {
  15792. obj.lang = defaultLang;
  15793. }
  15794. else {
  15795. obj.lang = "en";
  15796. }
  15797. //how to set isPublished? or set it later
  15798. obj.attributes = {};
  15799. obj.localizedAttributes = {};
  15800. aliases = aliases || null;
  15801. if (aliases) {
  15802. obj.attributes.aliases = aliases;
  15803. }
  15804. descriptions = descriptions || null;
  15805. if (descriptions) {
  15806. obj.localizedAttributes = descriptions;
  15807. }
  15808. //backward compatibility
  15809. if (description) {
  15810. if (!obj.localizedAttributes[obj.lang]) {
  15811. obj.localizedAttributes[obj.lang] = {};
  15812. }
  15813. obj.localizedAttributes[obj.lang].description = description;
  15814. }
  15815. this._internalJsonObj = obj;
  15816. }
  15817. else {
  15818. this._internalJsonObj = name;
  15819. }
  15820. this.initPredefinedFields(this._internalJsonObj);
  15821. },
  15822. initPredefinedFields: function(obj) {
  15823. //initialize fields
  15824. this.name = obj.name;
  15825. this.type = obj.type;
  15826. this.lang = obj.lang;
  15827. this.handlingFn = obj.handlingFn;
  15828. this.isHandled = obj.isHandled;
  15829. this.isPublished = obj.isPublished;
  15830. // if (this.handlingFn) {
  15831. // this.isHandled = true;
  15832. // }
  15833. // else {
  15834. // this.isHandled = false;
  15835. // }
  15836. // // set isPublished to true only when both isHandled and isPublished is not defined
  15837. // // this is required for backward compatiblity reason
  15838. // if ((obj.isPublished && obj.isPublished == "true") || obj.isPublished) {
  15839. // this.isPublished = true;
  15840. // }
  15841. },
  15842. getDescription: function(locale) {
  15843. return this._getLocalizedAttribute("description", locale);
  15844. },
  15845. getTitle: function(locale) {
  15846. return this._getLocalizedAttribute("title", locale);
  15847. },
  15848. _getLocalizedAttribute: function(attributeName, locale) {
  15849. var attValue = null, altAttValue = null;
  15850. var lc = com.ibm.mashups.enabler.context.Factory.getLocalizedContext(locale, this.lang);
  15851. var finalLocale = lc.getLocale(this);
  15852. if (this.localemapping && this.localemapping[finalLocale]) {
  15853. finalLocale = this.localemapping[finalLocale];
  15854. }
  15855. if (this._internalJsonObj.localizedAttributes) {
  15856. altAttValue = this._internalJsonObj.localizedAttributes[finalLocale];
  15857. if (altAttValue) {
  15858. attValue = altAttValue[attributeName];
  15859. }
  15860. }
  15861. if (!attValue) {
  15862. attValue = this[attributeName];
  15863. }
  15864. if (typeof attValue == "undefined") {
  15865. attValue = null;
  15866. }
  15867. return attValue;
  15868. },
  15869. setOnRemoveWire: function(/*String*/handler) {
  15870. if (typeof handler == "undefined" || handler === null) {
  15871. handler = "onRemoveWire";
  15872. }
  15873. //this.onRemoveWire = handler;
  15874. if (typeof this._internalJsonObj.attributes == "undefined") {
  15875. this._internalJsonObj.attributes = {};
  15876. }
  15877. this._internalJsonObj.attributes.onRemoveWire = handler;
  15878. return this;
  15879. },
  15880. getOnRemoveWire: function() {
  15881. //can remove?
  15882. if (typeof this._internalJsonObj.attributes != "undefined" && this._internalJsonObj.attributes.onRemoveWire) {
  15883. return this._internalJsonObj.attributes.onRemoveWire;
  15884. }
  15885. return null;
  15886. },
  15887. setOnNewWire: function(/*String*/handler) {
  15888. if (typeof handler == "undefined" || handler === null) {
  15889. handler = "onNewWire";
  15890. }
  15891. //this.onNewWire = handler;
  15892. if (typeof this._internalJsonObj.attributes == "undefined") {
  15893. this._internalJsonObj.attributes = {};
  15894. }
  15895. this._internalJsonObj.attributes.onNewWire = handler;
  15896. return this;
  15897. },
  15898. getOnNewWire: function() {
  15899. if (typeof this._internalJsonObj.attributes != "undefined" && this._internalJsonObj.attributes.onNewWire) {
  15900. return this._internalJsonObj.attributes.onNewWire;
  15901. }
  15902. return null;
  15903. },
  15904. getLocales: function() {
  15905. var locales = [];
  15906. var mapping = {};
  15907. if (this._internalJsonObj.localizedAttributes) {
  15908. for (var i in this._internalJsonObj.localizedAttributes) {
  15909. if (Object.prototype.hasOwnProperty.call(this._internalJsonObj.localizedAttributes,i)) {
  15910. locales.push(i);
  15911. var normalizedLocale = com.ibm.mm.enabler.utils.LocaleHelper.normalizeLocale(i);
  15912. if (normalizedLocale != i) {
  15913. mapping[normalizedLocale] = i;
  15914. }
  15915. }
  15916. }
  15917. }
  15918. this.localemapping = mapping;
  15919. return locales;
  15920. },
  15921. toString: function() {
  15922. //return null or unserialized string, dojo will throw exception if it's not a valid Json obj
  15923. var temp = this.toJson();
  15924. return dojo.toJson(temp);
  15925. },
  15926. _getInternalJsonObj: function() {
  15927. return this._internalJsonObj;
  15928. },
  15929. toJson: function() {
  15930. var internalJson = {};
  15931. for (var i in this._internalJsonObj) {
  15932. if (Object.prototype.hasOwnProperty.call(this._internalJsonObj,i)) {
  15933. if (i == "handlingFn") { //it could be functionpointer
  15934. if (dojo.isFunction(this._internalJsonObj[i])) {
  15935. internalJson[i] = "HANDLEFN";
  15936. continue;
  15937. }
  15938. }
  15939. internalJson[i] = dojo.clone(this._internalJsonObj[i]);
  15940. }
  15941. }
  15942. return internalJson;
  15943. },
  15944. clone: function() {
  15945. var temp = dojo.toJson(this._internalJsonObj);
  15946. if (temp) {
  15947. return new com.ibm.mm.iwidget.IEventDescriptionImpl(dojo.fromJson(temp));
  15948. }
  15949. else {
  15950. return null;
  15951. }
  15952. },
  15953. getAttribute: function(attName, locale) {
  15954. if (!attName) {
  15955. return null;
  15956. }
  15957. if (!locale) {
  15958. if (this._internalJsonObj.attributes && typeof this._internalJsonObj.attributes[attName] != "undefined") {
  15959. return this._internalJsonObj.attributes[attName];
  15960. }
  15961. //get value for default locale
  15962. if (this._internalJsonObj.localizedAttributes && this._internalJsonObj.localizedAttributes[this.lang]) {
  15963. var attValue = this._internalJsonObj.localizedAttributes[this.lang][attName];
  15964. if (attValue) {
  15965. return attValue;
  15966. }
  15967. }
  15968. return null; //if no such attributes or localized attributes
  15969. }
  15970. else {
  15971. return this._getLocalizedAttribute(attName, locale);
  15972. }
  15973. },
  15974. setAttribute: function(attName, attValue, locale) {
  15975. //todo; if no locale defined and attributes is predefined such as "title","description", set the value on default locale
  15976. //return a handle of this eventdescription, return null upon failure.
  15977. if (!attName) {
  15978. return null;
  15979. }
  15980. if (typeof attValue == "undefined") {
  15981. return null; // allow value to be null
  15982. }
  15983. if (!locale) {
  15984. if (typeof this._internalJsonObj.attributes == "undefined") {
  15985. this._internalJsonObj.attributes = {};
  15986. }
  15987. this._internalJsonObj.attributes[attName] = attValue;
  15988. if (attValue === null) {
  15989. delete this._internalJsonObj.attributes[attName];
  15990. }
  15991. return this;
  15992. }
  15993. if (!this._internalJsonObj.localizedAttributes[locale]) {
  15994. this._internalJsonObj.localizedAttributes[locale] = {};
  15995. }
  15996. this._internalJsonObj.localizedAttributes[locale][attName] = attValue;
  15997. if (attValue === null) {
  15998. delete this._internalJsonObj.localizedAttributes[locale][attName];
  15999. }
  16000. return this;
  16001. },
  16002. copyRuntimeProperties: function(eventDesc2Copy) {
  16003. if ((!this.handlingFn) && (eventDesc2Copy.handlingFn)) {
  16004. this.handlingFn = eventDesc2Copy.handlingFn;
  16005. }
  16006. if ((!this._internalJsonObj.handlingFn) && (eventDesc2Copy._internalJsonObj.handlingFn)) {
  16007. this._internalJsonObj.handlingFn = eventDesc2Copy._internalJsonObj.handlingFn;
  16008. }
  16009. if (typeof this._internalJsonObj.attributes == "undefined") {
  16010. this._internalJsonObj.attributes = {};
  16011. }
  16012. for (name in eventDesc2Copy._internalJsonObj.attributes) {
  16013. if (!this._internalJsonObj.attributes[name]) {
  16014. this._internalJsonObj.attributes[name] = eventDesc2Copy._internalJsonObj.attributes[name];
  16015. }
  16016. }
  16017. }
  16018. });
  16019. }
  16020. if(!dojo._hasResource["com.ibm.mashups.iwidget.IEventDescription"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  16021. dojo._hasResource["com.ibm.mashups.iwidget.IEventDescription"] = true;
  16022. dojo.provide("com.ibm.mashups.iwidget.IEventDescription");
  16023. }
  16024. if(!dojo._hasResource["com.ibm.mashups.iwidget.widget.EventProvider"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  16025. dojo._hasResource["com.ibm.mashups.iwidget.widget.EventProvider"] = true;
  16026. dojo.provide("com.ibm.mashups.iwidget.widget.EventProvider");
  16027. /**
  16028. * Interface defines functions to access handled or published event descriptions.
  16029. * @ibm-spi
  16030. * @ibm-module iWidget2
  16031. */
  16032. dojo.declare("com.ibm.mashups.iwidget.widget.EventProvider", null, {
  16033. /**
  16034. * @private
  16035. */
  16036. constructor: function() {
  16037. },
  16038. /**
  16039. This method returns an array of event description. Only published event of this widget will be returned.
  16040. @type {com.ibm.mashups.iwidget.IEventDescription}
  16041. @returns{com.ibm.mashups.iwidget.IEventDescription[] } array of event description
  16042. */
  16043. getWidgetPublishedEvents: function() {
  16044. },
  16045. /**
  16046. This method returns an array of event description. Only handled event of this widget will be returned.
  16047. @type {com.ibm.mashups.iwidget.IEventDescription[]}
  16048. @returns{com.ibm.mashups.iwidget.IEventDescription[] } array of event description
  16049. */
  16050. getWidgetHandledEvents: function() {
  16051. },
  16052. /**
  16053. This method returns the required event.
  16054. @param {String}name name of required public event
  16055. @type {com.ibm.mashups.iwidget.IEventDescription}
  16056. @returns{com.ibm.mashups.iwidget.IEventDescription } an event description it returns NULL if event can't be found.
  16057. */
  16058. getPublicEvent: function(name) {
  16059. }
  16060. });
  16061. }
  16062. if(!dojo._hasResource["com.ibm.mashups.iwidget.widget.Properties_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  16063. dojo._hasResource["com.ibm.mashups.iwidget.widget.Properties_API"] = true;
  16064. dojo.provide("com.ibm.mashups.iwidget.widget.Properties_API");
  16065. dojo.provide("com.ibm.mashups.iwidget.widget.Properties");
  16066. /**
  16067. * Interface defines functions to iterates , updates and persist Properties.
  16068. * @ibm-spi
  16069. * @ibm-module iWidget2
  16070. */
  16071. dojo.declare("com.ibm.mashups.iwidget.widget.Properties", null, {
  16072. /**
  16073. * @private
  16074. */
  16075. constructor: function() {
  16076. },
  16077. /**
  16078. * This method returns the value of the required item
  16079. * @param{String} itemName name of the item.Must never be NULL.
  16080. * @param{String} locale the locale of the value to fetch. if locale isn't defined, the
  16081. * <code>DEFAULT_LOCALE</code> will be used
  16082. * @return{String} return the value of required item
  16083. */
  16084. getItemValue: function(/*String*/itemName, locale) {
  16085. },
  16086. /**
  16087. * This method returns an array of Strings,providing the name of each item.
  16088. * @return{String[]} return an array of items names and return NULL if the set contains no item
  16089. */
  16090. getAllNames: function() {
  16091. return null;
  16092. },
  16093. /**
  16094. * This methods returns the locales for the item specified by <code>itemName</code>
  16095. * @param{String} itemName the name of the item for which do get the locales.
  16096. * @return{String[]} return an array of locales valid for the specified itemName, returns an empty array if no localized item values are available.
  16097. */
  16098. getItemLocales: function(itemName) {
  16099. },
  16100. /**
  16101. * This method allows the caller to check whether a specific item is readOnly or not.
  16102. * @param{String} itemName the item name of the item to check readOnly
  16103. * @return{Boolean} <code>true</code> if the item exists and is read only, <code>false</code> otherwise.
  16104. */
  16105. isReadOnly: function(itemName) {
  16106. }
  16107. });
  16108. }
  16109. if(!dojo._hasResource["com.ibm.mm.iwidget.widget.PropertiesImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  16110. dojo._hasResource["com.ibm.mm.iwidget.widget.PropertiesImpl"] = true;
  16111. dojo.provide("com.ibm.mm.iwidget.widget.PropertiesImpl");
  16112. dojo.declare("com.ibm.mm.iwidget.widget.PropertiesImpl", com.ibm.mashups.iwidget.widget.Properties, {
  16113. DELETE_TOKEN: "com.ibm.mm.iwidget.widget.DELETE_TOKEN",
  16114. TYPE_NEW: "newItem",
  16115. TYPE_UPDATE: "updatedValue",
  16116. TYPE_REMOVE: "removedItem",
  16117. /**
  16118. * @param items {ItemSet JSON} the items this Properties class is based on
  16119. * @param defaultProps {Properties} The default properties object
  16120. **/
  16121. constructor: function(items, defaultProps) {
  16122. this._defaultProperties = defaultProps;
  16123. // create the new object
  16124. this._items = {};
  16125. if (items) {
  16126. this._items = items;
  16127. }
  16128. this._localizedItems = {};
  16129. // define the default locale of this properties set
  16130. this.DEFAULT_LOCALE = ibmConfig[com.ibm.mashups.enabler.services.ConfigConstants.DEFAULT_LOCALE];
  16131. if (!this.DEFAULT_LOCALE) {
  16132. this.DEFAULT_LOCALE = "en";
  16133. }
  16134. },
  16135. /**
  16136. * Internal method which can be used by ENABLER components for determining the default locale of an Properties Element
  16137. */
  16138. _getItemDefaultLocale: function(itemName) {
  16139. var defLocale = null;
  16140. if (this._items[itemName]) {
  16141. if (this._items[itemName].defaultLocale) {
  16142. defLocale = this._items[itemName].defaultLocale;
  16143. }
  16144. }
  16145. if (!defLocale) {
  16146. defLocale = null;
  16147. }
  16148. return defLocale;
  16149. },
  16150. getLocalizedItemValue:function(itemName,locale){
  16151. //internal function, used by private ItemSet
  16152. //no fallback to default locale
  16153. if (!itemName || !locale) {
  16154. return;
  16155. }
  16156. if (!(itemName in this._items) && !this._defaultProperties) {
  16157. return null;
  16158. }
  16159. var item = this._items[itemName];
  16160. var value = null;
  16161. if (!item.values) {
  16162. return null;
  16163. }
  16164. var matchLocales = [];
  16165. for (var i in item.values) {
  16166. if (Object.prototype.hasOwnProperty.call(item.values,i)) {
  16167. matchLocales.push(i);
  16168. }
  16169. }
  16170. var normalizedLocale;
  16171. // check if we have a value for the specified locale
  16172. normalizedLocale = com.ibm.mm.enabler.utils.LocaleHelper.matchLocale(locale, matchLocales);
  16173. for (var i in item.values) {
  16174. if (normalizedLocale == com.ibm.mm.enabler.utils.LocaleHelper.normalizeLocale(i)) {
  16175. value = item.values[i];
  16176. break;
  16177. }
  16178. }
  16179. if (value == this.DELETE_TOKEN) {
  16180. return null;
  16181. }
  16182. return value;
  16183. },
  16184. getItemValue: function(itemName, locale) {
  16185. // if we don't have an item and don't have default properties, we can exit right away
  16186. if (!(itemName in this._items) && !this._defaultProperties) {
  16187. return null;
  16188. }
  16189. // if we don't have the item we can delegate to default props (which we checked earlier)
  16190. if (!(itemName in this._items)) {
  16191. return this._defaultProperties.getItemValue(itemName, locale);
  16192. }
  16193. // seems we have an item, so let's do the magic
  16194. var item = this._items[itemName];
  16195. var value = null;
  16196. if ((typeof locale == "undefined" || locale === null) && typeof item.value != "undefined" && item.value !== null) {
  16197. if (item.value == this.DELETE_TOKEN) {
  16198. return null;
  16199. }
  16200. return item.value;
  16201. }
  16202. if (!item.values) {
  16203. return null;
  16204. }
  16205. var matchLocales = [];
  16206. for (var i in item.values) {
  16207. if (Object.prototype.hasOwnProperty.call(item.values,i)) {
  16208. matchLocales.push(i);
  16209. }
  16210. }
  16211. var normalizedLocale;
  16212. // check if we have a value for the specified locale
  16213. if (locale) {
  16214. normalizedLocale = com.ibm.mm.enabler.utils.LocaleHelper.matchLocale(locale, matchLocales);
  16215. for (var i in item.values) {
  16216. if (normalizedLocale == com.ibm.mm.enabler.utils.LocaleHelper.normalizeLocale(i)) {
  16217. value = item.values[i];
  16218. break;
  16219. }
  16220. }
  16221. }
  16222. // test the default locale of the item
  16223. if (item.defaultLocale && value === null) {
  16224. normalizedLocale = com.ibm.mm.enabler.utils.LocaleHelper.matchLocale(item.defaultLocale, matchLocales);
  16225. for (var i in item.values) {
  16226. if (normalizedLocale == com.ibm.mm.enabler.utils.LocaleHelper.normalizeLocale(i)) {
  16227. value = item.values[i];
  16228. break;
  16229. }
  16230. }
  16231. }
  16232. // test the default of the sytem
  16233. if (this.DEFAULT_LOCALE && value === null) {
  16234. normalizedLocale = com.ibm.mm.enabler.utils.LocaleHelper.matchLocale(this.DEFAULT_LOCALE, matchLocales);
  16235. for (var i in item.values) {
  16236. if (normalizedLocale == com.ibm.mm.enabler.utils.LocaleHelper.normalizeLocale(i)) {
  16237. value = item.values[i];
  16238. break;
  16239. }
  16240. }
  16241. }
  16242. // otherwise the first locale wins
  16243. if (value === null) {
  16244. for (var lang in item.values) {
  16245. if (Object.prototype.hasOwnProperty.call(item.values,lang)) {
  16246. value = item.values[lang];
  16247. break;
  16248. }
  16249. }
  16250. }
  16251. if (value == this.DELETE_TOKEN) {
  16252. return null;
  16253. }
  16254. return value;
  16255. },
  16256. getItemLocales: function(itemName) {
  16257. var locales = [];
  16258. if (itemName in this._items && this._items[itemName].values) {
  16259. for (var locale in this._items[itemName].values) {
  16260. if (Object.prototype.hasOwnProperty.call(this._items[itemName].values,locale)) {
  16261. locales.push(locale);
  16262. }
  16263. }
  16264. }
  16265. /*if (itemName in this._items && this._items[itemName].value) {
  16266. locales.push("");
  16267. }*/
  16268. if (locales.length === 0) {
  16269. return null;
  16270. }
  16271. return locales;
  16272. },
  16273. getAllNames: function() {
  16274. //return empty array if there's no item
  16275. var defaultNames = [];
  16276. if (this._defaultProperties) {
  16277. defaultNames = this._defaultProperties.getAllNames();
  16278. }
  16279. var mergedItems = {};
  16280. for (var i = 0; i < defaultNames.length; i++) {
  16281. mergedItems[defaultNames[i]] = null;
  16282. }
  16283. for (var itemName in this._items) {
  16284. if (this._items[itemName] && this._items[itemName]._change && this._items[itemName]._change.changeType == this.TYPE_REMOVE) {
  16285. if (itemName in mergedItems) {
  16286. delete mergedItems[itemName];
  16287. }
  16288. }
  16289. else {
  16290. mergedItems[itemName] = null;
  16291. }
  16292. }
  16293. var names = [];
  16294. for (var itemName2 in mergedItems) {
  16295. if (Object.prototype.hasOwnProperty.call(mergedItems,itemName2)) {
  16296. names.push(itemName2);
  16297. }
  16298. }
  16299. return names;
  16300. },
  16301. isReadOnly: function(itemName) {
  16302. var item = this._items[itemName];
  16303. return (this._defaultProperties && this_defaultProperties.isReadOnly(itemName)) ||
  16304. (item && item.readOnly);
  16305. }
  16306. });
  16307. }
  16308. if(!dojo._hasResource["com.ibm.mashups.iwidget.widget.Properties"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  16309. dojo._hasResource["com.ibm.mashups.iwidget.widget.Properties"] = true;
  16310. dojo.provide("com.ibm.mashups.iwidget.widget.Properties");
  16311. }
  16312. if(!dojo._hasResource["com.ibm.mashups.iwidget.widget.PropertiesProvider"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  16313. dojo._hasResource["com.ibm.mashups.iwidget.widget.PropertiesProvider"] = true;
  16314. dojo.provide("com.ibm.mashups.iwidget.widget.PropertiesProvider");
  16315. /**
  16316. * Read-Only interface defines functions to access properties that's defined with iWidget.
  16317. * @ibm-spi
  16318. * @ibm-module iWidget2
  16319. */
  16320. dojo.declare("com.ibm.mashups.iwidget.widget.PropertiesProvider", null, {
  16321. /**
  16322. * @private
  16323. */
  16324. constructor: function() {
  16325. },
  16326. /**
  16327. This method returns an object that contains iDescriptor items as defined by iWidget spec. It contains default title and icon
  16328. @type com.ibm.mashups.iwidget.widget.Properties
  16329. @returns{com.ibm.mashups.iwidget.widget.Properties } object that contains iWidget iDescriptor items information
  16330. */
  16331. getIDescriptorItems: function() {
  16332. },
  16333. /**
  16334. This method returns an object that contains attributes as defined by iWidget spec.
  16335. @type com.ibm.mashups.iwidget.widget.Properties
  16336. @returns{com.ibm.mashups.iwidget.widget.Properties } object that contains iWidget iDescriptor items information
  16337. */
  16338. getAttributes: function() {
  16339. }
  16340. });
  16341. }
  16342. if(!dojo._hasResource["com.ibm.mashups.iwidget.widget.IWidgetDefinition_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  16343. dojo._hasResource["com.ibm.mashups.iwidget.widget.IWidgetDefinition_API"] = true;
  16344. dojo.provide("com.ibm.mashups.iwidget.widget.IWidgetDefinition_API");
  16345. dojo.provide("com.ibm.mashups.iwidget.widget.IWidgetDefinition");
  16346. /**
  16347. * Interface defines functions to access all the data object in widget definition. PropertiesProvider is not implemented.
  16348. * @ibm-spi
  16349. * @ibm-module iWidget2
  16350. */
  16351. dojo.declare("com.ibm.mashups.iwidget.widget.IWidgetDefinition",[com.ibm.mashups.iwidget.widget.EventProvider,com.ibm.mashups.iwidget.widget.PropertiesProvider],{
  16352. /**
  16353. * @private
  16354. */
  16355. constructor:function(){
  16356. },
  16357. /**
  16358. This method returns an array of supported modes such as "view" and "edit".
  16359. @returns{String[] } array of supported modes this iWidget supports.
  16360. */
  16361. getSupportedModes:function(){
  16362. },
  16363. /**
  16364. This method returns a JSON based spec compliant object that represents all the data that's defined in widget xml.<p/>
  16365. Rule to follow:<br/>
  16366. 1. Element -- "iw:iwidget" is considered to be root Element and a root object is created from here.<p/>
  16367. 2. Any attribute of this element will be a field in the root object. '_' will be added as prefix to field names.<br/>
  16368. ":" within any namespaced attribute will be replaced with "_".
  16369. <code>&lt;iw:iwidget id="map" xml:base="/root/test/" allowInstanceContent="false"......&gt;</code><br/>
  16370. { _id:"map",_xml_base:"/root/test/",_allowInstanceContent:"false"......}<p/>
  16371. 3. All repreatable elements, element name (append with "s") is used as a field name and an object is created to contain all the repeatable elements.
  16372. Within that object, value of "id" attribute is used as field name for an individual element if id attribute is available.<br/>
  16373. {<br/>
  16374. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resources:{<br/>
  16375. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"myId":{_id:"myId",_src:"my.js"},<br/>
  16376. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "myOtherId":{_id:"myOtherId",_src:"my2.js"}<br/>
  16377. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br/>
  16378. }<p/>
  16379. 4. For "iw:content" elements, "contents" is used as the key in the parent object and an object is created to contain all the content elements.<br/>
  16380. For each "content" element, "mode" attribute is used as the key and CDATA section is saved as the value.<br/>
  16381. {<br/>
  16382. &nbsp;&nbsp;&nbsp;contents:{<br/>
  16383. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "view": {<br/>
  16384. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "_mode": "view",<br/>
  16385. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "value": "mycontent"<br/>
  16386. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br/>
  16387. &nbsp;&nbsp;&nbsp; }<br/>
  16388. }<p/>
  16389. 5. For "iw:alt" elements,"alts" is used as the key in parent object and an object is created to contain all the alt elements.<br/>
  16390. For each "alt" element, "lang" attribute is used as the key and all the attributes are saved per attributes convention.<br/>
  16391. eventDescname:{<br/>
  16392. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_id:"eventDescnname",<br/>
  16393. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_payloadType:"payloadType",<br/>
  16394. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alts:{<br/>
  16395. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"en":{_lang:'en',_description:"description",_descriptionURI:"descriptionURI"},<br/>
  16396. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"zh":{_lang:'zh',_description:"description",_descriptionURI:"descriptionURI"}<br/>
  16397. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>
  16398. }<p/>
  16399. An example of simple iWidget and the return result.<br/>
  16400. <code>&lt;iw:iwidget id="stock" xmlns:iw="http://www.ibm.com/xmlns/prod/iWidget" iScope="stock" allowInstanceContent="true" supportedModes="view edit " mode="view" lang="en"></code><br/>
  16401. &nbsp;&nbsp;&nbsp;<code> &lt;iw:itemSet id="attributes" private="true" onItemSetChanged="changeItemSet"&gt;</code><br/>
  16402. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code> &lt;iw:item id="broker" readOnly="false" value="Etrade" /&gt;</code><br/>
  16403. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code> &lt;iw:item id="company" value="IBM" /&gt;</code><br/>
  16404. &nbsp;&nbsp;&nbsp;<code>&lt;/iw:itemSet&gt;</code><br/>
  16405. &nbsp;&nbsp;&nbsp;<code> &lt;iw:event id="sendStockData" eventDescName="sendStockDataDesc" published="true" onNewWire="sendData" /&gt; </code><br/>
  16406. &nbsp;&nbsp;&nbsp;<code> &lt;iw:eventDescription id="sendStockDataDesc" payloadType="stockData" title="Send stock data" lang="en" &gt;</code><br/>
  16407. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code>&lt;iw:alt title="Send stock data" lang="en" /&gt; </code><br/>
  16408. &nbsp;&nbsp;&nbsp;<code>&lt;/iw:eventDescription&gt;</code><br/>
  16409. &nbsp;&nbsp;&nbsp;<code>&lt;iw:resource src="stock.js" id="stock" /&gt;</code><br/>
  16410. &nbsp;&nbsp;&nbsp;<code>&lt;iw:content mode="view"&gt;
  16411. &lt;![CDATA[
  16412. mycontent
  16413. ]]&gt;
  16414. &lt;/iw:content&gt;</code><br/>
  16415. &nbsp;&nbsp;&nbsp;<code>&lt;/iw:iwidget&gt;</code><p/>
  16416. Example of returnin json object. <br/>
  16417. <code>
  16418. { _id:"map",_allowInstanceContent:"true",_iScope:"stock",_supportedModes:"view edit",_mode:"view",_lang:"en",<br/>
  16419. &nbsp;&nbsp;&nbsp; itemSets:{<br/>
  16420. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"attributes":{ _id:"attributes", _private:"true",_onItemSetChanged:"changedItemSet",<br/>
  16421. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; items:{ <br/>
  16422. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "broker":{ _id:"broker",_readOnly:"false", _value:"Etrade"},<br/>
  16423. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "company":{ _id:"company",_value;"IBM"} <br/>
  16424. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br/>
  16425. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br/>
  16426. &nbsp;&nbsp;&nbsp;},<br/>
  16427. &nbsp;&nbsp;&nbsp;events:{ <br/>
  16428. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"sendStockData":{ _id:"sendStockData", _eventDescName:"sendStockDataDesc", _published:"true",_onNewWire:"sendData"}<br/>
  16429. &nbsp;&nbsp;&nbsp;},<br/>
  16430. &nbsp;&nbsp;&nbsp;eventDescriptions:{<br/>
  16431. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"sendStockDataDesc":{ _id:"sendStockDataDesc", _payloadType:"stockData",_title:"Send stock data",_lang:"en",<br/>
  16432. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; alts:{<br/>
  16433. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "en":{ _lang:"en",_title:"Send stock data"} <br/>
  16434. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br/>
  16435. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br/>
  16436. &nbsp;&nbsp;&nbsp; },<br/>
  16437. &nbsp;&nbsp;&nbsp; resources:{<br/>
  16438. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"stock":{ _id:"stock", _src:"stock.js"}<br/>
  16439. &nbsp;&nbsp;&nbsp;},<br/>
  16440. &nbsp;&nbsp;&nbsp;contents:{<br/>
  16441. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "view": {<br/>
  16442. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "_mode": "view",<br/>
  16443. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "value": "mycontent"<br/>
  16444. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br/>
  16445. &nbsp;&nbsp;&nbsp; }<br/>
  16446. }<br/>
  16447. </code>
  16448. @returns{object} a JSON based, spec compliant object that represents all the data that's defined in widget.xml
  16449. */
  16450. toSpecObject:function(){
  16451. }
  16452. });
  16453. }
  16454. if(!dojo._hasResource["com.ibm.mm.iwidget.widget.IWidgetDefinitionDefaultImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  16455. dojo._hasResource["com.ibm.mm.iwidget.widget.IWidgetDefinitionDefaultImpl"] = true;
  16456. dojo.provide("com.ibm.mm.iwidget.widget.IWidgetDefinitionDefaultImpl");
  16457. //no support on EventProvider,
  16458. //todo toSpecObject should just return the json object
  16459. dojo.declare("com.ibm.mm.iwidget.widget.IWidgetDefinitionDefaultImpl", com.ibm.mashups.iwidget.widget.IWidgetDefinition, {
  16460. namespaces: {
  16461. "iw": "http://www.ibm.com/xmlns/prod/iWidget"
  16462. },
  16463. reservedAttributes: {
  16464. iScope: "iScope",
  16465. supportedModes: "supportedModes",
  16466. id: "id",
  16467. allowInstanceContent: "allowInstanceContent",
  16468. lang: "language",
  16469. "xml_lang":"_xml_lang",
  16470. "xmlns_iw": "_xmlns_iw",
  16471. supportedWindowStates: "supportedWindowStates",
  16472. "xml_base": "_xml_base",
  16473. sandbox:"sandbox"
  16474. },
  16475. constructor: function(/*/object*/widgetDef, xmlStr, specObject) {
  16476. this.widgetDef = widgetDef; //xmlStr is now widgetDef.xmlStr, xmlData is rarely used so only load when it's called in toSpec function.
  16477. if (xmlStr) {
  16478. this.xmlStr = xmlStr;
  16479. }
  16480. if (specObject) {
  16481. this.specObject = specObject;
  16482. this._specObjectToWidgetDef();
  16483. }
  16484. },
  16485. getXmlBase: function() {
  16486. if (this.widgetDef.xmlBase) {
  16487. return this.widgetDef.xmlBase;
  16488. }
  16489. return null;
  16490. },
  16491. getAllowInstanceContent: function() {
  16492. return this.widgetDef.allowInstanceContent;
  16493. },
  16494. getResources: function() {
  16495. if (!this.resources) {
  16496. this.resources = [];
  16497. }
  16498. return this.resources;
  16499. },
  16500. getIScope: function() {
  16501. return this.widgetDef.iScope;
  16502. },
  16503. getWidgetEvents: function() {
  16504. return this.widgetDef.widgetEvents;
  16505. },
  16506. getMarkupByMode: function(mode) {
  16507. if (this.widgetDef.markup) {
  16508. if (!mode) {
  16509. mode = "view";
  16510. }
  16511. var temp = this.widgetDef.markup[mode];
  16512. return temp;
  16513. }
  16514. else {
  16515. return null;
  16516. }
  16517. },
  16518. setMarkupByMode: function(mode, elem) {
  16519. if (this.widgetDef.markup) {
  16520. if (!mode) {
  16521. mode = "view";
  16522. }
  16523. this.widgetDef.markup[mode] = elem; //simple replacement
  16524. return this;
  16525. }
  16526. return null;
  16527. },
  16528. _getManagedItemSetListener: function(itemsetname) {
  16529. if (!itemsetname) {
  16530. return null;
  16531. }
  16532. if (itemsetname != iwConstants.ATTRIBUTES && itemsetname != iwConstants.IDESCRIPTOR) {
  16533. return null;
  16534. }
  16535. if (this.widgetDef.itemSetsArr) {
  16536. var defAttrItemSet = this.widgetDef.itemSetsArr[itemsetname];
  16537. if (defAttrItemSet && defAttrItemSet.onItemSetChanged) {
  16538. return defAttrItemSet.onItemSetChanged;
  16539. }
  16540. }
  16541. return null;
  16542. },
  16543. _getManagedItemSetItems: function(itemsetname, simpleAttributes) {
  16544. var properties = {};
  16545. if (this.widgetDef.itemSetsArr) {
  16546. var defAttrItemSet = this.widgetDef.itemSetsArr[itemsetname];
  16547. if (defAttrItemSet) {
  16548. for (var itemName in defAttrItemSet.items) {
  16549. if (Object.prototype.hasOwnProperty.call(defAttrItemSet.items, itemName)) {
  16550. properties[itemName] = defAttrItemSet.items[itemName]; // the new internal json itemset notation is compatible with the SPI
  16551. }
  16552. }
  16553. }
  16554. }
  16555. // determine the default locale for fallback
  16556. /*var lang = ibmConfig[com.ibm.mashups.enabler.services.ConfigConstants.DEFAULT_LOCALE];
  16557. if (!lang)
  16558. lang = "en";*/
  16559. simpleAttributes = simpleAttributes || null;
  16560. if (simpleAttributes) {
  16561. for (var attName in simpleAttributes) {
  16562. if (Object.prototype.hasOwnProperty.call(simpleAttributes,attName)) {
  16563. var value = simpleAttributes[attName];
  16564. if (typeof value != "undefined" && value !== null) {
  16565. var property = {};
  16566. //property.defaultLocale = lang;
  16567. property.readOnly = false;
  16568. //property.values = {};
  16569. //property.values[lang] = value;
  16570. property.value = value;
  16571. property.id = attName;
  16572. properties[attName] = property;
  16573. }
  16574. }
  16575. }
  16576. }
  16577. return new com.ibm.mm.iwidget.widget.PropertiesImpl(properties);
  16578. },
  16579. /**
  16580. * PropertiesProvider Impl
  16581. */
  16582. getAttributes: function() {
  16583. if (!this.attributeProperties) {
  16584. this.attributeProperties = this._getManagedItemSetItems(iwConstants.ATTRIBUTES, this.widgetDef.simpleAttributes);
  16585. }
  16586. return this.attributeProperties;
  16587. },
  16588. /**
  16589. * PropertiesProvider Impl
  16590. */
  16591. getIDescriptorItems: function() {
  16592. if (!this.idescriptorProperties) {
  16593. this.idescriptorProperties = this._getManagedItemSetItems(iwConstants.IDESCRIPTOR, this.widgetDef.iDescriptor);
  16594. }
  16595. return this.idescriptorProperties;
  16596. },
  16597. getAllItemSetNames: function() {
  16598. var names = [];
  16599. if (!this.widgetDef.itemSetsArr) {
  16600. return names;
  16601. }
  16602. for (var itemName in this.widgetDef.itemSetsArr) {
  16603. if (Object.prototype.hasOwnProperty.call(this.widgetDef.itemSetsArr,itemName)) {
  16604. var itemSetWrapper = this.widgetDef.itemSetsArr[itemName];
  16605. if (typeof(itemSetWrapper) != "undefined" && itemName != iwConstants.ATTRIBUTES && itemName != iwConstants.IDESCRIPTOR) {
  16606. names.push(itemSetWrapper.id);
  16607. }
  16608. }
  16609. }
  16610. return names;
  16611. },
  16612. getItemSet: function(/*String*/name) {
  16613. if (name == "attributes") {
  16614. return this.getAttributes();
  16615. }
  16616. var itemSetWrapper = this.widgetDef.itemSetsArr[name] || null;
  16617. if (!itemSetWrapper) {
  16618. return null;
  16619. }
  16620. return itemSetWrapper;
  16621. },
  16622. getWidgetId: function() {
  16623. return this.widgetDef.id;
  16624. },
  16625. getWidgetName: function() {
  16626. return this.widgetDef.id;
  16627. },
  16628. getPayloadDefs: function() {
  16629. return null;
  16630. },
  16631. getPayloadDef: function(name) {
  16632. return null;
  16633. },
  16634. getPayloadDefNames: function() {
  16635. var arr = [];
  16636. return arr;
  16637. },
  16638. getSupportedModes: function() {
  16639. var temp = this.widgetDef.supportedModes;
  16640. if (!temp) {
  16641. return null;
  16642. }
  16643. var arr = temp.split(" ");
  16644. return arr;
  16645. },
  16646. getSupportedWindowStates: function() {
  16647. var temp = this.widgetDef.supportedWindowStates;
  16648. if (!temp) {
  16649. return null;
  16650. }
  16651. var arr = temp.split(" ");
  16652. return arr;
  16653. },
  16654. getDefaultLanguage: function() {
  16655. return this.widgetDef.lang;
  16656. },
  16657. getMarkup: function() {
  16658. return this.widgetDef.markup;
  16659. },
  16660. _specObjectToWidgetDef: function() {
  16661. this.widgetDef = {};
  16662. if (null === this.specObject) {
  16663. return;
  16664. }
  16665. // id
  16666. var temp = this.specObject._id;
  16667. if (!temp) {
  16668. temp = this.specObject._name;
  16669. }
  16670. this.widgetDef.id = null;
  16671. this.widgetDef.name = null;
  16672. if (temp){
  16673. this.widgetDef.id = temp;
  16674. this.widgetDef.name = temp;
  16675. }
  16676. // allowInstanceContent
  16677. this.widgetDef.allowInstanceContent = false;
  16678. temp = this.specObject._allowInstanceContent;
  16679. if (temp && temp == "true") {
  16680. this.widgetDef.allowInstanceContent = true;
  16681. }
  16682. // iScope
  16683. temp = this.specObject._iScope;
  16684. this.widgetDef.iScope = null;
  16685. if (temp) {
  16686. this.widgetDef.iScope = temp;
  16687. }
  16688. // supportedModes
  16689. temp = this.specObject._supportedModes;
  16690. if (!temp) {
  16691. temp = "view";
  16692. }
  16693. this.widgetDef.supportedModes = temp;
  16694. // supportedWindowStates
  16695. temp = this.specObject._supportedWindowStates;
  16696. if (!temp) {
  16697. temp = "normal";
  16698. }
  16699. this.widgetDef.supportedWindowStates = temp;
  16700. // lang
  16701. temp = this.specObject._lang;
  16702. if (!temp) {
  16703. temp = this.specObject._xml_lang;
  16704. }
  16705. if (!temp){
  16706. temp = "en";
  16707. }
  16708. this.widgetDef.lang = temp;
  16709. // xml:base
  16710. temp = this.specObject._xml_base;
  16711. if (temp){
  16712. this.widgetDef.xmlBase = temp;
  16713. }
  16714. // iDescriptor
  16715. var iDescriptorItems = iwConstants.iDescriptorItems;
  16716. var iDescriptor = {};
  16717. for (var i in iDescriptorItems) {
  16718. if (Object.prototype.hasOwnProperty.call(iDescriptorItems,i)) {
  16719. var name = iDescriptorItems[i];
  16720. var value = this.specObject['_' + name];
  16721. if (typeof value == "undefined") {
  16722. value = null;
  16723. }
  16724. iDescriptor[name] = value;
  16725. }
  16726. }
  16727. this.widgetDef.iDescriptor = iDescriptor;
  16728. // simple attributes and widget events
  16729. var simpleAttributes = {};
  16730. var widgetEvents = {};
  16731. for (var j in this.specObject) {
  16732. if (Object.prototype.hasOwnProperty.call(this.specObject,j)) {
  16733. // only root level attributes
  16734. if (0 !== j.indexOf('_')) {
  16735. continue;
  16736. }
  16737. var attr = j;
  16738. attr = attr.substr(1);
  16739. if (attr.indexOf("on") !== 0 && !iwConstants.iDescriptorItems[attr] && !this.reservedAttributes[attr]) {
  16740. simpleAttributes[attr] = this.specObject[j];
  16741. }
  16742. else if (attr.indexOf("on") === 0) {
  16743. widgetEvents[attr] = this.specObject[j];
  16744. }
  16745. }
  16746. }
  16747. this.widgetDef.simpleAttributes = simpleAttributes;
  16748. this.widgetDef.widgetEvents = widgetEvents;
  16749. // markup
  16750. this.widgetDef.markup = this._extractMarkupFromSpecObject();
  16751. // itemSets
  16752. var itemSets = this._extractItemSetsFromSpecObject(this.widgetDef);
  16753. if (null !== itemSets) {
  16754. this.widgetDef.itemSetsArr = itemSets;
  16755. }
  16756. // public events
  16757. this.widgetDef.publicEvents = this._extractEventsFromSpecObject();
  16758. // resources
  16759. this.widgetDef.resources = this._extractResourcesFromSpecObject();
  16760. // payload defs
  16761. // this.widgetDef.payloadDefs = this._extractPayloadDefsFromSpecObject();
  16762. // event descriptions
  16763. this.widgetDef.eventDescriptions = this._extractEventDescFromSpecObject();
  16764. },
  16765. // never used
  16766. // _extractEventsFromSpecObject: function() {
  16767. // // widget events
  16768. // var widgetEvents = {};
  16769. // for (var i in this.specObject) {
  16770. // var handler = this.specObject[i];
  16771. // if (typeof handler != "undefined" && handler != null) {
  16772. // widgetEvents[event.name] = handler;
  16773. // }
  16774. // }
  16775. // return widgetEvents;
  16776. // },
  16777. _extractMarkupFromSpecObject: function() {
  16778. var contents = this.specObject.contents;
  16779. var widgetDefContents = {};
  16780. for (var mode in contents) {
  16781. if (Object.prototype.hasOwnProperty.call(contents,mode)) {
  16782. if (contents[mode]) {
  16783. widgetDefContents[mode] = {};
  16784. if (contents[mode]._uri) {
  16785. widgetDefContents[mode].uri = contents[mode]._uri;
  16786. }
  16787. if (contents[mode].value) {
  16788. widgetDefContents[mode].content = contents[mode].value;
  16789. }
  16790. }
  16791. }
  16792. }
  16793. return widgetDefContents;
  16794. },
  16795. _extractItemSetsFromSpecObject: function(widgetDef) {
  16796. var itemSets = this.specObject.itemSets;
  16797. if (itemSets) {
  16798. var itemSetsArr = {};
  16799. var shareableItemSetsArr = {};
  16800. for (var i in itemSets) {
  16801. if (Object.prototype.hasOwnProperty.call(itemSets,i)) {
  16802. var itemSet = itemSets[i];
  16803. var id = i;
  16804. var onItemSetChanged = itemSet._onItemSetChanged;
  16805. var temp = itemSet._private;
  16806. var isPrivate = true;
  16807. if (temp && temp == "false") {
  16808. isPrivate = false;
  16809. }
  16810. var alias = itemSet._alias?itemSet._alias:null;
  16811. var descriptionRef = itemSet._description;
  16812. var itemSetWrapper = {
  16813. id: id,
  16814. onItemSetChanged: onItemSetChanged,
  16815. isPrivate: isPrivate
  16816. };
  16817. if (alias){
  16818. itemSetWrapper.alias = alias;
  16819. }
  16820. itemSetWrapper.items = {};
  16821. var items = itemSet.items; // WARNING: this assumes that an itemset only contains items !
  16822. for (var j in items) {
  16823. if (Object.prototype.hasOwnProperty.call(items,j)) {
  16824. var item = items[j];
  16825. var readOnly = false;
  16826. var readOnlyAtt = item._readOnly;
  16827. if (readOnlyAtt && readOnlyAtt == "true") {
  16828. readOnly = true;
  16829. }
  16830. var id2 = item._id;
  16831. var alias2 = item._alias?item._alias:null;
  16832. var value = item._value;
  16833. var lang = item._lang;
  16834. if (!lang){
  16835. lang = item._xml_lang;
  16836. }
  16837. var anItem = {};
  16838. anItem.id = id2;
  16839. if (alias2){
  16840. anItem.alias = alias2;
  16841. }
  16842. anItem.readOnly = readOnly;
  16843. if (lang) {
  16844. anItem.defaultLocale = lang;
  16845. }
  16846. //value could be ""
  16847. if (typeof value != "undefined" && value !== null && !lang) {
  16848. anItem.value = value;
  16849. }
  16850. if (typeof value != "undefined" && value !== null && lang){
  16851. anItem.values = {};
  16852. anItem.values[lang]=value;
  16853. }
  16854. var values = item.alts;
  16855. for (var v in values) {
  16856. if (Object.prototype.hasOwnProperty.call(values,v)) {
  16857. var valueNode = values[v];
  16858. var locale = v;
  16859. var localeValue = valueNode._value;
  16860. if (!anItem.values) {
  16861. anItem.values = {};
  16862. }
  16863. anItem.values[locale] = localeValue;
  16864. // if default value for default locale is defined in alts, remove default value here so no duplicates
  16865. if (lang && locale == lang && anItem.value){
  16866. delete anItem.value;
  16867. }
  16868. }
  16869. }
  16870. itemSetWrapper.items[id2] = anItem;
  16871. }
  16872. }
  16873. if (isPrivate === true) {
  16874. itemSetsArr[id] = itemSetWrapper;
  16875. }
  16876. else {
  16877. shareableItemSetsArr[id] = itemSetWrapper;
  16878. }
  16879. }
  16880. }
  16881. widgetDef.shareableItemSetsArr = shareableItemSetsArr;
  16882. return itemSetsArr;
  16883. }
  16884. return null;
  16885. },
  16886. _extractEventsFromSpecObject: function() {
  16887. var events = this.specObject.events;
  16888. var eventsArray = {};
  16889. if (events && events.length !== 0) {
  16890. for (var j in events) {
  16891. if (Object.prototype.hasOwnProperty.call(events,j)) {
  16892. var event = events[j];
  16893. //todo. handler attributes
  16894. var iEvent = {};
  16895. for (var i in event) {
  16896. if (Object.prototype.hasOwnProperty.call(event,i)) {
  16897. var name = i;
  16898. if (0 === i.indexOf('_')) {
  16899. name = name.substr(1);
  16900. }
  16901. var value = event[i];
  16902. if (name == "eventDescName") {
  16903. name = "description"; //backward compatibility
  16904. }
  16905. if (name == "handled") {
  16906. name = "isHandled"; //align with js representation
  16907. }
  16908. if (name == "published") {
  16909. name = "isPublished"; //align with js representation
  16910. }
  16911. if (value) {
  16912. iEvent[name] = value;
  16913. }
  16914. }
  16915. }
  16916. eventsArray[iEvent.id] = iEvent;
  16917. }
  16918. }
  16919. }
  16920. return eventsArray;
  16921. },
  16922. _extractResourcesFromSpecObject: function() {
  16923. var resources = [];
  16924. var nodes = this.specObject.resources;
  16925. var j = 0;
  16926. if (nodes && nodes.length !== 0) {
  16927. for (var i in nodes) {
  16928. if (Object.prototype.hasOwnProperty.call(nodes,i)) {
  16929. var node = nodes[i];
  16930. var resource = {};
  16931. var id = node._id;
  16932. if (!id) {
  16933. id = node._globalid;
  16934. }
  16935. resource[iwConstants.RESOURCE.id] = id?id:null;
  16936. var src = node._src;
  16937. if (!src) {
  16938. src = node._uri;
  16939. }
  16940. resource[iwConstants.RESOURCE.src] = src;
  16941. resource[iwConstants.RESOURCE.version] = node._version?node._version:null;
  16942. resource[iwConstants.RESOURCE.callback] = node._callback?node._callback:null;
  16943. resource[iwConstants.RESOURCE.mimeType] = node._mimeType?node._mimeType:null;
  16944. resource[iwConstants.RESOURCE.blockInit] = node._blockInit?node._blockInit:null;
  16945. resource[iwConstants.RESOURCE.globalid] = node._globalid?node._globalid:null;
  16946. resource[iwConstants.RESOURCE.skipLoad] = node._skipLoad?node._skipLoad:null;
  16947. resources[j] = resource;
  16948. j++;
  16949. }
  16950. }
  16951. }
  16952. return resources;
  16953. },
  16954. _extractPayloadDefsFromSpecObject: function() {
  16955. var payloadDefsArr = {};
  16956. var payloadDefs = this.specObject.payloadDefs;
  16957. for (var i in payloadDefs) {
  16958. if (Object.prototype.hasOwnProperty.call(payloadDefs,i)) {
  16959. var aNode = payloadDef[i];
  16960. // MDG to do fix!
  16961. // var payloadDef = com.ibm.mm.iwidget.Utils.getPayloadDef(aNode);
  16962. //payloadDefsArr[i]=payloadDef;
  16963. }
  16964. }
  16965. },
  16966. //todo!
  16967. _extractEventDescFromSpecObject: function() {
  16968. var eventDescriptions = {};
  16969. var eventDescs = this.specObject.eventDescriptions;
  16970. if (eventDescs && eventDescs.length !== 0) {
  16971. for (var i in eventDescs) {
  16972. if (Object.prototype.hasOwnProperty.call(eventDescs,i)) {
  16973. var node = eventDescs[i];
  16974. var eventDescription = {};
  16975. var id = i;
  16976. eventDescription.id = id;
  16977. eventDescription.payloadType = node._payloadType;
  16978. eventDescription.description = node._description;
  16979. eventDescription.title = node._title;
  16980. eventDescription.descriptionURI = node._descriptionURI?node._descriptionURI:null;
  16981. //eventDescription.aliases = node._aliases?node._aliases:null;
  16982. var lang = node._lang;
  16983. if (!lang ){
  16984. lang = node._xml_lang;
  16985. }
  16986. if (lang) {
  16987. eventDescription.lang = lang;
  16988. }
  16989. var children = node.alts;
  16990. for (var j in children) {
  16991. if (Object.prototype.hasOwnProperty.call(children,j)) {
  16992. var aNode = children[j];
  16993. var temp = {};
  16994. temp.description = aNode._description;
  16995. temp.title = aNode._title;
  16996. temp.descriptionURI = aNode._descriptionURI?aNode_descriptionURI:null;
  16997. if (!eventDescription.descriptions){
  16998. eventDescription.descriptions = {};
  16999. }
  17000. eventDescription.descriptions[j] = temp;
  17001. }
  17002. }
  17003. eventDescriptions[id] = eventDescription;
  17004. }
  17005. }
  17006. }
  17007. return eventDescriptions;
  17008. },
  17009. toSpecObject: function() {
  17010. if (this.specObject) {
  17011. return this.specObject;
  17012. }
  17013. var outputJSON = {};
  17014. return outputJSON;
  17015. }
  17016. });
  17017. com.ibm.mm.iwidget.widget.IWidgetDefinitionImpl = com.ibm.mm.iwidget.widget.IWidgetDefinitionDefaultImpl;
  17018. // IMPORTANT
  17019. // ibmConfig.enablerLayerModules is a comma separated string of all supported modules at runtime
  17020. // This section dynamically loads the Extended representation when the variable enablerLayerModules contains the given module
  17021. if ((ibmConfig.enablerLayerModules) && (dojo.indexOf(ibmConfig.enablerLayerModules, "iWidget") >= 0)) {
  17022. dojo["require"]("com.ibm.mm.iwidget.widget.IWidgetDefinitionExtendedImpl"); // JSLINT-IGNORE: This needs to be done to allow modularization and to support the minimal layer
  17023. }
  17024. }
  17025. if(!dojo._hasResource["com.ibm.mashups.iwidget.widget.IWidgetDefinition"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  17026. dojo._hasResource["com.ibm.mashups.iwidget.widget.IWidgetDefinition"] = true;
  17027. dojo.provide("com.ibm.mashups.iwidget.widget.IWidgetDefinition");
  17028. }
  17029. if(!dojo._hasResource["com.ibm.mashups.iwidget.widget.ModifiableProperties_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  17030. dojo._hasResource["com.ibm.mashups.iwidget.widget.ModifiableProperties_API"] = true;
  17031. dojo.provide("com.ibm.mashups.iwidget.widget.ModifiableProperties_API");
  17032. dojo.provide("com.ibm.mashups.iwidget.widget.ModifiableProperties");
  17033. /**
  17034. * Modifiable interface defines functions to iterates , updates and persist Properties.
  17035. * @ibm-spi
  17036. * @ibm-module iWidget2
  17037. */
  17038. dojo.declare("com.ibm.mashups.iwidget.widget.ModifiableProperties", [com.ibm.mashups.iwidget.widget.Properties], {
  17039. /**
  17040. * @private
  17041. */
  17042. constructor: function() {
  17043. },
  17044. /**
  17045. * This method creates or overwrites the value of the required item
  17046. * @param{String}itemName name of the item. Must never be NULL.
  17047. * @param{String} itemValue value of the item. Must never be NULL.
  17048. * @param{Boolean} readOnly whether the item value is read only (on this level).
  17049. * @param{String} locale the locale in which the item value is
  17050. * @return{com.ibm.mashups.iwidget.widget.Properties} return an handle of InstanceProperties upon successful, NULL upon failure.
  17051. */
  17052. setItemValue: function(itemName, itemValue, readOnly, locale) {
  17053. },
  17054. /**
  17055. * Removes the named item from the set.
  17056. * @param{String} itemName name of the item that should be removed.Must never be NULL.
  17057. * @return{com.ibm.mashups.iwidget.widget.Properties} return an handle of InstanceProperties upon successful, NULL upon failure..
  17058. */
  17059. removeItem: function(itemName) {
  17060. //summary:This method sets an value of an iDescriptor item
  17061. },
  17062. /**
  17063. * Removes the specified item value with the given locale.
  17064. * @param{String} itemName the name of the item for which to remove the value.
  17065. * @param{String} locale the locale of the value to remove. Must never be NULL
  17066. * @return{void}
  17067. */
  17068. removeItemValue: function(itemName, locale) {
  17069. }
  17070. });
  17071. }
  17072. if(!dojo._hasResource["com.ibm.mm.iwidget.widget.ModifiablePropertiesImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  17073. dojo._hasResource["com.ibm.mm.iwidget.widget.ModifiablePropertiesImpl"] = true;
  17074. dojo.provide("com.ibm.mm.iwidget.widget.ModifiablePropertiesImpl");
  17075. dojo.declare("com.ibm.mm.iwidget.widget.ModifiablePropertiesImpl", [com.ibm.mashups.iwidget.widget.ModifiableProperties, com.ibm.mm.iwidget.widget.PropertiesImpl], {
  17076. constructor: function(items, defaultProps) {
  17077. this._dirty = false;
  17078. },
  17079. _buildChange: function(item, itemName, oldVal, newVal, isRemove) {
  17080. var isDirty = item._dirty;
  17081. if (!isDirty) {
  17082. item._dirty = true;
  17083. }
  17084. var change = item._change ? item._change : {};
  17085. change.id = itemName;
  17086. if (isRemove) {
  17087. //if it's remove action
  17088. if (isDirty && change.changeType && change.changeType == this.TYPE_NEW) {
  17089. item._dirty = false;
  17090. delete item._change;
  17091. return;
  17092. }
  17093. else if (isDirty) {
  17094. change.changeType = this.TYPE_REMOVE;
  17095. return;
  17096. }
  17097. item._change.changeType = this.TYPE_REMOVE;
  17098. item._change.oldVal = oldVal;
  17099. return;
  17100. }
  17101. if (isDirty && change.changeType) {
  17102. if (change.changeType == this.TYPE_NEW) {
  17103. change.newVal = newVal;
  17104. }
  17105. else {
  17106. change.changeType = this.TYPE_UPDATE;
  17107. change.newVal = newVal;
  17108. }
  17109. }
  17110. else {
  17111. if (oldVal) {
  17112. change.oldVal = oldVal;
  17113. }
  17114. if (newVal) {
  17115. change.newVal = newVal;
  17116. }
  17117. if (oldVal) {
  17118. change.changeType = this.TYPE_UPDATE;
  17119. }
  17120. else {
  17121. change.changeType = this.TYPE_NEW;
  17122. }
  17123. }
  17124. item._change = change;
  17125. return;
  17126. },
  17127. setItemValue: function(itemName, itemValue, readOnly, locale) {
  17128. if (!itemName || !itemValue) {
  17129. return null;
  17130. }
  17131. if (itemName in this._items) {
  17132. if (this._defaultProperties && this._defaultProperties.isReadOnly(itemName)) {
  17133. return null;
  17134. }
  17135. }
  17136. var oldValue = {};
  17137. var newValue = {};
  17138. var isReadOnly;
  17139. if (!locale || (locale && locale == "")) { //that means this is a nonlocalized item
  17140. if (itemName in this._items) {
  17141. oldValue = {};
  17142. newValue = {};
  17143. if (this._items[itemName].values) {
  17144. oldValue = dojo.clone(this._items[itemName].values);
  17145. if (this._items[itemName].value) {
  17146. oldValue[""] = this._items[itemName].value;
  17147. }
  17148. newValue = dojo.clone(this._items[itemName].values);
  17149. newValue[""] = itemValue;
  17150. }
  17151. else {
  17152. if (this._items[itemName].value) {
  17153. oldValue[""] = this._items[itemName].value;
  17154. }
  17155. newValue[""] = itemValue;
  17156. }
  17157. this._items[itemName].value = itemValue;
  17158. this._buildChange(this._items[itemName], itemName, oldValue, newValue);
  17159. }
  17160. else {
  17161. var anItem = {};
  17162. anItem.id = itemName;
  17163. //anItem.name = itemName;
  17164. anItem.value = itemValue;
  17165. isReadOnly = !!readOnly;
  17166. anItem.readOnly = isReadOnly;
  17167. this._items[itemName] = anItem;
  17168. newValue = {};
  17169. newValue[""] = itemValue;
  17170. this._items[itemName] = this._items[itemName] ? this._items[itemName] : {};
  17171. this._buildChange(this._items[itemName], itemName, null, newValue);
  17172. }
  17173. if (this._items[itemName]._dirty) {
  17174. this._dirty = true;
  17175. }
  17176. return this;
  17177. }
  17178. var normalizedLocale = locale.replace(/-/g, "_"); // normalize the locale
  17179. if (itemName in this._items) {
  17180. oldValue = {};
  17181. newValue = {};
  17182. //this is update
  17183. if (this._items[itemName].values) {
  17184. oldValue = dojo.clone(this._items[itemName].values);
  17185. }
  17186. this._items[itemName].values[normalizedLocale] = itemValue;
  17187. newValue = dojo.clone(this._items[itemName].values);
  17188. if (this._items[itemName].value) {
  17189. oldValue[""] = this._items[itemName].value;
  17190. newValue[""] = this._items[itemName].value;
  17191. }
  17192. this._items[itemName].readOnly = readOnly;
  17193. this._buildChange(this._items[itemName], itemName, oldValue, itemValue);
  17194. if (this._items[itemName]._dirty) {
  17195. this._dirty = true;
  17196. }
  17197. return this;
  17198. }
  17199. //if it's a new item
  17200. var item = {};
  17201. item.values = {};
  17202. item.values[normalizedLocale] = itemValue;
  17203. item.id = itemName;
  17204. isReadOnly = !!readOnly;
  17205. item.readOnly = isReadOnly;
  17206. this._items[itemName] = item;
  17207. newValue = dojo.clone(item.values);
  17208. this._buildChange(this._items[itemName], itemName, null, newValue);
  17209. if (this._items[itemName]._dirty) {
  17210. this._dirty = true;
  17211. }
  17212. return this;
  17213. },
  17214. removeItem: function(itemName) {
  17215. //remove all the values of the Item
  17216. // check if this item is read-only on the parent level
  17217. if (this._defaultProperties && this._defaultProperties.isReadOnly(itemName)) {
  17218. throw "The specified item [" + itemName + "] is readOnly!";
  17219. }
  17220. var change = {};
  17221. var deleted = false;
  17222. if (itemName in this._items) {
  17223. //delete this._items[itemName]; //this._items only keeps track of any change
  17224. if (this._items[itemName]._dirty) {
  17225. this._items[itemName].value = this.DELETE_TOKEN;
  17226. this._items[itemName].values = this.DELETE_TOKEN;
  17227. change = this._items[itemName]._change ? this._items[itemName]._change : {};
  17228. if (change.changeType == this.TYPE_NEW) {
  17229. delete this._items[itemName];
  17230. return this;
  17231. }
  17232. else {
  17233. change.changeType = this.TYPE_REMOVE; //keep old value
  17234. }
  17235. }
  17236. else {
  17237. var oldValue = {};
  17238. if (this._items[itemName].values) {
  17239. oldValue = dojo.clone(this._items[itemName].values);
  17240. }
  17241. if (this._items[itemName].value) {
  17242. oldValue[""] = this._items[itemName].value;
  17243. }
  17244. this._items[itemName].value = this.DELETE_TOKEN;
  17245. this._items[itemName].values = this.DELETE_TOKEN;
  17246. change = {};
  17247. change.changeType = this.TYPE_REMOVE;
  17248. change.itemName = itemName;
  17249. change.oldVal = oldValue;
  17250. this._items[itemName]._change = change;
  17251. this._items[itemName]._dirty = true;
  17252. }
  17253. deleted = true;
  17254. }
  17255. if (deleted) {
  17256. this._dirty = true;
  17257. return this;
  17258. }
  17259. else {
  17260. return null;
  17261. }
  17262. },
  17263. removeItemValue: function(itemName, locale) {
  17264. if (!locale) {
  17265. //remove nonlocalized value
  17266. locale = "";
  17267. }
  17268. // check if this item is read-only on the parent level
  17269. if (this._defaultProperties && this._defaultProperties.isReadOnly(itemName)) {
  17270. throw "The specified item [" + itemName + "] is readOnly!";
  17271. }
  17272. var normalizedLocale = locale.replace(/-/g, "_"); // normalize the locale
  17273. var deleted = false;
  17274. var change = {};
  17275. if (itemName in this._items) {
  17276. if (this._items[itemName]._dirty) {
  17277. change = this._items[itemName]._change ? this._items[itemName]._change : {};
  17278. if (change.changeType == this.TYPE_REMOVE) {
  17279. return null; //item is already removed
  17280. }
  17281. else if (change.changeType == this.TYPE_NEW) { //don't change type
  17282. if (normalizedLocale == "" && this._items[itemName].value && this._items[itemName].value != this.DELETE_TOKEN) {
  17283. delete this._items[itemName].value;
  17284. if (this._items[itemName]._change.newVal[""]) {
  17285. delete this._items[itemName]._change.newVal[""];
  17286. }
  17287. deleted = true;
  17288. }
  17289. if (normalizedLocale != "") {
  17290. if (this._items[itemName].values[normalizedLocale]) {
  17291. delete this._items[itemName].values[normalizedLocale];
  17292. if (this._items[itemName]._change.newVal[normalizedLocale]) {
  17293. delete this._items[itemName]._change.newVal[normalizedLocale];
  17294. }
  17295. deleted = true;
  17296. }
  17297. }
  17298. if (this._isEmpty(this._items[itemName]._change.newVal)) {
  17299. delete this._items[itemName]._dirty;
  17300. delete this._items[itemName]._change;
  17301. }
  17302. }
  17303. else { //update
  17304. if (normalizedLocale == "" && this._items[itemName].value && this._items[itemName].value != this.DELETE_TOKEN) {
  17305. delete this._items[itemName].value;
  17306. if (this._items[itemName]._change.newVal[""]) {
  17307. delete this._items[itemName]._change.newVal[""];
  17308. }
  17309. deleted = true;
  17310. }
  17311. if (this._items[itemName].values[normalizedLocale]) {
  17312. delete this._items[itemName].values[normalizedLocale];
  17313. if (this._items[itemName]._change.newVal[normalizedLocale]) {
  17314. delete this._items[itemName]._change.newVal[normalizedLocale];
  17315. }
  17316. deleted = true;
  17317. }
  17318. }
  17319. }
  17320. else {
  17321. var oldValue = {};
  17322. var newValue = {};
  17323. if (normalizedLocale == "" && this._items[itemName].value) {
  17324. change = {};
  17325. change.id = itemName;
  17326. oldValue = {};
  17327. newValue = {};
  17328. if (this._items[itemName].values) {
  17329. change.changeType = this.TYPE_UPDATE;
  17330. oldValue = dojo.clone(this._items[itemName].values);
  17331. oldValue[""] = this._items[itemName][""];
  17332. change.oldVal = oldValue;
  17333. change.newVal = dojo.clone(this._items[itemName].values);
  17334. delete this._items[itemName].value;
  17335. }
  17336. else {
  17337. change.changeType = this.TYPE_REMOVE;
  17338. oldValue[""] = this._items[itemName][""];
  17339. change.oldVal = oldValue;
  17340. delete this._items[itemName].value;
  17341. }
  17342. this._items[itemName]._change = change;
  17343. this._items[itemName]._dirty = true;
  17344. deleted = true;
  17345. }
  17346. if (normalizedLocale in this._items[itemName].values) {
  17347. change = {};
  17348. change.id = itemName;
  17349. oldValue = {};
  17350. newValue = {};
  17351. if (this._items[itemName].value) {
  17352. change.changeType = this.TYPE_UPDATE;
  17353. oldValue = dojo.clone(this._items[itemName].values);
  17354. oldValue[""] = this._items[itemName][""];
  17355. change.oldVal = oldValue;
  17356. change.newVal = dojo.clone(this._items[itemName].values);
  17357. change.newVal[""] = this._items[itemName].value;
  17358. delete change.newVal[normalizedLocale];
  17359. delete this._items[itemName].value;
  17360. }
  17361. else {
  17362. oldValue = dojo.clone(this._items[itemName].values);
  17363. delete this._items[itemName].values[normalizedLocale];
  17364. if (this._isEmpty(this._items[itemName].values)) {
  17365. change.changeType = this.TYPE_REMOVE;
  17366. }
  17367. else {
  17368. change.changeType = this.TYPE_UPDATE;
  17369. change.newVal = dojo.clone(this._items[itemName].values);
  17370. }
  17371. change.oldVal = oldValue;
  17372. }
  17373. this._items[itemName]._change = change;
  17374. this._items[itemName]._dirty = true;
  17375. deleted = true;
  17376. }
  17377. }
  17378. }
  17379. if (deleted) {
  17380. this._dirty = true;
  17381. return this;
  17382. }
  17383. else {
  17384. return null;
  17385. }
  17386. },
  17387. _isDirty: function() {
  17388. return this._dirty;
  17389. },
  17390. _setDirty: function(value) {
  17391. this._dirty = value;
  17392. },
  17393. _isItemDirty: function(itemName) {
  17394. if (!itemName) {
  17395. return false;
  17396. }
  17397. var isDirty = false;
  17398. if (this._items[itemName]) {
  17399. isDirty = this._items[itemName]._dirty;
  17400. }
  17401. return isDirty;
  17402. },
  17403. _setItemDirty: function(itemName, value) {
  17404. if (!itemName) {
  17405. return;
  17406. }
  17407. if (this._items[itemName]) {
  17408. this._items[itemName]._dirty = value;
  17409. if (typeof value != "undefined" && !value) {
  17410. delete this._items[itemName]._dirty;
  17411. delete this._items[itemName]._change;
  17412. }
  17413. if (this._items[itemName].values && this._items[itemName].values == this.DELETE_TOKEN) {
  17414. delete this._items[itemName].values;
  17415. }
  17416. if (this._items[itemName].value && this._items[itemName].value == this.DELETE_TOKEN) {
  17417. delete this._items[itemName].value;
  17418. }
  17419. if (!this._items[itemName].value && !this._items[itemName].values) {
  17420. delete this._items[itemName];
  17421. }
  17422. }
  17423. },
  17424. _getInternalItemValue: function(itemName) {
  17425. if (this._items[itemName]) {
  17426. return this._items[itemName];
  17427. }
  17428. return null;
  17429. },
  17430. _isEmpty: function(obj) {
  17431. return com.ibm.mm.enabler.utils.Misc.isEmpty(obj);
  17432. },
  17433. _getRequiredValue: function(obj, locale) {
  17434. if (!obj) {
  17435. return null;
  17436. }
  17437. if (dojo.isString(obj)) {
  17438. return obj;
  17439. }
  17440. if (locale) {
  17441. if (obj[locale]) {
  17442. return obj[locale];
  17443. }
  17444. else {
  17445. return null;
  17446. }
  17447. }
  17448. var singleValue = null;
  17449. var j = 0;
  17450. for (var i in obj) {
  17451. if (Object.prototype.hasOwnProperty.call(obj,i)) {
  17452. if (i == "") {
  17453. singleValue = obj[i];
  17454. }
  17455. j++;
  17456. }
  17457. }
  17458. if (singleValue && j == 1) {
  17459. return singleValue;
  17460. }
  17461. return obj;
  17462. },
  17463. _updateProperties:function(updatedProperties){
  17464. //used by sandboxed mode... updates is sent from wrapper to stub
  17465. //merge the updates, latest one overwrites the old one
  17466. var updatedItems = dojo.mixin(this._items,updatedProperties);
  17467. this._items = updatedItems;
  17468. this._dirty = true;
  17469. },
  17470. toJson:function(){
  17471. return this._items;
  17472. }
  17473. });
  17474. }
  17475. if(!dojo._hasResource["com.ibm.mashups.iwidget.widget.ModifiableProperties"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  17476. dojo._hasResource["com.ibm.mashups.iwidget.widget.ModifiableProperties"] = true;
  17477. dojo.provide("com.ibm.mashups.iwidget.widget.ModifiableProperties");
  17478. }
  17479. if(!dojo._hasResource["com.ibm.mashups.iwidget.widget.ModifiablePropertiesProvider"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  17480. dojo._hasResource["com.ibm.mashups.iwidget.widget.ModifiablePropertiesProvider"] = true;
  17481. dojo.provide("com.ibm.mashups.iwidget.widget.ModifiablePropertiesProvider");
  17482. /**
  17483. * Modifiable interface defines functions to access properties that's defined with iWidget.
  17484. * @ibm-spi
  17485. * @ibm-module iWidget2
  17486. */
  17487. dojo.declare("com.ibm.mashups.iwidget.widget.ModifiablePropertiesProvider", null, {
  17488. /**
  17489. * @private
  17490. */
  17491. constructor: function() {
  17492. },
  17493. /**
  17494. This method returns an object that contains iDescriptor items as defined by iWidget spec. It contains default title and icon
  17495. @type com.ibm.mashups.iwidget.widget.ModifiableProperties
  17496. @returns{com.ibm.mashups.iwidget.widget.ModifiableProperties } object that contains iWidget iDescriptor items information
  17497. */
  17498. getIDescriptorItems: function() {
  17499. },
  17500. /**
  17501. This method returns an object that contains attributes as defined by iWidget spec.
  17502. @type com.ibm.mashups.iwidget.widget.ModifiableProperties
  17503. @returns{com.ibm.mashups.iwidget.widget.ModifiableProperties } object that contains iWidget iDescriptor items information
  17504. */
  17505. getAttributes: function() {
  17506. }
  17507. });
  17508. }
  17509. if(!dojo._hasResource["com.ibm.mashups.iwidget.widget.ModifiableWireProvider"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  17510. dojo._hasResource["com.ibm.mashups.iwidget.widget.ModifiableWireProvider"] = true;
  17511. dojo.provide("com.ibm.mashups.iwidget.widget.ModifiableWireProvider");
  17512. /**
  17513. * Interface defines functions to access handled or published event descriptions.
  17514. * @ibm-spi
  17515. * @ibm-module iWidget2
  17516. */
  17517. dojo.declare("com.ibm.mashups.iwidget.widget.ModifiableWireProvider", com.ibm.mashups.iwidget.widget.WireProvider, {
  17518. /**
  17519. * @private
  17520. */
  17521. constructor: function(id) {
  17522. },
  17523. /**
  17524. * @param {String}sourceWidgetId id of the widget that will publish the event
  17525. * @param {String}sourceEventName name of the event source widget will publish
  17526. * @param {String}targetEventName name of the event the receiving widget and this event will handle the event published by source widget
  17527. * @type void
  17528. */
  17529. addWire: function(sourceWidgetId, sourceEventName, targetEventName) {
  17530. },
  17531. /**
  17532. * @param {String}sourceWidgetId id of the widget that will publish the event
  17533. * @param {String}sourceEventName name of the event source widget will publish
  17534. * @param {String}targetEventName name of the event the receiving widget and this event will handle the event published by source widget
  17535. * @type void
  17536. */
  17537. removeWire: function(sourceWidgetId, sourceEventName, targetEventName) {
  17538. }
  17539. });
  17540. }
  17541. if(!dojo._hasResource["com.ibm.mashups.iwidget.widget.IWidgetInstance_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  17542. dojo._hasResource["com.ibm.mashups.iwidget.widget.IWidgetInstance_API"] = true;
  17543. dojo.provide("com.ibm.mashups.iwidget.widget.IWidgetInstance_API");
  17544. dojo.provide("com.ibm.mashups.iwidget.widget.IWidgetInstance");
  17545. /**
  17546. * Interface defines functions to access all the instance level descriptive data.
  17547. * @ibm-spi
  17548. * @ibm-module iWidget2
  17549. */
  17550. dojo.declare("com.ibm.mashups.iwidget.widget.IWidgetInstance", [com.ibm.mashups.iwidget.widget.ModifiablePropertiesProvider, com.ibm.mashups.iwidget.widget.ModifiableWireProvider], {
  17551. /**
  17552. * @private
  17553. */
  17554. constructor: function() {
  17555. }
  17556. });
  17557. }
  17558. if(!dojo._hasResource["com.ibm.mm.iwidget.Utils"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  17559. dojo._hasResource["com.ibm.mm.iwidget.Utils"] = true;
  17560. dojo.provide("com.ibm.mm.iwidget.Utils");
  17561. dojo.declare("com.ibm.mm.iwidget.UtilsDefaultImpl", null, {
  17562. constructor: function() {
  17563. },
  17564. widgetClassRE: new RegExp("(mm:|mm_|iw-)iWidget"),
  17565. findElementByAttribute: function(/*String*/att,/*String*/ value,/*DOMElement*/ root,/*[]*/ element, hasMultiple){
  17566. var aRoot = root;
  17567. if (!root.childNodes) {
  17568. return false;
  17569. }
  17570. if (att == "class") {
  17571. dojo.query("." + value, root).forEach(function(ele){
  17572. element.push(ele);
  17573. });
  17574. return element.length !== 0;
  17575. }
  17576. else if (att == "query") {
  17577. dojo.query(value, root).forEach(function(ele){
  17578. element.push(ele);
  17579. });
  17580. return element.length !== 0;
  17581. }
  17582. //other attributes
  17583. if (root.getElementsByTagName) {
  17584. var nodes = root.getElementsByTagName("*");
  17585. for (var i = 0, l = nodes.length; i < l; i++) {
  17586. var aNode = nodes[i];
  17587. if (aNode && aNode.getAttribute) {
  17588. var childValue = aNode.getAttribute(att);
  17589. if (childValue == value) {
  17590. element.push(aNode);
  17591. if (!hasMultiple) {
  17592. return true;
  17593. }
  17594. }
  17595. }
  17596. }
  17597. }
  17598. // made this order change for 20459. The above code should fix 20459 for dojo test. If it fails 20403 and 20330, the following code will catch it
  17599. // This is to avoid using the hacking code
  17600. // made the change for 20403 and 20330 since IE7 returns wrong value with code in the other attributes section above
  17601. if (att == "id") {
  17602. dojo.query("#" + value, root).forEach(function(ele){
  17603. element.push(ele);
  17604. });
  17605. return element.length !== 0;
  17606. }
  17607. return false;
  17608. },
  17609. getClass: function(/*object*/node){
  17610. var childValue = node.getAttribute("class");
  17611. childValue = childValue ? childValue : node.getAttribute("className");
  17612. return childValue;
  17613. },
  17614. checkParentElement: function(/*Node*/selfNode, /*RegExp*/ classToFind){
  17615. if (selfNode) {
  17616. var dadNode = selfNode.parentNode;
  17617. if (dadNode) {
  17618. if (dadNode.className) {
  17619. if (dadNode.className.match(classToFind)) {
  17620. return dadNode.id;
  17621. }
  17622. }
  17623. return this.checkParentElement(dadNode, classToFind);
  17624. }
  17625. }
  17626. return null;
  17627. },
  17628. getWidgetParent: function(/*Domnode*/node, /*RegExp*/ classToFind){
  17629. if (dojo.isString(node)) {
  17630. node = dojo.byId(node);
  17631. }
  17632. if (!classToFind) {
  17633. classToFind = this.widgetClassRE;
  17634. }
  17635. return this.checkParentElement(node, classToFind);
  17636. },
  17637. getParents: function(/*widget*/widget,/*array*/ arr){
  17638. var parent = widget.getParent();
  17639. if (parent) {
  17640. arr.push(parent);
  17641. this.getParents(parent, arr);
  17642. }
  17643. return;
  17644. },
  17645. /**
  17646. * This utility method takes an id from the markup and returns
  17647. * an unprefixed id to pass into an enabler model (like Widget,
  17648. * Wire or Event.) IE7 doesn't support ids that start with a
  17649. * number so the server may encode the ids with a prefix,
  17650. * like 'id_' to make an id valid.
  17651. *
  17652. * If the markup id starts with the prefix from
  17653. * ibmConfig["com.ibm.mashups.iWidget.idPrefix"] this method
  17654. * will remove the prefix.
  17655. *
  17656. * If the id does not start with the prefix no action will be
  17657. * taken.
  17658. *
  17659. * @param {String} id from the markup
  17660. * @return {String} the unprefixed id to pass to the enabler
  17661. * models
  17662. */
  17663. getModelID: function(/*string*/id){
  17664. var ret = id;
  17665. var prefix = ibmConfig[com.ibm.mashups.enabler.services.ConfigConstants.ID_PREFIX];
  17666. if (prefix && dojo.isString(ret)) {
  17667. var indx = ret.indexOf(prefix);
  17668. if (indx === 0) {
  17669. ret = ret.substring(prefix.length);
  17670. }
  17671. }
  17672. return ret;
  17673. },
  17674. /**
  17675. * This utility method takes an id from an enabler (like Widget,
  17676. * Wire or Event) and returns a prefixed markup id. IE7 doesn't
  17677. * support ids that start with a number so the server may encode
  17678. * the ids with a prefix, like 'id_' to make an id valid.
  17679. *
  17680. * If the model id starts with a number this method will take
  17681. * prefix from ibmConfig["com.ibm.mashups.iWidget.idPrefix"]
  17682. * and prepend it to the id passed in.
  17683. *
  17684. *
  17685. * @param {String} id retrieved from an enabler model
  17686. * @return {String} the prefixed id to match the markup returned
  17687. * from the server
  17688. */
  17689. getMarkupID: function(/*string*/id) {
  17690. var ret = id;
  17691. var prefix = ibmConfig[com.ibm.mashups.enabler.services.ConfigConstants.ID_PREFIX];
  17692. if (prefix && dojo.isString(ret)) {
  17693. ret = prefix + ret;
  17694. }
  17695. return ret;
  17696. },
  17697. stripHashPrefix: function(str) {
  17698. if (dojo.isString(str)) {
  17699. var pos = str.indexOf('#');
  17700. if (pos !== -1) { // not enough to just strip first character, because IE prepends the URL.
  17701. return str.substr(1 + pos);
  17702. }
  17703. }
  17704. return str;
  17705. },
  17706. /**
  17707. * This method is internal only, it is mainly used for classes that use the "Model" type of instances
  17708. */
  17709. _getWidgetTitle: function(widgetId) {
  17710. return null;
  17711. }
  17712. });
  17713. // IMPORTANT
  17714. // ibmConfig.enablerLayerModules is a comma separated string of all supported modules at runtime
  17715. // This section dynamically loads the Extended representation when the variable enablerLayerModules contains the given module
  17716. if ((ibmConfig.enablerLayerModules) && (dojo.indexOf(ibmConfig.enablerLayerModules, "iWidget") >= 0)) {
  17717. dojo["require"]("com.ibm.mm.iwidget.UtilsExtended"); // JSLINT-IGNORE: This needs to be done to allow modularization and to support the minimal layer
  17718. } else {
  17719. com.ibm.mm.iwidget.Utils = new com.ibm.mm.iwidget.UtilsDefaultImpl();
  17720. }
  17721. }
  17722. if(!dojo._hasResource["com.ibm.mm.iwidget.widget.IWidgetInstanceDefaultImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  17723. dojo._hasResource["com.ibm.mm.iwidget.widget.IWidgetInstanceDefaultImpl"] = true;
  17724. dojo.provide("com.ibm.mm.iwidget.widget.IWidgetInstanceDefaultImpl");
  17725. dojo.declare("com.ibm.mm.iwidget.widget.IWidgetInstanceDefaultImpl", com.ibm.mashups.iwidget.widget.IWidgetInstance, {
  17726. constructor: function(wrapper, /*RootElement*/widgetSpan,/*String*/ id){
  17727. this.wrapper = wrapper;
  17728. this.rootElement = widgetSpan;
  17729. this.id = id;
  17730. this.ns = widgetSpan.className.substr(0, 3);
  17731. var nodes = [];
  17732. var className = this.ns + "Definition";
  17733. com.ibm.mm.iwidget.Utils.findElementByAttribute("query", "> ."+className, this.rootElement, nodes, false);
  17734. if (nodes && nodes.length > 0) {
  17735. var node = nodes[0];
  17736. var url = node.getAttribute("href");
  17737. if (typeof(url) != "undefined" && url !== null) {
  17738. this.widgetXMLUrl = url;
  17739. }
  17740. }
  17741. },
  17742. _destroy: function(){
  17743. // #17713 one leak for widgetWrapper.rootElement (iw-iWidget DIV)
  17744. if (this.rootElement) {
  17745. this.rootElement = null;
  17746. }
  17747. },
  17748. getDefaultViewContent: function(){
  17749. if (this.defaultViewContent) {
  17750. return this.defaultViewContent;
  17751. }
  17752. var className = this.ns + "Content";
  17753. var node = null;
  17754. var nodeList = dojo.query("> ." + className+"."+iwConstants.mode_view, this.rootElement);
  17755. if (nodeList) {
  17756. node = nodeList[0];
  17757. }
  17758. if (!node) {
  17759. nodeList = dojo.query("> ." + className, this.rootElement);
  17760. if (nodeList) {
  17761. node = nodeList[0];
  17762. }
  17763. }
  17764. if (node) {
  17765. this.defaultViewContent = node.innerHTML;
  17766. return this.defaultViewContent;
  17767. }
  17768. else {
  17769. return null;
  17770. }
  17771. },
  17772. getWidgetEvents: function(){
  17773. //simple events including all the predefined events and onSth. event
  17774. if (this.widgetEvents) {
  17775. return this.widgetEvents;
  17776. }
  17777. var widgetEvents = {};
  17778. var attributes = this.rootElement.attributes;
  17779. for (var i = 0; i < attributes.length; i++) {
  17780. var attribute = attributes[i];
  17781. if (attribute.name !== null && attribute.name.indexOf("on") === 0) {
  17782. var handler = this.rootElement.getAttribute(attribute.name);
  17783. if (typeof handler != "undefined" && handler !== null) {
  17784. widgetEvents[attribute.name] = handler;
  17785. }
  17786. }
  17787. }
  17788. this.widgetEvents = widgetEvents;
  17789. return this.widgetEvents;
  17790. },
  17791. _addWire: function(wire){
  17792. },
  17793. _removeWire: function(id){
  17794. },
  17795. addWire: function(sourceWidget, sourceEvent, targetEvent){
  17796. },
  17797. removeWire: function(sourceWidget, sourceEvent, targetEvent){
  17798. },
  17799. _getPublicEvents: function(){
  17800. return null;
  17801. },
  17802. getWires: function(){
  17803. return [];
  17804. },
  17805. getWireModel: function(){
  17806. return null;
  17807. },
  17808. /**
  17809. * ModifiablePropertiesProvider Impl
  17810. */
  17811. getAttributes: function(){
  17812. if (!this.attributeProperties) {
  17813. //return all the attributes as JSON data
  17814. var attributes = this.getItemSets()[iwConstants.ATTRIBUTES];
  17815. var properties = {};
  17816. if (attributes) {
  17817. for (var itemName in attributes) {
  17818. if (Object.prototype.hasOwnProperty.call(attributes, itemName)) {
  17819. properties[itemName] = attributes[itemName]; // we are compatible with the new internal itemset format
  17820. }
  17821. }
  17822. }
  17823. this.attributeProperties = new com.ibm.mm.iwidget.widget.ModifiablePropertiesImpl(properties);
  17824. }
  17825. return this.attributeProperties;
  17826. },
  17827. /**
  17828. * ModifiablePropertiesProvider Impl
  17829. */
  17830. getIDescriptorItems: function(){
  17831. if (!this.idescriptorProperties) {
  17832. //return all the attributes as JSON data
  17833. var iDescriptor = this.getItemSets()[iwConstants.IDESCRIPTOR];
  17834. var properties = {};
  17835. if (iDescriptor) {
  17836. for (var itemName in iDescriptor) {
  17837. if (Object.prototype.hasOwnProperty.call(iDescriptor, itemName)) {
  17838. properties[itemName] = iDescriptor[itemName]; // we are compatible with the new internal itemset format
  17839. // (this is working here, because on instance level we got the idescriptor from markup, not def)
  17840. }
  17841. }
  17842. }
  17843. this.idescriptorProperties = new com.ibm.mm.iwidget.widget.ModifiablePropertiesImpl(properties);
  17844. }
  17845. return this.idescriptorProperties;
  17846. },
  17847. _getItemSets: function(){
  17848. if (this.itemSets) {
  17849. return this.itemSets;
  17850. }
  17851. this.loadItemSets();
  17852. return this.itemSets;
  17853. },
  17854. getItemSets: function(){
  17855. //returns a list of itemsets: each itemset is like following
  17856. // { itemname1:object,itemname2;object}
  17857. //
  17858. return this._getItemSets();
  17859. },
  17860. getItemSet: function(itemSetName){
  17861. //returns json object as indicated in _loadItem
  17862. //{ itemName1:{},itemName2:{}}
  17863. if (!itemSetName) {
  17864. return null;
  17865. }
  17866. var itemSets = this._getItemSets();
  17867. if (itemSets && itemSets[itemSetName]) {
  17868. return itemSets[itemSetName];
  17869. }
  17870. },
  17871. loadItemSets: function(){
  17872. //this.itemSets = this._loadItemSets(this.rootElement, this.ns);
  17873. this.itemSets = this._loadItemSetsOptimized(this.rootElement, this.ns);
  17874. },
  17875. _loadItemSetsOptimized: function(rootElement, ns){
  17876. var itemSets = {};
  17877. if (rootElement.childNodes.length) {
  17878. dojo.query('> .'+ns+com.ibm.mm.iwidget.Constants.CSSCLASS_INSTANCE.iwItemSet+' > .'+ns+com.ibm.mm.iwidget.Constants.CSSCLASS_INSTANCE.iwItem, rootElement).forEach(function(item){
  17879. var setName = dojo.attr(item.parentNode, 'title');
  17880. if (setName) {
  17881. if (!itemSets[setName]) {
  17882. itemSets[setName] = {};
  17883. }
  17884. var anItem = this._loadItemOptimized(item, ns);
  17885. itemSets[setName][anItem.id] = anItem;
  17886. }
  17887. }, this);
  17888. }
  17889. return itemSets;
  17890. },
  17891. _loadItemOptimized: function(elem, ns){
  17892. var css = com.ibm.mm.iwidget.Constants.CSSCLASS_INSTANCE;
  17893. var item = {
  17894. id: com.ibm.mm.iwidget.Utils.stripHashPrefix(dojo.attr(elem, 'href')),
  17895. readOnly: dojo.hasClass(elem, ns + css.iwReadOnly)
  17896. };
  17897. var lang = dojo.attr(elem, 'lang');
  17898. if (lang) {
  17899. item.defaultLocale = lang;
  17900. }
  17901. var value;
  17902. var children = dojo.query('> .' + ns + css.iwValue, elem);
  17903. if (children.length) {
  17904. item.values = {};
  17905. children.forEach(function(valElem){
  17906. var locale = dojo.attr(valElem, 'lang') || lang;
  17907. item.values[locale] = com.ibm.mm.enabler.utils.Dom.textContent(valElem);
  17908. });
  17909. }
  17910. else {
  17911. value = com.ibm.mm.enabler.utils.Dom.textContent(elem);
  17912. if (dojo.isString(value)) {
  17913. item.value = dojo.string.trim(value);
  17914. }
  17915. }
  17916. return item;
  17917. },
  17918. // invalidate itemsets
  17919. _invalidateItemSets: function(name){
  17920. if (!name) {
  17921. // invalidate all itemset
  17922. this.itemSets = {};
  17923. }
  17924. else {
  17925. // invalidate a single itemsets
  17926. this.itemSets[name] = {};
  17927. }
  17928. },
  17929. _getInstanceMarkup: function(){
  17930. var node = dojo.clone(this.rootElement);
  17931. //remove content div if it's available
  17932. dojo.query("> ." + this.ns + "Content", node).forEach(function(contentNode){
  17933. com.ibm.mm.enabler.utils.Dom.destroyNode(contentNode);
  17934. });
  17935. dojo.query("> ." + this.ns + "loading", node).forEach(function(contentNode){
  17936. com.ibm.mm.enabler.utils.Dom.destroyNode(contentNode);
  17937. });
  17938. var tempEl = document.createElement("div");
  17939. tempEl.appendChild(node);
  17940. var html = tempEl.innerHTML;
  17941. return html;
  17942. }
  17943. });
  17944. com.ibm.mm.iwidget.widget.IWidgetInstanceImpl = com.ibm.mm.iwidget.widget.IWidgetInstanceDefaultImpl;
  17945. // IMPORTANT
  17946. // ibmConfig.enablerLayerModules is a comma separated string of all supported modules at runtime
  17947. // This section dynamically loads the Extended representation when the variable enablerLayerModules contains the given module
  17948. if ((ibmConfig.enablerLayerModules) && (dojo.indexOf(ibmConfig.enablerLayerModules, "iWidget") >= 0)) {
  17949. dojo["require"]("com.ibm.mm.iwidget.widget.IWidgetInstanceExtendedImpl"); // JSLINT-IGNORE: This needs to be done to allow modularization and to support the minimal layer
  17950. }
  17951. }
  17952. if(!dojo._hasResource["com.ibm.mashups.iwidget.widget.IWidgetInstance"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  17953. dojo._hasResource["com.ibm.mashups.iwidget.widget.IWidgetInstance"] = true;
  17954. dojo.provide("com.ibm.mashups.iwidget.widget.IWidgetInstance");
  17955. }
  17956. if(!dojo._hasResource["com.ibm.mashups.iwidget.widget.IWidgetWrapper_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  17957. dojo._hasResource["com.ibm.mashups.iwidget.widget.IWidgetWrapper_API"] = true;
  17958. dojo.provide("com.ibm.mashups.iwidget.widget.IWidgetWrapper_API");
  17959. dojo.provide("com.ibm.mashups.iwidget.widget.IWidgetWrapper");
  17960. /**
  17961. * IWidgetWrapper interface represents a runtime instance of an iWidget on the page. Information provided by the IWidgetWrapper is an aggregation of definition level data and instance level data.
  17962. * To get desriptive data that's specific to instance level and definition level. It should use Provider api that's implemented by IWidgetDefinition or IWidgetIstance.
  17963. * @ibm-spi
  17964. * @ibm-module iWidget2
  17965. */
  17966. dojo.declare("com.ibm.mashups.iwidget.widget.IWidgetWrapper", [com.ibm.mashups.iwidget.widget.WireProvider, com.ibm.mashups.iwidget.widget.EventProvider], {
  17967. /**
  17968. * @private
  17969. */
  17970. constructor: function() {
  17971. },
  17972. /**
  17973. This method returns iWidgetDefinition of this runtime instance.<br/>
  17974. <code>var deferred = widgetWrapper.getIWidgetDefinition();</code><br/>
  17975. <code>deferred.setFinishedCallback(callback,parameters);</code><br/>
  17976. <code>deferred.start(true);</code><br/>
  17977. here are the callback parameters that will be passed into callback function: <br/>
  17978. &nbsp;&nbsp;&nbsp;&nbsp;<code>resource</code> - IWidgetDefinition object <br>
  17979. &nbsp;&nbsp;&nbsp;&nbsp;<code>statusCode</code> - the overall HTTP status,code of the action (the highest status code of the involved operations).<br>
  17980. &nbsp;&nbsp;&nbsp;&nbsp;<code>params</code> - the parameters passed into the callback <br>
  17981. @type com.ibm.mashups.enabler.Deferred
  17982. @returns{com.ibm.mashups.enabler.Deferred} a deferred object used to start this operation.
  17983. @see com.ibm.mashups.iwidget.widget.IWidgetDefinition
  17984. */
  17985. getIWidgetDefinition: function() {
  17986. },
  17987. /**
  17988. Sets the iWidgetDefinition for this runtime instance
  17989. @param{com.ibm.mashups.iwidget.widget.IWidgetDefinition} widgetDefinition IWidgetDefinition to use for this runtime instance. Must not be null.
  17990. @type{void}
  17991. @return{void}
  17992. */
  17993. setIWidgetDefinition: function(widgetDefinition) {
  17994. },
  17995. /**
  17996. This method returns iWidgetInstance which contains all the descriptive data for this iWidget instance
  17997. @type com.ibm.mashups.iwidget.widget.IWidgetInstance
  17998. @returns{com.ibm.mashups.iwidget.widget.IWidgetInstance } iWidgetInstance object
  17999. */
  18000. getIWidgetInstance: function() {
  18001. },
  18002. /**
  18003. * This method returns the a clone of the content of the widget as it is inside of the DOM.<br/>It removes automatically
  18004. * any markup that was added to the DOM using microformats (given that the microformat implements the unProcess handler).<br/>
  18005. * This method does not remove any additional DOM changes that where done by the widget itself and applies the unProcess only<br/>
  18006. * to the subnodes of the actual widget node.<br/><br/>
  18007. * If your widget needs to take special action to it's DOM nodes before the getMarkup is processing it, you can define the method<br/>
  18008. * <code>_onGetMarkup</code> in your widgets JavaScript file. This method, as part of the iScope, will always be called before the actual<br/>
  18009. * markup is processed.<br/><br/>
  18010. * <b>The synchrounus mode of returned Deferred is not supported.</b>
  18011. * @type com.ibm.mashups.enabler.Deferred
  18012. * @returns {com.ibm.mashups.enabler.Deferred} a deferred object used to fetch the actual markup.
  18013. */
  18014. getMarkup: function() {
  18015. },
  18016. /**
  18017. This method returns true if an iwidget instance is already loaded on the page dom.
  18018. @type Boolean
  18019. @returns{Boolean } true if widget is already completely rendered on the page.
  18020. */
  18021. isLoaded: function() {
  18022. },
  18023. /**
  18024. * This method returns true if an iwidget instance is standalone on the page.
  18025. * @type Boolean
  18026. * @returns{Boolean} true if widget is standalone on the page.
  18027. */
  18028. isStandalone: function() {
  18029. },
  18030. /**
  18031. This method displays the widgets on the page if widget has not been displayed yet.
  18032. @type void
  18033. */
  18034. doRender: function() {
  18035. }
  18036. });
  18037. }
  18038. if(!dojo._hasResource["com.ibm.mm.enabler.aggregation.javascript.Filter"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  18039. dojo._hasResource["com.ibm.mm.enabler.aggregation.javascript.Filter"] = true;
  18040. dojo.provide("com.ibm.mm.enabler.aggregation.javascript.Filter");
  18041. function com_ibm_enabler_aggregation_javascript_globalEvalNonIE( /*String*/javascript) {
  18042. // summary: Evaluates a string of javascript in the global scope.
  18043. // description: Calling eval.call( self, ... ); from within a JS object apparently makes "this" point to the object from which the
  18044. // eval call was made even though the scope is set using the "call" function. Therefore we need to have this function
  18045. // available in the global scope and not as a member variable on a JS object.
  18046. eval.call(self, javascript);
  18047. }
  18048. dojo.declare("com.ibm.mm.enabler.aggregation.javascript.Filter", null, {
  18049. // summary: Base interface for a filter. Each implementation must implement
  18050. // the doFilter function.
  18051. // description: Passes the given event through to give the implementation of
  18052. // this filter a chance to alter or handle the event in some way.
  18053. constructor: function() {
  18054. },
  18055. doFilter: function( script) {
  18056. // summary: Filter the given event.
  18057. // description: Allows this filter to handle or alter the event. If this function
  18058. // returns true, processing is stopped and the event is considered "handled".
  18059. // script: the script block (string or HTMLElement)
  18060. //dojo.unimplemented( "com.ibm.mm.enabler.aggregation.JavascriptFilter.doFilter" );
  18061. },
  18062. evalGlobal: function( javascript) {
  18063. // summary: Evaluates the given javascript in the global context.
  18064. // javascript: a string of javascript to evaluate.
  18065. if (window.execScript) { // JSLINT-IGNORE: We have to use eval here
  18066. window.execScript(this._stripHTMLComments(javascript), "JavaScript"); // JSLINT-IGNORE: We have to use eval here
  18067. }
  18068. else {
  18069. //Using eval.call( window, javascript ) was apparently not really eval'ing
  18070. //in the global scope since 'this' was still referring to the Filter object
  18071. //and not the window object as it should have (or I think it should have)...
  18072. com_ibm_enabler_aggregation_javascript_globalEvalNonIE(javascript);
  18073. }
  18074. },
  18075. _stripHTMLComments: function(str) {
  18076. // summary: Strip all HTML comments from a script block.
  18077. // description: Although HTML comments are allowed in a script block by the browser
  18078. // IE throws up whenever you try and eval a javascript string in the global context
  18079. // that has HTML comments in the string.
  18080. var resultStr = str;
  18081. resultStr = resultStr.replace(/<!--[^(-->)]+-->/g, '');
  18082. return resultStr;
  18083. },
  18084. prepareDocumentWrite: function(buffer) {
  18085. // summary: Prepares support for document.write() and document.writeln
  18086. // description: Overrides the original document.write() and document.writeln()
  18087. // functions with functions writing to the buffer
  18088. var me = this;
  18089. document.write = function() { // JSLINT-IGNORE: We have to use eval here
  18090. me._documentWrite(buffer, document.write.arguments); // JSLINT-IGNORE: We have to use eval here
  18091. };
  18092. document.writeln = function(str) { // JSLINT-IGNORE: We have to use eval here
  18093. me._documentWrite(buffer, document.writeln.arguments); // JSLINT-IGNORE: We have to use eval here
  18094. };
  18095. },
  18096. _documentWrite: function(buffer, args) {
  18097. // summary: Internal document.write() function writing to the given buffer
  18098. // description: Just appends the given String arguments to our buffer
  18099. for (var i = 0, l = args.length; i < l; i++) {
  18100. buffer.content += args[i];
  18101. }
  18102. },
  18103. applyDocumentWrite: function( script, buffer) {
  18104. // summary: Injects the markup in the given buffer into the DOM
  18105. // description: Looks up the script element in the original DOM
  18106. // and injects the markup before that element
  18107. var cont = buffer.content || null;
  18108. if (cont !== null && cont.length > 0) {
  18109. var i = 0;
  18110. if (dojo.isIE) {
  18111. // Attention: IE needs the <br> tag available, otherwise <script> tags get stripped when using .innerHTML
  18112. cont = '<br>' + cont;
  18113. i++; // the <br> tag must not be copied, so stop iterating one earlier
  18114. }
  18115. var div = dojo.create("div",{
  18116. innerHTML: cont
  18117. });
  18118. var execute = dojo.isIE || dojo.isWebKit || dojo.isOpera; // IE, WebKit and Opera don't execute the inserted scripts automatically, so do it for them.
  18119. var children = div.childNodes || null;
  18120. if (children !== null && children.length > 0) {
  18121. // copy the nodes over into the DOM
  18122. var pred = script;
  18123. var l;
  18124. var scripts = [];
  18125. while (i < (l = children.length)) {
  18126. var node = children[l - 1];
  18127. // we need to inject the markup before the script element
  18128. // to properly handle table updates
  18129. dojo.place(node, pred, 'before');
  18130. if (execute && node.tagName && node.tagName.toLowerCase() == 'script') {
  18131. scripts.unshift(node);
  18132. }
  18133. pred = node;
  18134. }
  18135. if (execute) {
  18136. dojo.forEach(scripts, function(scr){
  18137. com.ibm.mm.enabler.aggregation.javascript.JAVASCRIPT_HANDLER.handle(scr);
  18138. });
  18139. }
  18140. }
  18141. dojo.destroy(div);
  18142. }
  18143. }
  18144. });
  18145. }
  18146. if(!dojo._hasResource["com.ibm.mm.enabler.aggregation.javascript.ExternalScriptFilter"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  18147. dojo._hasResource["com.ibm.mm.enabler.aggregation.javascript.ExternalScriptFilter"] = true;
  18148. dojo.provide("com.ibm.mm.enabler.aggregation.javascript.ExternalScriptFilter");
  18149. dojo.declare("com.ibm.mm.enabler.aggregation.javascript.ExternalScriptFilter", com.ibm.mm.enabler.aggregation.javascript.Filter, {
  18150. doFilter: function( /*HTMLElement*/script) {
  18151. // summary: Filter the given event.
  18152. // description: Allows this filter to handle or alter the event. If this function
  18153. // returns true, processing is stopped and the script is considered "handled".
  18154. // script: the script block (HTMLElement)
  18155. var url = this._getScriptUrl(script);
  18156. var handled = false;
  18157. if (url) {
  18158. // check if the AJAX proxy is enabled
  18159. var proxyURL = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME).getValue(com.ibm.mashups.enabler.services.ConfigConstants.PROXY_URL);
  18160. proxyURL = proxyURL || null;
  18161. if (proxyURL !== null) {
  18162. proxyURL += "/";
  18163. url = this._rewriteURL(url, proxyURL);
  18164. }
  18165. // prepare buffer for document.write/ln
  18166. var buffer = {
  18167. content: ""
  18168. };
  18169. this.prepareDocumentWrite(buffer);
  18170. this._loadExternalScript(url);
  18171. // apply document.write/ln to DOM
  18172. this.applyDocumentWrite(script, buffer);
  18173. handled = true;
  18174. }
  18175. return handled;
  18176. },
  18177. _getScriptUrl: function( /*HTMLElement*/script) {
  18178. // summary: Retrieve the src attribute value of a script tag if it exists.
  18179. // returns: the url for the script tag or null if the script tag doesn't specify a URL
  18180. var url = null;
  18181. if (script.getAttribute) {
  18182. url = script.getAttribute("src");
  18183. }
  18184. else {
  18185. var start = script.toLowerCase().indexOf("<script");
  18186. var end = script.toLowerCase().indexOf(">");
  18187. var scriptTagSubstr = script.substring(start, end);
  18188. var srcIndex = scriptTagSubstr.toLowerCase().indexOf("src");
  18189. if (srcIndex != -1) {
  18190. // figure out whether it's a src='blah' or src="blah"
  18191. var quoteIndex = scriptTagSubstr.indexOf("'", srcIndex);
  18192. var dblQuoteIndex = scriptTagSubstr.indexOf('"', srcIndex);
  18193. var markerChar = '"';
  18194. var markerIndex = dblQuoteIndex;
  18195. if (dblQuoteIndex == -1 || (quoteIndex != -1 && quoteIndex < dblQuoteIndex)) {
  18196. markerChar = "'";
  18197. markerIndex = quoteIndex;
  18198. }
  18199. var markerIndex2 = scriptTagSubstr.indexOf(markerChar, markerIndex + 1);
  18200. url = scriptTagSubstr.substring(markerIndex + 1, markerIndex2);
  18201. }
  18202. }
  18203. return url;
  18204. },
  18205. /**
  18206. * This is reused by space-extension remote script loading.
  18207. */
  18208. loadExternalScript: function( /*String*/url) {
  18209. var proxyURL = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME).getValue(com.ibm.mashups.enabler.services.ConfigConstants.PROXY_URL);
  18210. proxyURL = proxyURL || null;
  18211. if (proxyURL !== null) {
  18212. proxyURL += "/";
  18213. url = this._rewriteURL(url, proxyURL);
  18214. }
  18215. this._loadExternalScript(url);
  18216. },
  18217. _loadExternalScript: function( /*String*/url) {
  18218. var me = this;
  18219. dojo.xhrGet({
  18220. url: url,
  18221. load: function(data, ioArgs) {
  18222. me.evalGlobal(data);
  18223. },
  18224. sync: true,
  18225. handleAs: "text"
  18226. });
  18227. },
  18228. _rewriteURL: function(/*String*/targetUrl, /*String*/ proxyUrl) {
  18229. var newURL = proxyUrl;
  18230. var host = window.location.host;
  18231. var protocol = window.location.protocol;
  18232. // check if this is a proxy request:
  18233. if (targetUrl.indexOf("://") < 0 || targetUrl.indexOf(protocol) === 0 && targetUrl.indexOf(host) == protocol.length + 2) {
  18234. return targetUrl;
  18235. }
  18236. // rewrite
  18237. if (targetUrl.indexOf("https") === 0) {
  18238. newURL += "https/";
  18239. }
  18240. else {
  18241. newURL += "http/";
  18242. }
  18243. newURL += targetUrl.substr(targetUrl.indexOf("://") + 3);
  18244. return newURL;
  18245. }
  18246. });
  18247. }
  18248. if(!dojo._hasResource["com.ibm.mm.enabler.aggregation.javascript.FilterChain"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  18249. dojo._hasResource["com.ibm.mm.enabler.aggregation.javascript.FilterChain"] = true;
  18250. dojo.provide("com.ibm.mm.enabler.aggregation.javascript.FilterChain");
  18251. dojo.declare("com.ibm.mm.enabler.aggregation.javascript.FilterChain", null, {
  18252. constructor: function() {
  18253. this._filters = [];
  18254. },
  18255. // summary: Controls the registration and execution of the filters associated
  18256. // with this filter chain.
  18257. addFilter: function(filter) {
  18258. // summary: Register a filter at the end of the filter chain.
  18259. // filter: the filter to append
  18260. if (!this._filters) {
  18261. this._filters = [];
  18262. }
  18263. this._filters.push(filter);
  18264. },
  18265. applyFilters: function(script) {
  18266. // summary: Execute the filter chain.
  18267. // description: Calls doFilter on every filter registered in this filter chain
  18268. // until all filters have been called or one of the filters returns true.
  18269. // e: the event object
  18270. // returns: true if the event was handled, false if it was not
  18271. var returnValue = false;
  18272. for(var i = 0, l = this._filters.length; i < l && !returnValue; i++) {
  18273. returnValue = this._filters[i].doFilter(script);
  18274. }
  18275. return returnValue; //Boolean
  18276. }
  18277. });
  18278. }
  18279. if(!dojo._hasResource["com.ibm.mm.enabler.aggregation.javascript.InlineScriptFilter"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  18280. dojo._hasResource["com.ibm.mm.enabler.aggregation.javascript.InlineScriptFilter"] = true;
  18281. dojo.provide("com.ibm.mm.enabler.aggregation.javascript.InlineScriptFilter");
  18282. dojo.declare("com.ibm.mm.enabler.aggregation.javascript.InlineScriptFilter", com.ibm.mm.enabler.aggregation.javascript.Filter, {
  18283. doFilter: function( /*HTMLElement*/script) {
  18284. // summary: Filter the given event.
  18285. // description: Allows this filter to handle or alter the script. If this function
  18286. // returns true, processing is stopped and the script is considered "handled".
  18287. // script: the script block (HTMLElement)
  18288. var handled = false, tokenContents = "";
  18289. if (!dojo.isString(script)) {
  18290. //Use innerHTML because IE doesn't correctly provide the textContent for a script tag.
  18291. tokenContents = script.innerHTML;
  18292. }
  18293. else {
  18294. var scriptStr = script;
  18295. var firstIndex = scriptStr.indexOf(">");
  18296. var lastIndex = scriptStr.lastIndexOf("<");
  18297. tokenContents = scriptStr.substring(firstIndex + 1, lastIndex);
  18298. }
  18299. if (tokenContents) {
  18300. // prepare buffer for document.write/ln
  18301. var buffer = {
  18302. content: ""
  18303. };
  18304. this.prepareDocumentWrite(buffer);
  18305. // Eval the contents
  18306. this.evalGlobal(tokenContents);
  18307. handled = true;
  18308. // apply document.write/ln to DOM
  18309. this.applyDocumentWrite(script, buffer);
  18310. }
  18311. return handled;
  18312. }
  18313. });
  18314. }
  18315. if(!dojo._hasResource["com.ibm.mm.enabler.aggregation.javascript.WidgetJavascriptHandler"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  18316. dojo._hasResource["com.ibm.mm.enabler.aggregation.javascript.WidgetJavascriptHandler"] = true;
  18317. dojo.provide("com.ibm.mm.enabler.aggregation.javascript.WidgetJavascriptHandler");
  18318. dojo.declare("com.ibm.mm.enabler.aggregation.javascript.WidgetJavascriptHandler", null, {
  18319. constructor: function() {
  18320. this.filterChain = new com.ibm.mm.enabler.aggregation.javascript.FilterChain();
  18321. },
  18322. // summary: Examines all javascript included by a widget, modifies it if
  18323. // necessary and evaluates it in the global context.
  18324. // description: All script elements must be loaded manually since the widget
  18325. // markup is added asynchronously. This handler will evaluate a script
  18326. // element in the global context or load an external script file if necessary.
  18327. handle: function(script) {
  18328. // summary: Handles a script element added asynchronously.
  18329. // script: the script element
  18330. var val = this.filterChain.applyFilters(script);
  18331. }
  18332. });
  18333. }
  18334. if(!dojo._hasResource["com.ibm.mm.enabler.aggregation.javascript"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  18335. dojo._hasResource["com.ibm.mm.enabler.aggregation.javascript"] = true;
  18336. dojo.provide("com.ibm.mm.enabler.aggregation.javascript");
  18337. com.ibm.mm.enabler.aggregation.javascript.JAVASCRIPT_HANDLER = new com.ibm.mm.enabler.aggregation.javascript.WidgetJavascriptHandler();
  18338. //Register the filters. The order registered is the order executed.
  18339. com.ibm.mm.enabler.aggregation.javascript.JAVASCRIPT_HANDLER.filterChain.addFilter(new com.ibm.mm.enabler.aggregation.javascript.ExternalScriptFilter());
  18340. com.ibm.mm.enabler.aggregation.javascript.JAVASCRIPT_HANDLER.filterChain.addFilter(new com.ibm.mm.enabler.aggregation.javascript.InlineScriptFilter());
  18341. }
  18342. if(!dojo._hasResource["com.ibm.mashups.iwidget.Constants"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  18343. dojo._hasResource["com.ibm.mashups.iwidget.Constants"] = true;
  18344. dojo.provide("com.ibm.mashups.iwidget.Constants");
  18345. /**
  18346. * com.ibm.mashups.iwidget.Constants defines all the public iwidget framework constants.<br/>
  18347. * Each constants should be referred to as : com.ibm.mashups.iwidget.Constants.WIDGET_LOADED...
  18348. * @ibm-module iWidget2
  18349. */
  18350. dojo.declare("com.ibm.mashups.iwidget.Constants", null, {
  18351. /**
  18352. * Enabler would publish WIDGET_LOADED event when an iwidget is loaded. <br/>
  18353. * <b>Event</b>: com.ibm.mashups.iwidget.Constants.WIDGET_LOADED<br/>
  18354. * <b>Value</b>:"com.ibm.mashups.iwidget.widgetloaded"<br/>
  18355. * <b>Payload</b>: String -- widgetid<br/>
  18356. * For example:
  18357. * When event is published, a name convention is use: com.ibm.mashups.iwidget.Constants.WIDGET_LOADED+"."+widgetId
  18358. * An widget could subscribe to this event by using following SPI:
  18359. * var eventService = com.ibm.mashups.services.ServiceManager.getService("eventService");
  18360. * eventService.subscribeEvent(com.ibm.mashups.iwidget.Constants.WIDGET_LOADED+"."+widgetId,scopeobject,"mycallbackfn");
  18361. * @type String
  18362. * @ibm-spi
  18363. */
  18364. WIDGET_LOADED: "com.ibm.mashups.iwidget.widgetloaded",
  18365. /**
  18366. * Enabler would subscribe this event and page components could publish RESIZE_WIDGET event to indicate an iwidget need to be resized.<br/>
  18367. * When event is published, a name convention is used: com.ibm.mashups.iwidget.Constants.RESIZE_WIDGET+"."+widgetId
  18368. * Page component should publish event by using following SPI:
  18369. * var eventService = com.ibm.mashups.services.ServiceManager.getService("eventService");
  18370. * eventService.publishEvent(com.ibm.mashups.iwidget.Constants.RESIZE_WIDGET+"."+widgetId,payload);
  18371. * <b>Event</b>: com.ibm.mashups.iwidget.Constants.RESIZE_WIDGET<br/>
  18372. * <b>Value</b>:"com.ibm.mashups.iwidget.resizewidget"<br/>
  18373. * <b>Payload</b>: JSON object: {"newWidth": "","newHeight": ""}<br/>
  18374. * @type String
  18375. * @ibm-spi
  18376. */
  18377. RESIZE_WIDGET: "com.ibm.mashups.iwidget.resizewidget",
  18378. /**
  18379. * Enabler would subscribe this event and page components could publish UNLOAD_WIDGETS event to unload certain widgets.<br/>
  18380. * For example: layout widget could publish this event to unload all the widgets on the page upon page switch<br/>
  18381. * When all the requested iwidgets are unloaded, enabler would publish event --com.ibm.mashups.iwidget.Constants.WIDGETS_UNLOADED <br/>
  18382. * <b>Event</b>: com.ibm.mashups.iwidget.Constants.UNLOAD_WIDGETS<br/>
  18383. * <b>Value</b>:"com.ibm.mashups.iwidget.unloadwidgets"<br/>
  18384. * <b>Payload</b>: an array of widget id that need to be unloaded<br/>
  18385. * @type String
  18386. * @ibm-spi
  18387. */
  18388. UNLOAD_WIDGETS: "com.ibm.mashups.iwidget.unloadwidgets",
  18389. /**
  18390. * Enabler would publish WIDGETS_UNLOADED event when requested iwidgets are unloaded. This event is used together with com.ibm.mashups.iwidget.Constants.UNLOAD_WIDGETS.<br/>
  18391. * <b>Event</b>: com.ibm.mashups.iwidget.Constants.WIDGETS_UNLOADED<br/>
  18392. * <b>Value</b>:"com.ibm.mashups.iwidget.widgetsunloaded"<br/>
  18393. * <b>Payload</b>: an array of widget id that are unloaded<br/>
  18394. * @type String
  18395. * @ibm-spi
  18396. */
  18397. WIDGETS_UNLOADED: "com.ibm.mashups.iwidget.widgetsunloaded",
  18398. /**
  18399. * Enabler would publish WIDGET_MODECHANGED event when requested iwidget has switched from one mode to another mode. <br/>
  18400. * <b>Event</b>: com.ibm.mashups.iwidget.Constants.WIDGET_MODECHANGED<br/>
  18401. * <b>Value</b>:"com.ibm.mashups.iwidget.widgetmodechanged"<br/>
  18402. * <b>Payload</b>: JSON object: {id:"",oldMode:"",newMode:""}<br/>
  18403. * @type String
  18404. * @ibm-api
  18405. */
  18406. WIDGET_MODECHANGED: "com.ibm.mashups.iwidget.widgetmodechanged",
  18407. /**
  18408. * Enabler would subscribe this event and page components could publish CHANGE_WIDGETMODE event to change a mode of a widget.<br/>
  18409. * Page components should publish event as follows:
  18410. * var eventService = com.ibm.mashups.services.ServiceManager.getService("eventService");
  18411. * eventService.publishEvent(com.ibm.mashups.iwidget.Constants.CHANGE_WIDGETMODE,payload);
  18412. * following api is deprecated:
  18413. * com.ibm.mashups.services.ServiceManager.getService("eventService").fireEvent(this.iwidgetId, "onModeChanged", {
  18414. * newMode: mode,
  18415. * rootElementId: <DOMNode>
  18416. * });
  18417. * <b>Event</b>: com.ibm.mashups.iwidget.Constants.CHANGE_WIDGETMODE<br/>
  18418. * <b>Value</b>:"com.ibm.mashups.iwidget.changeWidgetMode"<br/>
  18419. * <b>Payload</b>: JSON object: {id:"",newMode:"",parentNode:<DOMNode>}<br/>
  18420. * @type String
  18421. * @ibm-api
  18422. */
  18423. CHANGE_WIDGETMODE: "com.ibm.mashups.iwidget.changewidgetmode",
  18424. /**
  18425. * Enabler would subscribe WIDGET_WINDOWSTATECHANGED event when iwidget has been switched from one window state to another another. <br/>
  18426. * <b>Event</b>: com.ibm.mashups.iwidget.Constants.WIDGET_WINDOWSTATECHANGED<br/>
  18427. * <b>Value</b>:"com.ibm.mashups.iwidget.widgetwindowstatechanged"<br/>
  18428. * <b>Payload</b>: JSON object: {id:"",oldWindowState:"",newWindowState:""}<br/>
  18429. * @type String
  18430. * @ibm-api
  18431. */
  18432. WIDGET_WINDOWSTATECHANGED: "com.ibm.mashups.iwidget.widgetwindowstatechanged",
  18433. /**
  18434. * Enabler would publish this event when widget is tried to change window state.<br/>
  18435. * <b>Event</b>: com.ibm.mashups.iwidget.Constants.CHANGE_WIDGETWINDOWSTATE<br/>
  18436. * <b>Value</b>:"com.ibm.mashups.iwidget.changeWidgetWindowState"<br/>
  18437. * <b>Payload</b>: JSON object: {id:"",newWindowState:"",oldWindowState:""}<br/>
  18438. * @type String
  18439. * @ibm-api
  18440. */
  18441. CHANGE_WIDGETWINDOWSTATE: "com.ibm.mashups.iwidget.changewidgetwindowstate",
  18442. /**
  18443. * Event that will be published when navigation state is committed.
  18444. * <b>Event</b>: com.ibm.mashups.iwidget.Constants.NAVSTATE_UPDATED<br/>
  18445. * <b>Value</b>:"com.ibm.mashups.enabler.model.state.onNavStateUpdated"<br/>
  18446. * For example: <br/>
  18447. * An widget could subscribe to this event by using following SPI:<br/>
  18448. * var eventService = com.ibm.mashups.services.ServiceManager.getService("eventService");<br/>
  18449. * eventService.subscribeEvent("com.ibm.mashups.enabler.model.state.onNavStateUpdated",scope,"mycallbackfn");<br/>
  18450. * In the callback function, an widget should use Accessor api to get the navstate they're interested </br>
  18451. * Following example use PageAccessor as an example<br/>
  18452. * var pageAccessor = com.ibm.mashups.enabler.model.state.AccessorFactory.getPageAccessor(navigationStateModel);<br/>
  18453. * var pageId = pageAccessor.getPageID(); <br/>
  18454. * @type String
  18455. */
  18456. NAVSTATE_UPDATED:"com.ibm.mashups.enabler.model.state.onNavStateUpdated"
  18457. });
  18458. com.ibm.mashups.iwidget.Constants = new com.ibm.mashups.iwidget.Constants();
  18459. }
  18460. if(!dojo._hasResource["com.ibm.mashups.iwidget.iEvents_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  18461. dojo._hasResource["com.ibm.mashups.iwidget.iEvents_API"] = true;
  18462. dojo.provide("com.ibm.mashups.iwidget.iEvents_API");
  18463. dojo.provide("com.ibm.mashups.iwidget.iEvents");
  18464. /**
  18465. * This interface defines methods that's used for event distribution and event management. Events service is accessible by using <b>"this.iContext"</b><p/>
  18466. * &nbsp;&nbsp;&nbsp; <code>this.iContext.iEvents</code><p/>
  18467. * To distribute an event:<p/>
  18468. * &nbsp;&nbsp;&nbsp; <code>this.iContext.iEvents.fireEvent("eventName");</code><p/>
  18469. *
  18470. * @ibm-api
  18471. * @ibm-module iWidget2
  18472. */
  18473. dojo.declare("com.ibm.mashups.iwidget.iEvents",null,
  18474. { /**
  18475. * @private
  18476. */
  18477. constructor:function () {
  18478. },
  18479. /**
  18480. This method informs the iContext to distribute an event with proper payload and payload type
  18481. @param{String} eventName name of the event that needs to be distributed.Must not be <code>null</code>.
  18482. @param{String} payloadType optional,type of the payload.
  18483. @param{object} payload optional,object of the payload that needs to be distributed together with the event
  18484. @type void
  18485. */
  18486. fireEvent:function(/*String*/eventName,/*String*/payloadType,/*object*/payload){
  18487. },
  18488. /**
  18489. This method simply creates a new event definition or updates an existing event if the name already exists. <br/>
  18490. It returns true if new event is created successfully or existing event is updated successfully. It returns false if it fails to create new event or update existing event.<br/>
  18491. @param{com.ibm.mashups.iwidget.IEventDescription} eventDesc IEventDescription object. Must not be <code>null</code>.
  18492. @type Boolean
  18493. @returns{Boolean} returns true if new event is created successfully or existing event is updated successfully. It returns false if it fails to create new event or update existing event.
  18494. */
  18495. setEvent:function(/* iEventDescription*/ eventDesc){
  18496. },
  18497. /**
  18498. Using this method will potentially allow optimizations to occur within the iContext. The returned boolean <br/>
  18499. indicates whether or not the request added all the described events to the iwidgets. <br/>
  18500. @param{com.ibm.mashups.iwidget.IEventDescription[]} eventDesc array of IEventDescription object. Must not be <code>null</code>.
  18501. @type Boolean
  18502. @returns{Boolean} returns true if all the events are created successfully or existing events are updated successfully. It returns false if not all events are processed successfully.
  18503. */
  18504. setEvents:function(/* iEventDescription[]*/ eventDescs){
  18505. },
  18506. /**
  18507. This method removes an existing event description.It returns true if event is removed successfully or event doesn't exist, otherwise it returns false. <br/>
  18508. @param{String} eventName event name. Must not be <code>null</code>.
  18509. @type Boolean
  18510. @returns{Boolean} returns true if event is removed successfully or event doesn't exist, otherwise it returns false.
  18511. */
  18512. removeEvent:function(/*String*/ eventName){
  18513. },
  18514. /**
  18515. This method removes specified events.It returns true if all the events are removed successfully , otherwise it returns false. <br/>
  18516. @param{String[]} eventName event name. Must not be <code>null</code>.
  18517. @type Boolean
  18518. @returns{Boolean} returns true if all the events are removed successfully, otherwise it returns false.
  18519. */
  18520. removeEvents:function(/*String[]*/ eventNames){
  18521. },
  18522. /**
  18523. The query method which takes a javascript object as condition, it returns a list of event descriptions which matches the given condition. <br/>
  18524. The scope of the events is limited to this iwidget instance. The returning result need to match all the conditions that's given. <br/>
  18525. For exampe, if a condition object looks like this: {type:'text', isHandled:true}<br/>
  18526. This method will return all the handled event description whose payload is text.<br/>
  18527. If no condition is provided, this method will return all the events. It returns null if no event is found for a given condition.Only predefined fields or non localized attributes should be used to define condition.
  18528. @param{Object} condition JSON object that contains the condition. Must not be <code>null</code>.
  18529. @type com.ibm.mashups.iwidget.IEventDescription
  18530. @returns{com.ibm.mashups.iwidget.IEventDescription} returns an array of event description that matches the condition. It returns null if no event is found for a given condition.
  18531. */
  18532. getEvents:function(/*Object*/ condition){
  18533. },
  18534. /**
  18535. This method allows to create a new IEventDescription object. All the data should be passed in as a JSON object.<br/>
  18536. Following rules applied to the JSON object:<br/>
  18537. 1. Predefined fields: name,type,isHandled,isPublished,lang,handlingFn<br/>
  18538. 2. Localized attributes: please see sample below<br/>
  18539. 3. Non-localized attributes: please see sample below<br/>
  18540. 4. Lotus Mashups provides a feature to allow a widget to register a private event so this event will not be exposed to other iwidgets by the wiring interface<br/>
  18541. &nbsp;&nbsp;&nbsp;private attribute is used to mark an event to be a private event. please see sample below<br/>
  18542. <code>
  18543. &nbsp;&nbsp;&nbsp;var obj = {name:"sendData", type:"text", isHandled:"true", lang:"en", handlingFn:"onSendData", <br/>
  18544. &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;localizedAttributes:{ <br/>
  18545. &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;"en":{"title":"mytitle_en","description":"mydescription_en"},<br/>
  18546. &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;"fr":{"title":"mytitle_fr","description":"mydescription_fr"} <br/>
  18547. &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;} , <br/>
  18548. &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;attributes:{ namespace:"com.ibm.mashups", onRemoveWire:"handleRemoveWire",private:"true"} <br/>
  18549. &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; };<br/>
  18550. &nbsp;&nbsp;&nbsp;var event = this.iContext.iEvents.createEventDescription(obj);<br/>
  18551. &nbsp;&nbsp;&nbsp;this.iContext.iEvents.setEvent(event);<br/>
  18552. </code>
  18553. @param{Object} object JSON object that contains all the data to create an IEventDescription. Must not be <code>null</code>.
  18554. @type com.ibm.mashups.iwidget.IEventDescription
  18555. @returns{com.ibm.mashups.iwidget.IEventDescription} returns an IEventDescription . It returns null if it fail to create the iEventDescription.
  18556. */
  18557. createEventDescription:function(/* Object */object){
  18558. }
  18559. });
  18560. }
  18561. if(!dojo._hasResource["com.ibm.mashups.iwidget.IEvent_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  18562. dojo._hasResource["com.ibm.mashups.iwidget.IEvent_API"] = true;
  18563. dojo.provide("com.ibm.mashups.iwidget.IEvent_API");
  18564. dojo.provide("com.ibm.mashups.iwidget.IEvent");
  18565. /**
  18566. * it carries various pieces of information when an event flows at runtime
  18567. *
  18568. * @ibm-api
  18569. * @ibm-module iWidget2
  18570. */
  18571. dojo.declare("com.ibm.mashups.iwidget.IEvent", null, {
  18572. constructor: function() {
  18573. /**
  18574. * @private
  18575. */
  18576. },
  18577. /**
  18578. The name of the event.
  18579. @type String
  18580. */
  18581. name:/*String*/ "",
  18582. /**
  18583. The type of any payload. If this is set to null, no information is being provided.
  18584. @type String
  18585. */
  18586. type:/*String*/ "",
  18587. /**
  18588. The data, if any, being provided by the source of the event.
  18589. @type Object
  18590. */
  18591. payload:/*object*/ null,
  18592. /**
  18593. The iWidget supplied id for the source iWidget.
  18594. @type String
  18595. */
  18596. source:/*String*/ ""
  18597. });
  18598. }
  18599. if(!dojo._hasResource["com.ibm.mashups.iwidget.IEvent"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  18600. dojo._hasResource["com.ibm.mashups.iwidget.IEvent"] = true;
  18601. dojo.provide("com.ibm.mashups.iwidget.IEvent");
  18602. }
  18603. if(!dojo._hasResource["com.ibm.mm.iwidget.IEventImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  18604. dojo._hasResource["com.ibm.mm.iwidget.IEventImpl"] = true;
  18605. dojo.provide("com.ibm.mm.iwidget.IEventImpl");
  18606. dojo.declare("com.ibm.mm.iwidget.IEventImpl", com.ibm.mashups.iwidget.IEvent, {
  18607. constructor: function(/*String*/name,/*String*/ type,/*Object*/ payload,/*String*/ source) {
  18608. this.name = name;
  18609. if (typeof type != "undefined") {
  18610. this.type = type;
  18611. }
  18612. else {
  18613. this.type = null;
  18614. }
  18615. if (typeof payload != "undefined") {
  18616. this.payload = payload;
  18617. }
  18618. else {
  18619. this.payload = null;
  18620. }
  18621. if (typeof source != "undefined") {
  18622. this.source = source;
  18623. }
  18624. else {
  18625. this.source = null;
  18626. }
  18627. this.source = source;
  18628. }
  18629. });
  18630. }
  18631. if(!dojo._hasResource["com.ibm.mm.iwidget.icontext.IContextIEventsImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  18632. dojo._hasResource["com.ibm.mm.iwidget.icontext.IContextIEventsImpl"] = true;
  18633. dojo.provide("com.ibm.mm.iwidget.icontext.IContextIEventsImpl");
  18634. dojo.declare("com.ibm.mm.iwidget.icontext.IContextIEventsImpl", com.ibm.mashups.iwidget.iEvents, {
  18635. constructor: function(wrapper) {
  18636. this.widget = wrapper;
  18637. this.id = wrapper.id;
  18638. this.svc = com.ibm.mashups.services.ServiceManager.getService("eventService");
  18639. this.timer = null;
  18640. this.timerEventQ = [];
  18641. this.allTargetWidgetsLoaded = false;
  18642. },
  18643. createEventDescription: function(/*json*/object) {
  18644. return new com.ibm.mm.iwidget.IEventDescriptionImpl(object);
  18645. },
  18646. getEvents: function(condition) {
  18647. //always return a data copy of each iEventDescription
  18648. //return null if no events is found
  18649. var eventModel = this.widget._getPublicEvents(); //get the internal eventModel
  18650. var events = eventModel.getEvents(condition);
  18651. //now build a copy of iEventDescription
  18652. if (!events) {
  18653. return null;
  18654. }
  18655. var arr = [];
  18656. for (var i in events) {
  18657. if (Object.prototype.hasOwnProperty.call(events,i)) {
  18658. arr.push(events[i].clone());
  18659. }
  18660. }
  18661. return arr;
  18662. },
  18663. setEvent: function(eventDesc) {
  18664. //create/update event
  18665. //return true if event is successful
  18666. // verify first whether the event is the same and no update is required
  18667. var eventModel = this.widget._getPublicEvents(); //get the internal eventModel
  18668. var rc = eventModel.eventExists(eventDesc.name);
  18669. var updateRequired = false;
  18670. if (rc) {
  18671. updateRequired = eventModel.isUpdateEventRequired(eventDesc);
  18672. }
  18673. else {
  18674. updateRequired = true;
  18675. }
  18676. if (updateRequired) {
  18677. var cs = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.iwidget.services.ContainerService.SERVICE_NAME);
  18678. if (cs) {
  18679. cs.switchToModifiablePersistenceMode(com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_EVENTS);
  18680. }
  18681. }
  18682. eventModel = this.widget._getPublicEvents(); //get the internal eventModel
  18683. rc = eventModel.eventExists(eventDesc.name);
  18684. if (rc) {
  18685. if (this.widget._inIframe()) {
  18686. this.svc._publishEvent(this.svc.WIDGETEVENT_PREFIX + "_stub_" + this.id, {
  18687. "scope": "eventmodel",
  18688. "methodname": "updateEvent",
  18689. "params": [eventDesc.toJson()]
  18690. }, this.id);
  18691. }
  18692. rc = eventModel.updateEvent(eventDesc);
  18693. }
  18694. else {
  18695. if (this.widget._inIframe()) {
  18696. this.svc._publishEvent(this.svc.WIDGETEVENT_PREFIX + "_stub_" + this.id, {
  18697. "scope": "eventmodel",
  18698. "methodname": "createEvent",
  18699. "params": [eventDesc.toJson()] //turn iEventDescription into an json object
  18700. }, this.id);
  18701. }
  18702. rc = eventModel.createEvent(eventDesc);
  18703. }
  18704. return rc;
  18705. },
  18706. removeEvent: function(eventName) {
  18707. var cs = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.iwidget.services.ContainerService.SERVICE_NAME);
  18708. if (cs) {
  18709. cs.switchToModifiablePersistenceMode(com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_EVENTS);
  18710. }
  18711. //remove event
  18712. //return true upon successful, if event doesn't exist or for other reason event can't be deleted, return false;
  18713. if (this.widget._inIframe()) {
  18714. this.svc._publishEvent(this.svc.WIDGETEVENT_PREFIX + "_stub_" + this.id, {
  18715. "scope": "eventmodel",
  18716. "methodname": "removeEvent",
  18717. "params": [eventName]
  18718. }, this.id);
  18719. }
  18720. var eventModel = this.widget._getPublicEvents(); //get the internal eventModel
  18721. var rc = eventModel.removeEvent(eventName);
  18722. return rc;
  18723. },
  18724. publishEvent: function(/*String*/eventName, payload, payloadType) {
  18725. //internal, deprecated, todo remove
  18726. return this.fireEvent(eventName, payloadType, payload);
  18727. },
  18728. fireEvent: function(/*String*/eventName, payloadType, payload) {
  18729. // 18152: Make sure all target widgets are loaded before firing event. Since wires are stored with the
  18730. // target widgets, the source widget could fireEvent before the target widgets, and therefore the wires,
  18731. // are loaded. By waiting until the target widgets are loaded, we ensure the needed wires are loaded.
  18732. if (this.allTargetWidgetsLoaded) {
  18733. this._fireEventFinish(eventName,payloadType,payload);
  18734. } else {
  18735. // Multiple fireEvents could come in while the asynchronous this.timer is processing, so queue up all
  18736. // fireEvents that come in so they can all get processed in _fireEventContinue in the order received.
  18737. this.timerEventQ.push({"eventName":eventName,"payloadType":payloadType,"payload":payload});
  18738. if (!this.timer) {
  18739. var widgetModel = com.ibm.mashups.iwidget.model.Factory.getGlobalWidgetModel();
  18740. var all_wires = dojo.query("."+this.widget.ns+"ReceivedEvent", this.widget.rootElement);
  18741. var target_widgets = [];
  18742. for (var i = 0; i < all_wires.length; i++) {
  18743. var sourceEvent = dojo.query("."+this.widget.ns+"SourceEvent", all_wires[i])[0];
  18744. if (sourceEvent) {
  18745. var href = sourceEvent.getAttribute("href");
  18746. if (href.indexOf(this.widget.id) != -1) {
  18747. var target_widget = widgetModel.find(all_wires[i].parentNode.id);
  18748. if (target_widget) {
  18749. target_widgets.push(target_widget);
  18750. }
  18751. }
  18752. }
  18753. }
  18754. this.timer_tries = 0;
  18755. this.timer = setInterval(dojo.hitch(this, "_fireEventContinue", target_widgets), 5);
  18756. }
  18757. }
  18758. },
  18759. _fireEventContinue:function(target_widgets){
  18760. for (var i = 0; i < target_widgets.length; i++) {
  18761. if (!target_widgets[i].isLoaded() && (this.timer_tries < 20)) { // should never reach 20, but just in case
  18762. this.timer_tries++;
  18763. return;
  18764. }
  18765. }
  18766. clearInterval(this.timer);
  18767. this.timer_tries = 0;
  18768. while (this.timerEventQ.length > 0) {
  18769. var event = this.timerEventQ.shift(); // first in, first out
  18770. this._fireEventFinish(event.eventName,event.payloadType,event.payload);
  18771. }
  18772. this.allTargetWidgetsLoaded = true;
  18773. this.timer = null;
  18774. },
  18775. _fireEventFinish:function(/*String*/eventName,payloadType,payload){
  18776. //event description here...
  18777. var eventModel = this.widget._getPublicEvents();
  18778. //var isHandled = widgetWrapper.handleEvent(eventName,aEvent);
  18779. //handle internally only if it's not a handled event
  18780. var isHandledEvent = false;
  18781. var temp;
  18782. if (eventModel) {
  18783. temp = eventModel.find(eventName);
  18784. //assign payload type
  18785. if (temp) {
  18786. payloadType = temp.type;
  18787. }
  18788. if (temp && temp.handlingFn) {
  18789. isHandledEvent = true;
  18790. }
  18791. }
  18792. var aEvent = new com.ibm.mm.iwidget.IEventImpl(eventName, payloadType, payload, null);
  18793. if (!isHandledEvent) {
  18794. this.widget.handleEvent(aEvent);
  18795. }
  18796. //publish wire if it's a published event
  18797. if (eventModel) {
  18798. temp = eventModel.find(eventName);
  18799. if (temp && temp.isPublished) {
  18800. this.svc.publishWire(this.id, eventName, payload, payloadType);
  18801. }
  18802. }
  18803. },
  18804. setEvents: function(eventDescs) {
  18805. var eventModel = this.widget._getPublicEvents();
  18806. if (this.widget._inIframe()) {
  18807. var arr = [];
  18808. for (var i = 0; i < eventDescs.length; i++) {
  18809. arr.push(eventDescs[i].toJson());
  18810. }
  18811. this.svc._publishEvent(this.svc.WIDGETEVENT_PREFIX + "_stub_" + this.id, {
  18812. "scope": "eventmodel",
  18813. "methodname": "setEvents",
  18814. "params": [arr]
  18815. }, this.id);
  18816. }
  18817. rc = eventModel.setEvents(eventDescs);
  18818. return rc;
  18819. },
  18820. removeEvents: function(eventNames) {
  18821. //remove event
  18822. //return true upon successful, if event doesn't exist or for other reason event can't be deleted, return false;
  18823. if (this.widget._inIframe()) {
  18824. this.svc._publishEvent(this.svc.WIDGETEVENT_PREFIX + "_stub_" + this.id, {
  18825. "scope": "eventmodel",
  18826. "methodname": "removeEvents",
  18827. "params": [eventNames]
  18828. }, this.id);
  18829. }
  18830. var eventModel = this.widget._getPublicEvents(); //get the internal eventModel
  18831. var rc = eventModel.removeEvents(eventNames);
  18832. return rc;
  18833. }
  18834. });
  18835. }
  18836. if(!dojo._hasResource["com.ibm.mashups.iwidget.iEvents"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  18837. dojo._hasResource["com.ibm.mashups.iwidget.iEvents"] = true;
  18838. dojo.provide("com.ibm.mashups.iwidget.iEvents");
  18839. }
  18840. if(!dojo._hasResource["com.ibm.mashups.iwidget.io_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  18841. dojo._hasResource["com.ibm.mashups.iwidget.io_API"] = true;
  18842. dojo.provide("com.ibm.mashups.iwidget.io_API");
  18843. dojo.provide("com.ibm.mashups.iwidget.io");
  18844. /**
  18845. * This interface defines support the iContext is supplying regarding IO operations.<p/>
  18846. * &nbsp;&nbsp;&nbsp; <code>this.iContext.io.rewriteURI(aUri);</code><p/>
  18847. *
  18848. * @ibm-api
  18849. * @ibm-module iWidget2
  18850. */
  18851. dojo.declare("com.ibm.mashups.iwidget.io", null, {
  18852. /**
  18853. * @private
  18854. */
  18855. constructor: function() {
  18856. },
  18857. /**
  18858. This object wraps the native XMLHttpRequest support to provide a consistent page in the face of asynchronous updates, especially those which may cause server-side coordination between the server-side components related to multiple iWidgets on the page.
  18859. @type XMLHttpRequest
  18860. @returns{XMLHttpRequest} returns native XMLHttpRequest object.
  18861. */
  18862. XMLHttpRequest: function() {
  18863. },
  18864. /**
  18865. This method takes a URI as a parameter and returns a URI which the browser can resolve for accessing the supplied URI.
  18866. Examples of usage include resolving a relative URI against the source of the iWidget's definition and resolving other URIs to address any intermediate
  18867. gateways, such as a proxy server. <p/>
  18868. &nbsp;&nbsp;&nbsp;Sample usage that resolves URI to address a proxy server ,assume url to proxy server is "/mum/proxy".<br/>
  18869. <code>
  18870. &nbsp;&nbsp;&nbsp; var aUri = "http://yourco.com/mytest.js"; <br/>
  18871. &nbsp;&nbsp;&nbsp; var rc = this.iContext.io.rewriteURI(aUri); <br/>
  18872. </code>
  18873. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;the result will be "/mum/proxy/http/yourco.com/mytest.js"<br/>
  18874. <br/>
  18875. &nbsp;&nbsp;&nbsp;Sample usage that resolves a relative URI against the source of the iWidget's deinfition<br/>
  18876. &nbsp;&nbsp;&nbsp; Assume iwidget is included on a page as follows:<br/>
  18877. <code>
  18878. &nbsp;&nbsp;&nbsp; &lt;span id="yourcoWidget" class="iw-iWidget"&gt;&lt;a class="iw-Definition" href="/mm/widget-catalog/yourcoWidget.xml"&gt;&lt;/a&gt;&lt;/span&gt;<br/><br/>
  18879. &nbsp;&nbsp;&nbsp; var aUri = "mytest.js"; <br/>
  18880. &nbsp;&nbsp;&nbsp; var rc = this.iContext.io.rewriteURI(aUri); <br/>
  18881. </code>
  18882. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;the result will be "/mm/widget-catalog/mytest.js" <br/>
  18883. <br/>
  18884. &nbsp;&nbsp;&nbsp;Sample usage that resolves a relative URI against the source of the iWidget's deinfition for an image resource.<br/>
  18885. &nbsp;&nbsp;&nbsp; Assume iwidget is included on a page as follows:<br/>
  18886. <code>
  18887. &nbsp;&nbsp;&nbsp; &lt;span id="yourcoWidget" class="iw-iWidget"&gt;&lt;a class="iw-Definition" href="http://yourco.com/mm/widget-catalog/yourcoWidget.xml"&gt;&lt;/a&gt;&lt;/span&gt;<br/><br/>
  18888. </code>
  18889. &nbsp;&nbsp;&nbsp;the url for the img resource of following code will be "http://yourco.com/mm/widget-catalog/mytest.gif" <br/>
  18890. <code>
  18891. &nbsp;&nbsp;&nbsp; var aUri = "mytest.gif"; <br/>
  18892. &nbsp;&nbsp;&nbsp; var returnUri = this.iContext.io.rewriteURI(aUri,false); <br/>
  18893. &nbsp;&nbsp;&nbsp; var img = dojo.byId(id); <br/>
  18894. &nbsp;&nbsp;&nbsp; img.src = returnUri;<br/>
  18895. </code>
  18896. @param{String} uri URI that needs to be resolved. Must not be <code>null</code>.
  18897. @param{Boolean} isXhr optional,boolean indicating the url is used as xhr. If no value is provided, the default is true.
  18898. @type String
  18899. @returns{String} return a URI which the browser can resolve for accessing the supplied URI. Must not be <code>null</code>.
  18900. */
  18901. rewriteURI: function(/*String*/uri,/*Boolean*/ isXhr) {
  18902. return null;
  18903. },
  18904. /**
  18905. This convenience method creates a new XMLHttpRequest and send the request with all supplied arguments on the XMLHttpRequest. <br/>
  18906. The supported fields within the arguments object include: <br/>
  18907. <code><br/>
  18908. {<br/>
  18909. &nbsp;&nbsp;&nbsp; "requestVerb": {"get" | "post" | "put" | "delete"}, <br/>
  18910. &nbsp;&nbsp;&nbsp;"url": {url},<br/>
  18911. &nbsp;&nbsp;&nbsp;"handleAs": {handleAs},<br/>
  18912. &nbsp;&nbsp;&nbsp;"sync": {boolean},<br/>
  18913. &nbsp;&nbsp;&nbsp;"preventCache": {boolean},<br/>
  18914. &nbsp;&nbsp;&nbsp;"content": {content},<br/>
  18915. &nbsp;&nbsp;&nbsp;"headers": {headers},<br/>
  18916. &nbsp;&nbsp;&nbsp;"timeout": {int},<br/>
  18917. &nbsp;&nbsp;&nbsp;"user": {user},<br/>
  18918. &nbsp;&nbsp;&nbsp;"password": {password},<br/>
  18919. &nbsp;&nbsp;&nbsp;"form": {form},<br/>
  18920. &nbsp;&nbsp;&nbsp;"msgData": {msgData},<br/>
  18921. &nbsp;&nbsp;&nbsp;"load": {load},<br/>
  18922. &nbsp;&nbsp;&nbsp;"error": {error},<br/>
  18923. &nbsp;&nbsp;&nbsp;"handle": {handle}<br/>
  18924. }<br/>
  18925. </code><br/>
  18926. @param{Object} args supported properties as listed above.
  18927. @type void
  18928. */
  18929. xhrReq:function(/*Object*/ args){
  18930. return;
  18931. }
  18932. });
  18933. }
  18934. if(!dojo._hasResource["com.ibm.mm.iwidget.icontext.IContextIOImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  18935. dojo._hasResource["com.ibm.mm.iwidget.icontext.IContextIOImpl"] = true;
  18936. dojo.provide("com.ibm.mm.iwidget.icontext.IContextIOImpl");
  18937. dojo.declare("com.ibm.mm.iwidget.icontext.IContextIOImpl", com.ibm.mashups.iwidget.io, {
  18938. constructor: function(wrapper) {
  18939. this.id = wrapper.id;
  18940. this.widget = wrapper;
  18941. },
  18942. XMLHttpRequest: function() {
  18943. return dojo._xhrObj();
  18944. },
  18945. rewriteURI: function(/*String*/uri, isXhr) {
  18946. var returnUri = this.widget._rewriteURI(uri, isXhr);
  18947. return returnUri;
  18948. },
  18949. getWebAppRootPath: function() {
  18950. //not all the widgets has context path, following are the examples:
  18951. //a. "http://host:test/accuweather" --> absolute path
  18952. //b. "/accuweather" --> full path
  18953. if (this.rootPath) {
  18954. return this.rootPath;
  18955. }
  18956. var rawUri = this.widget.getIWidgetInstance().widgetXMLUrl;
  18957. rawUri = this.widget._getRawBaseUri(rawUri); // resolve end point
  18958. rawUri = this.widget._getResolvedPocUri(rawUri); //resolve Poc Uri
  18959. var returnUri = null;
  18960. if (rawUri && rawUri.indexOf("/")===0){
  18961. var temp = rawUri.substring(1);
  18962. if (temp.indexOf("/")>0) {
  18963. returnUri = "/"+temp.substring(0,temp.indexOf("/"));
  18964. }else{
  18965. returnUri = rawUri;
  18966. }
  18967. }
  18968. if (returnUri) {
  18969. this.rootPath = returnUri;
  18970. return returnUri;
  18971. }
  18972. if (rawUri && rawUri.indexOf("://") > 0) {
  18973. var parts = rawUri.split("/");
  18974. if (parts.length >= 4) {
  18975. returnUri = parts[0] + "//" + parts[2] + "/" + parts[3];
  18976. }
  18977. }
  18978. if (returnUri) {
  18979. this.rootPath = returnUri;
  18980. return returnUri;
  18981. }
  18982. return null;
  18983. },
  18984. request: function(requestVerb, uri, callbackFn, message,/* [{headerName, value}] */ requestHeader) {
  18985. //Sends an HTTP request with the given method
  18986. //The method argument should be uppercase.
  18987. //sample callback Fn
  18988. /*function callbackFunction(){
  18989. if (this.readyState != 4) return;
  18990. var response = this.responseText;
  18991. }
  18992. */
  18993. var xhr = dojo._xhrObj();
  18994. var realUri = this.rewriteURI(uri);
  18995. var async = false;
  18996. if (callbackFn) {
  18997. xhr.onreadystatechange = callbackFn;
  18998. //sets it to asynchronous only if a callbackFn is provided, per xhr spec, user agent should consider default is true if it's omitted
  18999. async = true;
  19000. }
  19001. var method = requestVerb || null;
  19002. if (!requestVerb) {
  19003. method = this.httpmethods.GET;
  19004. }
  19005. if (requestVerb) {
  19006. if (!this.httpmethods[requestVerb]) {
  19007. method = this.httpmethods.GET;
  19008. }
  19009. }
  19010. //user/password xhr.open(method,realUri,async,user,pwd);
  19011. xhr.open(method, realUri, async);
  19012. //xhr.send();
  19013. //console.debug(method + " " + realUri);
  19014. var contentType = null;
  19015. var _defaultContentType = "application/x-www-form-urlencoded";
  19016. if (requestHeader) {
  19017. //Authors are strongly encouraged to ensure that they have specified the Content-Type header via setRequestHeader() before invoking send() with a non-null data argument.
  19018. for (var i = 0; i < requestHeader.length; i++) {
  19019. var anItem = requestHeader[i];
  19020. var headerName = anItem[headerName];
  19021. var value = anItem[value];
  19022. if (headerName == "Content-Type") {
  19023. contentType = value;
  19024. }
  19025. else {
  19026. xhr.setRequestHeader(headerName, value);
  19027. }
  19028. }
  19029. }
  19030. xhr.setRequestHeader("Content-Type", (contentType || _defaultContentType));
  19031. //user/password xhr.open(method,realUri,async,user,pwd);
  19032. if (method == this.httpmethods.PUT || method == this.httpmethods.POST) {
  19033. if (message) {
  19034. xhr.send(message);
  19035. }
  19036. }
  19037. else {
  19038. xhr.send(null);
  19039. }
  19040. return xhr;
  19041. },
  19042. xhrReq:function(args){
  19043. if (!args) {
  19044. return;
  19045. }
  19046. if (!args.requestVerb || !args.url || !args.handleAs){ return;}
  19047. var requestVerb = args.requestVerb;
  19048. if (requestVerb && !this.requestVerbs[requestVerb]){
  19049. requestVerb = this.requestVerbs.get;
  19050. }
  19051. if (requestVerb && requestVerb == this.requestVerbs.get){
  19052. var obj = args;
  19053. delete obj.requestVerb;
  19054. dojo.xhrGet(obj);
  19055. return;
  19056. }
  19057. if (requestVerb && requestVerb == this.requestVerbs.put){
  19058. var obj1 = args;
  19059. delete obj1.requestVerb;
  19060. if (obj1.msgData){
  19061. obj1.putData = obj1.msgData;
  19062. delete obj1.msgData;
  19063. }
  19064. dojo.xhrPut(obj1);
  19065. return;
  19066. }
  19067. if (requestVerb && requestVerb == this.requestVerbs["delete"]){
  19068. var obj2 = args;
  19069. delete obj2.requestVerb;
  19070. dojo.xhrDelete(obj2);
  19071. return;
  19072. }
  19073. if (requestVerb && requestVerb == this.requestVerbs.post){
  19074. var obj3 = args;
  19075. delete obj3.requestVerb;
  19076. if (obj3.msgData){
  19077. obj3.postData = obj3.msgData;
  19078. delete obj3.msgData;
  19079. }
  19080. dojo.xhrPost(obj3);
  19081. return;
  19082. }
  19083. },
  19084. httpmethods: {
  19085. GET: "GET",
  19086. PUT: "PUT",
  19087. POST: "POST",
  19088. DELETE: "DELETE"
  19089. },
  19090. requestVerbs:{
  19091. get: "get",
  19092. put: "put",
  19093. post: "post",
  19094. "delete": "delete"
  19095. }
  19096. });
  19097. }
  19098. if(!dojo._hasResource["com.ibm.mashups.iwidget.io"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  19099. dojo._hasResource["com.ibm.mashups.iwidget.io"] = true;
  19100. dojo.provide("com.ibm.mashups.iwidget.io");
  19101. }
  19102. if(!dojo._hasResource["com.ibm.mashups.iwidget.iContext_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  19103. dojo._hasResource["com.ibm.mashups.iwidget.iContext_API"] = true;
  19104. dojo.provide("com.ibm.mashups.iwidget.iContext_API");
  19105. dojo.provide("com.ibm.mashups.iwidget.iContext");
  19106. /**
  19107. * This interface defines methods that the iWidget can use to interact with the iContext.
  19108. * An iContext instance is created specifically for each iWidget instance and a reference will be set in iWidget encapsulation object.
  19109. * Thus within iWidget encapsulation class, iContext should be referred to by using <b>"this.iContext"</b><p/>
  19110. * &nbsp;&nbsp;&nbsp; <code>var root = this.iContext.getRootElement();</code><p/>
  19111. *
  19112. * @ibm-api
  19113. */
  19114. dojo.declare("com.ibm.mashups.iwidget.iContext", null, {
  19115. /**
  19116. * @private
  19117. */
  19118. constructor: function() {
  19119. },
  19120. /**
  19121. * Defines constants available in iContext.<br/>
  19122. * Constants defined within iContext can be referred as follows:</p>
  19123. *
  19124. * &nbsp;&nbsp;&nbsp; <code>this.iContext.constants.mode.VIEW</code><br/>
  19125. * &nbsp;&nbsp;&nbsp; <code>this.iContext.constants.mode.EDIT</code><br/>
  19126. * &nbsp;&nbsp;&nbsp; <code>this.iContext.constants.mode.PERSONALIZE</code><br/>
  19127. * &nbsp;&nbsp;&nbsp;<code>this.iContext.constants.mode.HELP</code><br/>
  19128. * &nbsp;&nbsp;&nbsp;<code>this.iContext.constants.ATTRIBUTES</code><br/>
  19129. * &nbsp;&nbsp;&nbsp;<code>this.iContext.constants.IDESCRIPTOR</code><br/>
  19130. * &nbsp;&nbsp;&nbsp;<code>this.iContext.constants.USERPROFILE</code><br/>
  19131. * </code>
  19132. * @type Object
  19133. * @ibm-module iWidget2
  19134. */
  19135. constants: {
  19136. /*@type object*/
  19137. mode: {
  19138. /*@type String*/
  19139. VIEW:/*String*/ "view",//The generated markup fragment(s) should reflect normal interaction with the iWidget
  19140. /*@type String*/
  19141. EDIT:/*String*/ "edit",//The generated markup fragment(s) should reflect iWidget interactions for editing iWidget attributes scoped to this instance of iwidget, but applicable to all users
  19142. /*@type String*/
  19143. PERSONALIZE:/*String*/ "personalize",//The generated markup fragment(s) should reflect iWidget interactions for personalizing iwidget attributes scoped to this instance on the iWidget for this user
  19144. /*@type String*/
  19145. CONFIG:/*String*/ "config",//The generated markup fragment(s) should reflect iWidget interactions for editing iwidget attributes scoped to all instances of the iWidget for all users
  19146. /*@type String*/
  19147. HELP:/*String*/ "help"//The iWidget should generate markup fragment(s) to assist the user with interacting with the iWidget
  19148. },
  19149. event: {
  19150. /*@type String*/
  19151. TITLE:/*String*/ "title",//Name for the Attribute holding event title
  19152. /*@type String*/
  19153. DESCRIPTION:/*String*/ "description"//Name for the Attribute holding event description
  19154. },
  19155. /*@type String*/
  19156. ATTRIBUTES:/*String*/ "attributes", //Name for the ManagedItemSet holding the customization attributes.
  19157. /*@type String*/
  19158. IDESCRIPTOR:/*String*/ "idescriptor", //Name for the ManagedItemSet holding the items describing the iWidget
  19159. /*@type String*/
  19160. USERPROFILE:/*String*/ "userprofile", //Name for the ManagedItemSet holding data about the user
  19161. /*@type Object*/
  19162. keys: {
  19163. /*@type int*/
  19164. SHIFT:/*int*/ 1,
  19165. /*@type int*/
  19166. ALT:/*int*/ 2,
  19167. /*@type int*/
  19168. CTRL:/*int*/ 4,
  19169. /*@type int*/
  19170. META:/*int*/ 8,
  19171. /*@type int*/
  19172. CAPSLOCK:/*int*/ 16
  19173. },
  19174. windowstate: {
  19175. /*@type String*/
  19176. NORMAL:/*String*/ "normal",
  19177. /*@type String*/
  19178. MINIMIZE:/*String*/ "minimize",
  19179. /*@type String*/
  19180. MAXIMIZE:/*String*/ "maximize"
  19181. },
  19182. status: {
  19183. /*@type int*/
  19184. SUCCESS:/*int*/ 200,
  19185. /*@type int*/
  19186. TIMEOUT:/*int*/ 408,
  19187. /*@type int*/
  19188. NOTFOUND:/*int*/ 404,
  19189. /*@type int*/
  19190. INTERROR:/*int*/ 500,
  19191. /*@type int*/
  19192. OTHER:/*int*/ 303
  19193. },
  19194. changeType: {
  19195. /*@type String*/
  19196. CHANGEDVALUE:/*String*/ "changedValue",
  19197. /*@type String*/
  19198. NEWITEM:/*String*/ "newItem",
  19199. /*@type String*/
  19200. REMOVEDITEM:/*String*/ "removedItem"
  19201. }
  19202. },
  19203. /**
  19204. * This method returns the unique identifier for this instance of the iWidget in the current evironment (usually a web page).
  19205. * @type String
  19206. * @return{String} widgetId unique identifier of the iWidget. return <code>null</code> if element is not available.
  19207. * @ibm-module iWidget2
  19208. */
  19209. getWidgetId: function() {
  19210. return null;
  19211. },
  19212. /**
  19213. * Returns the iContext supplied element containing the content for the current mode of the iwidget such that the iWidget can easily do things such as search its own markup.
  19214. * @type DOMElement
  19215. * @return{DOMElement} rootElement of the iWidget. return <code>null</code> if element is not available.
  19216. * @ibm-module iWidget2
  19217. */
  19218. getRootElement: function() {
  19219. return null;
  19220. },
  19221. /**
  19222. * This method provides the same semantics as the DOM method with the same name, but restricts the search to the iWidget's markup rather than the entire page
  19223. * @param{String} id element id. Must not be <code>null</code>.
  19224. * @param{DOMElement} root optional DOMElement to define a search scope, it will search in the scope of current active mode if root is not provided.
  19225. * @type DOMElement
  19226. * @return{DOMElement} return the element, or <code>null</code> if element is not found.
  19227. * @ibm-module iWidget2
  19228. */
  19229. getElementById: function(/*String*/id,/*DOMNode*/ root) {
  19230. return null;
  19231. },
  19232. /**
  19233. * This method returns the ManagedItemSet that provides access to the iWidget's customization attributes.
  19234. * If there is no ManagedItemSet related to the iWidget's customization attributes, this method MUST create an empty set and return it.
  19235. * @type com.ibm.mashups.iwidget.itemset.ManagedItemSet
  19236. * @return{com.ibm.mashups.iwidget.itemset.ManagedItemSet } return the ManagedItemSet or empty ManagedItemSet if no customization attributes is found.
  19237. * @ibm-module iWidget2
  19238. */
  19239. getiWidgetAttributes: function() {
  19240. return {};
  19241. },
  19242. /**
  19243. * This method returns an ItemSet corresponding to the requested name. If it does not already exist, an ItemSet will be created and associated with the supplied name.
  19244. * @param{String}name name of ItemSet. Must not be <code>null</code>.
  19245. * @param{Boolean}isPrivate deprecated,please use getShareableItemSet()if it's a ShareableItemSet.
  19246. * @type com.ibm.mashups.iwidget.itemset.ItemSet
  19247. * @return{com.ibm.mashups.iwidget.itemset.ItemSet} return the requested ItemSet or <code> null</code> if access is denied.
  19248. * @ibm-module iWidget2
  19249. */
  19250. getItemSet: function(/*String*/name,/*Boolean*/ isPrivate) {
  19251. return null;
  19252. },
  19253. /**
  19254. * This method returns an ShareableItemSet corresponding to the requested name. If it does not already exist, an ItemSet will be created and associated with the supplied name.
  19255. * @param{String}name name of ItemSet. Must not be <code>null</code>.
  19256. * @type com.ibm.mashups.iwidget.itemset.ItemSet
  19257. * @return{com.ibm.mashups.iwidget.itemset.ShareableItemSet} return the requested ItemSet or <code> null</code> if access is denied.
  19258. * @ibm-module iWidget2
  19259. */
  19260. getShareableItemSet: function(/*String*/name) {
  19261. return null;
  19262. },
  19263. /**
  19264. * Provides means for iWidget to declare dependency on set of shared resource support dynamic loads in asynchronous manner. JS and CSS resources are supported.
  19265. * @param{String} globalid globalid of the Item that needs to be loaded. Must not be <code>null</code>.
  19266. * @param{String}version optional
  19267. * @param{String}uri uri of the resource. Must not be <code>null</code>.
  19268. * @param{Object}cb optional
  19269. * @param{String}mimeType optional
  19270. * @type void
  19271. * @ibm-module iWidget2
  19272. */
  19273. requires: function(/*String*/globalid,/*String*/ version,/*String*/ uri,/*function*/ cb,/*String*/ mimeType) {
  19274. },
  19275. /**
  19276. * This method returns an instance of type Object which was initialized prior to the loading of the iWidget (either as a generic Object or an instance of the encapsulation Object ) . Its purpose is to support proper
  19277. * encapsulation of the iWidget's assets (variables and methods) such that multiple instances of the iWidget can be loaded into a
  19278. * single page's DOM without stepping on each other.
  19279. * So iWidget resources can refer to any functions that's defined within iWidget encapsulation object by using iContext.iScope().fn();
  19280. * @type Object
  19281. * @return{Object} return an instance of the encapsulation class or return a generic object
  19282. * @ibm-module iWidget2
  19283. */
  19284. iScope: function() {
  19285. return null;
  19286. },
  19287. /**
  19288. * This method requests the iContext to process the markup such that it can be inserted into the iWidget's markup and properly interact with the page.
  19289. * (i.e. all the iContext reference in the markup needs to be properly namespaced). Where, when and how the markup is inserted into the page
  19290. * is the responsibility of the iWidget.
  19291. * @param{String}markup markupString that needs to be processed. Must not be <code>null</code>.
  19292. * @type String
  19293. * @return On success this method MUST return the processed markup while on failure it MUST return null
  19294. * @ibm-module iWidget2
  19295. */
  19296. processMarkup: function(/*String*/markup) {
  19297. return null;
  19298. },
  19299. /**
  19300. * This method requests the iContext to process the subtree under the supplied node for the purpose of resolving and instantiating any referenced iWidgets.
  19301. * @param{DOMNode}root root element of the subtree. Must not be <code>null</code>.
  19302. * @type void
  19303. * @ibm-module iWidget2
  19304. */
  19305. processiWidgets: function(/*DOMNode*/root) {
  19306. //summary: This method requests the iContext to process the subtree under the supplied node for the purpose of resolving and instantiating any referenced iWidgets.
  19307. //root: root element of the subtree
  19308. },
  19309. /**
  19310. * This method returns an array of Elements within the iWidget's markup which have the supplied value as one of those specified by the Element's "class" attribute.
  19311. * @param{String}classname name of class attribute. Must not be <code>null</code>.
  19312. * @param{DOMElement}root root element of the subtree. Must not be <code>null</code>
  19313. * @type DOMElement[]
  19314. * @return{DOMElement[]} return an array of elements
  19315. * @ibm-module iWidget2
  19316. */
  19317. getElementByClass: function(/*String*/classname,/*DOMElement*/ root) {
  19318. return null;
  19319. },
  19320. /**
  19321. * This method returns the ManagedItemSet that provides access to the user's profile data.
  19322. * @type com.ibm.mashups.iwidget.itemset.ManagedItemSet
  19323. * @return{com.ibm.mashups.iwidget.itemset.ManagedItemSet } if there is no ManagedItemSet related to the user's profile, this method creates an empty set and returns it. If access to the user's profile is denied, this method returns null.
  19324. * @ibm-module iWidget
  19325. */
  19326. getUserProfile: function() {
  19327. return null;
  19328. },
  19329. /**
  19330. * This method returns the ManagedItemSet that provides access to iWidget's descriptive items.
  19331. * @type com.ibm.mashups.iwidget.itemset.ManagedItemSet
  19332. * @return {com.ibm.mashups.iwidget.itemset.ManagedItemSet } If there is no ManagedItemSet related to the iWidget's descriptive items this method creates an empty set and returns it..
  19333. * @ibm-module iWidget2
  19334. ja */
  19335. getiDescriptor: function() {
  19336. return null;
  19337. },
  19338. /**
  19339. * This object provides access to io service. io service is accessible by using "this.iContext.io".<p/>
  19340. * @type com.ibm.mashups.iwidget.io
  19341. * @ibm-module iWidget2
  19342. */
  19343. io: {},
  19344. /**
  19345. * This object provides access to events service. event service is accessible by using "this.iContext.iEvents".<p/>
  19346. * @type com.ibm.mashups.iwidget.iEvents
  19347. * @ibm-module iWidget
  19348. */
  19349. iEvents: {}
  19350. });
  19351. }
  19352. if(!dojo._hasResource["com.ibm.mm.iwidget.icontext.IContextDefaultImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  19353. dojo._hasResource["com.ibm.mm.iwidget.icontext.IContextDefaultImpl"] = true;
  19354. dojo.provide("com.ibm.mm.iwidget.icontext.IContextDefaultImpl");
  19355. dojo.declare("com.ibm.mm.iwidget.icontext.IContextDefaultImpl", com.ibm.mashups.iwidget.iContext, {
  19356. constructor: function(wrapper){
  19357. //information accessible from iwidget
  19358. this.widgetwrapper = wrapper;
  19359. this.widgetId = wrapper.id;
  19360. this.scope = {};
  19361. //todo: root is associated with mode
  19362. //this.rootElement = wrapper.rootElement;
  19363. //keep this.rootElement and this.ns since this will break some widget code
  19364. this.rootElement = dojo.byId(this.widgetId);
  19365. this.ns = this.rootElement.className.substr(0, 3);
  19366. this._initEvents();
  19367. this._initIO();
  19368. this._initMMExtension();
  19369. },
  19370. _destroy: function(){
  19371. // # 17713, leak for one iw-iWidget DIV
  19372. if (this.rootElement) {
  19373. this.rootElement = null;
  19374. }
  19375. },
  19376. getWidgetId: function(){
  19377. if (this.widgetId) {
  19378. return this.widgetId;
  19379. }
  19380. return null;
  19381. },
  19382. _initEvents: function(){
  19383. this.iEvents = null;
  19384. },
  19385. _initMMExtension: function(){
  19386. this._mm = null;
  19387. },
  19388. getRootElement: function(){
  19389. //summary: returns the root element of the iWidget such that iWidget can easily do things such as
  19390. // searching its own markup. RootElement can also be a convenient place to place items which iWidget wishes
  19391. // to access later.
  19392. //we generate it dynamically so it can work for sandboxed iwidget
  19393. return dojo.byId(this.widgetId);
  19394. },
  19395. getElementById: function(/*String*/id, root){
  19396. //summary: this method provides the same semantics as the DOM method by the same name with the distinction that
  19397. // this method will restrict the search to the iWidget's markup rather than entire page
  19398. if (!root) {
  19399. root = this._getContentRoot();
  19400. }
  19401. //following dojo.query will query by id however it doesn't work, so use our legacy stuff instead
  19402. /*
  19403. var nodeList = dojo.query("#"+id,root);
  19404. if (nodeList.length >= 1){
  19405. return nodeList[0];
  19406. }
  19407. return null;
  19408. */
  19409. var element = [];
  19410. var rc = com.ibm.mm.iwidget.Utils.findElementByAttribute("id", id, root, element, false);
  19411. if (rc) {
  19412. return element[0];
  19413. }
  19414. else {
  19415. return null;
  19416. }
  19417. },
  19418. getiWidgetAttributes: function(){
  19419. //Summary: returns an ManagedItemSet which provides access to the iWidget's customization attributes.
  19420. // The returned ManagedItemSet will be the same as getItemSet(iContext.constants.itemset.ATTRIBUTES).
  19421. // returns empty set if there's no ItemSet.
  19422. var attrs = this.widgetwrapper.getAttributes();
  19423. return attrs;
  19424. },
  19425. getItemSet: function(/*String*/name,/*boolean*/ isPrivate){
  19426. if (typeof name == "undefined" || name === null) {
  19427. return null;
  19428. }
  19429. if (name == iwConstants.ATTRIBUTES) {
  19430. return this.getiWidgetAttributes();
  19431. }
  19432. if (name == iwConstants.USERPROFILE) {
  19433. return this.getUserProfile();
  19434. }
  19435. if (name == iwConstants.IDESCRIPTOR) {
  19436. return this.getiDescriptor();
  19437. }
  19438. var itemSet = this.widgetwrapper.getWidgetItemSet(name);
  19439. return itemSet;
  19440. },
  19441. iScope: function(){
  19442. return this.scope;
  19443. },
  19444. processMarkup: function(/*string*/markup){
  19445. //return null upon failure
  19446. var oldMarkup = markup.replace(/_IWID_/g, "_" + this.widgetId + "_");
  19447. var finalMarkup = oldMarkup.replace(/iContext(?=\.|\s|\(|\))/g, "_" + this.widgetId + "_iContext");
  19448. return finalMarkup;
  19449. },
  19450. getElementByClass: function(classname, root){
  19451. if (!root) {
  19452. root = this._getContentRoot();
  19453. }
  19454. //todo: use dojo.query
  19455. var nodeList = dojo.query("." + classname, root);
  19456. if (typeof nodeList != "undefined" && nodeList !== null) {
  19457. if (nodeList.length === 0) {
  19458. return null;
  19459. }
  19460. else {
  19461. var elements = [];
  19462. for (var i = 0; i < nodeList.length; i++) {
  19463. elements.push(nodeList[i]);
  19464. }
  19465. return elements;
  19466. }
  19467. }
  19468. return null;
  19469. },
  19470. getWidgetXMLPath: function(){
  19471. var url = this.widgetwrapper.getIWidgetInstance().widgetXMLUrl;
  19472. var queryStart = url.indexOf("?");
  19473. if (0 < queryStart) {
  19474. url = url.substring(0, queryStart);
  19475. }
  19476. var url2 = com.ibm.mm.enabler.EndpointUtils.checkForEndpoints(url);
  19477. if (url2) {
  19478. url = url2;
  19479. }
  19480. return url;
  19481. },
  19482. _getWidgetBaseUri: function(){
  19483. var widgetBaseUri = this.widgetwrapper.getIWidgetInstance().widgetXMLUrl;
  19484. var queryStart = widgetBaseUri.indexOf("?");
  19485. if (0 < queryStart) {
  19486. widgetBaseUri = widgetBaseUri.substring(0, queryStart);
  19487. }
  19488. return widgetBaseUri.substring(0, widgetBaseUri.lastIndexOf("/") + 1);
  19489. },
  19490. _getContentRoot: function(){
  19491. var contentRoot = this.getRootElement();
  19492. var currentMode = this.widgetwrapper.currentMode;
  19493. if (!currentMode) {
  19494. currentMode = "view";
  19495. }
  19496. var currentWindow = this.widgetwrapper.windowManager[currentMode];
  19497. if (currentWindow) {
  19498. var temp = currentWindow.root;
  19499. if (temp) {
  19500. contentRoot = temp;
  19501. }
  19502. }
  19503. return contentRoot;
  19504. },
  19505. getiDescriptor: function(){
  19506. var iDescriptor = this.widgetwrapper.getIDescriptorItems();
  19507. return iDescriptor;
  19508. },
  19509. // simply stubbed out for minimal
  19510. _initIO: function(){
  19511. this.io = new com.ibm.mm.iwidget.icontext.IContextIOImpl(this.widgetwrapper);
  19512. },
  19513. getUserProfile: function(){
  19514. //todo: warning
  19515. return null;
  19516. },
  19517. requires: function(/*String*/requiredItem,/*String*/ version,/*String*/ uri,/*function*/ cb, mimeType){
  19518. //todo: warning
  19519. return;
  19520. },
  19521. processiWidgets: function(/*domnode*/root){
  19522. //todo: warning
  19523. return;
  19524. }
  19525. });
  19526. com.ibm.mm.iwidget.icontext.IContextImpl = com.ibm.mm.iwidget.icontext.IContextDefaultImpl;
  19527. // IMPORTANT
  19528. // ibmConfig.enablerLayerModules is a comma separated string of all supported modules at runtime
  19529. // This section dynamically loads the Extended representation when the variable enablerLayerModules contains the given module
  19530. if ((ibmConfig.enablerLayerModules) && (dojo.indexOf(ibmConfig.enablerLayerModules, "iWidget") >= 0)) {
  19531. dojo["require"]("com.ibm.mm.iwidget.icontext.IContextExtendedImpl"); // JSLINT-IGNORE: This needs to be done to allow modularization and to support the minimal layer
  19532. }
  19533. }
  19534. if(!dojo._hasResource["com.ibm.mashups.iwidget.iContext"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  19535. dojo._hasResource["com.ibm.mashups.iwidget.iContext"] = true;
  19536. dojo.provide("com.ibm.mashups.iwidget.iContext");
  19537. }
  19538. if(!dojo._hasResource["com.ibm.mashups.iwidget.itemset.ManagedItemSetCallbackModel"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  19539. dojo._hasResource["com.ibm.mashups.iwidget.itemset.ManagedItemSetCallbackModel"] = true;
  19540. dojo.provide("com.ibm.mashups.iwidget.itemset.ManagedItemSetCallbackModel");
  19541. /**
  19542. * This API defines the callback functions for ManagedItemSet.
  19543. * @ibm-api
  19544. * @ibm-module iWidget2
  19545. */
  19546. dojo.declare("com.ibm.mashups.iwidget.itemset.ManagedItemSetCallbackModel", null, {
  19547. /**
  19548. @private
  19549. */
  19550. constructor: function() {
  19551. },
  19552. /**
  19553. This method defines the callback function after save operation. IWidget may provide this function when invoke <code> managedItemSet.save(callbackfn)</code>.
  19554. The iContext will invoke callbackfn upon save completion.
  19555. @param{String}managedItemSetName name of ManagedItemSet: attributes,idescriptor,userprofile. Must never be <code>null</code>.
  19556. @param{Boolean}success boolean indicates if save operation is successful or not.
  19557. @type void
  19558. */
  19559. postSaveCallbackFn: function(/*String*/managedItemSetName,/*Boolean*/ success) {
  19560. }
  19561. });
  19562. }
  19563. if(!dojo._hasResource["com.ibm.mashups.iwidget.itemset.ManagedItemSet_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  19564. dojo._hasResource["com.ibm.mashups.iwidget.itemset.ManagedItemSet_API"] = true;
  19565. dojo.provide("com.ibm.mashups.iwidget.itemset.ManagedItemSet_API");
  19566. dojo.provide("com.ibm.mashups.iwidget.itemset.ManagedItemSet");
  19567. /**
  19568. Interface to a simple abstraction of a datamodel. This provides a base from which more sofisticated datamodel can be built.
  19569. There're 3 default ManagedItemSet provided in Lotus Mashups. They are attributes, userprofile and idescriptor.<p/>
  19570. @ibm-api
  19571. @ibm-module iWidget2
  19572. */
  19573. dojo.declare("com.ibm.mashups.iwidget.itemset.ManagedItemSet",null, {
  19574. /**
  19575. @private
  19576. */
  19577. constructor: function() {
  19578. },
  19579. /**
  19580. This method requests the iContext save the current state of the ManagedItemSet.
  19581. The iContext MAY also choose to save the ManagedItemSet at times other than when iWidgets request a save.
  19582. This method MAY operate asynchronously. The iContext MUST invoke any supplied callbackFn upon completion of the save attempt.
  19583. It need to be implemented by each subclass...signiture of callback function is as follows</br>
  19584. &nbsp;&nbsp;&nbsp;<code>function(in String managedItemSetName, in Boolean success);</code>
  19585. @param{com.ibm.mashups.iwidget.itemset.ManagedItemSetCallbackModel.postSaveCallbackFn}callbackfn optional callback function
  19586. @type void
  19587. @deprecated use commit(callbackfn) instead
  19588. */
  19589. save: function(callbackfn) {
  19590. },
  19591. /**
  19592. This method requests the queued change be processed. This includes simultaneous changes to multiple items and any persistence or other propagation of the values.
  19593. This method MAY operate asynchronously. The iContext MUST invoke any supplied callbackFn upon completion of the commit attempt.
  19594. It need to be implemented by each subclass...signiture of callback function is as follows</br>
  19595. &nbsp;&nbsp;&nbsp;<code>function(in String managedItemSetName, in Boolean success);</code>
  19596. @param{com.ibm.mashups.iwidget.itemset.ManagedItemSetCallbackModel.postSaveCallbackFn}callbackfn optional callback function
  19597. @type void
  19598. */
  19599. commit: function(callbackfn) {
  19600. },
  19601. /**
  19602. This method sets an item within the ItemSet, creates or replaces an existing entry as needed.
  19603. To append a value to any existing item, suggest to get the current value of this item and append
  19604. the new value to the list and supply the result to this method.
  19605. Marking an item as ReadOnly indicates to the iContext that while this item maybe shared with other components
  19606. on the page, the access of those components should not include changing or removing item.
  19607. @param{String}itemName name of the item. Must never be <code>null</code>.
  19608. @param{String}value value of the item. Must never be <code>null</code>.
  19609. @param{Boolean}readOnly optional Boolean attribute to indicate this item is readOnly or not.Default value is false if this parameter is not provided.
  19610. @return{ItemSet} return an handle of ItemSet upon successful, <code>null</code> upon failure.
  19611. @deprecated use setItemValue(itemName,value) instead
  19612. */
  19613. setItemValue: function( /*String*/itemName, /*Object*/ value,/*boolean*/ readOnly) {
  19614. return this;
  19615. },
  19616. /**
  19617. This method sets an item within the ItemSet, creates or replaces an existing entry as needed.
  19618. With the actual setting/processing of the change happening when commit() is invoked.As ManagedItemSet are controlled by
  19619. the iContext, some items may be read only to the iwidget.
  19620. @param{String}itemName name of the item. Must never be <code>null</code>.
  19621. @param{String}value value of the item. Must never be <code>null</code>.
  19622. @return{ItemSet} return an handle of ItemSet upon successful, <code>null</code> upon failure.
  19623. */
  19624. setItemValue: function( /*String*/itemName, /*Object*/ value) { // JSLINT-IGNORE: in Java functions with the same name but different signatures are allowed - this is only used for generating JavaDoc
  19625. return this;
  19626. },
  19627. /**
  19628. This method returns the value for the named item from the set.
  19629. @param{String}itemName name of the item. Must never be <code>null</code>.
  19630. @return{String} return value of the named item for the set, <code>null</code> upon failure.
  19631. */
  19632. getItemValue: function( /*String*/itemName) {
  19633. return null;
  19634. },
  19635. /**
  19636. This method returns an array of Strings, providing the name of each item.
  19637. @return{String[]} return an array of items names and return <code>null</code> if the set contains no item
  19638. */
  19639. getAllNames: function() {
  19640. return null;
  19641. },
  19642. /**
  19643. Removes the named item from the set.
  19644. @param{String}itemName name of the item that needs to be removed. Must never be <code>null</code>.
  19645. @return{ItemSet} return the handle to the ManagedItemSet upon successful, <code>null</code> upon failure.
  19646. */
  19647. removeItem: function(/*String*/itemName) {
  19648. return null;
  19649. },
  19650. /**
  19651. This method returns a new ItemSet which is a duplicate of the current ItemSet.
  19652. @return{ItemSet} return a new ItemSet which contains all the data item in the current ItemSet
  19653. @deprecated not used
  19654. */
  19655. clone: function() {
  19656. return null;
  19657. },
  19658. /**
  19659. This method returns a Boolean indicating whether or not the item specified by the supplied name can be modified by the user.
  19660. @param{String}itemName name of the required Item. Must never be <code>null</code>.
  19661. @return{Boolean} return a Boolean indicating whether or not the item specified by the supplied name can be modified by the user. Never <code>null</code>.
  19662. */
  19663. isReadOnly: function(/*String*/itemName) {
  19664. return null;
  19665. },
  19666. /**
  19667. As a limitation in Lotus Mashups, this method returns <code>null</code>.
  19668. @return{Object} return As a limitation in Lotus Mashups, this method returns <code>null</code>.
  19669. @deprecated not used
  19670. */
  19671. getItemSetDescription: function() {
  19672. return null;
  19673. },
  19674. /**
  19675. This function adds listener to this ShareableItemSet. So it will gets notified when this ShareableItemSet is updated.
  19676. @param{Function}listener js function that should already be properly scoped. Must never be <code>null</code>.
  19677. @return{String} return listener id if listener is registered successfully, return null if it's not.
  19678. */
  19679. addListener: function(/*Function*/listener) {
  19680. return null;
  19681. },
  19682. /**
  19683. This function removes the listener from this ShareableItemSet.
  19684. @param{String}listenerId listener id that's returned by the system when listener is added. Must never be <code>null</code>.
  19685. @return{Boolean} return true if listener is removed successfully.
  19686. */
  19687. removeListener: function(/*String*/listenerId) {
  19688. return true;
  19689. } //return true if listener is removed successfully
  19690. });
  19691. }
  19692. if(!dojo._hasResource["com.ibm.mashups.iwidget.services.EventService"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  19693. dojo._hasResource["com.ibm.mashups.iwidget.services.EventService"] = true;
  19694. dojo.provide("com.ibm.mashups.iwidget.services.EventService");
  19695. /**
  19696. * This interface defines iWidget EventService which provides a topic driven subscribe/publish mechanism.
  19697. * "fireEvent" and "broadcastEvent" are provided as convenience functions on top of this basic model.
  19698. * The service can be retrieved using the following code: <br>
  19699. * <code>var eventService = com.ibm.mashups.services.ServiceManager.getService(<br/>
  19700. * &nbsp;&nbsp;&nbsp;&nbsp;com.ibm.mashups.iwidget.services.EventService.SERVICE_NAME);</code><br/>
  19701. * @ibm-spi
  19702. * @ibm-module iWidget2
  19703. */
  19704. dojo.declare("com.ibm.mashups.iwidget.services.EventService",null, {
  19705. /**
  19706. * The service name to be used to fetch the service from the ServiceManager
  19707. * @type String
  19708. */
  19709. SERVICE_NAME: "eventService",
  19710. /**
  19711. * @private
  19712. */
  19713. constructor:function(){
  19714. },
  19715. /**
  19716. Allows page component to invoke a handled event that's defined in an iWidget.<br/>
  19717. For example, in Lotus Mashups, user can click "save" to save the attributes when user finished editing a widget .<br/>
  19718. Then the component that renders the "save" button could use this api to distribute an onModeChanged event to the widget.<br/>
  19719. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code>com.ibm.mashups.services.ServiceManager.getService("eventService").fireEvent(this.iwidgetId,"onModeChanged", {newMode:"view"}); </code><br/>
  19720. So the widget could get notified and go back to "view"mode.<br/>
  19721. Same function can also be achieved by using "publishEvent"<br/>
  19722. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code>com.ibm.mashups.services.ServiceManager.getService("eventService").publishEvent("widgetevents."+this.iwidgetId+"."+"onModeChanged", {newMode:"view"}); </code><br/>
  19723. @param{String } targetWidget id of target iWidget. Must never be NULL.
  19724. @param{String } targetEvent event name of target Event .Must never be NULL.
  19725. @param{Object } payload optional. data object that's distributed with an event. May be NULL.
  19726. @param{String } payloadType optional. type of the payload
  19727. @param{String } sourceid optional. id of source component that triggers this event
  19728. @type void
  19729. */
  19730. fireEvent: function(targetWidget,targetEvent,payload,payloadType,sourceid){
  19731. },
  19732. /**
  19733. Allows page components to broadcast an event to all the widgets/components on the page. There's no need for widgets to subscribe that topic first.<br/>
  19734. For example, mode selector iWidget may broadcast a "pageModeChanged" event when page mode is changed from view mode to edit mode.<br/>
  19735. Then all the widgets/components will get notified and all widgets/components that can handle "pageModeChanged" event will update accordingly.<br/>
  19736. A widget that can handle this event must have this event defined. <br/>
  19737. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code> &lt;iw:event id="pageModechanged" eventDescName="pageModeChanged_desc" handled="true" onEvent="handlePageModeChange" /&gt; </code><br/>
  19738. A component that can handle this event must subscribe this event by using:<br/>
  19739. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <code>serviceManager.getService("eventService").subscribeEvent ("pageModechanged",handlerFn,scope,sourceid)</code><br/>
  19740. Code example:<br/>
  19741. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code>com.ibm.mashups.services.ServiceManager.getService("eventService").broadcastEvent("pageModeChanged", payload,payloadtype,,sourceid); </code><br/>
  19742. Same function can also be achieved by using "publishEvent"<br/>
  19743. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code>com.ibm.mashups.services.ServiceManager.getService("eventService").publishEvent("*"+"."+"onModeChanged", {newMode:"view"}); </code><br/>
  19744. @param{String } targetEvent event name of target Event .Must never be NULL.
  19745. @param{Object } payload optional. data object that's distributed with an event. May be NULL.
  19746. @param{String } payloadType optional. type of the payload
  19747. @param{String } sourceid optional. id of client component that triggers this event.
  19748. @type void
  19749. */
  19750. broadcastEvent: function(targetEvent,payload,payloadType,sourceid){
  19751. },
  19752. /**
  19753. Allows page components to switch to a different page and broadcast an event to all the widgets/components on that page.<br/>
  19754. @param{String } targetEvent event name of target Event .Must never be NULL.
  19755. @param{Object } payload optional. data object that's distributed with an event. May be NULL.
  19756. @param{String } payloadType optional. type of the payload
  19757. @param{String } sourceid optional. id of client component that triggers this event.
  19758. @param{String } pageid optional. id of page to switch to and receive the event. If none is provided, no page switch will occur and event will broadcast to current page.
  19759. @type void
  19760. */
  19761. broadcastEvent: function(targetEvent,payload,payloadType,sourceid,pageid){ // JSLINT-IGNORE: cannot change public API
  19762. },
  19763. /**
  19764. Allows page components to switch to a different page and space and broadcast an event to all the widgets/components on that page.<br/>
  19765. @param{String } targetEvent event name of target Event .Must never be NULL.
  19766. @param{Object } payload optional. data object that's distributed with an event. May be NULL.
  19767. @param{String } payloadType optional. type of the payload
  19768. @param{String } sourceid optional. id of client component that triggers this event.
  19769. @param{String } pageid optional. id of page to switch to and receive the event. If none is provided, no page switch will occur and event will broadcast to current page.
  19770. @param{String } spaceid optional. id of space containing the page to switch to and receive the event. If none is provided, current space is assumed.
  19771. @type void
  19772. */
  19773. broadcastEvent: function(targetEvent,payload,payloadType,sourceid,pageid,spaceid){ // JSLINT-IGNORE: cannot change public API
  19774. },
  19775. /**
  19776. Allows page components to broadcast more than one event to all the widgets/components on the page.<br/>
  19777. @param{Array } eventsArray Array of objects each containing the following event information: &#123; "targetEvent": targetEvent, "payload": payload, "payloadType": payloadType &#125;. Must never be NULL.
  19778. @param{String } sourceid optional. id of client component that triggers this event.
  19779. @type void
  19780. */
  19781. broadcastEvents: function(eventsArray,sourceid){
  19782. },
  19783. /**
  19784. Allows page components to switch to a different page and broadcast more than one event to all the widgets/components on that page.<br/>
  19785. @param{Array } eventsArray Array of objects each containing the following event information: &#123; "targetEvent": targetEvent, "payload": payload, "payloadType": payloadType &#125;. Must never be NULL.
  19786. @param{String } sourceid optional. id of client component that triggers this event.
  19787. @param{String } pageid optional. id of page to switch to and receive the events. If none is provided, no page switch will occur and events will broadcast to current page.
  19788. @type void
  19789. */
  19790. broadcastEvents: function(eventsArray,sourceid,pageid){ // JSLINT-IGNORE: cannot change public API
  19791. },
  19792. /**
  19793. Allows page components to switch to a different page and space and broadcast more than one event to all the widgets/components on that page.<br/>
  19794. @param{Array } eventsArray Array of objects each containing the following event information: &#123; "targetEvent": targetEvent, "payload": payload, "payloadType": payloadType &#125;. Must never be NULL.
  19795. @param{String } sourceid optional. id of client component that triggers this event.
  19796. @param{String } pageid optional. id of page to switch to and receive the events. If none is provided, no page switch will occur and events will broadcast to current page.
  19797. @param{String } spaceid optional. id of space containing the page to switch to and receive the events. If none is provided, current space is assumed.
  19798. @type void
  19799. */
  19800. broadcastEvents: function(eventsArray,sourceid,pageid,spaceid){ // JSLINT-IGNORE: cannot change public API
  19801. },
  19802. /**
  19803. Allows page component to publish a global event that's available to all the other page components.<br/>
  19804. Event service supports global topics. For these topics all the page components could subscribe to it.<br/>
  19805. For example. when an iWidget is removed from page, a global event -"/enabler/unloadWidget" will be published by the skin component.<br/>
  19806. iWidget container is a subscriber of this topic, thus it can clean up the resource related to this iWidget accordingly.<br/>
  19807. @param{String } topic topic that's published.Must never be NULL.
  19808. @param{Object } payload optional. payload object.
  19809. @param{String } payloadType optional. type of the payload
  19810. @param{String } sourceid optional. id of client component that triggers this event.
  19811. @type void
  19812. */
  19813. publishEvent: function(topic,payload,payloadType,sourceid){
  19814. },
  19815. /**
  19816. Allows page component to subscribe a global event that's available to all the other page components.<br/>
  19817. Event service supports global topic. for these topics all the page listeners could subscribe to it.<br/>
  19818. For example. when an iWidget is removed from page, a global event -"/enabler/unloadWidget" will be published by the skin component.<br/>
  19819. iWidget container is a subscriber of this topic, thus it can clean up the resource related to this iWidget accordingly.
  19820. @param{String } event event name
  19821. @param{Object } object optional. scope object of the handlerFn. default scope is global scope.
  19822. @param{String} eventCallback optional. eventCallback that will be invoked when event is published
  19823. @param{String} subscribeCallback optional. callback to tell is subscription is good
  19824. @param{String } sourceid optional. id of client component that subscribes this event
  19825. @type void
  19826. */
  19827. subscribeEvent:function(event,object,eventCallback,subscribeCallback,sourceid){
  19828. },
  19829. /**
  19830. Allows page component to unsubscribe a global event that's available to all the other page components.<br/>
  19831. @param{Object } subscriptionHandler subscriptionHandler
  19832. @param{String } sourceid optional. id of client component that subscribes this event
  19833. @type void
  19834. */
  19835. unsubscribeEvent:function(subscriptionHandler,sourceid){
  19836. }
  19837. });
  19838. // make sure we can reference this globally
  19839. com.ibm.mashups.iwidget.services.EventService.SERVICE_NAME = "eventService";
  19840. }
  19841. if(!dojo._hasResource["com.ibm.mm.iwidget.manageditemset.IDescriptorDefaultImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  19842. dojo._hasResource["com.ibm.mm.iwidget.manageditemset.IDescriptorDefaultImpl"] = true;
  19843. dojo.provide("com.ibm.mm.iwidget.manageditemset.IDescriptorDefaultImpl");
  19844. dojo.declare("com.ibm.mm.iwidget.manageditemset.IDescriptorDefaultImpl", com.ibm.mashups.iwidget.itemset.ManagedItemSet, {
  19845. constructor: function(widget, defiDescriptor, instanceiDescriptor) {
  19846. this.widget = widget;
  19847. this.defiDescriptorItems = defiDescriptor; //associative array
  19848. this.instanceiDescriptorItems = instanceiDescriptor; //associative array
  19849. this.navStateModel = com.ibm.mashups.enabler.model.state.NavigationStateModelFactory.getNavigationStateModel();
  19850. this._updatedItems = {}; // only manages mode and windowstate here
  19851. },
  19852. readOnlyItems: {
  19853. defaultHeight: "defaultHeight",
  19854. defaultWidth: "defaultWidth",
  19855. displayLocale: "displayLocale",
  19856. messageLocale: "messageLocale",
  19857. author: "author",
  19858. email: "email",
  19859. website: "website",
  19860. version: "version",
  19861. icon: "icon"
  19862. },
  19863. writableItems: {
  19864. title: "title",
  19865. name: "name",
  19866. description: "description",
  19867. availableMessageLocales: "availableMessageLocales",
  19868. mode: "mode",
  19869. windowState: "windowState"
  19870. },
  19871. localizedItems: {
  19872. title: "title",
  19873. name: "name",
  19874. description: "description"
  19875. },
  19876. getItemValue: function(/*string*/name) {
  19877. if (typeof name == "undefined" || name === null) {
  19878. return null;
  19879. }
  19880. var value = null;
  19881. if (name == iwConstants.iDescriptorItems.mode) {
  19882. var widgetWrapper = this.widget;
  19883. if (widgetWrapper) {
  19884. value = widgetWrapper.currentMode;
  19885. }
  19886. }
  19887. else if (name == iwConstants.iDescriptorItems.displayLocale) {
  19888. var aLocale = ibmConfig.locale;
  19889. var configService = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);
  19890. var temp = configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.DISPLAY_LOCALE);
  19891. if (temp) {
  19892. aLocale = temp;
  19893. }
  19894. value = aLocale;
  19895. }
  19896. else if (name == iwConstants.iDescriptorItems.messageLocale) {
  19897. value = this._getMessageLocale();
  19898. }
  19899. else if (name == iwConstants.iDescriptorItems.windowState) {
  19900. value = this._getWindowState();
  19901. }
  19902. else {
  19903. value = this._getItemValue(/*String*/name);
  19904. }
  19905. return value;
  19906. },
  19907. _getWindowState: function() {
  19908. return "normal";
  19909. },
  19910. _getItemValue: function(/*String*/itemName) {
  19911. var defItem = null;
  19912. var instanceItem = null;
  19913. var locale = null;
  19914. if (this.localizedItems[itemName]) {
  19915. locale = this._getMessageLocale(); //replace with mesage locale
  19916. }
  19917. if (itemName == iwConstants.iDescriptorItems.title) {
  19918. // seems we have a title, so let's first try to get it from dyna content
  19919. instanceItem = this._getDynamicTitle();
  19920. }
  19921. if (instanceItem === null && this.instanceiDescriptorItems) {
  19922. instanceItem = this.instanceiDescriptorItems.getItemValue(itemName, locale);
  19923. }
  19924. if (instanceItem === null && this.defiDescriptorItems) {
  19925. defItem = this.defiDescriptorItems.getItemValue(itemName, locale);
  19926. if (typeof defItem == "undefined") {
  19927. defItem = null;
  19928. }
  19929. }
  19930. if (instanceItem !== null ) {
  19931. return instanceItem;
  19932. }
  19933. return defItem;
  19934. },
  19935. _getDynamicTitle: function() {
  19936. // noop in default
  19937. return null;
  19938. },
  19939. _setDynamicTitleOrIcon: function(name, value) {
  19940. // noop
  19941. },
  19942. setItemValue: function(name, value) {
  19943. if (typeof name == "undefined" || name === null) {
  19944. return null;
  19945. }
  19946. if (typeof value == "undefined" || value === null) {
  19947. return null;
  19948. }
  19949. if (this.readOnlyItems[name]) {
  19950. return null;
  19951. }
  19952. if (name == iwConstants.iDescriptorItems.mode) {
  19953. var supportedModes = this._getWidgetDef().getSupportedModes();
  19954. if (this._contains(supportedModes, value)) {
  19955. this._updatedItems[name] = value;
  19956. }
  19957. else {
  19958. return null;
  19959. }
  19960. }
  19961. if (name == iwConstants.iDescriptorItems.windowState) {
  19962. var supportedWindowStates = this._getWidgetDef().getSupportedWindowStates();
  19963. if (this._contains(supportedWindowStates, value)) {
  19964. this._updatedItems[name] = value;
  19965. }
  19966. else {
  19967. return null;
  19968. }
  19969. }
  19970. // dynamic title or icon
  19971. if (this.widget.id && ( name == iwConstants.iDescriptorItems.title || name == iwConstants.iDescriptorItems.icon)) {
  19972. this._setDynamicTitleOrIcon(name, value);
  19973. }
  19974. var locale = null;
  19975. if (this.localizedItems[name]) {
  19976. locale = this._getMessageLocale();
  19977. }
  19978. //save to instance level because this is the level next to view
  19979. //such as title/desription/icon, iContext always use the current locale
  19980. if (name == this.writableItems.title || name == this.writableItems.name || name == this.writableItems.description) {
  19981. this.instanceiDescriptorItems.setItemValue(name, value, false, locale);
  19982. }
  19983. if (name == iwConstants.iDescriptorItems.availableMessageLocales) {
  19984. this.instanceiDescriptorItems.setItemValue(name, value, false);
  19985. }
  19986. return this;
  19987. },
  19988. isReadOnly: function(name) {
  19989. if (typeof name == "undefined" || name === null) {
  19990. return false;
  19991. }
  19992. if (this.readOnlyItems[name]) {
  19993. return true;
  19994. }
  19995. else {
  19996. return false;
  19997. }
  19998. },
  19999. removeItem: function(name) {
  20000. //can't remove idescriptor items
  20001. return null;
  20002. },
  20003. getAllNames: function() {
  20004. var arr = {};
  20005. if (this.defiDescriptorItems) {
  20006. var defNames = this.defiDescriptorItems.getAllNames();
  20007. for (var i in defNames) {
  20008. if (Object.prototype.hasOwnProperty.call(defNames,i)) {
  20009. arr[defNames[i]] = true;
  20010. }
  20011. }
  20012. }
  20013. if (this.instanceiDescriptorItems) {
  20014. var instanceNames = this.instanceiDescriptorItems.getAllNames();
  20015. for (var j in instanceNames) {
  20016. if (Object.prototype.hasOwnProperty.call(instanceNames,j)) {
  20017. arr[instanceNames[j]] = true;
  20018. }
  20019. }
  20020. }
  20021. var nameArr = [];
  20022. for (var name in arr) {
  20023. if (Object.prototype.hasOwnProperty.call(arr,name)) {
  20024. nameArr.push(name);
  20025. }
  20026. }
  20027. return nameArr;
  20028. },
  20029. save: function(cb) {
  20030. return this.commit(cb);
  20031. },
  20032. commit: function(callbackfn) {
  20033. //todo, what if change mode,windowstate? each are different
  20034. if (this.serverless) {
  20035. this._saveMicroformat();
  20036. }
  20037. //need to process event one by one, mode first
  20038. if (this._updatedItems[iwConstants.iDescriptorItems.mode]) {
  20039. var newMode = this._updatedItems[iwConstants.iDescriptorItems.mode];
  20040. this.widget._handleOnModeChange(newMode);
  20041. }
  20042. if (this._updatedItems[iwConstants.iDescriptorItems.windowState]) {
  20043. var newWindowState = this._updatedItems[iwConstants.iDescriptorItems.windowState];
  20044. var oldWindowState = this._getWindowState();
  20045. var eventService = com.ibm.mashups.services.ServiceManager.getService("eventService");
  20046. eventService.publishEvent(com.ibm.mashups.iwidget.Constants.CHANGE_WIDGETWINDOWSTATE, {
  20047. id: this.widget.id,
  20048. newWindowState: newWindowState,
  20049. oldWindowState: oldWindowState
  20050. });
  20051. }
  20052. if (callbackfn) {
  20053. callbackfn(iwConstants.IDESCRIPTOR, true);
  20054. }
  20055. },
  20056. _saveMicroformat: function() { //for title/description/icon
  20057. this.widget.commit();
  20058. var payloadObj = {};
  20059. payloadObj.wid = this.widget.id;
  20060. this.widget.eventSvr._publishEvent(iwConstants.EVENTS.onAttributeSaved, payloadObj, this.widget.hubId);
  20061. },
  20062. addListener: function(/*obj*/fn) {
  20063. var widgetWrapper = this.widget;
  20064. var listenerId = widgetWrapper._registerListener(iwConstants.IDESCRIPTOR, fn);
  20065. return listenerId;
  20066. },
  20067. removeListener: function(/*String*/listenerId) {
  20068. var widgetWrapper = this.widget;
  20069. return widgetWrapper._removeListener(iwConstants.IDESCRIPTOR, listenerId);
  20070. },
  20071. _getWidgetDef: function() {
  20072. return this.widget.widgetDef;
  20073. },
  20074. _contains: function(arr, attribute) {
  20075. var rc = false;
  20076. for (var i = 0; i < arr.length; i++) {
  20077. if (attribute == arr[i]) {
  20078. rc = true;
  20079. break;
  20080. }
  20081. }
  20082. return rc;
  20083. },
  20084. _getMessageLocale: function() {
  20085. if (this.messageLocale) {
  20086. return this.messageLocale;
  20087. }
  20088. var aLocale = null;
  20089. var availableMessageLocales = this._getItemValue(iwConstants.iDescriptorItems.messageLocale);
  20090. if (availableMessageLocales) {
  20091. var locales = availableMessageLocales.split(" ");
  20092. var configService = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);
  20093. var temp = configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.DISPLAY_LOCALE);
  20094. if (temp) {
  20095. aLocale = this._getLocale(locales, temp, ibmConfig.locale);
  20096. }
  20097. }
  20098. if (!aLocale) {
  20099. aLocale = ibmConfig.locale;//most of our widgets use this today
  20100. }
  20101. this.messageLocale = aLocale;
  20102. return this.messageLocale;
  20103. },
  20104. _getLocale: function(localesArray, preferredLocale, defaultLocale) {
  20105. switch (localesArray.length) {
  20106. case 0:
  20107. // there is no localization
  20108. return null;
  20109. //break; // not necessary after return
  20110. case 1:
  20111. // there is only one localization, so use that
  20112. return com.ibm.mm.enabler.utils.LocaleHelper.normalizeLocale(localesArray[0]);
  20113. //break; // not necessary after return
  20114. default:
  20115. var preferredMatch = com.ibm.mm.enabler.utils.LocaleHelper.matchLocale(preferredLocale, localesArray);
  20116. if (preferredMatch) {
  20117. // yep, preferred was matched
  20118. return preferredMatch;
  20119. }
  20120. var defaultMatch = com.ibm.mm.enabler.utils.LocaleHelper.matchLocale(defaultLocale, localesArray);
  20121. if (defaultMatch) {
  20122. // default was matched
  20123. return defaultMatch;
  20124. }
  20125. // nothing was matched, return first (as defaultLocale is not available)
  20126. return com.ibm.mm.enabler.utils.LocaleHelper.normalizeLocale(localesArray[0]);
  20127. //break; // not necessary after return
  20128. }
  20129. }
  20130. });
  20131. com.ibm.mm.iwidget.manageditemset.IDescriptorImpl = com.ibm.mm.iwidget.manageditemset.IDescriptorDefaultImpl;
  20132. // IMPORTANT
  20133. // ibmConfig.enablerLayerModules is a comma separated string of all supported modules at runtime
  20134. // This section dynamically loads the Extended representation when the variable enablerLayerModules contains the given module
  20135. if ((ibmConfig.enablerLayerModules) && (dojo.indexOf(ibmConfig.enablerLayerModules, "iWidget") >= 0)) {
  20136. dojo["require"]("com.ibm.mm.iwidget.manageditemset.IDescriptorExtendedImpl"); // JSLINT-IGNORE: This needs to be done to allow modularization and to support the minimal layer
  20137. }
  20138. }
  20139. if(!dojo._hasResource["com.ibm.mashups.iwidget.itemset.ManagedItemSet"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  20140. dojo._hasResource["com.ibm.mashups.iwidget.itemset.ManagedItemSet"] = true;
  20141. dojo.provide("com.ibm.mashups.iwidget.itemset.ManagedItemSet");
  20142. }
  20143. if(!dojo._hasResource["com.ibm.mm.iwidget.manageditemset.PersistentAttributes"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  20144. dojo._hasResource["com.ibm.mm.iwidget.manageditemset.PersistentAttributes"] = true;
  20145. dojo.provide("com.ibm.mm.iwidget.manageditemset.PersistentAttributes");
  20146. // INTERNAL PRIVATE CLASS - do NOT use directly
  20147. // Use PersistentAttributes instead
  20148. dojo.declare("com.ibm.mm.iwidget.manageditemset.InternalPersistentAttributesToPreferenceModelAdapter", com.ibm.mashups.iwidget.itemset.ManagedItemSet, {
  20149. //Provides an the ItemSet interface to to the preference subsystem
  20150. constructor: function(widget, serverless, parent) {
  20151. if (serverless) {
  20152. this.serverless = true;
  20153. }
  20154. else {
  20155. this.serverless = false;
  20156. }
  20157. this.modes = iwConstants.mode;
  20158. this.widget = widget;
  20159. this.widgetInstance = this.widget.getIWidgetInstance();
  20160. this.instanceAttributes = this.widgetInstance.getAttributes();
  20161. this.defAttributes = this.widget.widgetDef.getAttributes();
  20162. this.parent = parent;
  20163. this.mode = this._getMode(null);
  20164. },
  20165. setItemValue: function(itemName, value, _merge) {
  20166. if (!itemName) {
  20167. return null;
  20168. }
  20169. if (!value) {
  20170. return null;
  20171. }
  20172. if (this.isReadOnly(itemName)) {
  20173. return null;
  20174. }
  20175. if (this.serverless) {
  20176. if (this.mode == this.modes.EDIT) {
  20177. //todo: replace with user preferred messagelocale
  20178. this.instanceAttributes.setItemValue(itemName, value);
  20179. //save to other level add more here
  20180. if (this.parent) {
  20181. return this.parent;
  20182. }
  20183. }
  20184. }
  20185. return null;
  20186. },
  20187. getItemValue: function(itemName, _merge) {
  20188. if (!itemName) {
  20189. return null;
  20190. }
  20191. var value;
  20192. if (this.serverless) {
  20193. if (typeof _merge === "undefined") {
  20194. _merge = true;
  20195. }
  20196. if (this.mode == this.modes.CONFIG) {
  20197. value = this.defAttributes.getItemValue(itemName);
  20198. if (typeof value === "undefined") {
  20199. value = null;
  20200. }
  20201. return value;
  20202. }
  20203. if (this.mode == this.modes.EDIT && !_merge) {
  20204. value = this.instanceAttributes.getItemValue(itemName);
  20205. if (typeof value === "undefined") {
  20206. value = null;
  20207. }
  20208. return value;
  20209. }
  20210. if (_merge) {
  20211. value = this.instanceAttributes.getItemValue(itemName);
  20212. if (!value) {
  20213. value = this.defAttributes.getItemValue(itemName);
  20214. }
  20215. if (typeof value === "undefined") {
  20216. value = null;
  20217. }
  20218. return value;
  20219. }
  20220. }
  20221. return null;
  20222. },
  20223. getAllNames: function(_merge) {
  20224. if (this.serverless) {
  20225. if (typeof _merge === "undefined") {
  20226. _merge = true;
  20227. }
  20228. var names;
  20229. if (this.mode == this.modes.CONFIG) {
  20230. names = this.defAttributes.getAllNames();
  20231. if (names && names.length && names.length === 0) {
  20232. return null;
  20233. }
  20234. return names;
  20235. }
  20236. if (this.mode == this.modes.EDIT && !_merge) {
  20237. names = this.instanceAttributes.getAllNames();
  20238. if (names && names.length && names.length === 0) {
  20239. return null;
  20240. }
  20241. return names;
  20242. }
  20243. var name;
  20244. if (_merge) {
  20245. names = this.instanceAttributes.getAllNames();
  20246. var obj = {};
  20247. if (names && names.length && names.length > 0) {
  20248. for (var i in names) {
  20249. if (Object.prototype.hasOwnProperty.call(names,i)) {
  20250. name = names[i];
  20251. obj[name] = name;
  20252. }
  20253. }
  20254. }
  20255. names = this.defAttributes.getAllNames();
  20256. if (names && names.length && names.length > 0) {
  20257. for (var j in names) {
  20258. if (Object.prototype.hasOwnProperty.call(names,j)) {
  20259. name = names[j];
  20260. obj[name] = name;
  20261. }
  20262. }
  20263. }
  20264. return this._getNamesArray(obj);
  20265. }
  20266. }
  20267. return null;
  20268. },
  20269. removeItem: function(itemName) {
  20270. if (!itemName) {
  20271. return null;
  20272. }
  20273. if (this.isReadOnly(itemName)) {
  20274. return null;
  20275. }
  20276. if (this.serverless) {
  20277. if (this.mode == this.modes.EDIT) {
  20278. this.instanceAttributes.removeItem(itemName);
  20279. if (this.parent) {
  20280. return this.parent;
  20281. }
  20282. }
  20283. }
  20284. return null;
  20285. },
  20286. isReadOnly: function(/*String*/itemName, _merge) {
  20287. //readOnly is set on definition level, per spec we only overwrite value in editmode
  20288. //however to keep things backward compatible, we allow define value in microformat as well.
  20289. if (!itemName) {
  20290. return false;
  20291. }
  20292. if (this.serverless) {
  20293. if (typeof _merge === "undefined") {
  20294. _merge = true;
  20295. }
  20296. if (this.mode == this.modes.CONFIG) {
  20297. return this.defAttributes.isReadOnly(itemName);
  20298. }
  20299. if (this.mode == this.modes.EDIT && _merge) {
  20300. var isReadOnly = this.defAttributes.isReadOnly(itemName);
  20301. if (!isReadOnly) {
  20302. isReadOnly = this.instanceAttributes.isReadOnly(itemName);
  20303. }
  20304. return isReadOnly;
  20305. }
  20306. if (this.mode == this.modes.EDIT) {
  20307. return this.instanceAttributes.isReadOnly(itemName);
  20308. }
  20309. }
  20310. return false;
  20311. },
  20312. commit: function(callbackfn) {
  20313. //should persist on all the mode level. however config is not supported in runtime model
  20314. //only edit mode needs to persist
  20315. if (this.serverless) {
  20316. this._saveMicroformat();
  20317. }
  20318. else {
  20319. return null;
  20320. }
  20321. if (callbackfn) {
  20322. callbackfn(iwConstants.ATTRIBUTES, true);
  20323. }
  20324. return (this);
  20325. },
  20326. _getNamesArray: function(items) {
  20327. var i = 0;
  20328. var names = [];
  20329. var name;
  20330. for (name in items) {
  20331. if (Object.prototype.hasOwnProperty.call(items,name)) {
  20332. names.push(name);
  20333. i++;
  20334. }
  20335. }
  20336. if (i === 0) {
  20337. return null;
  20338. }
  20339. return names;
  20340. },
  20341. _saveMicroformat: function() {
  20342. this.widget.commit();
  20343. var payloadObj = {};
  20344. payloadObj.wid = this.widget.id;
  20345. this.widget.eventSvr._publishEvent(iwConstants.EVENTS.onAttributeSaved, payloadObj, this.widget.hubId);
  20346. },
  20347. _getMode: function(_mode) {
  20348. var mode = this.modes.EDIT;
  20349. if (_mode) {
  20350. mode = _mode;
  20351. }
  20352. else {
  20353. mode = this.widget.currentMode;
  20354. }
  20355. //todo: we need to define all the systemmodes supported by the framework
  20356. //for runtime model, we only support edit
  20357. if (mode == this.modes.VIEW) {
  20358. mode = this.modes.EDIT;
  20359. }
  20360. return mode;
  20361. },
  20362. addListener: function(/*obj*/fn) {
  20363. var listenerId = this.widget._registerListener(iwConstants.ATTRIBUTES, fn);
  20364. return listenerId;
  20365. },
  20366. removeListener: function(/*String*/listenerId) {
  20367. return this.widget._removeListener(iwConstants.ATTRIBUTES, listenerId);
  20368. }
  20369. });
  20370. dojo.declare("com.ibm.mm.iwidget.manageditemset.PersistentAttributes", com.ibm.mashups.iwidget.itemset.ManagedItemSet, {
  20371. constructor: function(widgetWrapper, serverless) {
  20372. this._internalPersistentAttributesToPreferenceModelAdapter =
  20373. new com.ibm.mm.iwidget.manageditemset.InternalPersistentAttributesToPreferenceModelAdapter(widgetWrapper, serverless, this);
  20374. },
  20375. setItemValue: function(itemName, value) {
  20376. return this._internal().setItemValue(itemName, value, true);
  20377. },
  20378. getItemValue: function(itemName) {
  20379. return this._internal().getItemValue(itemName, true);
  20380. },
  20381. getAllNames: function() {
  20382. return this._internal().getAllNames(true);
  20383. },
  20384. removeItem: function(itemName) {
  20385. return this._internal().removeItem(itemName);
  20386. },
  20387. isReadOnly: function(itemName) {
  20388. return this._internal().isReadOnly(itemName, true);
  20389. },
  20390. save: function(callbackfn) {
  20391. return this.commit(callbackfn);
  20392. },
  20393. commit: function(callbackfn) {
  20394. return this._internal().commit(callbackfn);
  20395. },
  20396. _internal: function() { //todo: cleanup
  20397. return this._internalPersistentAttributesToPreferenceModelAdapter;
  20398. },
  20399. addListener: function(/*obj*/fn) {
  20400. return this._internal().addListener(fn);
  20401. },
  20402. removeListener: function(/*String*/listenerId) {
  20403. return this._internal().removeListener(listenerId);
  20404. }
  20405. });
  20406. }
  20407. if(!dojo._hasResource["com.ibm.mashups.iwidget.itemset.ItemSet"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  20408. dojo._hasResource["com.ibm.mashups.iwidget.itemset.ItemSet"] = true;
  20409. dojo.provide("com.ibm.mashups.iwidget.itemset.ItemSet");
  20410. /**
  20411. * Interface to a simple abstraction of a datamodel. This provides a base from which more sofisticated data models can be built.
  20412. * @ibm-api
  20413. * @ibm-module iWidget2
  20414. */
  20415. dojo.declare("com.ibm.mashups.iwidget.itemset.ItemSet", null, {
  20416. /**
  20417. @private
  20418. */
  20419. constructor: function() {
  20420. },
  20421. /**
  20422. This method sets an item within the ItemSet, creates or replaces an existing entry as needed.
  20423. Since only one value is allowed for any one name/locale combination, the supplied value replaces any existing value for the supplied name/locale.
  20424. When successful, this method MUST return a handle to the ItemSet while on failure it must return null.
  20425. @param{String}itemName name of the item. Must never be <code>null</code>.
  20426. @param{Object}value value of the item. Must never be <code>null</code>.
  20427. @param{String}locale specified locale. Must never be <code>null</code>.
  20428. @return{ItemSet} return an handle of ItemSet upon successful, <code>null</code> upon failure.
  20429. */
  20430. setLocalizedItemValue: function( /*String*/itemName, /*Object*/ value,/*String*/ locale) {
  20431. return this;
  20432. },
  20433. /**
  20434. This method sets an item within the ItemSet, creates or replaces an existing entry as needed.
  20435. To append a value to any existing item, suggest to get the current value of this item and append
  20436. the new value to the list and supply the result to this method.
  20437. Marking an item as ReadOnly indicates to the iContext that while this item maybe shared with other components
  20438. on the page, the access of those components should not include changing or removing item.
  20439. @param{String}itemName name of the item. Must never be <code>null</code>.
  20440. @param{Object}value value of the item. Must never be <code>null</code>.
  20441. @param{Boolean}readOnly optional Boolean attribute to indicate this item is readOnly or not.Default value is false if this parameter is not provided.
  20442. @return{ItemSet} return an handle of ItemSet upon successful, <code>null</code> upon failure.
  20443. @deprecated please use setItemValue(itemName,value) readOnly is always false
  20444. */
  20445. setItemValue: function( /*String*/itemName, /*Object*/ value,/*boolean*/ readOnly) {// JSLINT-IGNORE: in Java functions with the same name but different signatures are allowed - this is only used for generating JavaDoc
  20446. return this;
  20447. },
  20448. /**
  20449. This method sets a nonlocalized value of an item within the ItemSet, creates or replaces an existing entry as needed.
  20450. @param{String}itemName name of the item. Must never be <code>null</code>.
  20451. @param{Object}value value of the item. Must never be <code>null</code>.
  20452. @return{ItemSet} return an handle of ItemSet upon successful, <code>null</code> upon failure.
  20453. */
  20454. setItemValue: function( /*String*/itemName, /*Object*/ value) {// JSLINT-IGNORE: in Java functions with the same name but different signatures are allowed - this is only used for generating JavaDoc
  20455. return this;
  20456. },
  20457. /**
  20458. This method returns the value for the named item in the specified locale. On failure this method MUST return null.
  20459. @param{String}itemName name of the item. Must never be <code>null</code>.
  20460. @param{String}locale specified locale. Must never be <code>null</code>.
  20461. @return{Object} return value of the item, <code>null</code> upon failure.
  20462. */
  20463. getLocalizedItemValue: function( /*String*/itemName,/*String*/locale) {
  20464. return null;
  20465. },
  20466. /**
  20467. This method returns the nonlocalized value for the named item from the set.
  20468. @param{String}itemName name of the item. Must never be <code>null</code>.
  20469. @return{ItemSet} return the named item for the set, <code>null</code> upon failure.
  20470. */
  20471. getItemValue: function( /*String*/itemName) {
  20472. return null;
  20473. },
  20474. /**
  20475. This method returns an array of Strings, providing the name of each item.
  20476. @return{String[]} return an array of items names and return <code>null</code> if the set contains no item
  20477. */
  20478. getAllNames: function() {
  20479. return null;
  20480. },
  20481. /**
  20482. Removes the named item from the set.
  20483. @param{String}itemName name of the item that needs to be removed. Must never be <code>null</code>.
  20484. @return{ItemSet} return the handle to the ItemSet upon successful, <code>null</code> upon failure.
  20485. */
  20486. removeItem: function(/*String*/itemName) {
  20487. return null;
  20488. },
  20489. /**
  20490. Removes the non localized value of the item from the set.
  20491. @param{String}itemName name of the item that needs to be removed. Must never be <code>null</code>.
  20492. @return{ItemSet} return the handle to the ItemSet upon successful, <code>null</code> upon failure.
  20493. */
  20494. removeItemValue: function(/*String*/itemName) {
  20495. return null;
  20496. },
  20497. /**
  20498. Removes the value of the item from the set for a specified locale.
  20499. @param{String}itemName name of the item that needs to be removed. Must never be <code>null</code>.
  20500. @param{String}locale a specified locale. Must never be <code>null</code>.
  20501. @return{ItemSet} return the handle to the ItemSet upon successful, <code>null</code> upon failure.
  20502. */
  20503. removeLocalizedItemValue: function(/*String*/itemName,/*String*/locale) {
  20504. return null;
  20505. },
  20506. /**
  20507. The method returns an array of strings, each providing a locale where a value is defined. The empty string"" is
  20508. returned for a value without a locale. if the set does not contain the names item, this method must return null.
  20509. @param{String}itemName name of the item. Must never be <code>null</code>.
  20510. @return{String[]} return an array each providing a locale where a value is defined.
  20511. */
  20512. getLocalesWithValues: function(/*String*/itemName) {
  20513. return null;
  20514. },
  20515. /**
  20516. This method returns a new ItemSet which is a duplicate of the current ItemSet.
  20517. @return{ItemSet} return a new ItemSet which contains all the data item in the current ItemSet
  20518. @deprecated not used
  20519. */
  20520. clone: function() {
  20521. return null;
  20522. },
  20523. /**
  20524. This method returns a Boolean indicating whether or not the item specified by the supplied name can be modified by the user.
  20525. @param{String}itemName name of the required Item. Must never be <code>null</code>.
  20526. @return{Boolean} return a Boolean indicating whether or not the item specified by the supplied name can be modified by the user. Never <code>null</code>.
  20527. @deprecated always return false
  20528. */
  20529. isReadOnly: function(/*String*/itemName) {
  20530. return false;
  20531. },
  20532. /**
  20533. As a limitation in Lotus Mashups, this method returns <code>null</code>.
  20534. @return{Object} return As a limitation in Lotus Mashups, this method returns <code>null</code>.
  20535. @deprecated not used
  20536. */
  20537. getItemSetDescription: function() {
  20538. return null;
  20539. },
  20540. /**
  20541. This function adds listener to this ShareableItemSet. So it will gets notified when this ShareableItemSet is updated.
  20542. @param{Function}listener js function that should already be properly scoped. Must never be <code>null</code>.
  20543. @return{String} return listener id if listener is registered successfully, return null if it's not.
  20544. @deprecated not used
  20545. */
  20546. addListener: function(/*Function*/listener) {
  20547. return null;
  20548. },
  20549. /**
  20550. This function removes the listener from this ShareableItemSet.
  20551. @param{String}listenerId listener id that's returned by the system when listener is added. Must never be <code>null</code>.
  20552. @return{Boolean} return true if listener is removed successfully.
  20553. @deprecated not used
  20554. */
  20555. removeListener: function(/*String*/listenerId) {
  20556. return true;
  20557. } //return true if listener is removed successfully
  20558. });
  20559. }
  20560. if(!dojo._hasResource["com.ibm.mm.iwidget.itemset.ItemsetDefaultImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  20561. dojo._hasResource["com.ibm.mm.iwidget.itemset.ItemsetDefaultImpl"] = true;
  20562. dojo.provide("com.ibm.mm.iwidget.itemset.ItemsetDefaultImpl");
  20563. dojo.declare("com.ibm.mm.iwidget.itemset.ItemSetDefaultImpl", com.ibm.mashups.iwidget.itemset.ItemSet, {
  20564. constructor: function(parent, defData, name) {
  20565. this.widget = parent; //widget wrapper;
  20566. this.name = name;
  20567. //no persistence is needed thus we have only one merged data layer at runtime
  20568. var instance = this.widget.getIWidgetInstance();
  20569. var instanceProperties = null;
  20570. if (instance) {
  20571. instanceProperties = instance.getItemSet(name);
  20572. }
  20573. var properties = {};
  20574. if (defData) {
  20575. if (defData) {
  20576. for (var itemName1 in defData.items) {
  20577. if (Object.prototype.hasOwnProperty.call(defData.items,itemName1)) {
  20578. properties[itemName1] = dojo.clone(defData.items[itemName1]); // the new internal json itemset notation is compatible with the SPI
  20579. }
  20580. }
  20581. }
  20582. this.properties = new com.ibm.mm.iwidget.widget.ModifiablePropertiesImpl(properties);
  20583. }
  20584. if (!this.properties) {
  20585. this.properties = new com.ibm.mm.iwidget.widget.ModifiablePropertiesImpl(properties);
  20586. }
  20587. if (instanceProperties) {
  20588. for (var itemName in instanceProperties) { //overwrite only
  20589. //if (defData.items[itemName]) {
  20590. if (Object.prototype.hasOwnProperty.call(instanceProperties,itemName)) {
  20591. var anItem = instanceProperties[itemName];
  20592. if (anItem.values) {
  20593. for (var j in anItem.values) {
  20594. if (Object.prototype.hasOwnProperty.call(anItem.values,j)) {
  20595. //always readOnly
  20596. this.properties.setItemValue(itemName, anItem.values[j], false, j);
  20597. }
  20598. }
  20599. }
  20600. if (anItem.value) {
  20601. this.properties.setItemValue(itemName, anItem.value);
  20602. }
  20603. }
  20604. }
  20605. }
  20606. },
  20607. _getResourceBundle: function() {
  20608. if (!this.iwMessages) {
  20609. this.iwMessages = dojo.i18n.getLocalization("com.ibm.mm.enabler", "iwMessages");
  20610. }
  20611. return this.iwMessages;
  20612. },
  20613. _logDeprecated:function(methodName,fn1,fn2){
  20614. this._getResourceBundle();
  20615. var warning = dojo.string.substitute(this.iwMessages.W_DEPRECATE_2, [fn1,fn2]);
  20616. },
  20617. getLocalesWithValues: function(/*String*/itemName) {
  20618. return this.properties.getItemLocales(itemName);
  20619. },
  20620. setLocalizedItemValue:function(itemName,value,locale){
  20621. if (!itemName || !locale) {
  20622. return null;
  20623. }
  20624. if (!(typeof value != "undefined" && value !== null)){
  20625. return null;
  20626. }
  20627. rc = this.properties.setItemValue(itemName,value,false,locale);
  20628. if (rc){
  20629. return this;
  20630. }
  20631. return null;
  20632. },
  20633. setItemValue: function( /*String*/itemName, /*Object*/ value,/*String*/ locale) {
  20634. if (!itemName ) {
  20635. return null;
  20636. }
  20637. if (!(typeof value != "undefined" && value !== null)){
  20638. return null;
  20639. }
  20640. //locale should be deprecated,use setLocalizedItemValue instead
  20641. if (!locale){
  20642. rc = this.properties.setItemValue(itemName,value,false);
  20643. }else if (locale && !dojo.isString(locale)){
  20644. this._logDeprecated("setItemValue","ItemSet.setItemValue(itemName,value,readOnly)","ItemSet.setItemValue(item,value)");
  20645. rc = this.properties.setItemValue(itemName,value,false);
  20646. }else{
  20647. this._logDeprecated("setItemValue","ItemSet.setItemValue(itemName,value,locale)","ItemSet.setLocalizedItemValue(item,value,locale)");
  20648. return this.setLocalizedItemValue(itemName,value,locale);
  20649. }
  20650. if (rc) {
  20651. return this;
  20652. }
  20653. return null;
  20654. },
  20655. getLocalizedItemValue: function( /*String*/itemName, locale) {
  20656. if (!itemName || !locale) {
  20657. return null;
  20658. }
  20659. return this.properties.getLocalizedItemValue(itemName, locale);
  20660. },
  20661. getItemValue: function( /*String*/itemName, locale) {
  20662. if (!itemName ) {
  20663. return null;
  20664. }
  20665. if (locale){
  20666. this._logDeprecated("getItemValue","ItemSet.getItemValue(itemName,locale)","ItemSet.getLocalizedItemValue(item,locale)");
  20667. return this.getLocalizedItemValue(itemName,locale);
  20668. }
  20669. return this.properties.getItemValue(itemName);
  20670. },
  20671. getAllNames: function() {
  20672. rc = this.properties.getAllNames();
  20673. if (rc && rc.length === 0) {
  20674. return null;
  20675. }
  20676. return rc;
  20677. },
  20678. removeItem: function(/*String*/itemName, locale) {
  20679. if (!itemName ) {
  20680. return null;
  20681. }
  20682. if (locale){
  20683. this._logDeprecated("removeItem","ItemSet.removeItem(itemName,locale)","ItemSet.removeLocalizedItemValue(itemName,locale)");
  20684. return this.removeLocalizedItemValue(itemName,locale);
  20685. }
  20686. rc = this.properties.removeItem(itemName);
  20687. if (rc) {
  20688. return this;
  20689. }
  20690. return null;
  20691. },
  20692. removeLocalizedItemValue:function(itemName,locale){
  20693. if (!itemName || !locale) { return null;}
  20694. rc = this.properties.removeItemValue(itemName,locale);
  20695. if (rc) {
  20696. return this;
  20697. }
  20698. return null;
  20699. },
  20700. removeItemValue:function(itemName){
  20701. if (!itemName ) { return null;}
  20702. rc = this.properties.removeItemValue(itemName);
  20703. if (rc) {
  20704. return this;
  20705. }
  20706. return null;
  20707. }
  20708. });
  20709. }
  20710. if(!dojo._hasResource["com.ibm.mm.iwidget.DeferredLiveTextUnprocessStubImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  20711. dojo._hasResource["com.ibm.mm.iwidget.DeferredLiveTextUnprocessStubImpl"] = true;
  20712. dojo.provide("com.ibm.mm.iwidget.DeferredLiveTextUnprocessStubImpl");
  20713. dojo.declare("com.ibm.mm.iwidget.DeferredLiveTextUnprocessStubImpl", com.ibm.mm.enabler.DeferredImpl, {
  20714. constructor: function(wrapper) {
  20715. this.wrapper = wrapper;
  20716. },
  20717. start: function(sync) {
  20718. // defaults to false
  20719. if (sync) {
  20720. return;
  20721. }
  20722. //todo, what should we return if widget is sandboxed?
  20723. var widgetInstance = this.wrapper.getIWidgetInstance();
  20724. var tempMarkup = dojo.clone(this.wrapper.rootElement);
  20725. this._unchangeCompleteCallback(tempMarkup);
  20726. },
  20727. setIncludeParent: function(value) {
  20728. this.includeParent = value;
  20729. },
  20730. getIncludeParent: function() {
  20731. return this.includeParent;
  20732. },
  20733. _unchangeCompleteCallback: function(node) {
  20734. if (dojo.isFunction(this.getFinishedCallback())) {
  20735. this.finish(node, 200);
  20736. }
  20737. }
  20738. });
  20739. }
  20740. if(!dojo._hasResource["com.ibm.mashups.iwidget.services.ContainerService_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  20741. dojo._hasResource["com.ibm.mashups.iwidget.services.ContainerService_API"] = true;
  20742. dojo.provide("com.ibm.mashups.iwidget.services.ContainerService_API");
  20743. dojo.provide("com.ibm.mashups.iwidget.services.ContainerService");
  20744. /**
  20745. * @ibm-spi
  20746. * @ibm-module iWidget2
  20747. */
  20748. dojo.declare("com.ibm.mashups.iwidget.services.ContainerService",null, {
  20749. /**
  20750. * The service name to be used to fetch the service from the ServiceManager
  20751. * @type String
  20752. */
  20753. SERVICE_NAME: "iWidgetContainerService",
  20754. /**
  20755. * Constant defining the provider for event information
  20756. * @type String
  20757. */
  20758. PROVIDER_EVENTS: "events",
  20759. /**
  20760. * Constant defining the provider for wire information
  20761. * @type String
  20762. */
  20763. PROVIDER_WIRES: "wires",
  20764. /**
  20765. * Constant defining the provider for attribute information
  20766. * @type String
  20767. */
  20768. PROVIDER_ATTRIBUTES: "attributes",
  20769. registerOnChangeListener:function(provider, contextAndCallback) {
  20770. },
  20771. /**
  20772. * Sets the persistence mode for the given type to the given new mode.
  20773. *
  20774. * @param {String} provider One of the PROVIDER_* constants defined in this service. Must never be NULL.
  20775. * @return {String} the current persistence mode for the given provider. May be NULL.
  20776. */
  20777. getPersistenceMode:function(provider, newMode) {
  20778. },
  20779. /**
  20780. * Sets the persistence mode for all providers into their respective modifiable mode.
  20781. *
  20782. * @type void
  20783. */
  20784. switchToModifiablePersistenceMode:function() {
  20785. }
  20786. });
  20787. // make sure we can reference this globally
  20788. com.ibm.mashups.iwidget.services.ContainerService.SERVICE_NAME = "iWidgetContainerService";
  20789. com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_EVENTS = "events";
  20790. com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_WIRES = "wires";
  20791. com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_ATTRIBUTES = "attributes";
  20792. }
  20793. if(!dojo._hasResource["com.ibm.mm.iwidget.services.ContainerServiceImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  20794. dojo._hasResource["com.ibm.mm.iwidget.services.ContainerServiceImpl"] = true;
  20795. dojo.provide("com.ibm.mm.iwidget.services.ContainerServiceImpl");
  20796. /*
  20797. * This is injected on the fly and not fetched through an API. Therefore we need to define the @ibm-module so that the build process is picking it up
  20798. * @ibm-module iWidget2
  20799. *
  20800. * This value defines the order in which the packages should be printed out into the dojo profile. Default is 100.
  20801. * Any number that is smaller causes this class to be written out before any other with a higher number
  20802. * @ibm-dojo-profile-level 40
  20803. */
  20804. // inject this service into the ServiceManager at the end. Therefore we have to require the implementation
  20805. dojo.declare("com.ibm.mm.iwidget.services.ContainerServiceImpl", com.ibm.mashups.iwidget.services.ContainerService, {
  20806. constructor: function(){
  20807. this._modes = null;
  20808. this._modModes = null;
  20809. this.TOPIC_BASE = "/"+("com.ibm.mm.iwidget.services.ContainerServiceImpl".replace(/\./ig,'/'))+"/";
  20810. this.TOPIC_CHANGE = this.TOPIC_BASE + "change";
  20811. this.TOPIC_CHANGE_EVENTS = this.TOPIC_CHANGE + "/events";
  20812. this.TOPIC_CHANGE_WIRES = this.TOPIC_CHANGE + "/wires";
  20813. this.TOPIC_CHANGE_ATTRIBUTES = this.TOPIC_CHANGE + "/attributes";
  20814. this._topics = {};
  20815. this._topics[com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_EVENTS] = this.TOPIC_CHANGE_EVENTS;
  20816. this._topics[com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_WIRES] = this.TOPIC_CHANGE_WIRES;
  20817. this._topics[com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_ATTRIBUTES] = this.TOPIC_CHANGE_ATTRIBUTES;
  20818. },
  20819. _invalidate: function() {
  20820. this._modes = null;
  20821. this._modModes = null;
  20822. },
  20823. _init:function() {
  20824. if (this._modes) {
  20825. return;
  20826. }
  20827. var cs = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);
  20828. var genericPersistenceMode = cs.getValue(com.ibm.mashups.enabler.services.ConfigConstants.PERSISTENCE_MODE);
  20829. var eventPersistenceMode = cs.getValue(com.ibm.mashups.enabler.services.ConfigConstants.PERSISTENCE_MODE_EVENTS);
  20830. var wirePersistenceMode = cs.getValue(com.ibm.mashups.enabler.services.ConfigConstants.PERSISTENCE_MODE_WIRES);
  20831. var attributePersistenceMode = cs.getValue(com.ibm.mashups.enabler.services.ConfigConstants.PERSISTENCE_MODE_ATTRIBUTES);
  20832. this._modes = {};
  20833. this._modes[com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_EVENTS] = (eventPersistenceMode) ? eventPersistenceMode : genericPersistenceMode;
  20834. this._modes[com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_WIRES] = (wirePersistenceMode) ? wirePersistenceMode : genericPersistenceMode;
  20835. this._modes[com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_ATTRIBUTES] = (attributePersistenceMode) ? attributePersistenceMode : genericPersistenceMode;
  20836. eventPersistenceMode = cs.getValue(com.ibm.mashups.enabler.services.ConfigConstants.PERSISTENCE_MODE_EVENTS_MODIFIABLE);
  20837. wirePersistenceMode = cs.getValue(com.ibm.mashups.enabler.services.ConfigConstants.PERSISTENCE_MODE_WIRES_MODIFIABLE);
  20838. attributePersistenceMode = cs.getValue(com.ibm.mashups.enabler.services.ConfigConstants.PERSISTENCE_MODE_ATTRIBUTES_MODIFIABLE);
  20839. this._modModes = {};
  20840. this._modModes[com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_EVENTS] = (eventPersistenceMode) ? eventPersistenceMode : genericPersistenceMode;
  20841. this._modModes[com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_WIRES] = (wirePersistenceMode) ? wirePersistenceMode : genericPersistenceMode;
  20842. this._modModes[com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_ATTRIBUTES] = (attributePersistenceMode) ? attributePersistenceMode : genericPersistenceMode;
  20843. },
  20844. registerOnChangeListener:function(provider, contextAndCallback) {
  20845. this._init();
  20846. var handle = dojo.subscribe(this._topics[provider], contextAndCallback.context, contextAndCallback.callback);
  20847. if (dojo.isFunction(contextAndCallback.unregister)) {
  20848. dojo.hitch(contextAndCallback.context, contextAndCallback.unregister)(handle);
  20849. }
  20850. },
  20851. getPersistenceMode:function(provider, newMode) {
  20852. this._init();
  20853. return this._modes[provider];
  20854. },
  20855. switchToModifiablePersistenceMode:function(provider) {
  20856. this._init();
  20857. var oldModeEvents = this._modes[com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_EVENTS];
  20858. var newModeEvents = this._modModes[com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_EVENTS];
  20859. var oldModeWires = this._modes[com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_WIRES];
  20860. var newModeWires = this._modModes[com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_WIRES];
  20861. var oldModeAttributes = this._modes[com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_ATTRIBUTES];
  20862. var newModeAttributes = this._modModes[com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_ATTRIBUTES];
  20863. this._modes[com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_EVENTS] = newModeEvents;
  20864. this._modes[com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_WIRES] = newModeWires;
  20865. this._modes[com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_ATTRIBUTES] = newModeAttributes;
  20866. if (oldModeEvents != newModeEvents) {
  20867. dojo.publish(this._topics[com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_EVENTS],
  20868. [com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_EVENTS, oldModeEvents, newModeEvents]);
  20869. dojo.publish(this._topics[com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_WIRES],
  20870. [com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_WIRES, oldModeWires, newModeWires]);
  20871. dojo.publish(this._topics[com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_ATTRIBUTES],
  20872. [com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_ATTRIBUTES, oldModeAttributes, newModeAttributes]);
  20873. }
  20874. }
  20875. });
  20876. com.ibm.mashups.services.ServiceManager.setService(com.ibm.mashups.iwidget.services.ContainerService.SERVICE_NAME, new com.ibm.mm.iwidget.services.ContainerServiceImpl());
  20877. }
  20878. if(!dojo._hasResource["com.ibm.mashups.iwidget.services.ContainerService"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  20879. dojo._hasResource["com.ibm.mashups.iwidget.services.ContainerService"] = true;
  20880. dojo.provide("com.ibm.mashups.iwidget.services.ContainerService");
  20881. }
  20882. if(!dojo._hasResource["com.ibm.mm.iwidget.manageditemset.AttributesModeDelegate"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  20883. dojo._hasResource["com.ibm.mm.iwidget.manageditemset.AttributesModeDelegate"] = true;
  20884. dojo.provide("com.ibm.mm.iwidget.manageditemset.AttributesModeDelegate");
  20885. dojo.declare("com.ibm.mm.iwidget.manageditemset.AttributesModeDelegate", com.ibm.mashups.iwidget.itemset.ManagedItemSet, {
  20886. constructor: function(persistentAttributesFactoryService, wrapper) {
  20887. this.persistentAttributesFactoryService = persistentAttributesFactoryService;
  20888. this.wrapper = wrapper;
  20889. this.callbackHandle = {context:this, callback:"_attributesProviderModeChange",
  20890. unregister: function(handle) {
  20891. this.wrapper.unregisterArray.push(handle);
  20892. }
  20893. };
  20894. this.widgetAttributes = [];
  20895. this.widgetAttributesReplay = [];
  20896. this._skipRecord = false;
  20897. // init
  20898. this._getAttributes();
  20899. },
  20900. _attributesProviderModeChange: function(provider, oldMode, newMode) {
  20901. this.widgetAttributes = [];
  20902. this._getAttributes();
  20903. // replay here into the new persistence mode
  20904. var modeSelector = this._getModeSelector();
  20905. var replayArray = this.widgetAttributesReplay[modeSelector];
  20906. if (replayArray) {
  20907. this._skipRecord = true;
  20908. for (var i=0; i<replayArray.length; i++) {
  20909. var replay = replayArray[i];
  20910. if (replay[0] == "set") {
  20911. this.setItemValue(replay[1], replay[2]);
  20912. }
  20913. else if (replay[0] == "remove") {
  20914. this.removeItem(replay[1]);
  20915. }
  20916. }
  20917. this._skipRecord = false;
  20918. }
  20919. this.widgetAttributesReplay = [];
  20920. this.widgetAttributesReplay[modeSelector] = [];
  20921. },
  20922. _getModeSelector: function() {
  20923. // the rules for the modes are:
  20924. // config -> config
  20925. // edit -> edit
  20926. // personalize -> personalize
  20927. // view --> personalize
  20928. // "else" --> personalize
  20929. var currentMode = this.wrapper._getCurrentMode();
  20930. var modeSelector = iwConstants.mode.PERSONALIZE;
  20931. if (currentMode == iwConstants.mode.CONFIG || currentMode == iwConstants.mode.EDIT) {
  20932. modeSelector = currentMode;
  20933. }
  20934. return modeSelector;
  20935. },
  20936. _getAttributes:function() {
  20937. var modeSelector = this._getModeSelector();
  20938. this.widgetAttributes[modeSelector] = this.widgetAttributes[modeSelector] || null;
  20939. if (this.widgetAttributes[modeSelector] === null) {
  20940. this.widgetAttributes[modeSelector] = this.persistentAttributesFactoryService.createPersistentAttributes(this.wrapper, this.callbackHandle);
  20941. // we only want to register one callback handler to clean out all modes
  20942. this.callbackHandle = null;
  20943. }
  20944. return this.widgetAttributes[modeSelector];
  20945. },
  20946. _record: function(array) {
  20947. if (!this._skipRecord) {
  20948. // first element is function name, everything after that parameters
  20949. var modeSelector = this._getModeSelector();
  20950. this.widgetAttributesReplay[modeSelector] = this.widgetAttributesReplay[modeSelector] || null;
  20951. if (this.widgetAttributesReplay[modeSelector] === null) {
  20952. this.widgetAttributesReplay[modeSelector] = [];
  20953. }
  20954. this.widgetAttributesReplay[modeSelector].push(array);
  20955. //console.log("recorded ",array);
  20956. }
  20957. },
  20958. _clearReplay: function()
  20959. {
  20960. var modeSelector = this._getModeSelector();
  20961. this.widgetAttributesReplay[modeSelector] = [];
  20962. },
  20963. setItemValue: function(itemName, value) {
  20964. this._record(["set",itemName, value]);
  20965. return this._getAttributes().setItemValue(itemName, value);
  20966. },
  20967. getItemValue: function(itemName) {
  20968. return this._getAttributes().getItemValue(itemName, true);
  20969. },
  20970. getAllNames: function() {
  20971. return this._getAttributes().getAllNames(true);
  20972. },
  20973. removeItem: function(itemName) {
  20974. this._record(["remove",itemName]);
  20975. return this._getAttributes().removeItem(itemName);
  20976. },
  20977. isReadOnly: function(itemName) {
  20978. return this._getAttributes().isReadOnly(itemName, true);
  20979. },
  20980. save: function(callbackfn) {
  20981. var cs = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.iwidget.services.ContainerService.SERVICE_NAME);
  20982. if (cs) {
  20983. cs.switchToModifiablePersistenceMode(com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_ATTRIBUTES);
  20984. }
  20985. this._clearReplay();
  20986. return this._getAttributes().save(callbackfn);
  20987. },
  20988. commit: function(callbackfn) {
  20989. var cs = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.iwidget.services.ContainerService.SERVICE_NAME);
  20990. if (cs) {
  20991. cs.switchToModifiablePersistenceMode(com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_ATTRIBUTES);
  20992. }
  20993. this._clearReplay();
  20994. return this._getAttributes().commit(callbackfn);
  20995. },
  20996. addListener: function(/*obj*/fn) {
  20997. return this._getAttributes().addListener(fn);
  20998. },
  20999. removeListener: function(/*String*/listenerId) {
  21000. return this._getAttributes().removeListener(listenerId);
  21001. }
  21002. });
  21003. }
  21004. if(!dojo._hasResource["com.ibm.mm.iwidget.DeferredLoadImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  21005. dojo._hasResource["com.ibm.mm.iwidget.DeferredLoadImpl"] = true;
  21006. dojo.provide("com.ibm.mm.iwidget.DeferredLoadImpl");
  21007. // deferred Load
  21008. dojo.declare("com.ibm.mm.iwidget.DeferredLoadImpl", com.ibm.mm.enabler.DeferredImpl, {
  21009. constructor: function(uri, id, widgetDef) {
  21010. this.uri = uri;
  21011. if (typeof id == "undefined") {
  21012. id = null;
  21013. }
  21014. this.id = id;
  21015. if (typeof widgetDef == "undefined") {
  21016. widgetDef = null;
  21017. }
  21018. this.widgetDef = widgetDef;
  21019. },
  21020. // defaults to synchronous
  21021. start: function(sync) {
  21022. if (this.widgetDef) {
  21023. this._handleCallback(this.widgetDef, 200); //resource first, status code second
  21024. return this.widgetDef;
  21025. }
  21026. var mode = (typeof(sync) == 'undefined') ? true : sync;
  21027. var widgetLoadService = com.ibm.mashups.services.ServiceManager.getService("widgetLoadService");
  21028. widgetLoadService.getWidgetXML(this.uri, mode, dojo.hitch(this, "_handleLoad"), this.id);
  21029. if (sync) {
  21030. return this.widgetDef;
  21031. }
  21032. return null;
  21033. },
  21034. _handleLoad: function(data, statuscode, xhr) {
  21035. if (xhr) {
  21036. statuscode = xhr.status;
  21037. }
  21038. if (statuscode != 200) {
  21039. data = null; //set to null value
  21040. }
  21041. this.widgetDef = data;
  21042. this._handleCallback(data, status);
  21043. },
  21044. _handleCallback: function(widgetDef, status) {
  21045. this.finish(widgetDef, status);
  21046. }
  21047. });
  21048. }
  21049. if(!dojo._hasResource["com.ibm.mm.iwidget.widget.IWidgetWrapperDefaultImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  21050. dojo._hasResource["com.ibm.mm.iwidget.widget.IWidgetWrapperDefaultImpl"] = true;
  21051. dojo.provide("com.ibm.mm.iwidget.widget.IWidgetWrapperDefaultImpl");
  21052. /*
  21053. * TODO
  21054. * @ibm-module iWidget2
  21055. */
  21056. dojo.declare("com.ibm.mm.iwidget.widget.IWidgetWrapperDefaultImpl", com.ibm.mashups.iwidget.widget.IWidgetWrapper, {
  21057. constructor: function(widgetSpan, id) {
  21058. this._internalIbmModes = iwConstants._INTERNALIBMMODES;
  21059. //parsing microformat
  21060. this.rootElement = widgetSpan;
  21061. this.id = id || dojo.attr(widgetSpan,'id');
  21062. this.hubId = this.id; //hubClientId -- used for communication with openajax hub, for main view, it's the same as instanceid
  21063. this.simpleWidgetEvents = {};
  21064. this.loaded = false;
  21065. this.standalone = null;
  21066. this.widgetAttributes = null; // defer creation
  21067. this.widgetItemSets = null; // defer creation to getWidgetItemSet or getItemSets
  21068. this.ns = widgetSpan.className.substr(0, 3);
  21069. this.windowManager = {}; // an associative array of window entities, key is windowid(for release1,it's mode);
  21070. // value is simple json object: {id:"edit",root:rootElement,active:false}
  21071. this.iwMessages = null;
  21072. this.eventSvr = com.ibm.mashups.services.ServiceManager.getService("eventService");
  21073. this._jsHandler = com.ibm.mm.enabler.aggregation.javascript.JAVASCRIPT_HANDLER;
  21074. this.eventHandlers = [];
  21075. this.unregisterArray = [];
  21076. //backward compatibility
  21077. this.publishedEvents = {};
  21078. this.handledEvents = {};
  21079. },
  21080. getID: function() {
  21081. return this.id;
  21082. },
  21083. getIWidgetInstance: function() {
  21084. if (this.widgetInstance) {
  21085. return this.widgetInstance;
  21086. }
  21087. this.widgetInstance = new com.ibm.mm.iwidget.widget.IWidgetInstanceImpl(this, this.rootElement, this.id);
  21088. return this.widgetInstance;
  21089. },
  21090. setIWidgetDefinition: function(widgetDef) {
  21091. this.widgetDef = widgetDef;
  21092. },
  21093. getIWidgetDefinition: function() {
  21094. if (this.loaded) {
  21095. return new com.ibm.mm.iwidget.DeferredLoadImpl(this.getIWidgetInstance().widgetXMLUrl, this.id, this.widgetDef);
  21096. }
  21097. else {
  21098. return new com.ibm.mm.iwidget.DeferredLoadImpl(this.getIWidgetInstance().widgetXMLUrl, this.id);
  21099. }
  21100. },
  21101. getMarkup: function() {
  21102. return new com.ibm.mm.iwidget.DeferredLiveTextUnprocessStubImpl(this);
  21103. },
  21104. doRender: function() {
  21105. try {
  21106. this.prepare();
  21107. this.execute();
  21108. }
  21109. catch (e) {
  21110. //throw e;
  21111. }
  21112. },
  21113. prepare: function() {
  21114. var variableName = "_" + this.id + "_" + "iContext";
  21115. if (!this.isModal()) {
  21116. dojo.global[variableName] = new com.ibm.mm.iwidget.icontext.IContextImpl(this, this.ns);
  21117. }
  21118. else {
  21119. var mainframeId = this._mainframeId;
  21120. var iContextInstance = parent[mainframeId][variableName];
  21121. dojo.global[variableName] = iContextInstance;
  21122. }
  21123. //subscribe event handler so event can be handled
  21124. //if (this._inIframe()) console.log("subscribe hubClient:"+this.eventSvr.WIDGETEVENT_PREFIX + this.hubId);
  21125. var eventServiceHandler = this.eventSvr._subscribeEvent(this.eventSvr.WIDGETEVENT_PREFIX + this.hubId, this, "handleEvent", null, this.hubId);
  21126. if (!this._inIframe()) {
  21127. this.eventHandlers.push(eventServiceHandler);
  21128. }
  21129. },
  21130. execute: function() {
  21131. this._initialize(dojo.hitch(this, function(){
  21132. this._doRender();
  21133. }));
  21134. },
  21135. _initialize: function(callback) {
  21136. var lang = this.widgetDef.getDefaultLanguage();
  21137. if (typeof lang != "undefined" && lang !== null) {
  21138. this.defaultLanguage = lang;
  21139. }
  21140. else {
  21141. this.defaultLanguage = "en";
  21142. }
  21143. var aMode = this._getInitDefaultMode();
  21144. if (aMode === null) {
  21145. aMode = iwConstants.mode_view;
  21146. }
  21147. this.currentMode = aMode;
  21148. if (this._handleSaveMode) {
  21149. this._handleSaveMode();
  21150. }
  21151. this._initManagedItemSet();
  21152. if (callback) {
  21153. callback();
  21154. }
  21155. },
  21156. _getResourceBundle: function() {
  21157. return null;
  21158. },
  21159. _logUpdateMarkupError: function(mode) {
  21160. },
  21161. _getMarkupByMode: function(mode) {
  21162. var wInfo = this.widgetDef;
  21163. var elem = wInfo.getMarkupByMode(mode);
  21164. if (elem && elem.uri) {
  21165. var uri = this._rewriteURI(elem.uri);
  21166. dojo.xhrGet({
  21167. url: uri,
  21168. handleAs: "text",
  21169. sync: true,
  21170. load: function(result) {
  21171. if (result) {
  21172. var newElem = {};
  21173. newElem.content = result;
  21174. wInfo.setMarkupByMode(mode, newElem);
  21175. }
  21176. },
  21177. error: function(data, ioArgs) {
  21178. delete elem.uri;
  21179. }
  21180. });
  21181. }
  21182. var markup = null;
  21183. if (wInfo.getMarkupByMode(mode)) {
  21184. markup = wInfo.getMarkupByMode(mode).content;
  21185. }
  21186. return markup;
  21187. },
  21188. _updateTitle: function() {
  21189. // noop
  21190. },
  21191. _updateMarkup: function(mode, contentDiv) {
  21192. var markup = this._getMarkupByMode(mode);
  21193. if (mode == iwConstants.mode_view) {
  21194. if (this.widgetDef.getAllowInstanceContent()) {
  21195. var temp = this.getIWidgetInstance().getDefaultViewContent();
  21196. if (temp && temp !== null) {
  21197. markup = temp;
  21198. }
  21199. }
  21200. }
  21201. if (typeof markup == "undefined" || markup === null) {
  21202. this._logUpdateMarkupError(mode);
  21203. return true;
  21204. }
  21205. //parse the mark and replace iContext with _widgetid_iContext
  21206. var updatedMarkup = this._prepareMarkup(markup);
  21207. updatedMarkup = updatedMarkup.replace(/^\s+|\s+$/, '');
  21208. if (updatedMarkup.indexOf("<script") === 0) {
  21209. updatedMarkup = "&nbsp;" + updatedMarkup;
  21210. }
  21211. //append all the nodes to a temporary div element
  21212. var tempDIV = document.createElement("DIV");
  21213. tempDIV.innerHTML = updatedMarkup;
  21214. // find the script elements
  21215. var scriptElems = tempDIV.getElementsByTagName("script");
  21216. if (scriptElems !== null) {
  21217. // iterate over script elements and attach an id attribute ,
  21218. // this is necessary so if there's document.write, it got over written
  21219. // otherwise you will get a blank page!
  21220. for (var i = 0, l = scriptElems.length; i < l; i++) {
  21221. var scriptElem = scriptElems[i];
  21222. // include an id if there is none so far
  21223. // (needed to lookup script in original DOM later on)
  21224. var id = scriptElem.getAttribute("id");
  21225. if (id === null || id == "") {
  21226. scriptElem.setAttribute("id", "_scr#" + i);
  21227. }
  21228. }
  21229. }
  21230. // update the DOM before executing the scripts
  21231. // (the scripts might rely on elements in the DOM)
  21232. //var contentDiv = this.rootElement.lastChild;
  21233. contentDiv.innerHTML = tempDIV.innerHTML;
  21234. //destroy tempDiv
  21235. com.ibm.mm.enabler.utils.Dom.destroyNode(tempDIV);
  21236. return true;
  21237. },
  21238. _prepareMarkup: function(markup) {
  21239. var oldMarkup = markup.replace(/_IWID_/g, "_" + this.id + "_");
  21240. //?= is javascript 1.5 feature
  21241. var finalMarkup = oldMarkup.replace(/iContext(?=\.|\s|\(|\))/g, "_" + this.id + "_iContext");
  21242. return finalMarkup;
  21243. },
  21244. destroy: function() {
  21245. if (this.loaded && !this.isModal()) {
  21246. this._handleEventInternal(iwConstants.EVENTS.onUnLoad);
  21247. }
  21248. if (!this._inIframe()) {
  21249. var wireModel = this.getIWidgetInstance().getWireModel();
  21250. //remove any wires coming into this widget (any wires that this widget is a target of)
  21251. if (wireModel) {
  21252. var myWires = wireModel.getWires();
  21253. if (myWires) {
  21254. var j = myWires.length;
  21255. for (var k = j - 1; k >= 0; k--) {
  21256. var wireSourceID = myWires[k].getSourceWidgetID();
  21257. wireModel.removeWire(wireSourceID);
  21258. this.commit();
  21259. }
  21260. }
  21261. }
  21262. //remove any wires going out of this widget (any wires that this widget is a source of)
  21263. var targets = null;
  21264. if (wireModel) {
  21265. targets = wireModel.getTargets();
  21266. }
  21267. if (targets) {
  21268. var widgetModel = com.ibm.mashups.iwidget.model.Factory.getGlobalWidgetModel();
  21269. for (var i in targets) {
  21270. if (Object.prototype.hasOwnProperty.call(targets,i)) {
  21271. var widget = widgetModel.find(i);
  21272. if (widget) {
  21273. var wires = widget.getIWidgetInstance().getWireModel();
  21274. wires.removeWire(this.id); // remove all the wires that contains "this.id" as source
  21275. widget.commit();
  21276. }
  21277. }
  21278. }
  21279. }
  21280. for (var x in this.eventHandlers) {
  21281. if (Object.prototype.hasOwnProperty.call(this.eventHandlers,x)) {
  21282. this.eventSvr._unsubscribeEvent(this.eventHandlers[x], this.hubId);
  21283. }
  21284. }
  21285. this.eventSvr._getHubAdapter(this.hubId).removeInlineHubClient(this.hubId);
  21286. if (dojo.global["_" + this.id + "_" + "iContext"])//when iframe is removed,this could be null
  21287. {
  21288. dojo.global["_" + this.id + "_" + "iContext"]._destroy();
  21289. dojo.global["_" + this.id + "_" + "iContext"] = null;
  21290. }
  21291. }
  21292. else {
  21293. //delete dojo.global["_"+this.id+"_"+"iContext"]; //doesn't work on IE7, can't delete from global context
  21294. if (!this.isModal()) {
  21295. this.eventSvr.disconnectHubClient();
  21296. if (dojo.global["_" + this.id + "_" + "iContext"])//when iframe is removed,this could be null
  21297. {
  21298. dojo.global["_" + this.id + "_" + "iContext"] = null;
  21299. }
  21300. }
  21301. }
  21302. if (this.rootElement) {
  21303. this.rootElement = null;
  21304. }
  21305. if (this.windowManager) {
  21306. this.windowManager = null;
  21307. }
  21308. //notify target widget to removeWire
  21309. // #17713 destroy the widgetInstance
  21310. this.widgetInstance._destroy();
  21311. },
  21312. _doRender: function() {
  21313. //update the title
  21314. if (!this._inIframe()) {
  21315. this._updateTitle();
  21316. }
  21317. var tempDiv = document.createElement("div");
  21318. tempDiv.className = this.ns + "Content";
  21319. this.rootElement.appendChild(tempDiv);
  21320. var contentDiv = this.rootElement.lastChild;
  21321. dojo.addClass(contentDiv, this.currentMode);
  21322. contentDiv.style.visibility = "hidden";
  21323. if (this._inIframe()) {
  21324. dojo.style(contentDiv, "height", "100%");
  21325. }
  21326. //need to render default mode for modal dialog since some widgets will create dom in onload etc...
  21327. var defIDescriptor = this.widgetDef.getIDescriptorItems();
  21328. var defaultMode = defIDescriptor.getItemValue(iwConstants.iDescriptorItems.mode);
  21329. if (this.isModal() && this.currentMode != defaultMode) {
  21330. //create a div tag for main view
  21331. var tempDiv1 = document.createElement("div");
  21332. tempDiv1.className = this.ns + "Content";
  21333. this.rootElement.appendChild(tempDiv1);
  21334. contentDiv1 = this.rootElement.lastChild;
  21335. dojo.addClass(contentDiv1, defaultMode);
  21336. contentDiv1.style.visibility = "hidden";
  21337. contentDiv1.style.display = "none";
  21338. this._updateMarkup(defaultMode, contentDiv1);
  21339. }
  21340. this._updateMarkup(this.currentMode, contentDiv);
  21341. this._loadWidgetSharedResource(dojo.partial(this._finishRender, contentDiv, this));
  21342. },
  21343. _finishRender: function(contentDiv, wrapper) {
  21344. // Important for timing to subscribe to this event before loading widget
  21345. try {
  21346. var eventHandler = wrapper.eventSvr._subscribeEvent(com.ibm.mashups.iwidget.Constants.RESIZE_WIDGET + "." + wrapper.id, wrapper, "handleSizeChanged", null, wrapper.id);
  21347. wrapper.eventHandlers.push(eventHandler);
  21348. wrapper._createiScope();
  21349. //contentDiv = wrapper.rootElement?
  21350. wrapper._evalScripts(contentDiv);
  21351. wrapper.windowManager[wrapper.currentMode] = {
  21352. id: wrapper.currentMode,
  21353. root: contentDiv,
  21354. active: true,
  21355. external: false
  21356. };
  21357. // remove the iw-loading div
  21358. dojo.query("> ." + wrapper.ns + "loading", wrapper.rootElement).forEach(function(elem) {
  21359. com.ibm.mm.enabler.utils.Dom.destroyNode(elem);
  21360. });
  21361. wrapper.onLoad();
  21362. //now handle queued events if there's any
  21363. if (typeof wrapper._eventqueue != "undefined" && wrapper._eventqueue !== null) {
  21364. for (var event in wrapper._eventqueue) {
  21365. if (Object.prototype.hasOwnProperty.call(wrapper._eventqueue, event)) {
  21366. wrapper.handleEvent(wrapper._eventqueue[event]);
  21367. }
  21368. }
  21369. }
  21370. }catch(e){
  21371. return;
  21372. }
  21373. dojo.query("." + wrapper.currentMode, wrapper.rootElement).style({
  21374. "visibility": "" //display:"none" will make mode selector not displaying properly
  21375. //set visible will work funny in FF, the node will be visible even parent node is set to be invisible
  21376. });
  21377. },
  21378. _evalScripts: function(contentDiv) {
  21379. dojo.query("script",contentDiv).forEach(function(script) {
  21380. this._jsHandler.handle(script);
  21381. },this);
  21382. },
  21383. onLoad: function() {
  21384. if (!this.isModal()) { //no need to call onload anymore since it should already be initialized
  21385. this._handleEventInternal(iwConstants.EVENTS.onLoad);
  21386. }
  21387. //update state like onNavStateChanged
  21388. this.updateState();
  21389. //tell the stub widget is loaded
  21390. var iEvent = new com.ibm.mm.iwidget.IEventImpl("on" + this.currentMode,null,{oldMode:null});
  21391. this._handleEventInternal("on" + this.currentMode,iEvent);
  21392. this.loaded = true;
  21393. try {
  21394. //tell builder widget is loaded
  21395. dojo.publish(com.ibm.mashups.iwidget.Constants.WIDGET_LOADED + "." + this.id, [this.id]);
  21396. }
  21397. catch (e) {
  21398. //workaround
  21399. throw e;
  21400. }
  21401. this.eventSvr._publishEvent(com.ibm.mashups.iwidget.Constants.WIDGET_LOADED + "." + this.hubId, this.hubId);
  21402. },
  21403. updateState: function() {
  21404. return;
  21405. },
  21406. _getSimpleEventHandler: function(/*String*/eventName) {
  21407. if (this.simpleWidgetEvents && typeof this.simpleWidgetEvents[eventName] != "undefined") {
  21408. return this.simpleWidgetEvents[eventName];
  21409. }
  21410. var handler = this.widgetDef.getWidgetEvents()[eventName];
  21411. if (!handler) {
  21412. handler = eventName;
  21413. }
  21414. var scope = this._getHandlerScope(handler);
  21415. var handlerObj = null;
  21416. if (scope) {
  21417. handlerObj = dojo.hitch(scope, handler);
  21418. this.simpleWidgetEvents[eventName] = handlerObj;
  21419. }
  21420. else if (handler.indexOf("on") === 0) {
  21421. //get Uppercase event like onedit --> onEdit
  21422. var newhandler = "on" + handler.substr(2, 1).toUpperCase() + handler.substr(3);
  21423. if (newhandler != handler) {
  21424. scope = this._getHandlerScope(newhandler);
  21425. if (scope) {
  21426. handlerObj = dojo.hitch(scope, newhandler);
  21427. this.simpleWidgetEvents[eventName] = handlerObj;
  21428. }
  21429. }
  21430. }
  21431. return handlerObj;
  21432. },
  21433. _getHandlerScope: function(/*String*/handler) {
  21434. //returns a global function or scope object
  21435. var fn = dojo.global["_" + this.id + "_" + handler];
  21436. if (typeof(fn) == "undefined") {
  21437. var widgetScope = dojo.global["_" + this.id + "_iContext"].iScope();
  21438. if (widgetScope && widgetScope[handler]) {
  21439. fn = widgetScope;
  21440. }
  21441. }
  21442. if (typeof fn == "undefined" || fn === null) {
  21443. fn = dojo.global[handler];
  21444. }
  21445. if (typeof fn == "undefined" || fn === null) {
  21446. return null;
  21447. }
  21448. else {
  21449. return fn;
  21450. }
  21451. },
  21452. handleEvent: function(payload) {
  21453. //event handler that subscribes to event handler
  21454. var declaredClass = payload.declaredClass;
  21455. if (declaredClass == "com.ibm.mm.iwidget.IEventImpl") {
  21456. var eventName = payload.name;
  21457. return this._handleEvent(eventName, payload);
  21458. }
  21459. },
  21460. _handleEvent: function(eventName, iEvent) {
  21461. iEvent = this._deserializePayload(iEvent);
  21462. //check here. it's just one payload with {eventName,iEvent}
  21463. if (typeof eventName == "undefined" || eventName === null) {
  21464. return false;
  21465. }
  21466. if (!this.loaded) {
  21467. if (!this._eventqueue) {
  21468. this._eventqueue = {};
  21469. }
  21470. this._eventqueue[eventName] = iEvent;
  21471. return;
  21472. }
  21473. //handle onModeChanged event
  21474. try {
  21475. /* if (eventName == iwConstants.EVENTS.onNavStateChanged) {
  21476. return this._handleOnNavStateChanged(iEvent);
  21477. } */
  21478. if (eventName == iwConstants.EVENTS.onModeChanged) {
  21479. if (this._inIframe()) {
  21480. //publish event to stub widget
  21481. var payloadObj = {};
  21482. payloadObj.methodname = "_handleOnModeChange";
  21483. payloadObj.hubclient = this.hubId;
  21484. payloadObj.params = [iEvent.payload];
  21485. //var id = "_stub_"+this.id.slice(0,this.id.lastIndexOf("_"));
  21486. var id = "_stub_" + this.id;
  21487. this.eventSvr._publishEvent(iwConstants.WIDGETEVENT_PREFIX + id, payloadObj, this.hubId);
  21488. return;
  21489. }
  21490. return this._handleModeChange(iEvent);
  21491. }
  21492. return this._handleEventInternal(eventName, iEvent);
  21493. }
  21494. catch (e) {
  21495. throw e;
  21496. }
  21497. },
  21498. _deserializePayload: function(iEvent) {
  21499. // complex payload objects must be deserialized from json for case when widgets are sandboxed
  21500. // to be serializable, complex payload objects must implement toJson method that returns json in format {"className":"x","json":"y"}
  21501. // to be deserializable, complex payload objects must have a constructor with an argument that accepts the "y" json value returned from toJson
  21502. if (typeof iEvent.payload == 'string' && iEvent.payload.indexOf("className") != -1 && iEvent.payload.indexOf("json") != -1) {
  21503. try {
  21504. var deserialized = dojo.fromJson(iEvent.payload);
  21505. if (deserialized.className && typeof deserialized.className == 'string' && deserialized.className.length > 0 && deserialized.json && typeof deserialized.json == 'string') {
  21506. var deserialized_payload = deserialized.json;
  21507. // check if this is a table object that requires an additional deserialization of its payload before it is instanciated as a table - 15594
  21508. if (deserialized.className=="com.ibm.mm.data.table" && deserialized_payload.indexOf("data") != -1) {
  21509. deserialized_payload = dojo.fromJson(deserialized_payload);
  21510. }
  21511. iEvent.payload = new (dojo.getObject(deserialized.className))(deserialized_payload);
  21512. }
  21513. }
  21514. catch (e) {
  21515. throw e;
  21516. }
  21517. }
  21518. return iEvent;
  21519. },
  21520. _handleOnModeChange: function(newMode) {
  21521. var aEvent = new com.ibm.mm.iwidget.IEventImpl("onModeChanged", null, {
  21522. newMode: newMode
  21523. }, null);
  21524. this._handleModeChange(aEvent);
  21525. },
  21526. _handleModeChange: function(iEvent) {
  21527. var isHandled = false;
  21528. var oldMode = this.currentMode;
  21529. var payload = iEvent.payload;
  21530. if (typeof payload == "undefined" || payload === null) {
  21531. return false;
  21532. }
  21533. if (dojo.isString(payload)) {
  21534. payload = dojo.fromJson(payload);
  21535. }
  21536. if (typeof payload == "undefined" || payload === null) {
  21537. return false;
  21538. }
  21539. var newMode = payload.newMode || null;
  21540. var newRoot = payload.rootElementId || null;
  21541. // support one active mode only, thus don't support this operation
  21542. if (newMode !== null && newMode == this.currentMode) {
  21543. return false;
  21544. }
  21545. if (newMode === null) {
  21546. return false;
  21547. }
  21548. var external = newRoot !== null;
  21549. var updatedNewRoot = newRoot;
  21550. var defaultMode = this._getDefaultMode();
  21551. if (!defaultMode) {
  21552. defaultMode = "view";
  21553. }
  21554. var oldWindow = this.windowManager[newMode] || null;
  21555. // make sure that we only make default logic if the widget was launched with default mode
  21556. if (this._inIframe() && oldWindow !== null && defaultMode == newMode) {
  21557. //swtich back to view mode
  21558. this.currentMode = newMode;
  21559. if (this._handleSaveMode) {
  21560. this._handleSaveMode();
  21561. }
  21562. // update newMode window state
  21563. this.windowManager[newMode].active = true;
  21564. if (updatedNewRoot !== null) {
  21565. this.windowManager[newMode].root = updatedNewRoot;
  21566. }
  21567. dojo.style(this.windowManager[newMode].root, "display", "");
  21568. // update oldMode window state
  21569. var oldModeWindow = this.windowManager[oldMode];
  21570. oldModeWindow.active = false;
  21571. if (oldModeWindow.root) {
  21572. dojo.style(oldModeWindow.root, "display", "none");
  21573. }
  21574. this._handleOnModeEvent(newMode,oldMode);
  21575. return;
  21576. }
  21577. //change:e
  21578. var isWindowAvailable = false;
  21579. if (typeof oldWindow != "undefined" && oldWindow !== null) {
  21580. var oldRoot = oldWindow.root;
  21581. if (!oldWindow.external && oldRoot !== null && newRoot === null) {
  21582. updatedNewRoot = oldRoot;
  21583. isWindowAvailable = true;
  21584. isHandled = true;
  21585. //how to verify a node doesn't exist anymore?
  21586. // turn on this window
  21587. dojo.style(oldRoot, "display", "");
  21588. }
  21589. }
  21590. //create new window and update markup
  21591. if (!isWindowAvailable) {
  21592. if (updatedNewRoot === null) {
  21593. var tempDiv = document.createElement("div");
  21594. tempDiv.className = this.ns + "Content";
  21595. this.rootElement.appendChild(tempDiv);
  21596. updatedNewRoot = this.rootElement.lastChild;
  21597. dojo.addClass(updatedNewRoot, newMode);
  21598. }
  21599. isHandled = this._updateMarkup(newMode, updatedNewRoot);
  21600. }
  21601. if (isHandled) {
  21602. //hide current view
  21603. var currentWindow = this.windowManager[this.currentMode];
  21604. var currentRoot = currentWindow.root;
  21605. if (currentWindow.external) {
  21606. dojo.style(currentRoot, "display", "none");//todo, destroy external window?
  21607. this.windowManager[this.currentMode] = null;
  21608. }
  21609. else if (newRoot !== null) { //if the newRoot is provided, don't hide current window. leave builder to do this.
  21610. currentWindow.active = false;
  21611. }
  21612. else {
  21613. currentWindow.active = false;
  21614. dojo.style(currentRoot, "display", "none");
  21615. }
  21616. //change current mode
  21617. oldMode = this.currentMode;
  21618. this.currentMode = newMode;
  21619. if (this._handleSaveMode) {
  21620. this._handleSaveMode();
  21621. }
  21622. // save/reset new window
  21623. this.windowManager[newMode] = {
  21624. id: newMode,
  21625. root: updatedNewRoot,
  21626. active: true,
  21627. external: external
  21628. };
  21629. if (!isWindowAvailable) {
  21630. this._evalScripts(updatedNewRoot);
  21631. }
  21632. this._handleOnModeEvent(newMode,oldMode);
  21633. }
  21634. if (isHandled && !this._inIframe()) {
  21635. dojo.publish(iwConstants.EVENTS.modeChanged, [this.id, oldMode, newMode]);
  21636. payload = {};
  21637. payload.id = this.id;
  21638. payload.oldMode = oldMode;
  21639. payload.newMode = newMode;
  21640. this.eventSvr._publishEvent(com.ibm.mashups.iwidget.Constants.WIDGET_MODECHANGED, payload, this.hubId);
  21641. }
  21642. if (this._inIframe()) {
  21643. //switch from view -->edit very rare use case since mode switch are triggered from skin
  21644. //just tell stub mode is updated
  21645. var payloadObj = {};
  21646. payloadObj.methodname = "_handleOnModeUpdated";
  21647. payloadObj.hubclient = this.hubId;
  21648. payloadObj.params = [iEvent.payload];
  21649. //var id = "_stub_"+this.id.slice(0,this.id.lastIndexOf("_"));
  21650. var id = "_stub_" + this.id;
  21651. this.eventSvr._publishEvent(iwConstants.WIDGETEVENT_PREFIX + id, payloadObj, this.hubId);
  21652. }
  21653. return isHandled;
  21654. },
  21655. _handleOnModeUpdated: function(mode) {
  21656. var newMode = mode.newMode || mode;
  21657. // in case we get the update for the mode we are already in, don't switch
  21658. if (newMode == this.currentMode) {
  21659. return;
  21660. }
  21661. this.currentMode = newMode;
  21662. if (this._handleSaveMode) {
  21663. this._handleSaveMode();
  21664. }
  21665. this.windowManager[newMode] = {
  21666. id: this.id,
  21667. active: true,
  21668. external: true
  21669. };
  21670. },
  21671. _handleOnModeEvent: function(mode,oldMode) {
  21672. if (this._inIframe()) {
  21673. dojo.setContext(com.ibm.mashups.iwidget.model.Factory.getGlobalWidgetModel().global, com.ibm.mashups.iwidget.model.Factory.getGlobalWidgetModel().doc);
  21674. if (dojo.isIE) {
  21675. if (document._mmcreateElement) {
  21676. document.createElement = document._mmcreateElement;
  21677. }
  21678. if (document._mmgetElementsByTagName) {
  21679. document.getElementsByTagName = document._mmgetElementsByTagName;
  21680. }
  21681. }
  21682. }
  21683. var isHandled = false;
  21684. //handle event
  21685. var eventName = "on" + mode;
  21686. if (!oldMode) {
  21687. oldMode = null;
  21688. }
  21689. var iEvent = new com.ibm.mm.iwidget.IEventImpl(eventName,null,{oldMode:oldMode});
  21690. isHandled = this._handleEventInternal(eventName,iEvent);
  21691. return isHandled;
  21692. },
  21693. _handleEventInternal: function(/*String*/eventName, iEvent) {
  21694. if (typeof eventName == "undefined" || eventName === null) {
  21695. return false;
  21696. }
  21697. var isHandled = false;
  21698. var handlerFn = null;
  21699. if (eventName.indexOf("on") === 0) {
  21700. var eventHandler = this._getSimpleEventHandler(eventName);
  21701. if (eventHandler !== null) {
  21702. handlerFn = eventHandler;
  21703. }
  21704. }
  21705. if (handlerFn === null) {
  21706. handlerFn = this.getPublicEventHandler(eventName);
  21707. }
  21708. if (dojo.isFunction(handlerFn)) {
  21709. try {
  21710. if (iEvent) {
  21711. //transform data if necessary
  21712. if (this._transform) {
  21713. iEvent = this._transform(eventName, iEvent);
  21714. }
  21715. dojo.partial(handlerFn)(iEvent);
  21716. }
  21717. else {
  21718. dojo.partial(handlerFn)();
  21719. }
  21720. }
  21721. catch (e) {
  21722. throw e;
  21723. }
  21724. isHandled = true;
  21725. }
  21726. return isHandled;
  21727. },
  21728. getPublicEventHandler: function(/*String|Function*/eventName) {
  21729. return null;
  21730. },
  21731. _getParent: function() {
  21732. if (!this.parent) {
  21733. this.parent = com.ibm.mm.iwidget.Utils.getWidgetParent(this.rootElement);
  21734. }
  21735. this.parent = this.parent || null;
  21736. return this.parent;
  21737. },
  21738. _setParent: function(parent) {
  21739. this.parent = parent;
  21740. },
  21741. getAttributes: function() {
  21742. //Summary: returns an ManagedItemSet which provides access to the iWidget's customization attributes.
  21743. // The returned ManagedItemSet will be teh same as getItemSet(iContext.constants.itemset.ATTRIBUTES).
  21744. // returns empty set if there's no ItemSet.Return null if iWidget customization attributes is not
  21745. // supported
  21746. if (!this.widgetAttributes) {
  21747. var service = com.ibm.mashups.services.ServiceManager.getService("persistentAttributesFactoryService");
  21748. this.widgetAttributes = new com.ibm.mm.iwidget.manageditemset.AttributesModeDelegate(service, this);
  21749. }
  21750. return this.widgetAttributes;
  21751. },
  21752. getWidgetItemSets: function() {
  21753. if (this.widgetItemSets) {
  21754. return this.widgetItemSets;
  21755. }
  21756. this.widgetItemSets = {};
  21757. if (this.widgetDef) {
  21758. var names = this.widgetDef.getAllItemSetNames();
  21759. for (var i = 0, l = names.length; i < l; i++) {
  21760. var id = names[i];
  21761. var itemSetWrapper = this.widgetDef.getItemSet(id);
  21762. var anItemSet = new com.ibm.mm.iwidget.itemset.ItemSetDefaultImpl(this, itemSetWrapper, id);
  21763. this.widgetItemSets[id] = anItemSet;
  21764. }
  21765. }
  21766. return this.widgetItemSets;
  21767. },
  21768. getWidgetItemSet: function(/*String*/name) {
  21769. var widgetItemSets = this.getWidgetItemSets();
  21770. var rtnVal = null;
  21771. if (widgetItemSets) {
  21772. rtnVal = widgetItemSets[name];
  21773. if (!rtnVal) {
  21774. rtnVal = new com.ibm.mm.iwidget.itemset.ItemSetDefaultImpl(this, null, name);
  21775. this.widgetItemSets[name] = rtnVal;
  21776. }
  21777. }
  21778. return rtnVal;
  21779. },
  21780. _loadWidgetSharedResource: function(cb2) {
  21781. if (cb2) {
  21782. cb2();
  21783. }
  21784. },
  21785. _createiScope: function() {
  21786. if (!this.isModal()) {
  21787. var iScope = this.widgetDef.getIScope();
  21788. var iScopeInstance = null;
  21789. if (typeof iScope != "undefined" && iScope !== null) {
  21790. try {
  21791. iScopeInstance = new (dojo.getObject(iScope))();
  21792. }
  21793. catch (err) {
  21794. }
  21795. }
  21796. this.iScope = iScopeInstance ||
  21797. {};
  21798. dojo.global["_" + this.id + "_iContext"].scope = this.iScope;
  21799. this._executeCallbackQueue();
  21800. }
  21801. else {
  21802. this.iScope = dojo.global["_" + this.id + "_iContext"].scope;
  21803. }
  21804. this.iScope.iContext = dojo.global["_" + this.id + "_iContext"];
  21805. },
  21806. getIDescriptorItems: function() {
  21807. if (this.iDescriptor) {
  21808. return this.iDescriptor;
  21809. }
  21810. //read only for now
  21811. this.iDescriptor = new com.ibm.mm.iwidget.manageditemset.IDescriptorImpl(this, this.widgetDef.getIDescriptorItems(), this.getIWidgetInstance().getIDescriptorItems());
  21812. return this.iDescriptor;
  21813. },
  21814. _getInitDefaultMode:function(){
  21815. if (this._getModeFromNavStateModel) {
  21816. var aMode = this._getModeFromNavStateModel();
  21817. if (typeof aMode != "undefined" && aMode !== null) {
  21818. return aMode;
  21819. }
  21820. }
  21821. return this._getDefaultMode();
  21822. },
  21823. _getDefaultMode: function() {
  21824. var instanceIDescriptor = this.getIWidgetInstance().getIDescriptorItems();
  21825. if (typeof instanceIDescriptor != "undefined" && instanceIDescriptor !== null) {
  21826. var instanceItem = instanceIDescriptor.getItemValue(iwConstants.iDescriptorItems.mode);
  21827. if (instanceItem) {
  21828. return instanceItem;
  21829. }
  21830. }
  21831. var defIDescriptor = this.widgetDef.getIDescriptorItems();
  21832. var defItem = null;
  21833. if (typeof defIDescriptor != "undefined" && defIDescriptor !== null) {
  21834. defItem = defIDescriptor.getItemValue(iwConstants.iDescriptorItems.mode);
  21835. }
  21836. return defItem || null;
  21837. },
  21838. _getMarkup: function(includeParent) {
  21839. //returning Markup to proxy widget stub
  21840. var that = this;
  21841. var cb = function(node, status) {
  21842. that.eventSvr._publishEvent(that.eventSvr.WIDGETEVENT_PREFIX + that.id + ".onMarkupReturned", node);
  21843. };
  21844. var deferred = this.getMarkup();
  21845. deferred.setIncludeParent(includeParent);
  21846. deferred.setFinishedCallback(cb);
  21847. deferred.start();
  21848. },
  21849. _inIframe: function() {
  21850. return false;
  21851. },
  21852. commit: function(noSync) {
  21853. var widgetInstance = this.getIWidgetInstance();
  21854. var instanceAttributes = null;
  21855. if (this._inIframe() && !noSync) { //if it's within iframe, synchronize all the data change...
  21856. //send attributes/wiremodel to the stub for now...
  21857. var dataObj = {};
  21858. instanceAttributes = widgetInstance.getAttributes();
  21859. if (instanceAttributes && instanceAttributes._isDirty()) {
  21860. dataObj.attributes = dojo.clone(instanceAttributes.toJson());
  21861. }
  21862. var wireModel = widgetInstance.getWireModel();
  21863. if (wireModel && wireModel.isDirty()) {
  21864. dataObj.wiremodel = wireModel.toJson();
  21865. }
  21866. var payloadObj = {};
  21867. payloadObj.methodname = "_handleDataSync";
  21868. payloadObj.hubclient = this.hubId;
  21869. payloadObj.params = [dataObj];
  21870. //send any updates to stub widget first
  21871. var id = "_stub_" + this.id;
  21872. this.eventSvr._publishEvent(iwConstants.WIDGETEVENT_PREFIX + id, payloadObj, this.hubId);
  21873. //here's the flow main dialog -- stub
  21874. return;
  21875. }
  21876. // need to check attribute properties and idescriptor attributes
  21877. instanceAttributes = widgetInstance.getAttributes();
  21878. if (instanceAttributes && instanceAttributes._isDirty()) {
  21879. //source onItemSetChanged to the widget
  21880. this._notifyWidget(this, "attributes", instanceAttributes);
  21881. this._writePropertiesToDOM(this, "attributes", instanceAttributes);
  21882. instanceAttributes._setDirty(false);
  21883. }
  21884. var instanceIDescriptor = widgetInstance.getIDescriptorItems();
  21885. if (instanceIDescriptor && instanceIDescriptor._isDirty()) {
  21886. //source onItemSetChanged to the widget
  21887. this._notifyWidget(this, "idescriptor", instanceIDescriptor);
  21888. this._writePropertiesToDOM(this, "idescriptor", instanceIDescriptor);
  21889. instanceIDescriptor._setDirty(false);
  21890. }
  21891. //check wires
  21892. var wiremodel = widgetInstance.getWireModel();
  21893. if (wiremodel && wiremodel.isDirty()) {
  21894. wiremodel.commit();
  21895. }
  21896. },
  21897. _writePropertiesToDOM: function(widgetWrapper, itemSetName, properties) {
  21898. var ns = widgetWrapper.ns;
  21899. var root = widgetWrapper.rootElement;
  21900. // query the markup for the given itemSetName
  21901. var itemSets = dojo.query('span.' + ns + 'ItemSet[title="' + itemSetName + '"]', root);
  21902. // iterate through the itemsets and delete those that are already inside of the markup
  21903. for (var i = 0, l = itemSets.length; i < l; i++) {
  21904. var itemSet = itemSets[i];
  21905. if (root == itemSet.parentNode) {
  21906. root.removeChild(itemSet);
  21907. }
  21908. }
  21909. // create the new ItemSet span
  21910. var newItemSet = document.createElement("span");
  21911. newItemSet.className = ns + 'ItemSet';
  21912. newItemSet.title = itemSetName;
  21913. newItemSet.style.display = "none";
  21914. newItemSet.style.visibility = "hidden";
  21915. // append it to the DOM
  21916. root.appendChild(newItemSet);
  21917. var names = properties.getAllNames();
  21918. if (!names) {
  21919. return;
  21920. }
  21921. // iterate through all the items in the itemset
  21922. for (var k = 0, l2 = names.length; k < l2; k++) {
  21923. var itemName = names[k];
  21924. var newItem = document.createElement("a");
  21925. newItem.className = ns + 'Item';
  21926. newItem.style.visibility = "hidden";
  21927. newItem.style.display = "none";
  21928. newItem.href = "#" + itemName;
  21929. // read only ? --todo, not spec compliant
  21930. if (properties.isReadOnly(itemName)) {
  21931. dojo.addClass(newItem, ns + "ReadOnly");
  21932. }
  21933. var locales = properties.getItemLocales(itemName);
  21934. if (!locales || (locales !== null && locales.length == 1 && locales[0] == "")) {
  21935. var value = properties.getItemValue(itemName);
  21936. if (value) {
  21937. newItem.appendChild(document.createTextNode(value));
  21938. }
  21939. newItemSet.appendChild(newItem);
  21940. }
  21941. else if (locales !== null) {
  21942. var defaultLocale = properties._getItemDefaultLocale(itemName);
  21943. if (!defaultLocale) {
  21944. defaultLocale = properties.DEFAULT_LOCALE; // this is not as nice as it should be
  21945. }
  21946. // create the new Element
  21947. newItem.setAttribute("lang", defaultLocale);
  21948. for (var j = 0; j < locales.length; j++) {
  21949. var langSpan = document.createElement("span");
  21950. langSpan.setAttribute("class", ns + "Value");
  21951. langSpan.setAttribute("lang", locales[j]);
  21952. var langValue = properties.getItemValue(itemName, locales[j]);
  21953. langSpan.appendChild(document.createTextNode(langValue));
  21954. newItem.appendChild(langSpan);
  21955. }
  21956. // append it to the itemset Span
  21957. newItemSet.appendChild(newItem);
  21958. }
  21959. }
  21960. },
  21961. _notifyWidget: function(widgetwrapper, itemsetname, properties) {
  21962. var names = properties.getAllNames();
  21963. if (!names) {
  21964. return;
  21965. }
  21966. var payload = {};
  21967. payload.itemSetName = itemsetname;
  21968. payload.changes = [];
  21969. // iterate through all the items in the itemset
  21970. for (var i = 0, l = names.length; i < l; i++) {
  21971. var itemName = names[i];
  21972. if (properties._isItemDirty && properties._isItemDirty(itemName)) {
  21973. var value = properties._getInternalItemValue(itemName);
  21974. if (value && value._change) {
  21975. var _change = dojo.clone(value._change);
  21976. if (_change.newVal) {
  21977. _change.newVal = properties._getRequiredValue(_change.newVal);
  21978. }
  21979. if (_change.oldVal) {
  21980. _change.oldVal = properties._getRequiredValue(_change.oldVal);
  21981. }
  21982. payload.changes.push(_change);
  21983. }
  21984. properties._setItemDirty(itemName, false);
  21985. }
  21986. }
  21987. var listeners = this._getListeners(itemsetname);
  21988. for (var x in listeners) {
  21989. if (Object.prototype.hasOwnProperty.call(listeners,x)) {
  21990. listeners[x](payload);
  21991. }
  21992. }
  21993. },
  21994. isModal: function() {
  21995. //indicate if this is an iframe rendered in a modal dialog
  21996. //return this._isModal? this._isModal:false;
  21997. return false;
  21998. },
  21999. isLoaded: function() {
  22000. return this.loaded;
  22001. },
  22002. isStandalone: function() {
  22003. if (this.standalone === null) {
  22004. this.standalone = dojo.hasClass(this.rootElement,
  22005. com.ibm.mm.iwidget.Constants.CSSCLASS_PREFIXED_INSTANCE.iwStandalone);
  22006. }
  22007. return this.standalone;
  22008. },
  22009. handleSizeChanged: function(payload) {
  22010. if (payload.newWidth) {
  22011. this.width = payload.newWidth;
  22012. }
  22013. if (payload.newHeight) {
  22014. this.height = payload.newHeight;
  22015. }
  22016. var aEvent = new com.ibm.mm.iwidget.IEventImpl(iwConstants.EVENTS.onSizeChanged, null, payload, null);
  22017. this._handleEvent(iwConstants.EVENTS.onSizeChanged, aEvent);
  22018. },
  22019. _isEmpty: function(obj) {
  22020. return com.ibm.mm.enabler.utils.Misc.isEmpty(obj);
  22021. },
  22022. _getListeners: function(itemSetName) {
  22023. //only iwConstants.ATTRIBUTES && iwConstants.IDESCRIPTOR
  22024. if (!this.listenerManager) {
  22025. return null;
  22026. }
  22027. if (!this.listenerManager[itemSetName]) {
  22028. return null;
  22029. }
  22030. return this.listenerManager[itemSetName];
  22031. },
  22032. _registerListener: function(itemSetName, fn) {
  22033. if (!this.listenerManager) {
  22034. this.listenerManager = {};
  22035. }
  22036. this.listenerManager[itemSetName] = this.listenerManager[itemSetName] ? this.listenerManager[itemSetName] : {};
  22037. var listenerId = this._generateListenerId();
  22038. var me = this;
  22039. var listener = function(payload) {
  22040. var changes = payload.changes ? payload.changes : null;
  22041. if (changes.length > 0) {
  22042. var iEvent = new com.ibm.mm.iwidget.IEventImpl("onItemSetChanged", null, payload);
  22043. if (dojo.isString(fn)) {
  22044. var scope = me._getHandlerScope(fn);
  22045. if (scope) {
  22046. fn = dojo.hitch(scope, fn);
  22047. }
  22048. }
  22049. if (dojo.isFunction(fn)) {
  22050. dojo.partial(fn)(iEvent);
  22051. }
  22052. }
  22053. };
  22054. this.listenerManager[itemSetName][listenerId] = listener;
  22055. return listenerId;
  22056. },
  22057. _removeListener: function(itemSetName, id) {
  22058. if (!itemSetName || typeof id == "undefined" || id === null) {
  22059. return false;
  22060. }
  22061. if (!this.listenerManager) {
  22062. return false;
  22063. }
  22064. if (!this.listenerManager[itemSetName]) {
  22065. return false;
  22066. }
  22067. if (this.listenerManager[itemSetName][id]) {
  22068. delete this.listenerManager[itemSetName][id];
  22069. return true;
  22070. }
  22071. return false;
  22072. },
  22073. _generateListenerId: function() {
  22074. if (typeof this._listenerCt == "undefined") {
  22075. this._listenerCt = 0;
  22076. }
  22077. else {
  22078. this._listenerCt++;
  22079. }
  22080. return this._listenerCt;
  22081. },
  22082. _initManagedItemSet: function() { //register listener for idescriptor and attributes
  22083. var listener = null;
  22084. if (typeof(this.widgetDef) != "undefined") {
  22085. listener = this.widgetDef._getManagedItemSetListener(iwConstants.ATTRIBUTES);
  22086. if (listener !== null) {
  22087. this._registerListener(iwConstants.ATTRIBUTES, listener);
  22088. }
  22089. listener = this.widgetDef._getManagedItemSetListener(iwConstants.IDESCRIPTOR);
  22090. if (listener !== null) {
  22091. this._registerListener(iwConstants.IDESCRIPTOR, listener);
  22092. }
  22093. }
  22094. },
  22095. _getRawUri:function(){
  22096. var rawUri = this.getIWidgetInstance().widgetXMLUrl;
  22097. if (this.widgetDef.getXmlBase()) {
  22098. rawUri = this.widgetDef.getXmlBase();
  22099. }
  22100. return rawUri;
  22101. },
  22102. _initBaseUri:function(rawUri){
  22103. if (!rawUri) {
  22104. return;
  22105. }
  22106. this.rawBaseUri = this._getRawBaseUri(rawUri);
  22107. this.widgetBaseUri = this._getResolvedPocUri(this.rawBaseUri);
  22108. this.widgetBaseUriXhr = this._getXhrUri(this.widgetBaseUri);
  22109. if (this.rawBaseUri.indexOf(":/") != -1) {
  22110. var serverRoot = this._getServerRoot(this.rawBaseUri);
  22111. if (serverRoot) {
  22112. this.serverRoot = this._getResolvedPocUri(serverRoot);
  22113. this.serverRootXhr = this._getXhrUri(this.serverRoot);
  22114. }
  22115. }
  22116. },
  22117. _rewriteURI: function(/*String*/uri, isXhr) {
  22118. if (!this.widgetBaseUri) {
  22119. var rawUri = this._getRawUri();
  22120. this._initBaseUri(rawUri);
  22121. }
  22122. return this._rewriteURIWithContext(uri,isXhr,this.widgetBaseUri,this.widgetBaseUriXhr,this.serverRoot,this.serverRootXhr);
  22123. },
  22124. _rewriteURIWithContext:function(uri,isXhr,widgetBaseUri,widgetBaseUriXhr,serverRoot,serverRootXhr) {
  22125. if (typeof isXhr == "undefined") {
  22126. isXhr = true;
  22127. }
  22128. var uri2 = com.ibm.mm.enabler.EndpointUtils.checkForEndpoints(uri);
  22129. if (uri2) {
  22130. uri = uri2;
  22131. }
  22132. var returnUri = uri;
  22133. var pathQuery, encPath;
  22134. if (isXhr) {
  22135. if (uri.indexOf(":/") != -1) { //valid schema is defined. absolute url
  22136. returnUri = com.ibm.mm.enabler.utils.URLHelper.rewriteURL(uri);
  22137. }
  22138. else if (serverRootXhr !== null && uri.indexOf(serverRootXhr) === 0) {
  22139. // seems the uri is already rewritten, so reuse it
  22140. returnUri = uri;
  22141. }
  22142. else {
  22143. pathQuery = uri.split("?"); // split the query
  22144. encPath = com.ibm.mm.enabler.utils.Misc.encodePath(pathQuery[0]);
  22145. returnUri = encPath;
  22146. if (uri.indexOf("/") === 0) { //fullpath eg. /accuWeather/accuWeather.js
  22147. if (serverRootXhr) {
  22148. returnUri = serverRootXhr + encPath.substring(1);
  22149. }
  22150. }
  22151. else {
  22152. if (widgetBaseUriXhr){
  22153. returnUri = widgetBaseUriXhr + encPath;
  22154. }
  22155. }
  22156. if (pathQuery.length == 2) {
  22157. returnUri += "?" + pathQuery[1];
  22158. }
  22159. }
  22160. }
  22161. else {
  22162. if (uri.indexOf(":/") === -1) { //not absolute path
  22163. pathQuery = uri.split("?"); // split the query
  22164. encPath = com.ibm.mm.enabler.utils.Misc.encodePath(pathQuery[0]);
  22165. if (uri.indexOf("/") === 0) { //fullpath
  22166. if (serverRoot) {
  22167. returnUri = serverRoot + encPath.substring(1);
  22168. }
  22169. }
  22170. else { //relative path
  22171. if (widgetBaseUri) {
  22172. returnUri = widgetBaseUri + encPath;
  22173. }
  22174. }
  22175. if (pathQuery.length === 2) {
  22176. returnUri += "?" + pathQuery[1];
  22177. }
  22178. }
  22179. }
  22180. return returnUri;
  22181. },
  22182. _getRawBaseUri:function(rawUri){
  22183. if (!rawUri) {
  22184. return null;
  22185. }
  22186. //don't solve res:/ here so server root can be figured out correctly
  22187. var queryStart = rawUri.indexOf("?");
  22188. if (0 < queryStart) {
  22189. rawUri = rawUri.substring(0, queryStart);
  22190. }
  22191. var uri2 = com.ibm.mm.enabler.EndpointUtils.checkForEndpoints(rawUri);
  22192. if (uri2) {
  22193. rawUri = uri2;
  22194. }
  22195. var rc = rawUri.substring(0, rawUri.lastIndexOf("/") + 1);
  22196. return rc;
  22197. },
  22198. _getResolvedPocUri:function(rawUri){
  22199. //solve res:/ to be the correct one
  22200. if (!rawUri) {
  22201. return null;
  22202. }
  22203. var rc = rawUri;
  22204. if (com.ibm.mm.enabler.utils.Misc.isPocUrl(rawUri) === true){
  22205. rc = com.ibm.mm.enabler.utils.URLHelper.rewriteURL(rawUri);
  22206. }
  22207. return rc;
  22208. },
  22209. _getXhrUri:function(baseUri){
  22210. if (!baseUri) {
  22211. return null;
  22212. }
  22213. var rc = baseUri;
  22214. if (baseUri.indexOf("/") !== 0) {
  22215. rc = com.ibm.mm.enabler.utils.URLHelper.rewriteURL(baseUri);
  22216. }
  22217. return rc;
  22218. },
  22219. _getServerRoot:function(rawUri){
  22220. if (!rawUri) {
  22221. return null;
  22222. }
  22223. if (rawUri.indexOf(":/") == -1) {
  22224. return null;
  22225. }
  22226. var serverRoot = null;
  22227. var indexOfScheme = rawUri.indexOf(":/");
  22228. serverRoot = rawUri.substring(0, indexOfScheme + 2); // value is "http:/" or "res:/"
  22229. if (rawUri.indexOf(":///") !== -1) {
  22230. serverRoot = rawUri.substring(0, indexOfScheme + 4); // "res:///" or "file:///"
  22231. }
  22232. else if (rawUri.indexOf("://") !== -1) { //http://www.ibm.com/
  22233. var indexOfRoot = rawUri.indexOf("/", indexOfScheme + 4);
  22234. serverRoot = rawUri.substring(0, indexOfRoot + 1); // "http://myhost/"
  22235. }
  22236. return serverRoot;
  22237. },
  22238. _executeCallbackQueue: function() {
  22239. return;
  22240. },
  22241. // used by other classes within implementation
  22242. _getCurrentMode: function() {
  22243. return this.currentMode;
  22244. }
  22245. });
  22246. com.ibm.mm.iwidget.widget.IWidgetWrapperImpl = com.ibm.mm.iwidget.widget.IWidgetWrapperDefaultImpl;
  22247. // IMPORTANT
  22248. // ibmConfig.enablerLayerModules is a comma separated string of all supported modules at runtime
  22249. // This section dynamically loads the Extended representation when the variable enablerLayerModules contains the given module
  22250. if ((ibmConfig.enablerLayerModules) && (dojo.indexOf(ibmConfig.enablerLayerModules, "iWidget") >= 0)) {
  22251. dojo["require"]("com.ibm.mm.iwidget.widget.IWidgetWrapperExtendedImpl"); // JSLINT-IGNORE: This needs to be done to allow modularization and to support the minimal layer
  22252. }
  22253. }
  22254. if(!dojo._hasResource["com.ibm.mashups.iwidget.widget.IWidgetWrapper"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  22255. dojo._hasResource["com.ibm.mashups.iwidget.widget.IWidgetWrapper"] = true;
  22256. dojo.provide("com.ibm.mashups.iwidget.widget.IWidgetWrapper");
  22257. }
  22258. if(!dojo._hasResource["com.ibm.mashups.iwidget.model.WidgetModel"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  22259. dojo._hasResource["com.ibm.mashups.iwidget.model.WidgetModel"] = true;
  22260. dojo.provide("com.ibm.mashups.iwidget.model.WidgetModel");
  22261. /**
  22262. * WidgetModel interface defines functions that expose information of a widget model.<br/>
  22263. * Global model available to all the page components.<br/>
  22264. * <code>var widgetModel = com.ibm.mashups.iwidget.model.Factory.getGlobalWidgetModel();</code>
  22265. * @ibm-spi
  22266. * @ibm-module iWidget2
  22267. */
  22268. dojo.declare("com.ibm.mashups.iwidget.model.WidgetModel",null,{
  22269. /**
  22270. * @private
  22271. */
  22272. constructor:function(id){
  22273. },
  22274. /**
  22275. Returns an iWidgetWrapper object which represents a runtime instance of an iWidget object. <br/>
  22276. Id is the "id" attribute that's defined in microformat. It's used to uniquely identify an iWidget instance on the page.<br/>
  22277. <code> &lt;span class="iw-iWidget" id="{id}"&gt; </code>
  22278. @param{String} id unique id of an iWidget wrapper. Must not be NULL.
  22279. @type com.ibm.mashups.iwidget.widget. IWidgetWrapper
  22280. @returns{com.ibm.mashups.iwidget.widget. IWidgetWrapper } an iWidget Wrapper of the required iWidget . iWidget Wrapper represents a runtime instance of an iWidget.
  22281. */
  22282. find:function(id){
  22283. },
  22284. /**
  22285. Returns whether or not the given node has children. NOT Implemented.
  22286. @param{com.ibm.mashups.iwidget.iWidgetWrapper} iWidgetWrapper parent iWidgetWrapper object. Must not be NULL.
  22287. @type Boolean
  22288. @returns{Boolean } returns TRUE if the given node has children.
  22289. */
  22290. hasChildren:function(iWidgetWrapper){
  22291. },
  22292. /**
  22293. Returns an array of iWidgetWrapper object. NOT Implemented.<br/>
  22294. @param{com.ibm.mashups.iwidget.widget.IWidgetWrapper} iWidgetWrapper parent object .Must not be NULL.
  22295. @param{Boolean} isNested optional. the default value is TRUE. It returns all the nested iWidgets if it's true. It returns only direct children if it's false.
  22296. @type com.ibm.mashups.iwidget.widget. IWidgetWrapper[]
  22297. @returns{com.ibm.mashups.iwidget.widget. IWidgetWrapper[]} return an array of iWidgetWrapper object .
  22298. */
  22299. getChildren:function(iWidgetWrapper,isNested){
  22300. },
  22301. /**
  22302. Returns the parent object of the specified iWidgetWrapper object . <br/>
  22303. @param{com.ibm.mashups.iwidget.widget. IWidgetWrapper} iWidgetWrapper iWidgetWrapper object. Must not be NULL.
  22304. @type com.ibm.mashups.iwidget.widget. IWidgetWrapper
  22305. @returns{com.ibm.mashups.iwidget.widget. IWidgetWrapper } returns parent node or NULL if the node has no parent.
  22306. */
  22307. getParent:function(iWidgetWrapper){
  22308. },
  22309. /**
  22310. Returns the deferred object used to start this operation and an IWidgetDefinition object is returned when deferred object is executed.<br/>
  22311. <code>var deferred = widgetModel.getWidgetDefinitionByUrl(url)</code><br/>
  22312. <code>deferred.setFinishedCallback(callback,parameters);</code><br/>
  22313. <code>deferred.start(false);</code><br/>
  22314. here are the callback parameters that will be passed into callback function: <br/>
  22315. &nbsp;&nbsp;&nbsp;&nbsp;<code>resource</code> - IWidgetDefinition object <br>
  22316. &nbsp;&nbsp;&nbsp;&nbsp;<code>statuscode</code> - the HTTP status,code of the action .<br>
  22317. &nbsp;&nbsp;&nbsp;&nbsp;<code>params</code> - optional. may use this to pass additional parameters into the callback .<br>
  22318. here is a sample implementation of callbackfunction:<br/>
  22319. &nbsp;&nbsp;&nbsp;&nbsp;<code>function callback(resource, statuscode, params) { </code><br/>
  22320. &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;<code> if (statuscode == 200) { </code><br/>
  22321. &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;<code> var defObj = resource;</code><br/>
  22322. &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;<code> ... }</code><br/>
  22323. &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;<code> } </code><br/>
  22324. @param{String} url url to load widget definition. Must not be NULL.
  22325. @type com.ibm.mashups.enabler.Deferred
  22326. @returns{com.ibm.mashups.enabler.Deferred} a deferred object used to start this operation.
  22327. @see com.ibm.mashups.iwidget.widget.IWidgetDefinition
  22328. @deprecated Use getWidgetDefinitionByURL instead.
  22329. */
  22330. getWidgetDefinitionByUrl:function(url){
  22331. },
  22332. /**
  22333. Returns the deferred object used to start this operation and an IWidgetDefinition object is returned when deferred object is executed.<br/>
  22334. <code>var deferred = widgetModel.getWidgetDefinitionByUrl(url)</code><br/>
  22335. <code>deferred.setFinishedCallback(callback,parameters);</code><br/>
  22336. <code>deferred.start(false);</code><br/>
  22337. here are the callback parameters that will be passed into callback function: <br/>
  22338. &nbsp;&nbsp;&nbsp;&nbsp;<code>resource</code> - IWidgetDefinition object <br>
  22339. &nbsp;&nbsp;&nbsp;&nbsp;<code>statuscode</code> - the HTTP status,code of the action .<br>
  22340. &nbsp;&nbsp;&nbsp;&nbsp;<code>params</code> - optional. may use this to pass additional parameters into the callback .<br>
  22341. here is a sample implementation of callbackfunction:<br/>
  22342. &nbsp;&nbsp;&nbsp;&nbsp;<code>function callback(resource, statuscode, params) { </code><br/>
  22343. &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;<code> if (statuscode == 200) { </code><br/>
  22344. &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;<code> var defObj = resource;</code><br/>
  22345. &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;<code> ... }</code><br/>
  22346. &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;<code> } </code><br/>
  22347. @param{String} url url to load widget definition. Must not be NULL.
  22348. @type com.ibm.mashups.enabler.Deferred
  22349. @returns{com.ibm.mashups.enabler.Deferred} a deferred object used to start this operation.
  22350. @see com.ibm.mashups.iwidget.widget.IWidgetDefinition
  22351. */
  22352. getWidgetDefinitionByURL:function(url){
  22353. },
  22354. /**
  22355. * Commits the modifications applied to this model and all dependent models.<br>
  22356. * @return {DeferredOperation} a deferred object used to start this operation.
  22357. * The return value when executed through the deferred object is <code>null</null>
  22358. */
  22359. commit:function(){
  22360. //summary: This method persists the data
  22361. },
  22362. /**
  22363. Returns iWidgetDefinition object for the specified JSON object. <br/>
  22364. @param{Object} json JSON object. Must not be NULL.
  22365. @type com.ibm.mashups.iwidget.widget. IWidgetWrapper
  22366. @return{com.ibm.mashups.iwidget.widget.IWidgetDefinition} returns the IWidgetDefinition representation of the JSON object.
  22367. @see com.ibm.mashups.iwidget.widget.IWidgetDefinition
  22368. */
  22369. createIWidgetDefinition:function(json) {
  22370. //create WidgetDefinition based on JSON object
  22371. },
  22372. /**
  22373. Creates a widget and associates it with a span element on the page <br/>
  22374. @param{Object} span DOMElement to associate the widget with. Must not be NULL.
  22375. @return{com.ibm.mashups.iwidget.widget.IWidgetWrapper} returns the IWidgetWrapper representation of the JSON object. May be NULL.
  22376. */
  22377. createWidget:function(span) {
  22378. }
  22379. });
  22380. }
  22381. if(!dojo._hasResource["com.ibm.mm.enabler.hub.ManagedHubImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  22382. dojo._hasResource["com.ibm.mm.enabler.hub.ManagedHubImpl"] = true;
  22383. dojo.provide("com.ibm.mm.enabler.hub.ManagedHubImpl");
  22384. dojo.declare("com.ibm.mm.enabler.hub.ManagedHubImpl", null, {
  22385. constructor: function() {
  22386. //implement singleton
  22387. //allow any products to use enabler extensionregistry to plugin their own publishMgr and subscribeMgr,security manager
  22388. //sample code
  22389. /*var extensions = [];
  22390. extensions.push({
  22391. "com.ibm.mm.enabler.hub.ManagedHubImpl.publishMgr": {
  22392. type: "around",
  22393. handler: function ( executor, fnArgs ) { //executor is the default impl. function
  22394. var topic = fnArgs[0];
  22395. var data = fnArgs[1];
  22396. var pubClientID = fnArgs[2];
  22397. var subClientID = fnArgs[3];
  22398. //do logic here...
  22399. return;
  22400. }
  22401. }
  22402. });
  22403. */
  22404. },
  22405. publishMgr: function(topic, data, pubClient, subClient) {
  22406. var pubClientID = pubClient ? pubClient.getClientID() : "manager";
  22407. var subClientID = subClient ? subClient.getClientID() : "manager";
  22408. var that = com.ibm.mm.enabler.hub.ManagedHubImpl._instance;
  22409. return true;
  22410. },
  22411. subscribeMgr: function(topic, client) {
  22412. var clientID = client ? client.getClientID() : "manager";
  22413. var that = com.ibm.mm.enabler.hub.ManagedHubImpl._instance;
  22414. return true;
  22415. },
  22416. securityMgr: function(source, alertType) {
  22417. var that = com.ibm.mm.enabler.hub.ManagedHubImpl._instance;
  22418. },
  22419. getInstance: function() {
  22420. //Hub api doc and sample is out of sync,need to confirm parameters
  22421. var hub = com.ibm.mm.enabler.hub.ManagedHubImpl._instance;
  22422. if (!hub) {
  22423. com.ibm.mm.enabler.hub.ManagedHubImpl._instance = new OpenAjax.hub.ManagedHub({
  22424. onPublish: this.publishMgr,
  22425. onSubscribe: this.subscribeMgr,
  22426. onSecurityAlert: this.securityMgr
  22427. });
  22428. hub = com.ibm.mm.enabler.hub.ManagedHubImpl._instance;
  22429. }
  22430. return hub;
  22431. }
  22432. });
  22433. com.ibm.mm.enabler.hub.ManagedHubImpl = new com.ibm.mm.enabler.hub.ManagedHubImpl();
  22434. }
  22435. if(!dojo._hasResource["com.ibm.mm.enabler.hub.SubDomainPoolImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  22436. dojo._hasResource["com.ibm.mm.enabler.hub.SubDomainPoolImpl"] = true;
  22437. dojo.provide("com.ibm.mm.enabler.hub.SubDomainPoolImpl");
  22438. dojo.declare("com.ibm.mm.enabler.hub.SubDomainPoolImpl", null, {
  22439. constructor: function(arr) {
  22440. if (arr) {
  22441. this._pool = arr;
  22442. this._internalPool = dojo.clone(this._pool);
  22443. }
  22444. else {
  22445. this._counter = 0;
  22446. this._reusedSubDomain = [];
  22447. }
  22448. this.configService = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);
  22449. this.reuseSubDomain = this.configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.SUBDOMAINREUSE);
  22450. },
  22451. getSize: function() {
  22452. if (this._internalPool) {
  22453. return this._internalPool.length;
  22454. }
  22455. return -1; //unlimited
  22456. },
  22457. //get next available
  22458. get: function() {
  22459. if (this._pool) {
  22460. return this._getFromPool();
  22461. }
  22462. var cnt = this._counter;
  22463. if (this.reuseSubDomain) {
  22464. if (this._reusedSubDomain.length > 0) {
  22465. cnt = this._reusedSubDomain.shift();
  22466. return cnt;
  22467. }
  22468. else {
  22469. this._counter++;
  22470. }
  22471. }
  22472. else {
  22473. this._counter++;
  22474. }
  22475. return "w" + cnt;
  22476. },
  22477. //add old one back to pool for use eg. widget is deleted from the page
  22478. add: function(subDomain) {
  22479. if (!this.reuseSubDomain) {
  22480. return;
  22481. }
  22482. if (this._pool) {
  22483. return this._addToPool(subDomain);
  22484. }
  22485. else {
  22486. this._reusedSubDomain.push(subDomain);
  22487. }
  22488. return;
  22489. },
  22490. _getFromPool: function() {
  22491. if (this._pool.length === 0) {
  22492. return null;
  22493. }
  22494. return this._pool.shift();
  22495. },
  22496. _addToPool: function(subDomain) {
  22497. this._pool.push(subDomain);
  22498. }
  22499. });
  22500. }
  22501. if(!dojo._hasResource["com.ibm.mm.enabler.hub.XHRHeaderExtensionImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  22502. dojo._hasResource["com.ibm.mm.enabler.hub.XHRHeaderExtensionImpl"] = true;
  22503. dojo.provide("com.ibm.mm.enabler.hub.XHRHeaderExtensionImpl");
  22504. dojo.declare("com.ibm.mm.enabler.hub.XHRHeaderExtensionImpl", null, {
  22505. constructor: function() {
  22506. this.originalDojoXHR = dojo.xhr;
  22507. dojo.xhr = dojo.hitch(this, function(/* String */method, /* dojo.__XhrArgs */ args, /* Boolean */ hasBody) {
  22508. if (!args.headers) {
  22509. args.headers = {};
  22510. }
  22511. args.headers["com.ibm.lotus.openajax.virtualhost"] = document.location.hostname;
  22512. args.headers["com.ibm.lotus.openajax.virtualport"] = document.location.port;
  22513. var ret = this.originalDojoXHR(method, args, hasBody);
  22514. return ret;
  22515. });
  22516. }
  22517. });
  22518. com.ibm.mm.enabler.hub.XHRHeaderExtension = new com.ibm.mm.enabler.hub.XHRHeaderExtensionImpl();
  22519. }
  22520. if(!dojo._hasResource["com.ibm.mm.enabler.hub.MainHubAdapterImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  22521. dojo._hasResource["com.ibm.mm.enabler.hub.MainHubAdapterImpl"] = true;
  22522. dojo.provide("com.ibm.mm.enabler.hub.MainHubAdapterImpl");
  22523. dojo.declare("com.ibm.mm.enabler.hub.MainHubAdapterImpl", null, {
  22524. constructor: function(managedhub) {
  22525. this._managedhub = managedhub;
  22526. //this._inlineContainerArr = {};
  22527. //this._iframeContainerArr = {};
  22528. this._inlineHubClients = {};
  22529. },
  22530. PREFIX_INLINE: "_inline_",
  22531. PREFIX_IFRAME: "_iframe_",
  22532. createInlineHubContainer: function(id) {
  22533. var fullId = this.PREFIX_INLINE + id;
  22534. var me = this;
  22535. function onClientConnect(container) {
  22536. }
  22537. function onClientDisconnect(container) {
  22538. }
  22539. function onClientSecurityAlert(container, securityAlert) {
  22540. }
  22541. function onClientError(container, error) {
  22542. }
  22543. var params = {
  22544. Container: {
  22545. onConnect: onClientConnect,
  22546. onDisconnect: onClientDisconnect,
  22547. onSecurityAlert: onClientSecurityAlert,
  22548. onError: onClientError
  22549. }
  22550. };
  22551. var client = new OpenAjax.hub.InlineContainer(this._managedhub, fullId, params);
  22552. return client;
  22553. },
  22554. createIframeHubContainer:function(id,/*domNode*/widget,/*uri*/uri,isModal,width,height, myOnClientSecurityAlert){
  22555. var fullId = this.PREFIX_IFRAME + id;
  22556. var configService = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);
  22557. var enablerContext = configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.CONTEXT_ROOT_ENABLER);
  22558. var tunnelPath = enablerContext + "/js/openajaxhub/rpc_relay.html";
  22559. var schema = window.location.protocol;
  22560. var host = window.location.hostname;
  22561. var port = window.location.port;
  22562. var tunnelUri = schema + "//" + host + ":" + port + tunnelPath;
  22563. if (port == "") {
  22564. tunnelUri = schema + "//" + host + tunnelPath;
  22565. }
  22566. var me = this;
  22567. function onClientConnect(container) {
  22568. }
  22569. function onClientDisconnect(container) {
  22570. }
  22571. function onClientSecurityAlert(container, securityAlert) {
  22572. }
  22573. try {
  22574. var w,h;
  22575. this.removeIframeHubContainer(id); // remove any that already exists so there is never duplicate
  22576. if (isModal && isModal == "true") {
  22577. w = "600px";
  22578. h = "400px";
  22579. }
  22580. else {
  22581. w = "100%";
  22582. h = "100%";
  22583. }
  22584. if (width) {
  22585. w = width;
  22586. }
  22587. if (height) {
  22588. h = height;
  22589. }
  22590. if (myOnClientSecurityAlert) {
  22591. onClientSecurityAlert = myOnClientSecurityAlert;
  22592. }
  22593. var client = new OpenAjax.hub.IframeContainer(this._managedhub, fullId, {
  22594. Container: {
  22595. onConnect: onClientConnect,
  22596. onDisconnect: onClientDisconnect,
  22597. // log:function(msg){
  22598. // console.log("!!!!!!"+msg);
  22599. // },
  22600. onSecurityAlert: onClientSecurityAlert
  22601. },
  22602. IframeContainer: {
  22603. //uri: "http://c" + i + ".foo.bar.com/hub11/samples/plain_hub/widgetSender.html",
  22604. uri: uri,
  22605. tunnelURI: tunnelUri,
  22606. // timeout:1000000000,
  22607. parent: widget,
  22608. // iframeAttrs:{ style: { width: "100%", height: "100%" },scrolling:"no" }
  22609. iframeAttrs: {
  22610. title: "iframe",
  22611. style: {
  22612. width: w,//need to set default size since IE7/6 either have wierd or no default size at all
  22613. height: h,
  22614. border: "0px",
  22615. overflow: "auto"
  22616. }/*,
  22617. id: "iframe_" + id,
  22618. name: id*/
  22619. },
  22620. timeout: 1200000
  22621. }
  22622. });
  22623. }
  22624. catch (e) {
  22625. }
  22626. },
  22627. createInlineHubClient: function(id) {
  22628. //create hub client and connect to hub
  22629. var fullId = this.PREFIX_INLINE + id;
  22630. var me = this;
  22631. var container = this._managedhub.getContainer(fullId);
  22632. function onHubClientSecurityAlert(source, alertType) {
  22633. }
  22634. var hubClient1 = new OpenAjax.hub.InlineHubClient({
  22635. HubClient: {
  22636. onSecurityAlert: onHubClientSecurityAlert
  22637. },
  22638. InlineHubClient: {
  22639. container: container
  22640. }
  22641. });
  22642. function onHubClientConnect(client, success, error) {
  22643. }
  22644. hubClient1.connect(onHubClientConnect);
  22645. this._inlineHubClients[fullId] = hubClient1;
  22646. return hubClient1;
  22647. },
  22648. _getInlineHubClient: function(id) {
  22649. if (!id) {
  22650. return null;
  22651. }
  22652. var fullId = this.PREFIX_INLINE + id;
  22653. var client = this._inlineHubClients[fullId];
  22654. if (typeof client == "undefined") {
  22655. client = null;
  22656. }
  22657. return client;
  22658. },
  22659. getInlineHubClient: function(id) {
  22660. if (!id) {
  22661. return this._managedhub;
  22662. }
  22663. var client = this._getInlineHubClient(id);
  22664. return client ? client : this._managedhub;
  22665. },
  22666. isInlineClient: function(id) {
  22667. var rc = false;
  22668. var hubClient = this._getInlineHubClient(id);
  22669. if (hubClient) {
  22670. rc = true;
  22671. }
  22672. return rc;
  22673. },
  22674. removeInlineHubClient: function(id) {
  22675. //eg. widget is removed from the page
  22676. var hubClient = this._getInlineHubClient(id);
  22677. var fullId = this.PREFIX_INLINE + id;
  22678. if (hubClient) {
  22679. var me = this;
  22680. var onHubClientDisconnect = function (client, success, error) {
  22681. };
  22682. hubClient.disconnect(onHubClientDisconnect);
  22683. delete this._inlineHubClients[fullId];
  22684. //var inlineContainer = this._inlineContainerArr[fullId];
  22685. var inlineContainer = this._managedhub.getContainer(fullId);
  22686. if (inlineContainer) {
  22687. this._managedhub.removeContainer(inlineContainer);
  22688. }
  22689. return;
  22690. }
  22691. },
  22692. getContainer:function(id,isIframe){
  22693. isIframe = isIframe || false;
  22694. if (isIframe === true) {
  22695. id = this.PREFIX_IFRAME + id;
  22696. }
  22697. return this._managedhub.getContainer(id);
  22698. },
  22699. removeIframeHubContainer: function(id) {
  22700. var fullId = this.PREFIX_IFRAME + id;
  22701. var iframeContainer = this._managedhub.getContainer(fullId);
  22702. if (iframeContainer) {
  22703. this._managedhub.removeContainer(iframeContainer);
  22704. }
  22705. },
  22706. returnSubDomain: function(subDomain) {
  22707. this.getSubDomainPool().add(subDomain);
  22708. },
  22709. getSubDomainSize: function() {
  22710. return this.getSubDomainPool().getSize();
  22711. },
  22712. getSubDomain: function() {
  22713. return this.getSubDomainPool().get();
  22714. },
  22715. getSubDomainPool: function() {
  22716. if (!this.subDomainPool) {
  22717. var configService = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);
  22718. var subDomains = configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.SUBDOMAINS);
  22719. if (subDomains) {
  22720. if (dojo.isArray(subDomains) && subDomains.length !== 0) {
  22721. this.subDomainPool = new com.ibm.mm.enabler.hub.SubDomainPoolImpl(subDomains);
  22722. }
  22723. }
  22724. if (!this.subDomainPool) {
  22725. this.subDomainPool = new com.ibm.mm.enabler.hub.SubDomainPoolImpl();
  22726. }
  22727. }
  22728. return this.subDomainPool;
  22729. }
  22730. });
  22731. }
  22732. if(!dojo._hasResource["com.ibm.mm.iwidget.services.EventService"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  22733. dojo._hasResource["com.ibm.mm.iwidget.services.EventService"] = true;
  22734. dojo.provide("com.ibm.mm.iwidget.services.EventService");
  22735. // inject this service into the ServiceManager at the end. Therefore we have to require the implementation
  22736. dojo.declare("com.ibm.mm.iwidget.services.EventServiceDefaultImpl", com.ibm.mashups.iwidget.services.EventService, {
  22737. constructor: function(){
  22738. this.subMgr = {};
  22739. this.managedhub = com.ibm.mm.enabler.hub.ManagedHubImpl.getInstance();
  22740. this.hubAdapter = new com.ibm.mm.enabler.hub.MainHubAdapterImpl(this.managedhub);
  22741. this._subscribeEventService();
  22742. if (this.registerServices) {
  22743. this.registerServices();
  22744. }
  22745. if (this.registerExtServices) {
  22746. this.registerExtServices();
  22747. }
  22748. },
  22749. getType: function(){
  22750. return com.ibm.mm.iwidget.Constants.eventservice.type.MAIN;
  22751. },
  22752. registerServices: function(){
  22753. //listen to request to change widget mode
  22754. var event = com.ibm.mashups.iwidget.Constants.CHANGE_WIDGETMODE;
  22755. var me = this;
  22756. var eventCallback = function(payload){
  22757. var widgetId = payload.id;
  22758. var newMode = payload.newMode;
  22759. var parentNode = payload.parentNode;
  22760. me.fireEvent(widgetId, "onModeChanged", {
  22761. newMode: newMode,
  22762. rootElementId: parentNode
  22763. });
  22764. };
  22765. this.subscribeEvent(event, null, eventCallback, null, null);
  22766. },
  22767. setId: function(id){
  22768. this.id = id;
  22769. },
  22770. getId: function(){
  22771. return "main";
  22772. },
  22773. _subscribeEventService: function(){
  22774. //dispatch event to each method....for now, just fireEvent
  22775. //in future, broadcastEvent... has security concern though
  22776. var that = this;
  22777. // message should contain
  22778. // methodname:fireEvent
  22779. // params:{}
  22780. // hubclient:hubclientid
  22781. function eventCallback(topic, message, subscribeData){
  22782. //(targetWidget,targetEvent,message.payload,message.payloadType,sourceWidget)
  22783. var methodname = message.methodname;
  22784. if (methodname) {
  22785. var fn = that[message.methodname];
  22786. if (fn) {
  22787. that[methodname].apply(that, message.params);
  22788. }
  22789. }
  22790. }
  22791. this.managedhub.subscribe("eventservice." + this.getId(), eventCallback, that, that._subscribeCallback);
  22792. },
  22793. _subscribeCallback: function(subHandle, success,/*OpenAjax.hub.Error*/ error){
  22794. //common _subscribeCallback function
  22795. if (!success) {
  22796. console.log("subscribe failed " + subHandle);
  22797. }
  22798. },
  22799. _getHubAdapter: function(){
  22800. return this.hubAdapter;
  22801. },
  22802. _getManagedHub: function(){
  22803. return this.managedhub;
  22804. },
  22805. WIDGETEVENT_PREFIX: iwConstants.WIDGETEVENT_PREFIX,
  22806. WILDCARD_PREFIX: iwConstants.WILDCARD_PREFIX,
  22807. subscribeWire: function(/*String*/sourceWidget,/*String*/ sourceEvent,/*String*/ targetWidget,/*String*/ targetEvent){
  22808. return false;
  22809. },
  22810. publishWire: function(/*String*/sourceWidget,/*String*/ sourceEvent,/*object*/ payload,/*String*/ payloadType){
  22811. return false;
  22812. },
  22813. unSubscribeWire: function(sourceWidget, sourceEvent, targetWidget, targetEvent){
  22814. return false;
  22815. },
  22816. addWire: function(sourceWidget, sourceEvent, targetWidget, targetEvent){
  22817. return false;
  22818. },
  22819. removeWire: function(sourceWidget, sourceEvent, targetWidget, targetEvent){
  22820. return false;
  22821. },
  22822. fireEvent: function(targetWidget, targetEvent, payload, payloadType, sourceWidget){
  22823. //allows a third party to fire a event in a target widget
  22824. var aEvent = new com.ibm.mm.iwidget.IEventImpl(targetEvent, payloadType, payload, sourceWidget);
  22825. //need to make sure the widget is loaded
  22826. var widgetModel = com.ibm.mashups.iwidget.model.Factory.getGlobalWidgetModel();
  22827. var widget = widgetModel.find(targetWidget);
  22828. var cb = function(eventSvr, targetWWrapper, aEvent, subscribeID){
  22829. var isInlineClient = eventSvr.hubAdapter.isInlineClient(targetWWrapper.id);
  22830. if (isInlineClient) {
  22831. eventSvr._publishEvent(eventSvr.WIDGETEVENT_PREFIX + targetWWrapper.id, aEvent, aEvent.source);
  22832. }
  22833. else {
  22834. var payloadObj = {};
  22835. if (aEvent.name == iwConstants.EVENTS.onModeChanged) {
  22836. payloadObj.methodname = "_handleOnModeChange";
  22837. payloadObj.params = [payload];
  22838. targetWWrapper.handleEvent(payloadObj);
  22839. return;
  22840. }
  22841. payloadObj.methodname = "fireEvent";
  22842. payloadObj.hubclient = eventSvr.getId();
  22843. payloadObj.params = [targetWWrapper.id, aEvent.name, aEvent.payload, aEvent.type];
  22844. eventSvr._publishEvent("eventservice." + targetWWrapper.id, payloadObj);
  22845. }
  22846. if (subscribeID) { //delete subscriber
  22847. var subHandle = eventSvr.subMgr[subscribeID];
  22848. if (subHandle) {
  22849. eventSvr.unsubscribeEvent(subHandle);
  22850. }
  22851. delete eventSvr.subMgr[subscribeID];
  22852. }
  22853. };
  22854. if (widget && widget.isLoaded()) {
  22855. cb(this, widget, aEvent);
  22856. }
  22857. else {
  22858. var that = this;
  22859. //subscribe widgetloaded event with callback
  22860. //var subscribeID = com.ibm.mashups.iwidget.Constants.WIDGET_LOADED + "." + targetWidget;
  22861. var subscribeID = dojox.uuid.generateRandomUuid();
  22862. var subHandle = this.subscribeEvent(com.ibm.mashups.iwidget.Constants.WIDGET_LOADED + "." + targetWidget, null, function(){
  22863. var widget = widgetModel.find(targetWidget);
  22864. cb(that, widget, aEvent, subscribeID);
  22865. });
  22866. this.subMgr[subscribeID] = subHandle;
  22867. }
  22868. },
  22869. //support pagechanged event and widget deleted event
  22870. publishEvent: function(sourceEvent, payload, payloadType, sourceid){
  22871. // dojo dojo.publish(topic: String, args: Array);
  22872. if (typeof sourceEvent == "undefined" || sourceEvent === null) {
  22873. return;
  22874. }
  22875. var temp;
  22876. if (sourceEvent.indexOf(this.WILDCARD_PREFIX) === 0) {
  22877. temp = this.WILDCARD_PREFIX;
  22878. return this.broadcastEvent(sourceEvent.substring(temp.length), payload, payloadType, sourceid);
  22879. }
  22880. else
  22881. if (sourceEvent.indexOf(this.WIDGETEVENT_PREFIX) === 0) {
  22882. temp = sourceEvent.substring(this.WIDGETEVENT_PREFIX.length);
  22883. var widget = temp.substring(0, temp.indexOf("."));
  22884. var event = temp.substring(temp.indexOf(".") + 1);
  22885. return this.fireEvent(widget, event, payload, payloadType, sourceid);
  22886. }
  22887. this._publishEvent(sourceEvent, payload, sourceid);
  22888. },
  22889. _publishEvent: function(event, payload, sourceid){
  22890. //internal use
  22891. /*payload; need to be json object if it's openajax hub, for now, it's dojo, so it need to be array*/
  22892. var client = this.hubAdapter.getInlineHubClient(sourceid);
  22893. if (typeof payload == "undefined" || payload === null) {
  22894. client.publish(event);
  22895. }
  22896. else {
  22897. client.publish(event, payload);
  22898. }
  22899. },
  22900. broadcastEvent: function(targetEvent, payload, payloadType, sourceid, pageid, spaceid){
  22901. var eventObj = {};
  22902. eventObj.targetEvent = targetEvent;
  22903. eventObj.payload = payload;
  22904. eventObj.payloadType = payloadType;
  22905. this.broadcastEvents([eventObj], sourceid, pageid, spaceid);
  22906. return;
  22907. },
  22908. broadcastEvents: function(eventsArray, sourceid, pageid, spaceid){
  22909. if ((eventsArray === null) || !dojo.isArray(eventsArray)) {
  22910. return;
  22911. }
  22912. var navStateModel = com.ibm.mashups.enabler.model.state.NavigationStateModelFactory.getNavigationStateModel();
  22913. var spaceAccessor = com.ibm.mashups.enabler.model.state.AccessorFactory.getSpaceAccessor(navStateModel);
  22914. var currentSpaceID = spaceAccessor.getSpaceID();
  22915. var pageAccessor = com.ibm.mashups.enabler.model.state.AccessorFactory.getPageAccessor(navStateModel, currentSpaceID);
  22916. var currentPageID = pageAccessor.getPageID();
  22917. var switchPage = ((pageid) && (typeof pageid == "string") && (pageid != currentPageID));
  22918. if (switchPage) {
  22919. this._switchPageForBroadcastEvents(eventsArray, sourceid, pageid, spaceid, navStateModel, spaceAccessor, currentSpaceID);
  22920. }
  22921. else {
  22922. var subscribeID;
  22923. var subHandle;
  22924. // no switch page - stay on current page
  22925. var widgetModel = com.ibm.mashups.iwidget.model.Factory.getGlobalWidgetModel();
  22926. var widgets = widgetModel.getAllWidgets();
  22927. var that = this;
  22928. var checkHandledEvents = function(widget, eventsArray, subscribeID){
  22929. var handledEvents = widget.getWidgetHandledEvents();
  22930. if (handledEvents === null) {
  22931. // This is a hack for 15760
  22932. // In some instances the handled events aren't initialized on the IWidgetWrapper.
  22933. // If handledEvents comes back null get the events off the IWidgetDefinition.
  22934. var widgetDefinition = widget.getIWidgetDefinition().start();
  22935. if (widgetDefinition) {
  22936. handledEvents = widgetDefinition.getWidgetHandledEvents();
  22937. }
  22938. }
  22939. if (handledEvents) {
  22940. for (var i = 0; i < eventsArray.length; i++) {
  22941. for (var j = 0; j < handledEvents.length; j++) {
  22942. if (eventsArray[i].targetEvent == handledEvents[j].name) {
  22943. that.fireEvent(widget.getID(), eventsArray[i].targetEvent, eventsArray[i].payload, eventsArray[i].payloadType, sourceid);
  22944. break;
  22945. }
  22946. }
  22947. }
  22948. }
  22949. if (subscribeID) {
  22950. var subHandle = that.subMgr[subscribeID];
  22951. if (subHandle) {
  22952. that.unsubscribeEvent(subHandle);
  22953. }
  22954. delete that.subMgr[subscribeID];
  22955. }
  22956. };
  22957. var isSubscribed = false;
  22958. for (var i in widgets) {
  22959. if (Object.prototype.hasOwnProperty.call(widgets, i)) {
  22960. var aWidget = widgets[i];
  22961. if (aWidget.isLoaded()) {
  22962. checkHandledEvents(aWidget, eventsArray);
  22963. }
  22964. else {
  22965. if (!aWidget.lazyLoad) {
  22966. isSubscribed = true;
  22967. subscribeID = dojox.uuid.generateRandomUuid();
  22968. subHandle = this.subscribeEvent(com.ibm.mashups.iwidget.Constants.WIDGET_LOADED + "." + aWidget.getID(), null, dojo.partial(checkHandledEvents, aWidget, eventsArray, subscribeID));
  22969. this.subMgr[subscribeID] = subHandle;
  22970. }
  22971. }
  22972. }
  22973. }
  22974. // we are not allowed to verify for subscription anymore as the target widget is not yet in the global widget model after page switch. This happens later
  22975. if ((eventsArray.length > 0) && (eventsArray[0].targetEvent === "com.ibm.mashups.builder.skinLoaded")) {
  22976. subscribeID = dojox.uuid.generateRandomUuid();
  22977. subHandle = this.subscribeEvent(com.ibm.mashups.iwidget.Constants.WIDGET_LOADED + "." + eventsArray[0].payload.widgetId, null, function(){
  22978. that._handleBroadcastEventsCache();
  22979. var subHandle = that.subMgr[subscribeID];
  22980. if (subHandle) {
  22981. that.unsubscribeEvent(subHandle);
  22982. }
  22983. });
  22984. this.subMgr[subscribeID] = subHandle;
  22985. }
  22986. for (var j = 0; j < eventsArray.length; j++) {
  22987. this._publishEvent(eventsArray[j].targetEvent, eventsArray[j].payload, sourceid);
  22988. }
  22989. }
  22990. return;
  22991. },
  22992. _switchPageForBroadcastEvents: function(eventsArray, sourceid, pageid, spaceid, navStateModel, spaceAccessor, currentSpaceID) {
  22993. // noop - implemented by subclass
  22994. // no pages in core or minimal layer, so only switch page in model layer
  22995. },
  22996. _handleBroadcastEventsCache: function(){
  22997. // noop - implemented by subclass
  22998. // no pages in core or minimal layer, so only switch page in model layer
  22999. },
  23000. _subscribeEvent: function(event, object, eventCallback, subscribeCallback, sourceid){
  23001. var client = this._getHubAdapter().getInlineHubClient(sourceid);
  23002. //return dojo.subscribe(event,object,eventCallback);
  23003. //return subscription id for openajax hub
  23004. var subHandle1 = client.subscribe(event, function(topic, data, subscriberData){ /*onData*/
  23005. var ec = eventCallback;
  23006. if (object && eventCallback) {
  23007. ec = dojo.hitch(object, eventCallback);
  23008. }
  23009. //Deserialize data,not necessary
  23010. if (ec) {
  23011. ec(data);
  23012. }
  23013. }, null /* scope */, function(subID, success, error){ /*onComplete*/
  23014. if (object && subscribeCallback) {
  23015. subscribeCallback = dojo.hitch(object, subscribeCallback);
  23016. }
  23017. if (subscribeCallback) {
  23018. subscribeCallback.apply(this, [subID, success, error]);
  23019. }
  23020. if (!success) {
  23021. console.log("subscription for " + subID + " failed");
  23022. return;
  23023. }
  23024. });
  23025. return subHandle1;
  23026. },
  23027. subscribeEvent: function(event, object, eventCallback, subscribeCallback, sourceid){
  23028. return this._subscribeEvent(event, object, eventCallback, subscribeCallback, sourceid);
  23029. },
  23030. _unsubscribeEvent: function(subscriptionHandler, sourceid){
  23031. var client = this._getHubAdapter().getInlineHubClient(sourceid);
  23032. try {
  23033. if (client) {
  23034. client.unsubscribe(subscriptionHandler);
  23035. }
  23036. }
  23037. catch (e) {//workaround for hub bug
  23038. console.log("unsubscribe failure:" + e);
  23039. }
  23040. },
  23041. unsubscribeEvent: function(subscriptionHandler, sourceid){
  23042. if (!subscriptionHandler) {
  23043. return;
  23044. }
  23045. this._unsubscribeEvent(subscriptionHandler, sourceid);
  23046. },
  23047. _generateWireId: function(sourceWidget, sourceEvent, targetWidget, targetEvent){
  23048. return sourceWidget + "_" + sourceEvent + "_" + targetWidget + "_" + targetEvent;
  23049. }
  23050. });
  23051. if (!ibmConfig.insideSandbox) {
  23052. com.ibm.mashups.services.ServiceManager.setService("eventService", "com.ibm.mm.iwidget.services.EventServiceDefaultImpl");
  23053. }
  23054. // IMPORTANT
  23055. // ibmConfig.enablerLayerModules is a comma separated string of all supported modules at runtime
  23056. // This section dynamically loads the Extended representation when the variable enablerLayerModules contains the given module
  23057. if ((ibmConfig.enablerLayerModules) && (dojo.indexOf(ibmConfig.enablerLayerModules, "iWidget") >= 0)) {
  23058. dojo["require"]("com.ibm.mm.iwidget.services.EventServiceExtended"); // JSLINT-IGNORE: This needs to be done to allow modularization and to support the minimal layer
  23059. dojo["require"]("com.ibm.mm.iwidget.services.IFrameEventServiceImpl"); // JSLINT-IGNORE: This needs to be done to allow modularization and to support the minimal layer
  23060. }
  23061. }
  23062. if(!dojo._hasResource["com.ibm.mm.iwidget.model.WidgetModel"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  23063. dojo._hasResource["com.ibm.mm.iwidget.model.WidgetModel"] = true;
  23064. dojo.provide("com.ibm.mm.iwidget.model.WidgetModel");
  23065. dojo.declare("com.ibm.mm.iwidget.model.WidgetModelDefaultImpl", com.ibm.mashups.iwidget.model.WidgetModel, {
  23066. constructor: function() {
  23067. this.widgetArr = {}; //associate array since it provides direct access
  23068. this.parentMap = {}; // maps from widget id to parent widget id
  23069. this.eventService = com.ibm.mashups.services.ServiceManager.getService("eventService");
  23070. this.eventService.subscribeEvent(com.ibm.mashups.iwidget.Constants.UNLOAD_WIDGETS, this, "_unloadWidgets");
  23071. if (!ibmConfig || (ibmConfig && typeof ibmConfig.loadingHTML != "string")) { // only preload anim gif if loadingHTML is not set
  23072. if (ibmConfig["loadingHTML.imageURL"]) {
  23073. this.processAnim = com.ibm.mm.enabler.utils.Misc.preloadImage(ibmConfig["loadingHTML.imageURL"], 20, 20);
  23074. }
  23075. else {
  23076. var url = new dojo.moduleUrl("com.ibm.mm.iwidget", "image/");
  23077. url = url + "progress-anim.gif";
  23078. this.processAnim = com.ibm.mm.enabler.utils.Misc.preloadImage(url, 20, 20);
  23079. }
  23080. }
  23081. dojo.addOnWindowUnload(this, "_onWindowUnload");
  23082. this.global = dojo.global;
  23083. this.doc = dojo.doc;
  23084. },
  23085. _onWindowUnload: function() {
  23086. try {
  23087. var arr = [];
  23088. for (var i in this.widgetArr) {
  23089. if (Object.prototype.hasOwnProperty.call(this.widgetArr,i)) {
  23090. this._unloadWidget(i); //use _unloadWidget to avoid pulish event com.ibm.mashups.iwidget.Constants.WIDGETS_UNLOADED
  23091. }
  23092. }
  23093. }
  23094. catch (e) {
  23095. console.log("_onWindowUnload " + e.message);
  23096. }
  23097. },
  23098. createWidget: function(/*DomElment*/widgetSpan) {
  23099. // for now by design id is required attribute for each widget
  23100. var id = widgetSpan.getAttribute("id");
  23101. if (typeof(id) == "undefined") {
  23102. return null;
  23103. }
  23104. // each fragment is uniquely identified by the widget id, thus we don't
  23105. // support different fragment that shares the same id the old one will
  23106. //be deleted
  23107. var oldWidget = this.widgetArr[id];
  23108. if (typeof oldWidget != "undefined" && oldWidget !== null) {
  23109. var oldfragment = oldWidget.rootElement;
  23110. if (oldfragment == widgetSpan) { //eg. switch skin if it's the same dom node
  23111. return oldWidget;
  23112. }
  23113. else {
  23114. this._unloadWidget(id);
  23115. }
  23116. }
  23117. var aWidget = new com.ibm.mm.iwidget.widget.IWidgetWrapperImpl(widgetSpan, id);
  23118. this.widgetArr[id] = aWidget;
  23119. //this.parentMap[id] = aWidget._getParent();
  23120. this.parentMap[id] = "DEFER_TOKEN";
  23121. return aWidget;
  23122. },
  23123. createIWidgetDefinition: function(/*Object*/json) {
  23124. return new com.ibm.mm.iwidget.widget.IWidgetDefinitionImpl(null, null, json);
  23125. },
  23126. find: function(/*String*/id) {
  23127. var widget = this.widgetArr[id];
  23128. if (typeof widget != "undefined") {
  23129. if (widget.lazyLoad && !widget.loaded) {
  23130. this.renderWidget(widget);
  23131. delete widget.lazyLoad;
  23132. }
  23133. return widget;
  23134. }
  23135. return null;
  23136. },
  23137. getWidgetById: function(/*String*/id) { //deprecated
  23138. return this.find(id);
  23139. },
  23140. commit: function() {
  23141. return new com.ibm.mm.enabler.DeferredOperationImpl(this, this._commit);
  23142. },
  23143. _commit: function(deferred, sync) {
  23144. // iterate through my widgets and see whether any itemset is dirty or not.
  23145. for (var widgetId in this.widgetArr) {
  23146. if (Object.prototype.hasOwnProperty.call(this.widgetArr,widgetId)) {
  23147. var widgetWrapper = this.widgetArr[widgetId];
  23148. var widgetInstance = widgetWrapper.getIWidgetInstance();
  23149. if (!widgetInstance) {
  23150. continue;
  23151. }
  23152. widgetWrapper.commit();
  23153. }
  23154. }
  23155. },
  23156. _unloadWidgets: function(/*[]*/arr) {
  23157. var aWidget;
  23158. if (typeof arr != "undefined" || arr !== null) {
  23159. if (dojo.isArray(arr)) {
  23160. for (var i in arr) {
  23161. if (Object.prototype.hasOwnProperty.call(arr,i)) {
  23162. aWidget = arr[i];
  23163. this._unloadWidget(aWidget);
  23164. }
  23165. }
  23166. dojo.publish(com.ibm.mashups.iwidget.Constants.WIDGETS_UNLOADED, [arr]);
  23167. this.eventService.publishEvent(com.ibm.mashups.iwidget.Constants.WIDGETS_UNLOADED, arr);
  23168. }
  23169. else if (dojo.isString(arr)) {
  23170. this._unloadWidget(arr);
  23171. }
  23172. }
  23173. },
  23174. _unloadWidget: function(aWidget) {
  23175. if (typeof this.widgetArr[aWidget] != "undefined" && this.widgetArr[aWidget] !== null) {
  23176. var widgetwrapper = this.widgetArr[aWidget];
  23177. try {
  23178. widgetwrapper.destroy();
  23179. }
  23180. catch (e) {
  23181. }
  23182. delete this.widgetArr[aWidget];
  23183. if (this.parentMap[aWidget]) {
  23184. delete this.parentMap[aWidget];
  23185. }
  23186. }
  23187. },
  23188. getParent: function(widget) {
  23189. var parentId = this.parentMap[widget.getID()];
  23190. if (parentId && parentId == "DEFER_TOKEN") {
  23191. parentId = widget._getParent();
  23192. this.parentMap[widget.getID()] = parentId;
  23193. }
  23194. if (parentId) {
  23195. parent = this.find(parentId);
  23196. }
  23197. return parent || null;
  23198. },
  23199. hasChildren: function(widget) {
  23200. return (this.getChildren(widget, false).length === 0) ? false : true;
  23201. },
  23202. getChildren: function(widget, isNested) {
  23203. this._checkParentMap();
  23204. var children = [];
  23205. var nested = (typeof isNested == "undefined") ? true : isNested;
  23206. this._getChildren(widget, nested, children);
  23207. return children;
  23208. },
  23209. _checkParentMap: function() {
  23210. //make sure parent map is built
  23211. for (var id in this.widgetArr) {
  23212. if (Object.prototype.hasOwnProperty.call(this.widgetArr,id)) {
  23213. var parentId = this.parentMap[id];
  23214. if (parentId && parentId == "DEFER_TOKEN") {
  23215. var aWidget = this.widgetArr[id];
  23216. parentId = aWidget._getParent();
  23217. this.parentMap[id] = parentId;
  23218. }
  23219. }
  23220. }
  23221. },
  23222. _getChildren: function(parent, nested, children) {
  23223. // iterate parent map
  23224. for (var id in this.parentMap) {
  23225. // collect children
  23226. if (this.parentMap[id] == parent.getID()) {
  23227. var widget = this.find(id);
  23228. if (widget) {
  23229. children.push(widget);
  23230. if (nested) {
  23231. // collect nested children
  23232. this._getChildren(widget, nested, children);
  23233. }
  23234. }
  23235. }
  23236. }
  23237. },
  23238. // @deprecated
  23239. getWidgetDefinitionByUrl: function(url) {
  23240. return this.getWidgetDefinitionByURL(url);
  23241. },
  23242. getWidgetDefinitionByURL: function(url) {
  23243. return new com.ibm.mm.iwidget.DeferredLoadImpl(url);
  23244. },
  23245. getAllWidgets: function() {
  23246. return this.widgetArr;
  23247. },
  23248. renderWidget: function(/*Object*/iWidget) {
  23249. if (typeof iWidget == "undefined") {
  23250. return;
  23251. }
  23252. if (iWidget.loaded) {
  23253. return;
  23254. }
  23255. iWidget.doRender();
  23256. }
  23257. });
  23258. com.ibm.mm.iwidget.model.WidgetModelImpl = com.ibm.mm.iwidget.model.WidgetModelDefaultImpl;
  23259. // IMPORTANT
  23260. // ibmConfig.enablerLayerModules is a comma separated string of all supported modules at runtime
  23261. // This section dynamically loads the Extended representation when the variable enablerLayerModules contains the given module
  23262. if ((ibmConfig.enablerLayerModules) && (dojo.indexOf(ibmConfig.enablerLayerModules, "iWidget") >= 0)) {
  23263. dojo["require"]("com.ibm.mm.iwidget.model.WidgetModelExtended"); // JSLINT-IGNORE: This needs to be done to allow modularization and to support the minimal layer
  23264. }
  23265. }
  23266. if(!dojo._hasResource["com.ibm.mm.iwidget.model.FactoryImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  23267. dojo._hasResource["com.ibm.mm.iwidget.model.FactoryImpl"] = true;
  23268. dojo.provide("com.ibm.mm.iwidget.model.FactoryImpl");
  23269. dojo.declare("com.ibm.mm.iwidget.model.FactoryImpl", com.ibm.mashups.iwidget.model.Factory, {
  23270. constructor: function() {
  23271. },
  23272. getGlobalWidgetModel: function() {
  23273. if (!this._globalWidgetModel) {
  23274. this._globalWidgetModel = new com.ibm.mm.iwidget.model.WidgetModelImpl();
  23275. }
  23276. return this._globalWidgetModel;
  23277. }
  23278. });
  23279. com.ibm.mashups.iwidget.model.Factory = new com.ibm.mm.iwidget.model.FactoryImpl();
  23280. }
  23281. if(!dojo._hasResource["com.ibm.mashups.iwidget.model.Factory"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  23282. dojo._hasResource["com.ibm.mashups.iwidget.model.Factory"] = true;
  23283. dojo.provide("com.ibm.mashups.iwidget.model.Factory");
  23284. }
  23285. if(!dojo._hasResource["com.ibm.mm.enabler.model.state.NavigationStateProcessorImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  23286. dojo._hasResource["com.ibm.mm.enabler.model.state.NavigationStateProcessorImpl"] = true;
  23287. dojo.provide("com.ibm.mm.enabler.model.state.NavigationStateProcessorImpl");
  23288. dojo.declare("com.ibm.mm.enabler.model.state.NavigationStateProcessorImpl", com.ibm.mashups.enabler.model.state.NavigationStateProcessor, {
  23289. constructor: function(){
  23290. this.configService = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);
  23291. var persistenceURL = this.configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.NAVSTATE_PERSISTENCE_URL);
  23292. if (persistenceURL) {
  23293. this.persistenceURL = this._getAssociativeArray(persistenceURL);
  23294. }
  23295. var persistencePSTORE = this.configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.NAVSTATE_PERSISTENCE_PSTORE);
  23296. if (persistencePSTORE) {
  23297. this.persistencePSTORE = this._getAssociativeArray(persistencePSTORE);
  23298. }
  23299. var limit = this.configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.NAVSTATE_PERSISTENCE_URL_LIMIT);
  23300. var index = 10;
  23301. if (limit) {
  23302. index = parseInt(limit, 10);
  23303. }
  23304. this.urlpersistenceLIMIT = index;
  23305. var splimit = this.configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.NAVSTATE_PERSISTENCE_URL_SPLIMIT);
  23306. index = 2;
  23307. if (splimit) {
  23308. index = parseInt(splimit, 10);
  23309. }
  23310. this.urlpersistenceSPLIMIT = index;
  23311. this.isHuffmannEnabled = this.configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.NAVSTATE_HUFFMANNENCODE_ENABLED);
  23312. },
  23313. PID: "pid",
  23314. SHAREDPARAMETERSETS: "sps",
  23315. SID: "sid",
  23316. HUFFMANN_PREFIX: "mashup:huffman/",
  23317. encodeWidgetIdentifier: function(wid, nsm){
  23318. return wid;
  23319. },
  23320. decodeWidgetIdentifier: function(wid, nsm){
  23321. return wid;
  23322. },
  23323. dispose: function(callback){
  23324. var cookieManager = com.ibm.mashups.enabler.model.state.CookieManager;
  23325. var temp = cookieManager.disposeState();
  23326. if (callback) {
  23327. callback();
  23328. }
  23329. },
  23330. _getAssociativeArray: function(array){
  23331. var obj = {};
  23332. if (dojo.isString(array)) {
  23333. obj[array] = array;
  23334. return obj;
  23335. }
  23336. for (var i in array) {
  23337. if (Object.prototype.hasOwnProperty.call(array, i)) {
  23338. var value = array[i];
  23339. obj[value] = value;
  23340. }
  23341. }
  23342. return obj;
  23343. },
  23344. decode: function(url, callback){
  23345. if (url.indexOf(this.HUFFMANN_PREFIX) != -1) {
  23346. var arr = url.split(this.HUFFMANN_PREFIX);
  23347. var result = com.ibm.mm.enabler.encode.huffman.HuffmanURL.getDataFromHuffmanTree(arr[1]) || null;
  23348. if (result) {
  23349. url = arr[0] + result;
  23350. }
  23351. }
  23352. var hash = this._getHash(url) || null; //this is the alrerady uri encoded url
  23353. if (hash) {
  23354. if (url.indexOf("#") != -1) {
  23355. if (url.lastIndexOf("&") == (url.length - 1)) {
  23356. url = url.concat(hash);
  23357. }
  23358. else {
  23359. url = url.concat("#");
  23360. url = url.concat(hash);
  23361. }
  23362. }
  23363. else {
  23364. url = url.concat("#");
  23365. url = url.concat(hash);
  23366. }
  23367. }
  23368. var state = {};
  23369. var httpUrl = new com.ibm.mm.enabler.utils.HttpUrl(url);
  23370. var fragment = httpUrl.anchor;
  23371. fragment = decodeURIComponent(fragment);
  23372. if (fragment && fragment != "") {
  23373. /*This string:
  23374. "sid=testspace&pid=test&w0=testwidget&w0cp=%20spaces%20=blah"
  23375. results in this object structure:
  23376. {
  23377. sid: "testspace",
  23378. pid:"test",
  23379. w0:"testwidget",
  23380. w0cp: " spaces =blah"
  23381. }
  23382. */
  23383. var parameters = dojo.queryToObject(fragment);
  23384. var timestamp = new Date().getTime();
  23385. if (parameters.pid) {
  23386. state.pid = {};
  23387. state.pid.value = decodeURIComponent(parameters.pid);
  23388. state.pid.params = {};
  23389. state.pid.params.lm = timestamp;
  23390. }
  23391. if (parameters.sid) {
  23392. state.sid = {};
  23393. state.sid.value = decodeURIComponent(parameters.sid);
  23394. state.sid.params = {};
  23395. state.sid.params.lm = timestamp;
  23396. }
  23397. if (parameters.sps) {
  23398. state.sparams = {};
  23399. rawValue = dojo.fromJson(decodeURIComponent(parameters.sps));
  23400. //json object looks like this:
  23401. // { name1:{value:<>,params:{lm:<>}},
  23402. // name2:{value:<>,params:{lm:<>}}
  23403. // }
  23404. state.sparams = rawValue;
  23405. }
  23406. state.wparams = {};
  23407. //collect all the widget state parameters from url
  23408. //10 should be the default
  23409. //for example: w0,w1,w2...
  23410. for (var i in parameters) {
  23411. if (i.indexOf("w") === 0 && i.indexOf("cp") == -1 && i.indexOf("rp") == -1) {
  23412. var widgetData = {};
  23413. var index = i.substr(1) * 1 + timestamp;
  23414. var wID = parameters[i];
  23415. var wIndexCP = i + "cp";
  23416. var wIndexRP = i + "rp";
  23417. if (parameters[wIndexCP]) {
  23418. widgetData.value = widgetData.value ? widgetData.value : {};
  23419. try {
  23420. widgetData.value.cp = dojo.fromJson(decodeURIComponent(parameters[wIndexCP]));
  23421. }
  23422. catch (e) {
  23423. widgetData.value.cp = decodeURIComponent(parameters[wIndexCP]);
  23424. }
  23425. widgetData.params = widgetData.params ? widgetData.params : {};
  23426. widgetData.params.lm = index;
  23427. }
  23428. if (parameters[wIndexRP]) {
  23429. widgetData.value = widgetData.value ? widgetData.value : {};
  23430. try {
  23431. widgetData.value.rp = dojo.fromJson(decodeURIComponent(parameters[wIndexRP]));
  23432. }
  23433. catch (e2) {
  23434. widgetData.value.rp = decodeURIComponent(parameters[wIndexRP]);
  23435. }
  23436. widgetData.params = widgetData.params ? widgetData.params : {};
  23437. widgetData.params.lm = index;
  23438. }
  23439. state.wparams[wID] = widgetData;
  23440. }
  23441. else
  23442. if (i.indexOf("w") !== 0 && i != "pid" && i != "sid" && i != "sps" && i != "pageselection") {
  23443. //anything other than reserved parameters are state.params
  23444. var value = parameters[i];
  23445. state.params = state.params ? state.params : {};
  23446. state.params[i] = decodeURIComponent(value);
  23447. }
  23448. }
  23449. }
  23450. if (callback) {
  23451. callback(state);
  23452. }
  23453. if (!callback) {
  23454. return state;
  23455. }
  23456. },
  23457. _getFragmentFromData: function(obj, contains, notContains){
  23458. var urlData;
  23459. if (dojo.isString(obj)) {
  23460. urlData = obj;
  23461. }
  23462. else {
  23463. //var urlData = this._filterData(obj, contains, notContains);
  23464. urlData = dojo.clone(obj);
  23465. if (contains || notContains) {
  23466. urlData = this._filterData(obj, contains, notContains);
  23467. }
  23468. }
  23469. var realData = urlData;
  23470. if (!dojo.isString(realData)) {
  23471. if (this._isEmpty(realData)) {
  23472. realData = null;
  23473. }
  23474. else {
  23475. try {
  23476. realData = dojo.toJson(realData);
  23477. }
  23478. catch (e) {
  23479. realData = null;
  23480. }
  23481. }
  23482. }
  23483. return realData;
  23484. },
  23485. encode: function(state, callback, oldState, params, nsm){
  23486. //change above state into url fragment as defined in CDD and url encoded
  23487. var fragment = "";
  23488. // params overrides config setting:
  23489. // cp.noWidgets = "true" |
  23490. // cp.widgetsOnCurrentPage = "true" |
  23491. // cp.allWidgets = "true"
  23492. var urlCp = {};
  23493. var wm;
  23494. if (params && params.cp) {
  23495. urlCp = params.cp;
  23496. if (urlCp.widgetsOnCurrentPage == "true") {
  23497. wm = com.ibm.mashups.iwidget.model.Factory.getGlobalWidgetModel();
  23498. }
  23499. }
  23500. var data;
  23501. var pid;
  23502. var sid;
  23503. //pid
  23504. if (state.pid && state.pid.value) {
  23505. pid = state.pid.value;
  23506. }
  23507. if (!pid && state.sid && state.sid.value) {
  23508. sid = state.sid.value;
  23509. if (state.pageselection && state.pageselection[sid]) {
  23510. pid = state.pageselection[sid].value;
  23511. }
  23512. }
  23513. if (pid && this._contains("pid", this.persistenceURL)) {
  23514. fragment = fragment + "pid" + "=" + encodeURIComponent(pid) + "&";
  23515. }
  23516. //sid
  23517. if (!sid && state.sid && state.sid.value) {
  23518. sid = state.sid.value;
  23519. }
  23520. if (sid && this._contains("sid", this.persistenceURL)) {
  23521. fragment = fragment + "sid" + "=" + encodeURIComponent(sid) + "&";
  23522. }
  23523. for (var i in state) {
  23524. if (Object.prototype.hasOwnProperty.call(state, i)) {
  23525. if (i == "sparams") {
  23526. //json object looks like this:
  23527. // id: {
  23528. // global:{ name1:{value:<>,params:{lm:<>,_listener:[]}},
  23529. // name2:{value:<>,params:{lm:<>}},
  23530. // <scope>:{ name1:{value:<>,params:{lm:<>,_listener:[]}},
  23531. // name2:{value:<>,params:{lm:<>}}
  23532. // }
  23533. if (state[i]) {
  23534. var sparamsData = dojo.clone(state[i]) || null;
  23535. this._removeHiddenParameters(sparamsData);
  23536. this._removeEmptyObj(sparamsData);
  23537. if (sparamsData && this._contains("sparams", this.persistenceURL)) {
  23538. fragment = fragment + "sps" + "=" + encodeURIComponent(dojo.toJson(sparamsData)) + "&";
  23539. }
  23540. }
  23541. }
  23542. if (i == "pageselection" && state[i]) {
  23543. data = dojo.clone(state[i]) || null;
  23544. if (data && this._contains("pageselection", this.persistenceURL)) {
  23545. fragment = fragment + "pageselection" + "=" + encodeURIComponent(dojo.toJson(data)) + "&";
  23546. }
  23547. }
  23548. // widgets! -- only save widget customized state to url and parameters defined in this.persistenceURL
  23549. if (i == "wparams" && state[i] && !(urlCp.noWidgets == "true")) {
  23550. //it's a realarray after sorting
  23551. var widgetsData = this._sortData(dojo.clone(state[i]));//work with a clone copy...
  23552. if (widgetsData.length > this.urlpersistenceLIMIT) {
  23553. widgetsData = widgetsData.slice(widgetsData.length - this.urlpersistenceLIMIT);
  23554. }
  23555. var index = 0;
  23556. var realDataCp;
  23557. var realDataRp;
  23558. var allWidgets = urlCp.allWidgets == "true" || this._contains("cp", this.persistenceURL);
  23559. var widgetsOnPage = urlCp.widgetsOnCurrentPage == "true";
  23560. for (var j in widgetsData) {
  23561. if (Object.prototype.hasOwnProperty.call(widgetsData, j)) {
  23562. var widgetData = widgetsData[j] || null;
  23563. // add widget state only for widgets on the current page
  23564. if (widgetsOnPage && wm) {
  23565. if (widgetData && widgetData.wid) {
  23566. var wid = dojo.isFunction(this.decodeWidgetIdentifier) ? this.decodeWidgetIdentifier(widgetData.wid, nsm) : widgetData.wid;
  23567. if (wm.find(wid) === null) {
  23568. continue;
  23569. }
  23570. }
  23571. }
  23572. if (widgetData && widgetData.value) {
  23573. realDataCp = null;
  23574. realDataRp = null;
  23575. if (widgetData.value.cp && (allWidgets || widgetsOnPage)) {
  23576. realDataCp = this._getFragmentFromData(widgetData.value.cp) || null;
  23577. }
  23578. if (widgetData.value.rp) {
  23579. realDataRp = this._getFragmentFromData(widgetData.value.rp, this.persistenceURL) || null;
  23580. }
  23581. if (realDataCp || realDataRp) {
  23582. //always persist widget customized data
  23583. fragment = fragment + "w" + index + "=" + widgetData.wid + "&";
  23584. if (realDataCp) {
  23585. fragment = fragment + "w" + index + "cp=" + encodeURIComponent(realDataCp) + "&";
  23586. }
  23587. if (realDataRp) {
  23588. fragment = fragment + "w" + index + "rp=" + encodeURIComponent(realDataRp) + "&";
  23589. }
  23590. index++;
  23591. if (index >= this.urlpersistenceLIMIT) {
  23592. break;
  23593. }
  23594. }
  23595. }
  23596. }
  23597. }
  23598. }
  23599. //any params will be in the url
  23600. if (i == "params" && state[i]) {
  23601. var data1 = state[i];
  23602. for (var k in data1) {
  23603. if (Object.prototype.hasOwnProperty.call(data1, k)) {
  23604. fragment = fragment + k + "=" + encodeURIComponent(data1[k]) + "&";
  23605. }
  23606. }
  23607. }
  23608. }
  23609. }
  23610. if (this.isHuffmannEnabled) {
  23611. //need to generate url that's huffmann encoding enabled, don't encode pid for now... #pid
  23612. if (fragment.indexOf("&") != -1) {
  23613. data = fragment.substr(fragment.indexOf("&") + 1);
  23614. if (data.length > 0) {
  23615. data = com.ibm.mm.enabler.encode.huffman.HuffmanURL.createRawSchemeSpecificPartFromRegex(data, "[%&c=]");
  23616. fragment = fragment.substring(0, fragment.indexOf("&") + 1); //include "&"
  23617. fragment = fragment.concat(this.HUFFMANN_PREFIX);
  23618. fragment = fragment.concat(data);
  23619. }
  23620. }
  23621. }
  23622. //huffman encoding if required
  23623. if (callback) {
  23624. callback(fragment, params);
  23625. }
  23626. if (!callback) {
  23627. return fragment;
  23628. }
  23629. },
  23630. _removeHiddenParameters: function(obj){
  23631. for (var i in obj) {
  23632. if (Object.prototype.hasOwnProperty.call(obj, i)) {
  23633. if (i.indexOf("_") === 0) {
  23634. obj[i] = null;
  23635. delete obj[i];
  23636. }
  23637. else {
  23638. if (!dojo.isString(obj[i])) {
  23639. this._removeHiddenParameters(obj[i]);
  23640. }
  23641. }
  23642. }
  23643. }
  23644. },
  23645. _removeEmptyObj: function(obj){
  23646. // if the object is empty, we can exit right away
  23647. if (com.ibm.mm.enabler.utils.Misc.isEmpty(obj)) {
  23648. return;
  23649. }
  23650. for (var childName in obj) {
  23651. if (Object.prototype.hasOwnProperty.call(obj, childName)) {
  23652. // if the child is not an object (e.g. it is a string, we must not try to delte it
  23653. if (!dojo.isObject(obj[childName])) {
  23654. continue;
  23655. }
  23656. var childObj = obj[childName];
  23657. this._removeEmptyObj(childObj);
  23658. // now we can check whether the object is empty after we recursively removed empty childs
  23659. if (com.ibm.mm.enabler.utils.Misc.isEmpty(childObj)) {
  23660. obj[childName] = null;
  23661. delete obj[childName];
  23662. }
  23663. }
  23664. }
  23665. },
  23666. _removeQueryState: function(wru){
  23667. if (wru.indexOf("?") == -1) {
  23668. return wru;
  23669. }
  23670. var queryParams = wru.substring(wru.indexOf("?") + 1); //? is not included
  23671. if (queryParams && queryParams.indexOf("#") != -1) {
  23672. queryParams = queryParams.substring(0, queryParams.indexOf("#"));
  23673. }
  23674. var prefix = wru.substr(0, wru.indexOf("?")); //prefix before query parameter,"?" is not included
  23675. var st = null;
  23676. var newqueryParams = "";
  23677. if (queryParams && (queryParams.indexOf("nst=") === 0 || queryParams.indexOf("&nst=") >= 0)) {
  23678. var temp = queryParams.substr(queryParams.indexOf("nst=") + 3); //mystate&other=test
  23679. var postSt = "";
  23680. if (temp.indexOf("&") > 0) { //?nst=mystate&other=test
  23681. st = temp.substring(0, temp.indexOf("&")); //mystate
  23682. postSt = temp.substring(temp.indexOf("&")); //&other=test
  23683. }
  23684. else {
  23685. st = temp;
  23686. }
  23687. if (queryParams.indexOf("&nst=") != -1) {
  23688. //?other=test&nst=mystate --> other=test
  23689. newqueryParams = queryParams.substring(0, queryParams.indexOf("&nst="));
  23690. }
  23691. if (newqueryParams.length === 0 && postSt.length !== 0) {
  23692. newqueryParams = newqueryParams.concat(postSt.substring(1)); //remove "&" here
  23693. }
  23694. else {
  23695. newqueryParams = newqueryParams.concat(postSt);
  23696. }
  23697. }
  23698. else {
  23699. return wru; //if there's no state information encoded in params.
  23700. }
  23701. //add hash
  23702. var hash = wru.substr(wru.indexOf("#") + 1);
  23703. //remove "nst=" as query parameter
  23704. var newWru = prefix;
  23705. if (newqueryParams.length > 0) {
  23706. newWru = newWru.concat("?").concat(newqueryParams);
  23707. }
  23708. if (hash.length > 0) {
  23709. newWru = newWru.concat("#").concat(hash);
  23710. }
  23711. return newWru;
  23712. },
  23713. // @deprecated
  23714. generateUrl: function(state, callback, params, nsm){
  23715. return this.generateURL(state, callback, params);
  23716. },
  23717. generateURL: function(state, callback, params, nsm){
  23718. var additionalParams;
  23719. if (params && params.cp) {
  23720. additionalParams = {
  23721. cp: params.cp
  23722. };
  23723. }
  23724. var encodedFragment = additionalParams ? this.encode(state, null, null, additionalParams, nsm) : this.encode(state, null, null, null, nsm);
  23725. var href = window.location.href;
  23726. //remove "?nst=" here
  23727. href = this._removeQueryState(href);
  23728. var preHref = href;
  23729. if (href.indexOf("#") != -1) {
  23730. preHref = href.substr(0, href.indexOf("#"));
  23731. }
  23732. var url = preHref.concat("#");
  23733. url = url.concat(encodedFragment);
  23734. //{nohash:"true"}
  23735. if (params && params.nohash && params.nohash == "true") {
  23736. //now need to generate a url without hash, by default we use query "?nst=b"
  23737. //there could be =,& in the encodedFragment, need ot escape
  23738. encodedFragment = encodeURIComponent(encodedFragment);
  23739. if (preHref.indexOf("?") == -1) {
  23740. url = preHref.concat("?");
  23741. url = url.concat("nst=");
  23742. url = url.concat(encodedFragment);
  23743. }
  23744. else {
  23745. if (preHref.lastIndexOf("&") == (preHref.length - 1)) {
  23746. url = preHref.concat("nst=");
  23747. url = url.concat(encodedFragment);
  23748. }
  23749. else {
  23750. url = preHref.concat("&");
  23751. url = url.concat("nst=");
  23752. url = url.concat(encodedFragment);
  23753. }
  23754. }
  23755. }
  23756. if (callback) {
  23757. callback(url);
  23758. }
  23759. return url;
  23760. },
  23761. _getHash: function(wru){
  23762. if (wru.indexOf("?") == -1) {
  23763. return null;
  23764. }
  23765. if (wru.indexOf("#") != -1) {
  23766. var hashValue = wru.substr(wru.indexOf("#") + 1);
  23767. if (wru.indexOf("pid") != -1 || wru.indexOf("sid") != -1) {
  23768. return null;
  23769. }
  23770. }
  23771. var queryParams = wru.substring(wru.indexOf("?") + 1); //? is not included
  23772. if (queryParams && queryParams.indexOf("#") != -1) {
  23773. queryParams = queryParams.substring(0, queryParams.indexOf("#"));
  23774. }
  23775. //var prefix = wru.substr(0,wru.indexOf("?")); //prefix before query parameter,"?" is not included
  23776. var st = null;
  23777. //var newqueryParams = "";
  23778. if (queryParams && (queryParams.indexOf("nst=") === 0 || queryParams.indexOf("&nst=") >= 0)) {
  23779. var temp = queryParams.substr(queryParams.indexOf("nst=") + 4); //mystate&other=test
  23780. var postSt = "";
  23781. if (temp.indexOf("&") > 0) { //?nst=mystate&other=test
  23782. st = temp.substring(0, temp.indexOf("&")); //mystate
  23783. }
  23784. else {
  23785. st = temp;
  23786. }
  23787. st = decodeURIComponent(st); //returned state is still URIencoded
  23788. }
  23789. else {
  23790. return null; //if there's no state information encoded in params.
  23791. }
  23792. return st;
  23793. },
  23794. _sortData: function(widgetsData){
  23795. //sort data based on "lm" -- pass in an associative array
  23796. var arr = [];
  23797. for (var i in widgetsData) {
  23798. if (Object.prototype.hasOwnProperty.call(widgetsData, i)) {
  23799. widgetsData[i].wid = i;
  23800. var widgetData = widgetsData[i]; //i is widgetid
  23801. if (widgetData.params && widgetData.params.lm) {
  23802. arr.push(widgetData);
  23803. }
  23804. }
  23805. }
  23806. var sortby = function(a, b){
  23807. return (a.params.lm - b.params.lm);
  23808. };
  23809. arr.sort(sortby);
  23810. return arr; //an array sorted in accending order
  23811. },
  23812. _getLength: function(obj){
  23813. var length = 0;
  23814. for (var i in obj) {
  23815. if (Object.prototype.hasOwnProperty.call(obj, i)) {
  23816. length++;
  23817. }
  23818. }
  23819. return length;
  23820. },
  23821. _isEmpty: function(obj){
  23822. return com.ibm.mm.enabler.utils.Misc.isEmpty(obj);
  23823. },
  23824. _contains: function(value, obj){
  23825. if (!obj) {
  23826. return false;
  23827. }
  23828. if (obj[value]) {
  23829. return true;
  23830. }
  23831. return false;
  23832. },
  23833. _filterData: function(data, containsObj, notContainsObj){
  23834. //removes data fields that's not in the containsObj if notContainsObject is not provided
  23835. //removes data fields that's in notContainsObj and it's not in containsObj --> url
  23836. if (!containsObj && !notContainsObj) {
  23837. return data;
  23838. }
  23839. if (!notContainsObj) {
  23840. for (var i in data) {
  23841. if (Object.prototype.hasOwnProperty.call(data, i)) {
  23842. if (!this._contains(i, containsObj)) {
  23843. delete data[i];
  23844. }
  23845. }
  23846. }
  23847. return data;
  23848. }
  23849. for (var j in data) {
  23850. if (Object.prototype.hasOwnProperty.call(data, j)) {
  23851. if (!this._contains(j, containsObj) && this._contains(j, notContainsObj)) {
  23852. delete data[j];
  23853. }
  23854. }
  23855. }
  23856. return data;
  23857. },
  23858. preprocess: function(state, callback){
  23859. //call cookie preprocessor to process data
  23860. //collect data from cookie
  23861. var cookieManager = com.ibm.mashups.enabler.model.state.CookieManager;
  23862. var temp = cookieManager.getState();
  23863. //need to merge data
  23864. //pid/sid first
  23865. //if state already contains sid and even pid is null, don't load it
  23866. if (!state.pid && temp.pid && !state.sid) {
  23867. state.pid = temp.pid;
  23868. }
  23869. if (!state.sid && temp.sid) {
  23870. state.sid = temp.sid;
  23871. }
  23872. if (!state.pageselection && temp.pageselection) {
  23873. state.pageselection = temp.pageselection;
  23874. }
  23875. // this is only to support lc params
  23876. // which are only stored in the cookie
  23877. // and are only used by base Mashups
  23878. // to get layout template for the page
  23879. // which is used to determine
  23880. // if the width and height of widgets are still valid
  23881. state.lcparams = temp.lcparams || {};
  23882. //widget data collection
  23883. if (!state.wparams) {
  23884. state.wparams = {};
  23885. }
  23886. var widgetsStateData = state.wparams;
  23887. var widgetData = temp.wparams; //values in cookie
  23888. for (var i in widgetData) {
  23889. if (Object.prototype.hasOwnProperty.call(widgetData, i)) {
  23890. var widget = i;
  23891. var value = widgetData[i]; //data in cookie
  23892. var widgetStateData = widgetsStateData[widget];//data in state object
  23893. if (widgetStateData) {
  23894. value = dojo.mixin(value, dojo.clone(widgetStateData)); //merge data for widget,data in memory wins if duplicate, for example: "lm"
  23895. widgetsStateData[widget] = value; //set new dta in memory
  23896. }
  23897. else {
  23898. widgetsStateData[widget] = value;
  23899. }
  23900. }
  23901. }
  23902. if (callback) {
  23903. callback(state);
  23904. }
  23905. if (!callback) {
  23906. return state;
  23907. }
  23908. },
  23909. postprocess: function(state, callback, oldState, additionalParams){
  23910. //persist into cookie
  23911. var cookieManager = com.ibm.mashups.enabler.model.state.CookieManager;
  23912. for (var i in state) {
  23913. if (Object.prototype.hasOwnProperty.call(state, i)) {
  23914. if (i == "pid" || i == "sid" || i == "pageselection" || i == "sparams") {
  23915. if (this._contains(i, this.persistencePSTORE)) {
  23916. cookieManager.setState(i, state[i]);
  23917. }
  23918. }
  23919. // lcparams -- needed in case w,h are stored since this contains
  23920. // the name of the layout template for the page which is used to determine
  23921. // if the width and height of widgets are still valid
  23922. // specifically, if the page instance template is different from the navstate layout template
  23923. // then widgets' width and height on the relevant page are invalid
  23924. if (i == "lcparams" && state[i] && this.persistencePSTORE && (this.persistencePSTORE.w || this.persistencePSTORE.h)) {
  23925. var lcparamsState = {};
  23926. var lcparamsData = state[i];
  23927. for (var page in lcparamsData) {
  23928. if (Object.prototype.hasOwnProperty.call(lcparamsData, page)) { // it's really a page, not some inherited property
  23929. var layoutState = {};
  23930. var layoutData = lcparamsData[page];
  23931. layoutState.templateURL = layoutData.templateURL;
  23932. layoutState.params = layoutData.params;
  23933. lcparamsState[page] = layoutState;
  23934. // don't need any other data because mashups does not support saving/restore of layout containerd (column widths)
  23935. }
  23936. }
  23937. cookieManager.setState("lcparams", lcparamsState);
  23938. }
  23939. // widgets!
  23940. if (i == "wparams" && state[i]) {
  23941. var widgetsstate = {};
  23942. var widgetsData = state[i];
  23943. for (var j in widgetsData) {
  23944. if (Object.prototype.hasOwnProperty.call(widgetsData, j)) {
  23945. var widgetData = widgetsData[j] || null;
  23946. var wID = j;//wid
  23947. var pstoreData = {};
  23948. if (widgetData && widgetData.value) {
  23949. if (widgetData.value.rp) {
  23950. var rpData = this._filterData(dojo.clone(widgetData.value.rp), this.persistencePSTORE);
  23951. if (!this._isEmpty(rpData)) {
  23952. pstoreData.value = pstoreData.value ? pstoreData.value : {};
  23953. pstoreData.value.rp = rpData;
  23954. }
  23955. }
  23956. if (widgetData.value.cp && this._contains("cp", this.persistencePSTORE)) {
  23957. var cpData = this._filterData(dojo.clone(widgetData.value.cp), this.persistencePSTORE);
  23958. if (!this._isEmpty(cpData)) {
  23959. pstoreData.value = pstoreData.value ? pstoreData.value : {};
  23960. pstoreData.value.cp = cpData;
  23961. }
  23962. }
  23963. if (!this._isEmpty(pstoreData)) {
  23964. //if there's no value, no reason to save empty params. at least for now.
  23965. if (widgetData.params) {
  23966. pstoreData.params = widgetData.params;
  23967. }
  23968. widgetsstate[wID] = pstoreData;
  23969. }
  23970. }
  23971. }
  23972. }
  23973. cookieManager.setState("wparams", widgetsstate);
  23974. }
  23975. }
  23976. }
  23977. cookieManager.commit();
  23978. if (callback) {
  23979. callback(state, additionalParams);
  23980. }
  23981. if (!callback) {
  23982. return state;
  23983. }
  23984. }
  23985. });
  23986. }
  23987. if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.NavigationStateProcessor"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  23988. dojo._hasResource["com.ibm.mashups.enabler.model.state.NavigationStateProcessor"] = true;
  23989. dojo.provide("com.ibm.mashups.enabler.model.state.NavigationStateProcessor");
  23990. }
  23991. if(!dojo._hasResource["com.ibm.mm.enabler.model.state.NavigationStateProcessorFactoryImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  23992. dojo._hasResource["com.ibm.mm.enabler.model.state.NavigationStateProcessorFactoryImpl"] = true;
  23993. dojo.provide("com.ibm.mm.enabler.model.state.NavigationStateProcessorFactoryImpl");
  23994. dojo.declare("com.ibm.mm.enabler.model.state.NavigationStateProcessorFactoryImpl", null, {
  23995. constructor: function(){
  23996. },
  23997. getProcessor: function(){
  23998. if (!this._nsp) {
  23999. this._nsp = new com.ibm.mm.enabler.model.state.NavigationStateProcessorImpl();
  24000. }
  24001. return this._nsp;
  24002. }
  24003. });
  24004. com.ibm.mashups.enabler.model.state.NavigationStateProcessorFactory = new com.ibm.mm.enabler.model.state.NavigationStateProcessorFactoryImpl();
  24005. }
  24006. if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.NavigationStateNode_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  24007. dojo._hasResource["com.ibm.mashups.enabler.model.state.NavigationStateNode_API"] = true;
  24008. dojo.provide("com.ibm.mashups.enabler.model.state.NavigationStateNode_API");
  24009. dojo.provide("com.ibm.mashups.enabler.model.state.NavigationStateNode");
  24010. /**
  24011. * Interface representing a NavigationStateNode.
  24012. * @ibm-spi
  24013. * @ibm-module Base
  24014. */
  24015. dojo.declare("com.ibm.mashups.enabler.model.state.NavigationStateNode", com.ibm.mashups.enabler.Identifiable, {
  24016. /**
  24017. * Returns the value of this NavigationNode
  24018. * @return {Object} The value of the navigation node
  24019. */
  24020. get: function(){
  24021. },
  24022. /**
  24023. * Sets the value of navigation state node
  24024. * @param {Object} value The value of the navigation state node
  24025. * @type void
  24026. */
  24027. set: function(/*Object*/value){
  24028. }
  24029. });
  24030. }
  24031. if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.NavigationStateNode"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  24032. dojo._hasResource["com.ibm.mashups.enabler.model.state.NavigationStateNode"] = true;
  24033. dojo.provide("com.ibm.mashups.enabler.model.state.NavigationStateNode");
  24034. }
  24035. if(!dojo._hasResource["com.ibm.mm.enabler.model.state.NavigationStateNodeImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  24036. dojo._hasResource["com.ibm.mm.enabler.model.state.NavigationStateNodeImpl"] = true;
  24037. dojo.provide("com.ibm.mm.enabler.model.state.NavigationStateNodeImpl");
  24038. dojo.declare("com.ibm.mm.enabler.model.state.NavigationStateNodeImpl", [com.ibm.mashups.enabler.model.state.NavigationStateNode], {
  24039. constructor: function(navStateModel, key, value, id, ref) {
  24040. this.model = navStateModel;
  24041. this.key = key; //like pid
  24042. this.value = value;//real pid
  24043. if (id) {
  24044. this.id = id;
  24045. }
  24046. if (ref) {
  24047. this.ref = ref;
  24048. }
  24049. },
  24050. setID: function(id) {
  24051. this.id = id; //pointer to the position in jso object. wparams#widgetid#cp
  24052. },
  24053. setRef: function(ref) { //ref to the data in state json object: this._state["pid"]
  24054. this.ref = ref;
  24055. },
  24056. getID: function() {
  24057. return this.id;
  24058. },
  24059. getRef: function() {
  24060. return this.ref; //return the ref in state json object
  24061. },
  24062. getKey: function() {
  24063. return this.key;
  24064. },
  24065. getValue: function() {
  24066. return this.value;
  24067. },
  24068. get: function() { //return value only,not reference
  24069. return dojo.clone(this._ref);
  24070. },
  24071. set: function(value) {
  24072. this.ref = value; //overwrite
  24073. this.model.setDirty(true);
  24074. }
  24075. });
  24076. }
  24077. if(!dojo._hasResource["com.ibm.mm.enabler.model.state.NavigationStateModelImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  24078. dojo._hasResource["com.ibm.mm.enabler.model.state.NavigationStateModelImpl"] = true;
  24079. dojo.provide("com.ibm.mm.enabler.model.state.NavigationStateModelImpl");
  24080. dojo.declare("com.ibm.mm.enabler.model.state.NavigationStateModelImpl", [com.ibm.mashups.enabler.model.state.NavigationStateModel], {
  24081. DELIMITER: "#",
  24082. ROOT: "ROOT",
  24083. DELETE_TOKEN: "DELETE_TOKEN",
  24084. VALUE: "value",
  24085. PARAMS: "params",
  24086. constructor: function(state){
  24087. this.processor = com.ibm.mashups.enabler.model.state.NavigationStateProcessorFactory.getProcessor();
  24088. if (state) {
  24089. this._state = state;
  24090. this._rootNode = new com.ibm.mm.enabler.model.state.NavigationStateNodeImpl(this, this.ROOT, this._state, this.ROOT, this._state);
  24091. this._loaded = true;
  24092. }
  24093. else {
  24094. dojo.back.setInitialState({
  24095. back: this._loadCurrentPage,
  24096. forward: this._loadCurrentPage
  24097. });
  24098. this._loaded = false;
  24099. this.processor.decode(window.location.href, dojo.hitch(this, "_preprocess"));
  24100. }
  24101. this._sync = true;
  24102. },
  24103. _getUniqueWid: function(wid){
  24104. return dojo.isFunction(this.processor.encodeWidgetIdentifier) ? this.processor.encodeWidgetIdentifier(wid, this) : wid;
  24105. },
  24106. _refreshPage: function(){
  24107. //get full page refresh redirect url
  24108. var cb = function(url){
  24109. if (url) {
  24110. top.location.href = url;
  24111. }
  24112. };
  24113. var navStateModel = com.ibm.mashups.enabler.model.state.NavigationStateModelFactory.getNavigationStateModel();
  24114. com.ibm.mashups.enabler.model.state.UrlGeneratorFactory.getURLGenerator().getUrl(navStateModel, cb, {
  24115. nohash: "true"
  24116. });
  24117. },
  24118. _getFullUrl: function(cb, params){
  24119. return this.processor.generateURL(this._state, cb, params, this);
  24120. },
  24121. clone: function(){
  24122. var clone = dojo.clone(this._state);
  24123. return new com.ibm.mm.enabler.model.state.NavigationStateModelImpl(clone);
  24124. },
  24125. _preprocess: function(/*json*/state){
  24126. this.processor.preprocess(state, dojo.hitch(this, "_initializeState"));
  24127. },
  24128. _initialize: function(){
  24129. this.processor.decode(window.location.href, dojo.hitch(this, "_preprocess"));
  24130. },
  24131. _initializeState: function(/*json*/state){
  24132. this._state = state;
  24133. this._stateInternal = dojo.clone(state);
  24134. this._rootNode = new com.ibm.mm.enabler.model.state.NavigationStateNodeImpl(this, this.ROOT, this._state, this.ROOT, this._state);
  24135. this._isDirty = false;
  24136. this._isTransactionDirty = false;
  24137. //this._dirtyProperties = {};
  24138. this._isTransaction = false;
  24139. this._loaded = true;
  24140. },
  24141. _postprocess: function(/*json*/state, additionalParams){
  24142. //don't call encode if page is already unloaded
  24143. if (this._isDirty && (!this._pagemode || (this._pagemode && this._pagemode != "unload" && this._pagemode != "edit"))) {
  24144. this.processor.encode(state, dojo.hitch(this, "_finishCommit"), this._stateInternal, additionalParams, this);
  24145. }
  24146. else { //call callback
  24147. if (this._deferred) {
  24148. this._deferred.finish(null, com.ibm.mm.enabler.model.HttpStatusCodes.HTTP_OK);
  24149. delete this._deferred;
  24150. }
  24151. }
  24152. },
  24153. _loadCurrentPage: function(){
  24154. // this is a helper function for loading the current page, it is not bound to this context.
  24155. // it is used by the dojo.back mechanism
  24156. var nsm = com.ibm.mashups.enabler.model.state.NavigationStateModelFactory.getNavigationStateModel();
  24157. nsm._initialize();
  24158. var eventService = com.ibm.mashups.services.ServiceManager.getService("eventService");
  24159. eventService.publishEvent(nsm.ONNAVSTATEUPDATED);
  24160. },
  24161. _finishCommit: function(fragment, additionalParams, responseParams){
  24162. //update url fragment identifier accordingly
  24163. //todo
  24164. //update url
  24165. //var oldUrl = window.location.hash;
  24166. //var other = "";
  24167. //if (oldUrl && oldUrl != null){
  24168. // other = this._getDifference(oldUrl);
  24169. //}
  24170. //need to keep things that's in fragment already such as "pageContext".
  24171. //window.location.hash = "#"+fragment+other;
  24172. try {
  24173. var currentFragment = window.location.hash.substring(1);
  24174. if (additionalParams && additionalParams.addToHistory) {
  24175. if (fragment && currentFragment != fragment) {
  24176. dojo.back.addToHistory({
  24177. back: this._loadCurrentPage,
  24178. forward: this._loadCurrentPage,
  24179. changeUrl: fragment
  24180. });
  24181. }
  24182. }
  24183. }
  24184. catch (e) {
  24185. //defect 14585 IE has a maximum url length at 2083 character, catch the exception so widgets can continue rendering process
  24186. }
  24187. //broadcast page Navigation updated event
  24188. if (this._isDirty) {
  24189. var eventService = com.ibm.mashups.services.ServiceManager.getService("eventService");
  24190. eventService.publishEvent(this.ONNAVSTATEUPDATED);
  24191. }
  24192. //just call dojo.backbutton...
  24193. this._isDirty = false;
  24194. //cleanup set all the _isDirty flag into false
  24195. this._removeDirty(this._state);
  24196. //
  24197. this._stateInternal = dojo.clone(this._state);
  24198. //not used anymore?
  24199. //delete this._dirtyProperties;
  24200. //this._dirtyProperties = {};
  24201. // see if we should refresh or handle the callback
  24202. if (additionalParams && additionalParams.allowRedirect &&
  24203. responseParams &&
  24204. responseParams.doRedirect &&
  24205. !this._sync) {
  24206. this._refreshPage();
  24207. }
  24208. else
  24209. if (this._deferred) {
  24210. //handle callback
  24211. this._deferred.finish(null, com.ibm.mm.enabler.model.HttpStatusCodes.HTTP_OK);
  24212. delete this._deferred;
  24213. }
  24214. },
  24215. _removeDirty: function(obj){
  24216. for (var i in obj) {
  24217. if (Object.prototype.hasOwnProperty.call(obj, i)) {
  24218. if (i.params && i.params._isDirty) {
  24219. i.params._isDirty = false;
  24220. if (i.value && i.value == this.DELETE_TOKEN) {
  24221. obj[i] = null;
  24222. delete obj[i];
  24223. }
  24224. }
  24225. if (obj[i] && !dojo.isString(obj[i])) {
  24226. this._removeDirty(obj[i]);
  24227. }
  24228. }
  24229. }
  24230. },
  24231. setDirty: function(isDirty){
  24232. this._isDirty = isDirty;
  24233. },
  24234. isDirty: function(){
  24235. return this._isDirty;
  24236. },
  24237. _find: function(id){//id
  24238. //return the NavigationStateNode by id or return null
  24239. id = id || null;
  24240. if (!id) {
  24241. return null;
  24242. }
  24243. if (id == this.ROOT) {
  24244. return this._rootNode;
  24245. }
  24246. else {
  24247. var aNode = this._findReference(id) || null; //return the ref in this._state
  24248. if (aNode) {
  24249. var returnNode = new com.ibm.mm.enabler.model.state.NavigationStateNodeImpl(this);
  24250. returnNode.setID(id);
  24251. returnNode.setRef(aNode);
  24252. return returnNode;
  24253. }
  24254. }
  24255. return null;
  24256. },
  24257. create: function(context){
  24258. //{key:id,value:data}
  24259. //{key:"pid",value:pid}
  24260. //{key:"mywidgetid",value:json}
  24261. var key = context.key ? context.key : null;
  24262. var value = context.value ? context.value : null;
  24263. var aNode = new com.ibm.mm.enabler.model.state.NavigationStateNodeImpl(this, key, value);
  24264. return aNode;
  24265. },
  24266. insert: function(aNode, parentNode){
  24267. //For example, pid node should be inserted under rootnode
  24268. var parentData = parentNode.getRef();
  24269. var key = aNode.getKey();
  24270. var value = aNode.getValue() || null;
  24271. if (!value) {
  24272. value = {};
  24273. }
  24274. //if parentNode is wparams, then aNode is widget node, widget node need to have an index in value
  24275. var parentKey = parentNode.getID();
  24276. /*if (parentKey && parentKey != null && parentKey == "wparams") {
  24277. value.i = this._getIndex(parentData);
  24278. }*/
  24279. parentData[key] = value;//insert the node into JSON
  24280. return;
  24281. },
  24282. _getIndex: function(parentData){
  24283. var index = 0;
  24284. for (var i in parentData) {
  24285. if (Object.prototype.hasOwnProperty.call(parentData, i)) {
  24286. index++;
  24287. }
  24288. }
  24289. return index;
  24290. },
  24291. remove: function(aNode){
  24292. //get id
  24293. var id = aNode.getID();
  24294. var arr = id.split("#");
  24295. if (arr.length == 1) {
  24296. //remove from root
  24297. if (this._state[id]) {
  24298. delete this._state[id];
  24299. }
  24300. }
  24301. if (arr.length > 1) {
  24302. var key = id.substring(id.lastIndexOf("#") + 1);
  24303. var parentId = id.substring(0, id.lastIndexOf("#"));
  24304. var parentNode = this._find(parentId);
  24305. if (parentNode) {
  24306. var ref = parentNode.getRef();
  24307. if (ref[key]) {
  24308. delete ref[key];
  24309. }
  24310. }
  24311. }
  24312. return;
  24313. },
  24314. _getRoot: function(){
  24315. return this._rootNode;
  24316. },
  24317. _findReference: function(id){
  24318. if (id == this.ROOT) {
  24319. return this._state;
  24320. }
  24321. var found = false;
  24322. var arr = id.split("#");
  24323. var node = this._state;
  24324. if (!node) {
  24325. return null;
  24326. }
  24327. for (var i in arr) {
  24328. if (Object.prototype.hasOwnProperty.call(arr, i)) {
  24329. var j = arr[i];
  24330. found = false;
  24331. if (this._findMatch(node, j)) {
  24332. node = node[j];
  24333. found = true;
  24334. }
  24335. else {
  24336. break;
  24337. }
  24338. }
  24339. }
  24340. if (!found) {
  24341. return null;
  24342. }
  24343. return node;
  24344. },
  24345. _findMatch: function(node, key){
  24346. if (node[key]) {
  24347. return true;
  24348. }
  24349. return false;
  24350. },
  24351. commit: function(additionalParams){
  24352. return new com.ibm.mm.enabler.DeferredImpl(this, this._commit, additionalParams);
  24353. },
  24354. _commit: function(deferred, sync, additionalParams){ //default is synchronous
  24355. this._deferred = deferred;
  24356. this._sync = sync;
  24357. if (additionalParams && additionalParams.allowRedirect && this._sync) {
  24358. }
  24359. //commit all the itemset changed.
  24360. this._processShareableParameters();
  24361. //don't commit if it's edit mode...
  24362. if (this._isDirty && (!this._pagemode || (this._pagemode && this._pagemode != "edit"))) {
  24363. //persist to cookie
  24364. this._isTransactionDirty = true;
  24365. this.processor.postprocess(this._state, dojo.hitch(this, this._postprocess), this._stateInternal, additionalParams);
  24366. }
  24367. },
  24368. _processShareableParameters: function(){
  24369. var sparams = this._state.sparams;
  24370. if (!sparams) {
  24371. return;
  24372. }
  24373. var paramset = null;
  24374. for (var i in sparams) {
  24375. if (Object.prototype.hasOwnProperty.call(sparams, i)) {
  24376. //i is itemset name
  24377. var payload = {};
  24378. payload.itemSetName = i;
  24379. var changes = [];
  24380. for (var scope in sparams[i]) {
  24381. if (Object.prototype.hasOwnProperty.call(sparams[i], scope)) {
  24382. var itemValues = sparams[i][scope].value;
  24383. for (var j in itemValues) {
  24384. if (Object.prototype.hasOwnProperty.call(itemValues, j)) {
  24385. //j is itemName
  24386. var itemParams = itemValues[j].params;
  24387. if (itemParams && itemParams._isDirty) {
  24388. changes.push(itemParams._change);
  24389. if (itemValues[j].value == this.DELETE_TOKEN) {
  24390. itemValues[j] = null;
  24391. delete itemValues[j];
  24392. }
  24393. else {
  24394. itemValues[j].params = null;
  24395. delete itemValues[j].params;
  24396. }
  24397. }
  24398. }
  24399. }
  24400. if (changes.length > 0) {
  24401. payload.changes = changes;
  24402. if (sparams[i][scope].params && sparams[i][scope].params._listeners) {
  24403. var listeners = sparams[i][scope].params._listeners;
  24404. for (var t in listeners) {
  24405. if (Object.prototype.hasOwnProperty.call(listeners, t)) {
  24406. listeners[t](payload);
  24407. }
  24408. }
  24409. }
  24410. }
  24411. }
  24412. }
  24413. }
  24414. }
  24415. },
  24416. discard: function(){
  24417. this._state = dojo.clone(this._stateInternal);
  24418. this._rootNode = new com.ibm.mm.enabler.model.state.NavigationStateNodeImpl(this, this.ROOT, this._state, this.ROOT, this._state);
  24419. this._isDirty = false;
  24420. },
  24421. _getPageMode: function(){
  24422. if (!this._pagemode) {
  24423. return null;
  24424. }
  24425. return this._pagemode;
  24426. },
  24427. _setPageMode: function(pageMode){
  24428. if (pageMode) {
  24429. this._pagemode = pageMode;
  24430. }
  24431. },
  24432. dispose: function(){
  24433. this._state = {};
  24434. this._stateInternal = {};
  24435. this._rootNode = new com.ibm.mm.enabler.model.state.NavigationStateNodeImpl(this, this.ROOT, this._state, this.ROOT, this._state);
  24436. this._isDirty = false;
  24437. this._loaded = true;
  24438. this.processor.dispose();
  24439. },
  24440. startTransaction: function(){
  24441. // If _isTransaction is already true, do nothing.
  24442. if (this.isTransaction())
  24443. return;
  24444. // Otherwise set _isDirty false and _isTransaction true
  24445. // and save a clone of the NavState in case rollback is necessary
  24446. this.discard(); // just in case
  24447. this._isTransaction = true;
  24448. this._isTransactionDirty = false;
  24449. this._transactionRollbackState = dojo.clone(this._state);
  24450. // This is a fix for defect 19201
  24451. // Temporary widget ids such as 0 and 1
  24452. // are assigned to new widgets before the page is saved
  24453. // when the page is saved, real server ids are assigned
  24454. // and the wparams navstate is copied from the temporary ids.
  24455. // This is done in _copyWidgetStateInfo()
  24456. // in com.ibm.mm.enabler.widget.WidgetModelImpl
  24457. // but _copyWidgetStateInfo() does not delete the temporary ids.
  24458. // The temporary widget ids are reused when another page creates a new widget
  24459. // so the navstate from the new widget on the previous page
  24460. // ends up being applied to new widget on this other page -- which is wrong.
  24461. // Since it was not obvious to me that it was always safe
  24462. // to delete the temporary ids _copyWidgetStateInfo()
  24463. // and since the WidgetAccessor does not have a method to delete a widget
  24464. // the code below simply makes sure the navstate data
  24465. // associated with the temporary ids
  24466. // is deleted before the page edit begins (startTransaction is called)
  24467. // This is not ideal because it ties startTransaction() to Edit Page.
  24468. // But it is not terrible.
  24469. // We can evaluate this during knowledge transfer.
  24470. // -dosofsky, 28-mar-2011
  24471. var wparams = null;
  24472. if (this._state)
  24473. wparams = this._state.wparams;
  24474. if (wparams) {
  24475. var idService = com.ibm.mashups.enabler.services.IdentificationService;
  24476. var id;
  24477. for (id in wparams) {
  24478. if (!idService.isServerID(id))
  24479. delete wparams[id];
  24480. }
  24481. }
  24482. },
  24483. commitTransaction: function(){
  24484. // If _isTransaction is false, do nothing. Otherwise set _isTransaction false, and if isDirty is true call postprocess()
  24485. if (this.isTransaction()) {
  24486. this._isTransaction = false;
  24487. if (this._isTransactionDirty) {
  24488. this.discard();
  24489. this._stateInternal = this._transactionRollbackState;
  24490. this._transactionRollbackState = null; // discard copy of navstatemodel
  24491. this._isDirty = true;
  24492. // call postprocess()
  24493. this.processor.postprocess(this._state, dojo.hitch(this, this._postprocess), this._stateInternal);
  24494. this._isTransactionDirty = false;
  24495. }
  24496. }
  24497. return;
  24498. },
  24499. discardTransaction: function(){
  24500. // If _isTransaction is false, do nothing. Otherwise if _isTransactionDirty is true reset the NavState to the clone and call postprocess(). Regardless of the state of _isDirty, set _isTransaction false.
  24501. if (this.isTransaction()) {
  24502. if (this._isTransactionDirty) {
  24503. this.discard();
  24504. if (!(typeof this._transactionRollbackState == "undefined")) {
  24505. // when a page edit is discarded the pid, sid, and pageselection for
  24506. // the _transactionRollbackState should be the same as the _state
  24507. // but in a couple of cases, when a page is in edit mode,
  24508. // and the user selects another page tab or the "new page" page tab
  24509. // the page is switched to the other page or "new page"
  24510. // but then discardTransaction() is called
  24511. // and could roll back the the pid, sid, and/or pageselection
  24512. // to their values before the page was switched
  24513. // the code below prevents that problem; it fixes defects:
  24514. // 18785, 19150, and probably 19236
  24515. // -dosofsky, 21-mar-2011
  24516. var trs = this._transactionRollbackState;
  24517. var s = this._state;
  24518. if (s) {
  24519. if(s.pid)
  24520. trs.pid = dojo.clone(s.pid);
  24521. if(s.sid)
  24522. trs.sid = dojo.clone(s.sid);
  24523. if(s.pageselection)
  24524. trs.pageselection = dojo.clone(s.pageselection);
  24525. }
  24526. this._state = this._transactionRollbackState; // reset NavState to the clone state
  24527. this._rootNode = new com.ibm.mm.enabler.model.state.NavigationStateNodeImpl(this, this.ROOT, this._state, this.ROOT, this._state);
  24528. this._transactionRollbackState = null; // discard copy of navstatemodel
  24529. this._isDirty = true;
  24530. // call postprocess()
  24531. this.processor.postprocess(this._state, dojo.hitch(this, this._postprocess), this._stateInternal);
  24532. }
  24533. this._isTransactionDirty = false;
  24534. }
  24535. this._isTransaction = false;
  24536. }
  24537. return;
  24538. },
  24539. isTransaction: function(){
  24540. if (typeof this._isTransaction == "undefined") { // check if isTransaction flag exists
  24541. this._isTransaction = false;
  24542. }
  24543. return this._isTransaction;
  24544. },
  24545. _generateListenerId: function(){
  24546. if (!this._listenerCounter) {
  24547. this._listenerCounter = 1;
  24548. }
  24549. else {
  24550. this._listenerCounter++;
  24551. }
  24552. return this._listenerCounter;
  24553. }
  24554. });
  24555. // init the backbutton functionality, this is mandatory for having back button support working on IE !!!
  24556. //dojo.back.init();
  24557. }
  24558. if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.NavigationStateModel"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  24559. dojo._hasResource["com.ibm.mashups.enabler.model.state.NavigationStateModel"] = true;
  24560. dojo.provide("com.ibm.mashups.enabler.model.state.NavigationStateModel");
  24561. }
  24562. if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.NavigationStateModelFactory_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  24563. dojo._hasResource["com.ibm.mashups.enabler.model.state.NavigationStateModelFactory_API"] = true;
  24564. dojo.provide("com.ibm.mashups.enabler.model.state.NavigationStateModelFactory_API");
  24565. dojo.provide("com.ibm.mashups.enabler.model.state.NavigationStateModelFactory");
  24566. /**
  24567. * Interface for a NavigationStateModelFactory.<br/>
  24568. * <code>var navigationStateModel = com.ibm.mashups.enabler.model.state.NavigationStateModelFactory.getNavigationStateModel();</code><br/>
  24569. * @ibm-spi
  24570. * @ibm-module Base
  24571. */
  24572. dojo.declare( "com.ibm.mashups.enabler.model.state.NavigationStateModelFactory", null, {
  24573. /**
  24574. * Returns the NavigationStateModel of Mashup Server.
  24575. * @return {com.ibm.mashups.enabler.model.state.NavigationStateModel} The NavigationStateModel, never <code>null</code>.
  24576. */
  24577. getNavigationStateModel:function() {
  24578. }
  24579. });
  24580. }
  24581. if(!dojo._hasResource["com.ibm.mm.enabler.model.state.NavigationStateModelFactoryImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  24582. dojo._hasResource["com.ibm.mm.enabler.model.state.NavigationStateModelFactoryImpl"] = true;
  24583. dojo.provide("com.ibm.mm.enabler.model.state.NavigationStateModelFactoryImpl");
  24584. dojo.declare("com.ibm.mm.enabler.model.state.NavigationStateModelFactoryImpl", [com.ibm.mashups.enabler.model.state.NavigationStateModelFactory], {
  24585. constructor: function() {
  24586. },
  24587. getNavigationStateModel: function(state) {
  24588. // STATE is internal and may not be used as public API. It was introduced for sandboxing to initialize the NavState within the sandbox
  24589. if (!this.navigationstatemodel) {
  24590. this.navigationstatemodel = new com.ibm.mm.enabler.model.state.NavigationStateModelImpl(state);
  24591. }
  24592. return this.navigationstatemodel;
  24593. }
  24594. });
  24595. com.ibm.mashups.enabler.model.state.NavigationStateModelFactory = new com.ibm.mm.enabler.model.state.NavigationStateModelFactoryImpl();
  24596. }
  24597. if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.NavigationStateModelFactory"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  24598. dojo._hasResource["com.ibm.mashups.enabler.model.state.NavigationStateModelFactory"] = true;
  24599. dojo.provide("com.ibm.mashups.enabler.model.state.NavigationStateModelFactory");
  24600. }
  24601. if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.UrlGenerator_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  24602. dojo._hasResource["com.ibm.mashups.enabler.model.state.UrlGenerator_API"] = true;
  24603. dojo.provide("com.ibm.mashups.enabler.model.state.UrlGenerator_API");
  24604. dojo.provide("com.ibm.mashups.enabler.model.state.UrlGenerator");
  24605. /**
  24606. * Interface representing an UrlGenerator.
  24607. * @ibm-spi
  24608. * @ibm-module Base
  24609. */
  24610. dojo.declare( "com.ibm.mashups.enabler.model.state.UrlGenerator", null, {
  24611. /**
  24612. * Returns the URL based on navigation state model and additional parameters.
  24613. * Sample parameter: {nohash:"true"}
  24614. * if "nohash" is set to "true",the returned URL will not contain state in hash.
  24615. *
  24616. * @param {com.ibm.mashups.enabler.model.state.NavigationStateModel} navStateModel NavigationStateModel to generate URL
  24617. * @param {Function} callback callback funtion is invoked when URL is generated, URL will be passed into callback
  24618. * @param {JSON} params additional parameter in json format
  24619. * @type String
  24620. * @return {String} The URL that's generated based on navigationStateModel
  24621. * @deprecated Use getURL instead.
  24622. */
  24623. getUrl:function(navStateModel,callback,params) {
  24624. },
  24625. /**
  24626. * Returns the URL based on navigation state model and additional parameters.
  24627. * Sample parameter: {nohash:"true"}
  24628. * if "nohash" is set to "true",the returned URL will not contain state in hash.
  24629. *
  24630. * @param {com.ibm.mashups.enabler.model.state.NavigationStateModel} navStateModel NavigationStateModel to generate URL
  24631. * @param {Function} callback callback funtion is invoked when URL is generated, URL will be passed into callback
  24632. * @param {JSON} params additional parameter in json format
  24633. * @type String
  24634. * @return {String} The URL that's generated based on navigationStateModel
  24635. */
  24636. getURL:function(navStateModel,callback,params) {
  24637. }
  24638. });
  24639. }
  24640. if(!dojo._hasResource["com.ibm.mm.enabler.model.state.UrlGeneratorImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  24641. dojo._hasResource["com.ibm.mm.enabler.model.state.UrlGeneratorImpl"] = true;
  24642. dojo.provide("com.ibm.mm.enabler.model.state.UrlGeneratorImpl");
  24643. dojo.declare("com.ibm.mm.enabler.model.state.UrlGeneratorImpl", com.ibm.mashups.enabler.model.state.UrlGenerator, {
  24644. constructor: function() {
  24645. },
  24646. getUrl: function(navStateModel, callback, params) {
  24647. return this.getURL(navStateModel, callback, params);
  24648. },
  24649. getURL: function(navStateModel, callback, params) {
  24650. if (!navStateModel) {
  24651. return null;
  24652. }
  24653. var clone = navStateModel.clone(); //get a clone so it doesn't affect the original navStateModel
  24654. return clone._getFullUrl(callback, params);
  24655. }
  24656. });
  24657. }
  24658. if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.UrlGenerator"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  24659. dojo._hasResource["com.ibm.mashups.enabler.model.state.UrlGenerator"] = true;
  24660. dojo.provide( "com.ibm.mashups.enabler.model.state.UrlGenerator" );
  24661. }
  24662. if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.UrlGeneratorFactory_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  24663. dojo._hasResource["com.ibm.mashups.enabler.model.state.UrlGeneratorFactory_API"] = true;
  24664. dojo.provide("com.ibm.mashups.enabler.model.state.UrlGeneratorFactory_API");
  24665. dojo.provide("com.ibm.mashups.enabler.model.state.UrlGeneratorFactory");
  24666. /**
  24667. * Interface representing an UrlGeneratorFactory.
  24668. * @ibm-spi
  24669. * @ibm-module Base
  24670. */
  24671. dojo.declare( "com.ibm.mashups.enabler.model.state.UrlGeneratorFactory", null, {
  24672. /**
  24673. * Returns the url generator to get the url based on navigationstatemodel
  24674. * @type com.ibm.mashups.enabler.model.state.UrlGenerator
  24675. * @return {com.ibm.mashups.enabler.model.state.UrlGenerator} The url generator based on navigation state model
  24676. * @deprecated Use getURLGenerator instead.
  24677. */
  24678. getUrlGenerator:function() {
  24679. },
  24680. /**
  24681. * Returns the url generator to get the url based on navigationstatemodel
  24682. * @type com.ibm.mashups.enabler.model.state.UrlGenerator
  24683. * @return {com.ibm.mashups.enabler.model.state.UrlGenerator} The url generator based on navigation state model
  24684. */
  24685. getURLGenerator:function() {
  24686. }
  24687. });
  24688. }
  24689. if(!dojo._hasResource["com.ibm.mm.enabler.model.state.UrlGeneratorFactoryImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  24690. dojo._hasResource["com.ibm.mm.enabler.model.state.UrlGeneratorFactoryImpl"] = true;
  24691. dojo.provide("com.ibm.mm.enabler.model.state.UrlGeneratorFactoryImpl");
  24692. dojo.declare("com.ibm.mm.enabler.model.state.UrlGeneratorFactoryImpl", com.ibm.mashups.enabler.model.state.UrlGeneratorFactory, {
  24693. constructor: function() {
  24694. this._urlGenerator = new com.ibm.mm.enabler.model.state.UrlGeneratorImpl();
  24695. },
  24696. // @deprecated
  24697. getUrlGenerator: function() {
  24698. return this.getURLGenerator();
  24699. },
  24700. getURLGenerator: function() {
  24701. return this._urlGenerator;
  24702. }
  24703. });
  24704. com.ibm.mashups.enabler.model.state.UrlGeneratorFactory = new com.ibm.mm.enabler.model.state.UrlGeneratorFactoryImpl();
  24705. }
  24706. if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.UrlGeneratorFactory"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  24707. dojo._hasResource["com.ibm.mashups.enabler.model.state.UrlGeneratorFactory"] = true;
  24708. dojo.provide("com.ibm.mashups.enabler.model.state.UrlGeneratorFactory" );
  24709. }
  24710. if(!dojo._hasResource["com.ibm.mashups.enabler.strategy.HiddenMetaDataLoadingStrategy"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  24711. dojo._hasResource["com.ibm.mashups.enabler.strategy.HiddenMetaDataLoadingStrategy"] = true;
  24712. dojo.provide("com.ibm.mashups.enabler.strategy.HiddenMetaDataLoadingStrategy");
  24713. /**
  24714. * Interface to control, if hidden meta data are loaded with the MetaData
  24715. * interface or not.<br>
  24716. *
  24717. * @since 2.4
  24718. *
  24719. * @ibm-api
  24720. * @ibm-module Base
  24721. */
  24722. dojo.declare("com.ibm.mashups.enabler.strategy.HiddenMetaDataLoadingStrategy", com.ibm.mashups.enabler.strategy.Strategy, {
  24723. /**
  24724. * @param {String[]} names Array of hidden meta data names to load;
  24725. * must not be <code>null</code>
  24726. */
  24727. constructor: function(names){
  24728. this.names = names;
  24729. },
  24730. /**
  24731. * Indicates hidden meta data to load.
  24732. * @return {Boolean} <code>true</code> if to expose hidden meta data
  24733. */
  24734. getHiddenMetaDataToLoad: function(){
  24735. return this.names;
  24736. }
  24737. });
  24738. }
  24739. if(!dojo._hasResource["com.ibm.mashups.enabler.strategy.ListLoadAheadStrategy"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  24740. dojo._hasResource["com.ibm.mashups.enabler.strategy.ListLoadAheadStrategy"] = true;
  24741. dojo.provide("com.ibm.mashups.enabler.strategy.ListLoadAheadStrategy");
  24742. /**
  24743. * Interface that defines a load ahead strategy for loading elements of a list.
  24744. * When applied to a list model it will load the given number of elements at a
  24745. * time from the backend.<br>
  24746. * Example; A ListLoadAheadStrategy with interval = 10 will cause the model to
  24747. * load new data from the backend with every 10th call of the method next() when
  24748. * using the iterator of the list.
  24749. * @ibm-api
  24750. * @ibm-module Base
  24751. */
  24752. dojo.declare("com.ibm.mashups.enabler.strategy.ListLoadAheadStrategy", com.ibm.mashups.enabler.strategy.Strategy, {
  24753. /**
  24754. * @param {int} interval number of elements to be loaded ahead from the
  24755. * backend. must not be <code>null</code> or less than one.
  24756. */
  24757. constructor: function(interval){
  24758. this.interval = interval;
  24759. },
  24760. /**
  24761. * Returns the number of elements to load ahead
  24762. * @type int
  24763. * @return number of elements to load ahead
  24764. */
  24765. getInterval: function(){
  24766. return this.interval;
  24767. }
  24768. });
  24769. }
  24770. if(!dojo._hasResource["com.ibm.mashups.enabler.strategy.SyncMetaDataStrategy"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  24771. dojo._hasResource["com.ibm.mashups.enabler.strategy.SyncMetaDataStrategy"] = true;
  24772. dojo.provide("com.ibm.mashups.enabler.strategy.SyncMetaDataStrategy");
  24773. /**
  24774. * Interface to control, if a meta data set/deleted on a content node is synchronized to the respective navigation node and vice versa.
  24775. *
  24776. * @since 2.4
  24777. *
  24778. * @ibm-api
  24779. * @ibm-module Base
  24780. */
  24781. dojo.declare("com.ibm.mashups.enabler.strategy.SyncMetaDataStrategy", com.ibm.mashups.enabler.strategy.Strategy, {
  24782. });
  24783. }
  24784. if(!dojo._hasResource["com.ibm.mashups.enabler.strategy.TreeLoadAheadStrategy"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  24785. dojo._hasResource["com.ibm.mashups.enabler.strategy.TreeLoadAheadStrategy"] = true;
  24786. dojo.provide("com.ibm.mashups.enabler.strategy.TreeLoadAheadStrategy");
  24787. /**
  24788. * Interface that defines a load ahead strategy for loading elements wihin a
  24789. * tree hierarchy. When applied to a tree model it will load the given number
  24790. * of elements at a time from the backend.<br>
  24791. * Example; A TreeLoadAheadStrategy with parentLevel = 2 and childrenLevel = 2 will<br>
  24792. * <ul><li>load the parent as well as all the parents of the parent when calling
  24793. * getParent on a given node and</li>
  24794. * <li>load the children as well as all the children of the child when calling
  24795. * getChildren on a given node.</li></ul>
  24796. * @ibm-api
  24797. * @ibm-module Base
  24798. */
  24799. dojo.declare("com.ibm.mashups.enabler.strategy.TreeLoadAheadStrategy", com.ibm.mashups.enabler.strategy.Strategy, {
  24800. /**
  24801. * @param {int} parentLevel number of parent levels to be loaded ahead from
  24802. * the backend. must not be <code>null</code> or less than one.
  24803. * @param {int} childrenLevel number of children levels to be loaded ahead
  24804. * from the backend. must not be <code>null</code> or less than one.
  24805. */
  24806. constructor: function(parentLevel, childrenLevel){
  24807. this.parentLevel = parentLevel;
  24808. this.childrenLevel = childrenLevel;
  24809. },
  24810. /**
  24811. * Returns the number of children levels in the hierarchy to load ahead
  24812. * @return {int} number of children levels to load ahead
  24813. */
  24814. getChildrenLevel: function(){
  24815. return this.childrenLevel;
  24816. },
  24817. /**
  24818. * Returns the number of parent levels in the hierarchy to load ahead
  24819. * @return {int} number of parent levels to load ahead
  24820. */
  24821. getParentLevel: function(){
  24822. return this.parentLevel;
  24823. }
  24824. });
  24825. }
  24826. if(!dojo._hasResource["com.ibm.mashups.enabler.utils.EventTransformer_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  24827. dojo._hasResource["com.ibm.mashups.enabler.utils.EventTransformer_API"] = true;
  24828. dojo.provide("com.ibm.mashups.enabler.utils.EventTransformer_API");
  24829. dojo.provide("com.ibm.mashups.enabler.utils.EventTransformer");
  24830. /**
  24831. * Event Transformer that checks compatibility between events.
  24832. * Compatibility checks work bi-directionally, for example a source event with payload type time can
  24833. * be checked against a target event with payload xsd:time. The reverse direction can also be checked, i.e
  24834. * a source event with xsd:time checked against a target event with payload time. The compatibility check is
  24835. * applicable for xsd primitive data types and Mashup simple types.
  24836. *
  24837. * @ibm-module Base
  24838. */
  24839. dojo.declare("com.ibm.mashups.enabler.utils.EventTransformer", null, {
  24840. /**
  24841. * Checks the compatibility of sourceEvent and targetEvent.
  24842. *
  24843. * @ibm-api
  24844. *
  24845. * @param {com.ibm.mashups.iwidget.event} sourceEvent the event to be checked
  24846. * @param {com.ibm.mashups.iwidget.event} targetEvent the event that sourceEvent is checked against.
  24847. * @param {Boolean} relaxed If relaxed is true, then the checking of the type matches are flexible,
  24848. * if false then only direct type matches are checked
  24849. * @return {Boolean} true if events are compatible, false otherwise.
  24850. */
  24851. isTransformable: function(sourceEvent, targetEvent, relaxed){
  24852. }
  24853. });
  24854. }
  24855. if(!dojo._hasResource["com.ibm.mm.data.datatypes"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  24856. dojo._hasResource["com.ibm.mm.data.datatypes"] = true;
  24857. dojo.provide("com.ibm.mm.data.datatypes");
  24858. /**
  24859. @author <a href="mailto:litong01@us.ibm.com">Tong Li</a>
  24860. @author <a href="mailto:bizheng@cn.ibm.com">Zheng Bi</a>
  24861. @class com.ibm.mm.data.datatypes
  24862. @name com.ibm.mm.data.datatypes
  24863. */
  24864. dojo.declare("com.ibm.mm.data.datatypes", null, /** @lends com.ibm.mm.data.datatypes */ {
  24865. _alltypes: {
  24866. 'text': 1,
  24867. 'url': 1,
  24868. 'html': 1,
  24869. 'image': 1,
  24870. 'number': 1,
  24871. 'countrycode': 1,
  24872. 'languagecode': 1,
  24873. 'currency': 1,
  24874. 'boolean': 1,
  24875. 'date': 1,
  24876. 'time': 1,
  24877. 'timestamp': 1,
  24878. 'email': 1,
  24879. 'postalcode': 1,
  24880. 'phone': 1,
  24881. 'address': 1,
  24882. 'person': 1,
  24883. 'table': 1,
  24884. 'atom': 1,
  24885. 'xml': 1,
  24886. 'json': 1,
  24887. 'modeldata': 1,
  24888. 'xsd:string': 1,
  24889. 'xsd:boolean': 1,
  24890. 'xsd:decimal': 1,
  24891. 'xsd:float': 1,
  24892. 'xsd:double': 1,
  24893. 'xsd:duration': 1,
  24894. 'xsd:datetime': 1,
  24895. 'xsd:time': 1,
  24896. 'xsd:date': 1,
  24897. 'xsd:gyearmonth': 1,
  24898. 'xsd:gyear': 1,
  24899. 'xsd:gmonthday': 1,
  24900. 'xsd:gday': 1,
  24901. 'xsd:gmonth': 1,
  24902. 'xsd:hexbinary': 1,
  24903. 'xsd:base64binary': 1,
  24904. 'xsd:anyuri': 1,
  24905. 'xsd:qname': 1,
  24906. 'xsd:notation': 1,
  24907. 'js:string': 1,
  24908. 'js:number': 1,
  24909. 'js:date': 1,
  24910. 'js:boolean': 1
  24911. },
  24912. _simpleTypes: {
  24913. 'text': 1,
  24914. 'url': 1,
  24915. 'html': 1,
  24916. 'image': 1,
  24917. 'number': 1,
  24918. 'countrycode': 1,
  24919. 'languagecode': 1,
  24920. 'currency': 1,
  24921. 'boolean': 1,
  24922. 'date': 1,
  24923. 'time': 1,
  24924. 'timestamp': 1,
  24925. 'email': 1,
  24926. 'postalcode': 1,
  24927. 'phone': 1,
  24928. 'address': 1,
  24929. 'person': 1,
  24930. 'xsd:string': 1,
  24931. 'xsd:boolean': 1,
  24932. 'xsd:decimal': 1,
  24933. 'xsd:float': 1,
  24934. 'xsd:double': 1,
  24935. 'xsd:duration': 1,
  24936. 'xsd:datetime': 1,
  24937. 'xsd:time': 1,
  24938. 'xsd:date': 1,
  24939. 'xsd:gyearmonth': 1,
  24940. 'xsd:gyear': 1,
  24941. 'xsd:gmonthday': 1,
  24942. 'xsd:gday': 1,
  24943. 'xsd:gmonth': 1,
  24944. 'xsd:hexbinary': 1,
  24945. 'xsd:base64binary': 1,
  24946. 'xsd:anyuri': 1,
  24947. 'xsd:qname': 1,
  24948. 'xsd:notation': 1,
  24949. 'js:string': 1,
  24950. 'js:number': 1,
  24951. 'js:date': 1,
  24952. 'js:boolean': 1
  24953. },
  24954. _complexTypes: {
  24955. 'table': 1,
  24956. 'atom': 1,
  24957. 'xml': 1,
  24958. 'json': 1,
  24959. 'modeldata': 1
  24960. },
  24961. specialTypes: {
  24962. 'mashupdata': 1
  24963. },
  24964. _mappings: {
  24965. //mashup types
  24966. text: {
  24967. 'url': 1,
  24968. 'html': 1,
  24969. 'number': 1,
  24970. 'countrycode': 1,
  24971. 'languagecode': 1,
  24972. 'currency': 1,
  24973. 'boolean': 1,
  24974. 'date': 1,
  24975. 'time': 1,
  24976. 'timestamp': 1,
  24977. 'email': 1,
  24978. 'postalcode': 1,
  24979. 'phone': 1,
  24980. 'address': 1,
  24981. 'person': 1,
  24982. 'xsd:string': 1,
  24983. 'xsd:boolean': 1,
  24984. 'xsd:decimal': 1,
  24985. 'xsd:float': 1,
  24986. 'xsd:double': 1,
  24987. 'xsd:duration': 1,
  24988. 'xsd:datetime': 1,
  24989. 'xsd:time': 1,
  24990. 'xsd:date': 1,
  24991. 'xsd:gyearmonth': 1,
  24992. 'xsd:gyear': 1,
  24993. 'xsd:gmonthday': 1,
  24994. 'xsd:gday': 1,
  24995. 'xsd:gmonth': 1,
  24996. 'xsd:hexbinary': 1,
  24997. 'xsd:base64binary': 1,
  24998. 'xsd:anyuri': 1,
  24999. 'xsd:qname': 1,
  25000. 'xsd:notation': 1,
  25001. 'js:string': 1,
  25002. 'js:number': 1,
  25003. 'js:date': 1,
  25004. 'js:boolean': 1
  25005. },
  25006. 'url': {
  25007. 'xsd:anyuri': 1,
  25008. 'text': 1,
  25009. 'xsd:string': 1,
  25010. 'js:string': 1
  25011. },
  25012. 'html': {
  25013. 'text': 1,
  25014. 'xsd:string': 1,
  25015. 'js:string': 1
  25016. },
  25017. 'image': {},
  25018. 'number': {
  25019. 'xsd:decimal': 1,
  25020. 'xsd:float': 1,
  25021. 'xsd:double': 1,
  25022. 'js:number': 1,
  25023. 'text': 1,
  25024. 'xsd:string': 1,
  25025. 'js:string': 1
  25026. },
  25027. 'countrycode': {
  25028. 'text': 1,
  25029. 'xsd:string': 1,
  25030. 'js:string': 1
  25031. },
  25032. 'languagecode': {
  25033. 'text': 1,
  25034. 'xsd:string': 1,
  25035. 'js:string': 1
  25036. },
  25037. 'currency': {
  25038. 'text': 1,
  25039. 'xsd:string': 1,
  25040. 'js:string': 1
  25041. },
  25042. 'boolean': {
  25043. 'xsd:boolean': 1,
  25044. 'js:boolean': 1,
  25045. 'text': 1,
  25046. 'xsd:string': 1,
  25047. 'js:string': 1
  25048. },
  25049. 'date': {
  25050. 'timestamp': 1,
  25051. 'xsd:date': 1,
  25052. 'js:date': 1,
  25053. 'text': 1,
  25054. 'xsd:string': 1,
  25055. 'js:string': 1
  25056. },
  25057. 'time': {
  25058. 'timestamp': 1,
  25059. 'xsd:time': 1,
  25060. 'text': 1,
  25061. 'xsd:string': 1,
  25062. 'js:string': 1
  25063. },
  25064. 'timestamp': {
  25065. 'date': 1,
  25066. 'time': 1,
  25067. 'xsd:datetime': 1,
  25068. 'text': 1,
  25069. 'xsd:string': 1,
  25070. 'js:string': 1
  25071. },
  25072. 'email': {
  25073. 'text': 1,
  25074. 'xsd:string': 1,
  25075. 'js:string': 1
  25076. },
  25077. 'postalcode': {
  25078. 'text': 1,
  25079. 'xsd:string': 1,
  25080. 'js:string': 1
  25081. },
  25082. 'phone': {
  25083. 'text': 1,
  25084. 'xsd:string': 1,
  25085. 'js:string': 1
  25086. },
  25087. 'address': {
  25088. 'text': 1,
  25089. 'xsd:string': 1,
  25090. 'js:string': 1
  25091. },
  25092. 'person': {
  25093. 'text': 1,
  25094. 'xsd:string': 1,
  25095. 'js:string': 1
  25096. },
  25097. 'json': {},
  25098. //xsd types
  25099. 'xsd:string': {
  25100. 'text': 1,
  25101. 'url': 1,
  25102. 'html': 1,
  25103. 'number': 1,
  25104. 'countrycode': 1,
  25105. 'languagecode': 1,
  25106. 'currency': 1,
  25107. 'boolean': 1,
  25108. 'date': 1,
  25109. 'time': 1,
  25110. 'timestamp': 1,
  25111. 'email': 1,
  25112. 'postalcode': 1,
  25113. 'phone': 1,
  25114. 'address': 1,
  25115. 'person': 1,
  25116. 'xsd:boolean': 1,
  25117. 'xsd:decimal': 1,
  25118. 'xsd:float': 1,
  25119. 'xsd:double': 1,
  25120. 'xsd:duration': 1,
  25121. 'xsd:datetime': 1,
  25122. 'xsd:time': 1,
  25123. 'xsd:date': 1,
  25124. 'xsd:gyearmonth': 1,
  25125. 'xsd:gyear': 1,
  25126. 'xsd:gmonthday': 1,
  25127. 'xsd:gday': 1,
  25128. 'xsd:gmonth': 1,
  25129. 'xsd:hexbinary': 1,
  25130. 'xsd:base64binary': 1,
  25131. 'xsd:anyuri': 1,
  25132. 'xsd:qname': 1,
  25133. 'xsd:notation': 1,
  25134. 'js:string': 1,
  25135. 'js:number': 1,
  25136. 'js:date': 1,
  25137. 'js:boolean': 1
  25138. },
  25139. 'xsd:boolean': {
  25140. 'boolean': 1,
  25141. 'js:boolean': 1,
  25142. 'text': 1,
  25143. 'xsd:string': 1,
  25144. 'js:string': 1
  25145. },
  25146. 'xsd:decimal': {
  25147. 'number': 1,
  25148. 'js:number': 1,
  25149. 'text': 1,
  25150. 'xsd:string': 1,
  25151. 'js:string': 1
  25152. },
  25153. 'xsd:float': {
  25154. 'number': 1,
  25155. 'js:number': 1,
  25156. 'text': 1,
  25157. 'xsd:string': 1,
  25158. 'js:string': 1
  25159. },
  25160. 'xsd:double': {
  25161. 'number': 1,
  25162. 'js:number': 1,
  25163. 'text': 1,
  25164. 'xsd:string': 1,
  25165. 'js:string': 1
  25166. },
  25167. 'xsd:duration': {
  25168. 'text': 1,
  25169. 'xsd:string': 1,
  25170. 'js:string': 1
  25171. },
  25172. 'xsd:gmonthday': {
  25173. 'text': 1,
  25174. 'xsd:string': 1,
  25175. 'js:string': 1
  25176. },
  25177. 'xsd:gday': {
  25178. 'text': 1,
  25179. 'xsd:string': 1,
  25180. 'js:string': 1
  25181. },
  25182. 'xsd:gmonth': {
  25183. 'text': 1,
  25184. 'xsd:string': 1,
  25185. 'js:string': 1
  25186. },
  25187. 'xsd:hexbinary': {
  25188. 'text': 1,
  25189. 'xsd:string': 1,
  25190. 'js:string': 1
  25191. },
  25192. 'xsd:base64binary': {
  25193. 'text': 1,
  25194. 'xsd:string': 1,
  25195. 'js:string': 1
  25196. },
  25197. 'xsd:qname': {
  25198. 'text': 1,
  25199. 'xsd:string': 1,
  25200. 'js:string': 1
  25201. },
  25202. 'xsd:notation': {
  25203. 'text': 1,
  25204. 'xsd:string': 1,
  25205. 'js:string': 1
  25206. },
  25207. 'xsd:anyuri': {
  25208. 'url': 1,
  25209. 'text': 1,
  25210. 'xsd:string': 1,
  25211. 'js:string': 1
  25212. },
  25213. 'xsd:time': {
  25214. 'time': 1,
  25215. 'text': 1,
  25216. 'xsd:string': 1,
  25217. 'js:string': 1
  25218. },
  25219. 'xsd:date': {
  25220. 'date': 1,
  25221. 'js:date': 1,
  25222. 'text': 1,
  25223. 'xsd:string': 1,
  25224. 'js:string': 1
  25225. },
  25226. 'xsd:datetime': {
  25227. 'timestamp': 1,
  25228. 'text': 1,
  25229. 'xsd:string': 1,
  25230. 'js:string': 1
  25231. },
  25232. 'xsd:gyear': {
  25233. 'date': 1,
  25234. 'text': 1,
  25235. 'xsd:string': 1,
  25236. 'js:string': 1
  25237. },
  25238. 'xsd:gyearmonth': {
  25239. 'date': 1,
  25240. 'text': 1,
  25241. 'xsd:string': 1,
  25242. 'js:string': 1
  25243. },
  25244. //js types
  25245. 'js:string': {
  25246. 'text': 1,
  25247. 'url': 1,
  25248. 'html': 1,
  25249. 'number': 1,
  25250. 'countrycode': 1,
  25251. 'languagecode': 1,
  25252. 'currency': 1,
  25253. 'boolean': 1,
  25254. 'date': 1,
  25255. 'time': 1,
  25256. 'timestamp': 1,
  25257. 'email': 1,
  25258. 'postalcode': 1,
  25259. 'phone': 1,
  25260. 'address': 1,
  25261. 'person': 1,
  25262. 'xsd:string': 1,
  25263. 'xsd:boolean': 1,
  25264. 'xsd:decimal': 1,
  25265. 'xsd:float': 1,
  25266. 'xsd:double': 1,
  25267. 'xsd:duration': 1,
  25268. 'xsd:datetime': 1,
  25269. 'xsd:time': 1,
  25270. 'xsd:date': 1,
  25271. 'xsd:gyearmonth': 1,
  25272. 'xsd:gyear': 1,
  25273. 'xsd:gmonthday': 1,
  25274. 'xsd:gday': 1,
  25275. 'xsd:gmonth': 1,
  25276. 'xsd:hexbinary': 1,
  25277. 'xsd:base64binary': 1,
  25278. 'xsd:anyuri': 1,
  25279. 'xsd:qname': 1,
  25280. 'xsd:notation': 1,
  25281. 'js:number': 1,
  25282. 'js:date': 1,
  25283. 'js:boolean': 1
  25284. },
  25285. 'js:date': {
  25286. 'date': 1,
  25287. 'xsd:date': 1,
  25288. 'text': 1,
  25289. 'xsd:string': 1,
  25290. 'js:string': 1
  25291. },
  25292. 'js:number': {
  25293. 'xsd:decimal': 1,
  25294. 'xsd:float': 1,
  25295. 'xsd:double': 1,
  25296. 'number': 1,
  25297. 'text': 1,
  25298. 'xsd:string': 1,
  25299. 'js:string': 1
  25300. },
  25301. 'js:boolean': {
  25302. 'xsd:boolean': 1,
  25303. 'boolean': 1,
  25304. 'text': 1,
  25305. 'xsd:string': 1,
  25306. 'js:string': 1
  25307. }
  25308. },
  25309. _semanticMappings: {
  25310. text: {
  25311. 'xsd:string': 1,
  25312. 'js:string': 1
  25313. },
  25314. 'url': {
  25315. 'xsd:anyuri': 1
  25316. },
  25317. 'html': {},
  25318. 'image': {},
  25319. 'number': {
  25320. 'xsd:decimal': 1,
  25321. 'xsd:float': 1,
  25322. 'xsd:double': 1,
  25323. 'js:number': 1
  25324. },
  25325. 'countrycode': {},
  25326. 'languagecode': {},
  25327. 'currency': {},
  25328. 'boolean': {
  25329. 'xsd:boolean': 1,
  25330. 'js:boolean': 1
  25331. },
  25332. 'date': {
  25333. 'xsd:date': 1,
  25334. 'js:date': 1
  25335. },
  25336. 'time': {
  25337. 'xsd:time': 1
  25338. },
  25339. 'timestamp': {
  25340. 'xsd:datetime': 1
  25341. },
  25342. 'email': {},
  25343. 'postalcode': {},
  25344. 'phone': {},
  25345. 'address': {},
  25346. 'person': {},
  25347. 'json': {},
  25348. 'xsd:string': {
  25349. 'text': 1,
  25350. 'js:string': 1
  25351. },
  25352. 'xsd:boolean': {
  25353. 'boolean': 1,
  25354. 'js:boolean': 1
  25355. },
  25356. 'xsd:decimal': {
  25357. 'number': 1,
  25358. 'js:number': 1
  25359. },
  25360. 'xsd:float': {
  25361. 'number': 1,
  25362. 'js:number': 1
  25363. },
  25364. 'xsd:double': {
  25365. 'number': 1,
  25366. 'js:number': 1
  25367. },
  25368. 'xsd:duration': {},
  25369. 'xsd:gmonthday': {},
  25370. 'xsd:gday': {},
  25371. 'xsd:gmonth': {},
  25372. 'xsd:hexbinary': {},
  25373. 'xsd:base64binary': {},
  25374. 'xsd:qname': {},
  25375. 'xsd:notation': {},
  25376. 'xsd:anyuri': {
  25377. 'url': 1
  25378. },
  25379. 'xsd:time': {
  25380. 'time': 1
  25381. },
  25382. 'xsd:date': {
  25383. 'date': 1,
  25384. 'js:date': 1
  25385. },
  25386. 'xsd:datetime': {
  25387. 'timestamp': 1
  25388. },
  25389. 'xsd:gyear': {
  25390. 'date': 1
  25391. },
  25392. 'xsd:gyearmonth': {
  25393. 'date': 1
  25394. },
  25395. 'js:string': {
  25396. 'text': 1,
  25397. 'xsd:string': 1
  25398. },
  25399. 'js:date': {
  25400. 'date': 1,
  25401. 'xsd:date': 1
  25402. },
  25403. 'js:number': {
  25404. 'xsd:decimal': 1,
  25405. 'xsd:float': 1,
  25406. 'xsd:double': 1,
  25407. 'number': 1
  25408. },
  25409. 'js:boolean': {
  25410. 'xsd:boolean': 1,
  25411. 'boolean': 1
  25412. }
  25413. },
  25414. _SIMPLE_DATA_TYPE: 1,
  25415. _COMBINED_DATA_TYPE: 2,
  25416. _COMPLEX_DATA_TYPE: 3,
  25417. resourceBundle: null,
  25418. constructor: function(/* String */datatypecfg) {
  25419. this.resourceBundle = dojo.i18n.getLocalization("com.ibm.mm.data", "dataTypeStrings");
  25420. this.xsdNS = com.ibm.mm.enabler.model.NameSpaceFactory.getNameSpaceUri(com.ibm.mm.enabler.model.NameSpaceFactory.NS_XSD);
  25421. this.nsNS = com.ibm.mm.enabler.model.NameSpaceFactory.getNameSpaceUri(com.ibm.mm.enabler.model.NameSpaceFactory.NS_EVENT_DATATYPES);
  25422. this.jsNS = com.ibm.mm.enabler.model.NameSpaceFactory.getNameSpaceUri(com.ibm.mm.enabler.model.NameSpaceFactory.NS_JS);
  25423. this.xsdPrefix = "xsd:";
  25424. this.nsPrefix = "";
  25425. this.jsPrefix = "js:";
  25426. },
  25427. addDataType: function(/* String */typename, /* String */ typeCat) {
  25428. //Check type name
  25429. if (!typename) {
  25430. return;
  25431. }
  25432. this._alltypes.typename = 1;
  25433. //Check the type category
  25434. if (!typeCat || typeCat == this._SIMPLE_DATA_TYPE) {
  25435. this._simpleTypes.typename = 1;
  25436. }
  25437. else {
  25438. this._complexTypes.typename = 1;
  25439. }
  25440. },
  25441. removeDataType: function(/* String */typename) {
  25442. delete this._alltypes[typename];
  25443. },
  25444. addDataMapping: function(/* String */typename1, /* String */ typename2) {
  25445. if (this._mappings.typename1 === null) {
  25446. this._mappings.typename1 = {};
  25447. }
  25448. this._mappings[typename1][typename2] = 1;
  25449. },
  25450. removeDataMapping: function(/* String */typename1, /* String */ typename2) {
  25451. if (this._mappings[typename1] !== null) {
  25452. if (this._mappings[typename1][typename2] !== null) {
  25453. delete this._mappings[typename1][typename2];
  25454. }
  25455. }
  25456. },
  25457. getAllTypes: function() {
  25458. return dojo.clone(this._alltypes);
  25459. },
  25460. /**
  25461. * The method to return if two types should be considered as a match.
  25462. * It may need more work to include the combined data type mapping mechanism.
  25463. *
  25464. * @param {String} typename1 The first data type name(handle event)
  25465. * @param {String} typename2 The second data type name.(publish event)<b>
  25466. * @returns {Boolean}
  25467. */
  25468. doesTypeMatch: function(/* String */typename1, /* String */ typename2) {
  25469. var doesItMatch = false;
  25470. //null type does not match to any thing.
  25471. if (!typename1 || !typename2 ) {
  25472. return doesItMatch;
  25473. }
  25474. //date type is case-insensitive
  25475. typename1 = typename1.toLowerCase();
  25476. typename2 = typename2.toLowerCase();
  25477. //if two types are same or either type is any, then they are considered as a match.
  25478. if (typename1 == typename2 || typename1 == 'any' || typename2 == 'any') {
  25479. doesItMatch = true;
  25480. }
  25481. else {
  25482. //check the type of the "payload type"
  25483. var typeOfName1 = this.checkDataType(typename1);
  25484. switch (typeOfName1) {
  25485. //typename1 is simple data type
  25486. case this._SIMPLE_DATA_TYPE:
  25487. var typeOfName2 = this.checkDataType(typename2);
  25488. switch (typeOfName2) {
  25489. //Two simple data types, use the mapping to decide whether they match or not
  25490. case this._SIMPLE_DATA_TYPE:
  25491. if (this._mappings[typename1][typename2] == 1) {
  25492. doesItMatch = true;
  25493. }
  25494. break;
  25495. //Simple data type VS combine data type, compare the main type. (url.text's main type is :url)
  25496. case this._COMBINED_DATA_TYPE:
  25497. var mainTypeOfType2 = this.getMainType(typename2);
  25498. if (typename1 == mainTypeOfType2 || this._mappings[typename1][mainTypeOfType2] == 1) { //url can handle url.text
  25499. doesItMatch = true;
  25500. }
  25501. break;
  25502. default:
  25503. break;
  25504. }//end of switch(typeOfName2) {
  25505. break;
  25506. //For comebined type and complex data type as received data type, currently, consider match only when type names are exactly same
  25507. //we can add more logic here in future
  25508. case this._COMBINED_DATA_TYPE:
  25509. break;
  25510. case this._COMPLEX_DATA_TYPE:
  25511. break;
  25512. default:
  25513. break;
  25514. }// enf of switch(typeOfName1)
  25515. }
  25516. return doesItMatch;
  25517. },
  25518. /**
  25519. * The method to return if two types should be considered as a match with a much more flex rule
  25520. * on combined type: only cares about the main type
  25521. *
  25522. * @param {String} typename1 The first data type name(handle event)
  25523. * @param {String} typename2 The second data type name.(publish event)
  25524. * @param {Boolean} relaxed If relaxed is true, then the checking of the type matches are flexible,
  25525. * if false then only direct type matches are checked<b>
  25526. * @returns {Boolean}
  25527. */
  25528. doesTypeFlexMatch: function(/* String */typename1, /* String */ typename2, relaxed) {
  25529. var doesItMatch = false;
  25530. //null type does not match to any thing.
  25531. if (typename1 === null || typename2 === null) {
  25532. return doesItMatch;
  25533. }
  25534. if ((relaxed === null) || (typeof relaxed == "undefined")) {
  25535. //default to true
  25536. relaxed = true;
  25537. }
  25538. // get valid data type
  25539. typename1 = this.getNormalizedPayload(typename1);
  25540. typename2 = this.getNormalizedPayload(typename2);
  25541. //date type is case-insensitive
  25542. typename1 = typename1.toLowerCase();
  25543. typename2 = typename2.toLowerCase();
  25544. //if two types are same or either type is any, then they are considered as a match.
  25545. if (typename1 == typename2 || typename1 == 'any' || typename2 == 'any') {
  25546. doesItMatch = true;
  25547. }
  25548. else {
  25549. //check the type of the "payload type"
  25550. var typeOfName1 = this.checkDataType(typename1);
  25551. var typeOfName2, mainTypeOfType2;
  25552. switch (typeOfName1) {
  25553. //typename1 is simple data type
  25554. case this._SIMPLE_DATA_TYPE:
  25555. typeOfName2 = this.checkDataType(typename2);
  25556. switch (typeOfName2) {
  25557. //Two simple data types, use the mapping to decide whether they match or not
  25558. case this._SIMPLE_DATA_TYPE:
  25559. if (relaxed) {
  25560. if (this._mappings[typename1][typename2] == 1) {
  25561. doesItMatch = true;
  25562. }
  25563. }
  25564. else {
  25565. if (this._semanticMappings[typename1][typename2] == 1) {
  25566. doesItMatch = true;
  25567. }
  25568. }
  25569. break;
  25570. //Simple data type VS combine data type, compare the main type. (url.text's main type is :url)
  25571. case this._COMBINED_DATA_TYPE:
  25572. mainTypeOfType2 = this.getMainType(typename2);
  25573. if (relaxed) {
  25574. if (typename1 == mainTypeOfType2 || this._mappings[typename1][mainTypeOfType2] == 1) { //url can handle url.text
  25575. doesItMatch = true;
  25576. }
  25577. }
  25578. else {
  25579. if (typename1 == mainTypeOfType2 || this._semanticMappings[typename1][mainTypeOfType2] == 1) { //url can handle url.text
  25580. doesItMatch = true;
  25581. }
  25582. }
  25583. break;
  25584. default:
  25585. break;
  25586. }//end of switch(typeOfName2) {
  25587. break;
  25588. //For comebined type and complex data type as received data type, currently, consider match when they have the same mail(prefix) type
  25589. case this._COMBINED_DATA_TYPE:
  25590. typeOfName2 = this.checkDataType(typename2);
  25591. var mainTypeOfType1 = this.getMainType(typename1);
  25592. switch (typeOfName2) {
  25593. //Two simple data types, use the mapping to decide whether they match or not
  25594. case this._SIMPLE_DATA_TYPE:
  25595. if (relaxed) {
  25596. if (mainTypeOfType1 == typename2 || this._mappings[mainTypeOfType1][typename2] == 1) {
  25597. doesItMatch = true;
  25598. }
  25599. }
  25600. else {
  25601. if (mainTypeOfType1 == typename2 || this._semanticMappings[mainTypeOfType1][typename2] == 1) {
  25602. doesItMatch = true;
  25603. }
  25604. }
  25605. break;
  25606. //Simple data type VS combine data type, compare the main type. (url.text's main type is :url)
  25607. case this._COMBINED_DATA_TYPE:
  25608. mainTypeOfType2 = this.getMainType(typename2);
  25609. if (mainTypeOfType1 == mainTypeOfType2 || this._mappings[mainTypeOfType1][mainTypeOfType2] == 1) { //url can handle url.text
  25610. doesItMatch = true;
  25611. }
  25612. break;
  25613. default:
  25614. break;
  25615. }//end of switch(typeOfName2) {
  25616. break;
  25617. //case this._COMPLEX_DATA_TYPE:
  25618. default:
  25619. break;
  25620. }// end of switch(typeOfName1)
  25621. }
  25622. return doesItMatch;
  25623. },
  25624. /**
  25625. * The method to return the mail type of a combined data type. If it's not combined data type,
  25626. * For example:
  25627. * url.text will return url
  25628. *
  25629. * @param {String} typename
  25630. */
  25631. getMainType: function(/* String */typename) {
  25632. var dotPosition = typename.indexOf('.');
  25633. if (dotPosition < 0) {
  25634. return typename;
  25635. }
  25636. else {
  25637. return typename.substring(0, dotPosition);
  25638. }
  25639. },
  25640. checkDataType: function(/* String */typename) {
  25641. //Check if the type name is the format like url.text
  25642. typename = typename.toLowerCase();
  25643. var types = typename.split('.');
  25644. if (types.length == 1) { // Not combine data type
  25645. if (this._simpleTypes[typename] == 1) {
  25646. return this._SIMPLE_DATA_TYPE;
  25647. }
  25648. else {
  25649. return this._COMPLEX_DATA_TYPE;
  25650. }
  25651. }
  25652. else if (types.length == 2 || types.length == 3) { // type like: url.text || text.countrycode || url.text.countrycode
  25653. var prefixType = types[0];
  25654. var suffixType = types[types.length - 1];
  25655. //In v1.1, only support url as prefix and
  25656. //if (this._alltypes[prefixType] == 1 && this._alltypes[suffixType] == 1)
  25657. if (prefixType == "url" || suffixType == "languagecode" || suffixType == "countrycode") {
  25658. return this._COMBINED_DATA_TYPE;
  25659. }
  25660. else {
  25661. return this._COMPLEX_DATA_TYPE;
  25662. }
  25663. }
  25664. else {
  25665. return this._COMPLEX_DATA_TYPE;
  25666. }
  25667. },
  25668. getTypeLabel: function(/* String */typename, /* String */ locale) {
  25669. typename = typename.toLowerCase();
  25670. var shownType = typename;
  25671. var result = this.checkDataType(typename);
  25672. if (result == this._COMBINED_DATA_TYPE) {
  25673. var dotPosition = typename.indexOf('.');
  25674. var main = typename.substring(0, dotPosition);
  25675. var mainType = this.getSimpleTypeLabel(main, locale);
  25676. var sub = typename.substring(dotPosition + 1, typename.length);
  25677. var subType = this.getSimpleTypeLabel(sub, locale);
  25678. shownType = mainType + ' (' + subType + ')';
  25679. }
  25680. else {
  25681. shownType = this.getSimpleTypeLabel(typename, locale);
  25682. }
  25683. return shownType;
  25684. },
  25685. /**
  25686. * Get the usable version of the payload
  25687. * If there is a namespace prefix, normalize
  25688. * @param {String} payload
  25689. */
  25690. getNormalizedPayload: function(/* String */ payload) {
  25691. var payloadType = payload;
  25692. var result = payload;
  25693. var elipsePosition = payload.indexOf('{');
  25694. var endElipsePosition = payload.indexOf('}');
  25695. var prefix = "";
  25696. if (endElipsePosition > elipsePosition) {
  25697. payloadType = payload.substring(elipsePosition + 1, endElipsePosition);
  25698. result = payload.substring(endElipsePosition + 1, payload.length);
  25699. if (payloadType === this.xsdNS) {
  25700. prefix = this.xsdPrefix;
  25701. }
  25702. else
  25703. if (payloadType === this.jsNS) {
  25704. prefix = this.jsPrefix;
  25705. }
  25706. else
  25707. if (payloadType === this.nsNS) {
  25708. prefix = this.nsPrefix;
  25709. }
  25710. result = prefix + result;
  25711. }
  25712. return result;
  25713. },
  25714. /**
  25715. * Get the display name of the simple or complex data type. The rule here is
  25716. * 1. For the simple type predefined, return the display name for this locale
  25717. * 2. For user defined or complex data type, if it's composed with English characters, return the date type with first letter capitalized
  25718. * 3. Otherwise, return the original data type
  25719. * @param {String} typename
  25720. * @param {String} locale
  25721. */
  25722. getSimpleTypeLabel: function(/* String */typename, /* String */ locale) {
  25723. var label;
  25724. if (this.resourceBundle[typename]) {
  25725. label = this.resourceBundle[typename];
  25726. }
  25727. else {
  25728. label = typename.charAt(0).toUpperCase() + typename.substring(1);
  25729. }
  25730. return label;
  25731. }
  25732. });
  25733. }
  25734. if(!dojo._hasResource["com.ibm.mm.enabler.utils.EventTransformerImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  25735. dojo._hasResource["com.ibm.mm.enabler.utils.EventTransformerImpl"] = true;
  25736. dojo.provide("com.ibm.mm.enabler.utils.EventTransformerImpl");
  25737. // EventTransformer implementation
  25738. dojo.declare("com.ibm.mm.enabler.utils.EventTransformerImpl", [com.ibm.mashups.enabler.utils.EventTransformer], {
  25739. constructor: function(){
  25740. this.dataTypes = new com.ibm.mm.data.datatypes();
  25741. },
  25742. _transform: function(sourceEvent, targetEvent, relaxed){
  25743. var transformedEvent = null;
  25744. if (sourceEvent.type == targetEvent.type || sourceEvent.type == 'any' || targetEvent.type == 'any') {
  25745. transformedEvent = new com.ibm.mm.iwidget.IEventImpl(sourceEvent.name, sourceEvent.type, sourceEvent.payload, sourceEvent.source);
  25746. }
  25747. else {
  25748. var validMatch = this.isTransformable(sourceEvent, targetEvent, relaxed);
  25749. if (validMatch) {
  25750. var transformedPayload = null;
  25751. switch (targetEvent.type.toLowerCase()) {
  25752. case "time":
  25753. if (sourceEvent.type.toLowerCase() == "xsd:time") {
  25754. transformedPayload = this._xsdTimeToMmTime(sourceEvent.payload);
  25755. }
  25756. break;
  25757. case "date":
  25758. switch (sourceEvent.type.toLowerCase()) {
  25759. case "xsd:date":
  25760. transformedPayload = this._xsdDateToMmDate(sourceEvent.payload);
  25761. break;
  25762. case "js:date":
  25763. transformedPayload = this._jsDateToMmDate(sourceEvent.payload);
  25764. break;
  25765. }
  25766. break;
  25767. case "timestamp":
  25768. if (sourceEvent.type.toLowerCase() == "xsd:datetime") {
  25769. transformedPayload = this._xsdDateTimeToMmTimestamp(sourceEvent.payload);
  25770. }
  25771. break;
  25772. case "xsd:time":
  25773. if (sourceEvent.type.toLowerCase() == "time") {
  25774. transformedPayload = this._mmTimeToXsdTime(sourceEvent.payload);
  25775. }
  25776. break;
  25777. case "xsd:date":
  25778. switch (sourceEvent.type.toLowerCase()) {
  25779. case "date":
  25780. transformedPayload = this._mmDateToXsdDate(sourceEvent.payload);
  25781. break;
  25782. case "js:date":
  25783. transformedPayload = this._jsDateToXsdDate(sourceEvent.payload);
  25784. break;
  25785. }
  25786. break;
  25787. case "xsd:datetime":
  25788. if (sourceEvent.type.toLowerCase() == "timestamp") {
  25789. transformedPayload = this._mmTimestampToXsdDatetime(sourceEvent.payload);
  25790. }
  25791. break;
  25792. case "js:date":
  25793. switch (sourceEvent.type.toLowerCase()) {
  25794. case "xsd:date":
  25795. transformedPayload = this._xsdDateToJsDate(sourceEvent.payload);
  25796. break;
  25797. case "date":
  25798. transformedPayload = this._mmDateToJsDate(sourceEvent.payload);
  25799. break;
  25800. }
  25801. break;
  25802. }
  25803. if (transformedPayload !== null) {
  25804. transformedEvent = new com.ibm.mm.iwidget.IEventImpl(sourceEvent.name, targetEvent.type, transformedPayload, sourceEvent.source);
  25805. }
  25806. else {
  25807. // they are compatible and no payload transformation needed
  25808. transformedEvent = new com.ibm.mm.iwidget.IEventImpl(sourceEvent.name, targetEvent.type, sourceEvent.payload, sourceEvent.source);
  25809. }
  25810. }
  25811. }
  25812. return transformedEvent;
  25813. },
  25814. isTransformable: function(sourceEvent, targetEvent, relaxed){
  25815. return this.dataTypes.doesTypeFlexMatch(sourceEvent.type, targetEvent.type, relaxed);
  25816. },
  25817. _mmTimestampToXsdDatetime: function(timestamp){
  25818. var timestampDelimiter = "T";
  25819. var dateDelimiter = "-";
  25820. var timeDelimiter = ":";
  25821. var defaultFormat = /^([\d]{4})-([\d]{2})-([\d]{2})\s([\d]{2}):([\d]{2}):([\d]{2})$/; //YYYY-MM-DD hh:mm:ss
  25822. var longFormat = /^([\d]{4})-([\d]{2})-([\d]{2})\s([\d]{2}):([\d]{2}):([\d]{2})\.([\d]{4})$/; //YYYY-MM-DD hh:mm:ss.mmmm
  25823. var shortFormat = /^([\d]{4})([\d]{2})([\d]{2})\s([\d]{2})([\d]{2})([\d]{2})$/; //YYYYMMDD hhmmss
  25824. var isValidFormat = false;
  25825. //check YYYY-MM-DD hh:mm:ss.mmmm
  25826. isValidFormat = longFormat.test(timestamp);
  25827. if (isValidFormat) {
  25828. var newTimeStamp = timestamp.split(new RegExp("[.]{1}"))[0];
  25829. return newTimeStamp.replace(/\s/, timestampDelimiter);
  25830. }
  25831. else {
  25832. //check YYYY-MM-DD hh:mm:ss
  25833. isValidFormat = defaultFormat.test(timestamp);
  25834. if (isValidFormat) {
  25835. return timestamp.replace(/\s/, timestampDelimiter);
  25836. }
  25837. else {
  25838. //check YYYYMMDD hhmmss
  25839. isValidFormat = shortFormat.test(timestamp);
  25840. if (isValidFormat) {
  25841. var parts = shortFormat.exec(timestamp);
  25842. var yyyy = parts[1];
  25843. var months = parts[2];
  25844. var dd = parts[3];
  25845. var hh = parts[4];
  25846. var minutes = parts[5];
  25847. var ss = parts[6];
  25848. return yyyy + dateDelimiter + months + dateDelimiter + dd + timestampDelimiter + hh + timeDelimiter + minutes + timeDelimiter + ss;
  25849. }
  25850. else {
  25851. //not valid format
  25852. return null;
  25853. }
  25854. }
  25855. }
  25856. },
  25857. _mmDateToXsdDate: function(date){
  25858. //defaults
  25859. var delimiter = "-";
  25860. var defaultmm = "01";
  25861. var defaultdd = "01";
  25862. var defaultFormat = /^([\d]{4})-([\d]{2})-([\d]{2})$/; //YYYY-MM-DD
  25863. var yyyymmddFormat = /^([\d]{4})([\d]{2})([\d]{2})$/; //YYYYMMDD
  25864. var yyyymmFormat = /^([\d]{4})([\d]{2})$/; //YYYYMM
  25865. var yyyyFormat = /^([\d]{4})$/; //YYYY
  25866. var isValidFormat = false;
  25867. // split(new RegExp("[./]{1}"))
  25868. isValidFormat = defaultFormat.test(date);
  25869. if (isValidFormat) {
  25870. //already in correct format
  25871. return date;
  25872. }
  25873. else {
  25874. //check YYYYMMDD
  25875. isValidFormat = yyyymmddFormat.test(date);
  25876. var yyyy, mm, parts;
  25877. if (isValidFormat) {
  25878. parts = yyyymmddFormat.exec(date);
  25879. yyyy = parts[1];
  25880. mm = parts[2];
  25881. var dd = parts[3];
  25882. return yyyy + delimiter + mm + delimiter + dd;
  25883. }
  25884. else {
  25885. //check YYYYMM
  25886. isValidFormat = yyyymmFormat.test(date);
  25887. if (isValidFormat) {
  25888. parts = yyyymmFormat.exec(date);
  25889. yyyy = parts[1];
  25890. mm = parts[2];
  25891. return yyyy + delimiter + mm + delimiter + defaultdd;
  25892. }
  25893. else {
  25894. //check YYYY
  25895. isValidFormat = yyyyFormat.test(date);
  25896. if (isValidFormat) {
  25897. parts = yyyyFormat.exec(date);
  25898. yyyy = parts[1];
  25899. return yyyy + delimiter + defaultmm + delimiter + defaultdd;
  25900. }
  25901. else {
  25902. //not valid format
  25903. return null;
  25904. }
  25905. }
  25906. }
  25907. }
  25908. },
  25909. _mmTimeToXsdTime: function(time){
  25910. var delimiter = ":";
  25911. var defaultmm = "00";
  25912. var defaultss = "00";
  25913. var hhmmssmmmmFormat = /^\d{2}\:\d{2}\:\d{2}\.\d{4}$/; //hh:mm:ss.mmmm
  25914. var hhmmssFormat = /^\d{2}\:\d{2}\:\d{2}$/; //hh:mm:ss
  25915. var hhmmFormat = /^\d{2}\:\d{2}$/; //hh:mm
  25916. var hhFormat = /^\d{2}$/; //hh
  25917. var isValidFormat = false;
  25918. //check hh:mm:ss.mmmm
  25919. isValidFormat = hhmmssmmmmFormat.test(time);
  25920. if (isValidFormat) {
  25921. return time.split(new RegExp("[.]{1}"))[0];
  25922. }
  25923. else {
  25924. //check hh:mm:ss
  25925. isValidFormat = hhmmssFormat.test(time);
  25926. if (isValidFormat) {
  25927. //already in valid format
  25928. return time;
  25929. }
  25930. else {
  25931. //check hh:mm
  25932. isValidFormat = hhmmFormat.test(time);
  25933. if (isValidFormat) {
  25934. //already in valid format
  25935. return time + delimiter + defaultss;
  25936. }
  25937. else {
  25938. //check hh
  25939. isValidFormat = hhFormat.test(time);
  25940. if (isValidFormat) {
  25941. //already in valid format
  25942. return time + delimiter + defaultmm + delimiter + defaultss;
  25943. }
  25944. else {
  25945. //not in valid format
  25946. return null;
  25947. }
  25948. }
  25949. }
  25950. }
  25951. },
  25952. _xsdDateTimeToMmTimestamp: function(datetime){
  25953. var datetimeDelimiter = " ";
  25954. var defaultFormat = /^\d{4}\-\d{2}\-\d{2}\T\d{2}\:\d{2}\:\d{2}/; //YYYY-MM-DD hh:mm:ss
  25955. var isValidFormat = false;
  25956. isValidFormat = defaultFormat.test(datetime);
  25957. if (isValidFormat) {
  25958. var newDateTime = datetime.match(defaultFormat)[0];
  25959. return newDateTime.replace(/T/, datetimeDelimiter);
  25960. }
  25961. else {
  25962. //not in valid format
  25963. return null;
  25964. }
  25965. },
  25966. _xsdDateToMmDate: function(date){
  25967. var defaultFormat = /^\d{4}\-\d{2}\-\d{2}/; //YYYY-MM-DD
  25968. var isValidFormat = false;
  25969. isValidFormat = defaultFormat.test(date);
  25970. if (isValidFormat) {
  25971. return date.match(defaultFormat)[0];
  25972. }
  25973. else {
  25974. //not in valid format
  25975. return null;
  25976. }
  25977. },
  25978. _xsdTimeToMmTime: function(time){
  25979. var defaultFormat = /^\d{2}\:\d{2}\:\d{2}/; //HH-MM-SS
  25980. var isValidFormat = false;
  25981. isValidFormat = defaultFormat.test(time);
  25982. if (isValidFormat) {
  25983. return time.match(defaultFormat)[0];
  25984. }
  25985. else {
  25986. //not in valid format
  25987. return null;
  25988. }
  25989. },
  25990. _jsDateToMmDate: function(date){
  25991. //YYYY-MM-DD
  25992. if (date) {
  25993. var year = date.getFullYear();
  25994. var month = date.getMonth();
  25995. var day = date.getDate();
  25996. month = this._format(month.toString());
  25997. day = this._format(day.toString());
  25998. return year + "-" + month + "-" + day;
  25999. }
  26000. else {
  26001. return null;
  26002. }
  26003. },
  26004. _jsDateToXsdDate: function(date){
  26005. var xsdDate = null;
  26006. if (date) {
  26007. var year = date.getFullYear();
  26008. var month = date.getMonth();
  26009. var day = date.getDate();
  26010. var timezoneOffset = date.getTimezoneOffset();
  26011. month = this._format(month.toString());
  26012. day = this._format(day.toString());
  26013. xsdDate = year + "-" + month + "-" + day;
  26014. if (timezoneOffset !== 0) {
  26015. var timezone;
  26016. var hours;
  26017. var minutes;
  26018. if (timezoneOffset < 0) {
  26019. hours = Math.ceil(timezoneOffset / 60);
  26020. minutes = (timezoneOffset * -1) % 60;
  26021. if (minutes === 0) {
  26022. timezone = "-" + this._format((hours * -1).toString()) + ":00";
  26023. }
  26024. else {
  26025. timezone = "-" + this._format((hours * -1).toString()) + this._format(minutes);
  26026. }
  26027. xsdDate = xsdDate + timezone;
  26028. }
  26029. else {
  26030. hours = Math.floor(timezoneOffset / 60);
  26031. minutes = timezoneOffset % 60;
  26032. if (minutes === 0) {
  26033. timezone = "+" + this._format((hours).toString()) + ":00";
  26034. }
  26035. else {
  26036. timezone = "+" + this._format((hours).toString()) + this._format(minutes);
  26037. }
  26038. xsdDate = xsdDate + timezone;
  26039. }
  26040. }
  26041. }
  26042. return xsdDate;
  26043. },
  26044. _xsdDateToJsDate: function(date){
  26045. var defaultFormat = /^([\d]{4})-(\d\d)-(\d\d)/;
  26046. var isValidFormat = false;
  26047. isValidFormat = defaultFormat.test(date);
  26048. if (isValidFormat) {
  26049. var newDate = new Date(NaN);
  26050. var month;
  26051. var parts = defaultFormat.exec(date);
  26052. if (parts) {
  26053. month = parts[2];
  26054. newDate.setFullYear(parts[1], month - 1, parts[3]);
  26055. if (month != newDate.getMonth() + 1) {
  26056. newDate.setTime(NaN);
  26057. }
  26058. }
  26059. return newDate;
  26060. }
  26061. else {
  26062. //not in valid format
  26063. return null;
  26064. }
  26065. },
  26066. _mmDateToJsDate: function(date){
  26067. return this._xsdDateToJsDate(this._mmDateToXsdDate(date));
  26068. },
  26069. _format: function(value){
  26070. if (value.length == 1) {
  26071. //add preceding 0
  26072. value = "0" + value;
  26073. }
  26074. return value;
  26075. }
  26076. });
  26077. }
  26078. if(!dojo._hasResource["com.ibm.mashups.enabler.utils.EventTransformer"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  26079. dojo._hasResource["com.ibm.mashups.enabler.utils.EventTransformer"] = true;
  26080. dojo.provide("com.ibm.mashups.enabler.utils.EventTransformer");
  26081. }
  26082. if(!dojo._hasResource["com.ibm.mashups.enabler.widget.Constants_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  26083. dojo._hasResource["com.ibm.mashups.enabler.widget.Constants_API"] = true;
  26084. dojo.provide("com.ibm.mashups.enabler.widget.Constants_API");
  26085. dojo.provide("com.ibm.mashups.enabler.widget.Constants");
  26086. dojo.declare("com.ibm.mashups.enabler.widget.Constants", null, {
  26087. /**
  26088. * Handled events
  26089. * @type {String}
  26090. */
  26091. FILTER_HANDLED_EVENTS: "HandledEvents",
  26092. /**
  26093. * Published events
  26094. * @type {String}
  26095. */
  26096. FILTER_PUBLISHED_EVENTS: "PublishedEvents"
  26097. });
  26098. }
  26099. if(!dojo._hasResource["com.ibm.mm.enabler.widget.Constants"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  26100. dojo._hasResource["com.ibm.mm.enabler.widget.Constants"] = true;
  26101. dojo.provide("com.ibm.mm.enabler.widget.Constants");
  26102. dojo.declare("com.ibm.mm.enabler.widget.Constants", com.ibm.mashups.enabler.widget.Constants, {
  26103. constructor: function() {
  26104. },
  26105. PERSISTENCE_MODE_MODEL: "Model",
  26106. PERSISTENCE_MODE_MODEL_PREFERENCES: "ModelPreferences",
  26107. PERSISTENCE_MODE_DOM: "DOM"
  26108. });
  26109. com.ibm.mashups.enabler.widget.Constants = new com.ibm.mm.enabler.widget.Constants();
  26110. }
  26111. if(!dojo._hasResource["com.ibm.mashups.enabler.widget.Constants"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  26112. dojo._hasResource["com.ibm.mashups.enabler.widget.Constants"] = true;
  26113. dojo.provide("com.ibm.mashups.enabler.widget.Constants");
  26114. /**
  26115. * Constants for the widget model.
  26116. * @ibm-api
  26117. * @ibm-module iWidget2
  26118. * @since 2.4
  26119. */
  26120. }
  26121. if(!dojo._hasResource["com.ibm.mashups.iwidget.itemset.PersistentAttributesFactory"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  26122. dojo._hasResource["com.ibm.mashups.iwidget.itemset.PersistentAttributesFactory"] = true;
  26123. dojo.provide("com.ibm.mashups.iwidget.itemset.PersistentAttributesFactory");
  26124. /**
  26125. * @private
  26126. * @ibm-module iWidget2
  26127. */
  26128. dojo.declare("com.ibm.mashups.iwidget.itemset.PersistentAttributesFactory",null, {
  26129. /**
  26130. * Creates persistent attributes for the specified widget and persistence mode.
  26131. *
  26132. * @param {com.ibm.mashups.iwidget.widget.IWidgetWrapper} widget the widget for which to create the persistent attributes
  26133. * @param {String} persistenceMode the persistence mode for which to create the attributes
  26134. * @return {ManagedItemSet} the persistent attributes for the given widget / mode.
  26135. * If the specified mode is not supported by this method <tt>null</tt> will be returned.
  26136. */
  26137. createPersistentAttributes: function(widgetWrapper, persistenceMode) {
  26138. },
  26139. /**
  26140. * Returns the persistence modes that are supported by this factory.
  26141. * @return {String[]} the supported persistence modes.
  26142. */
  26143. getSupportedPersistenceMode: function() {
  26144. }
  26145. });
  26146. }
  26147. if(!dojo._hasResource["com.ibm.mashups.iwidget.services.PersistentAttributesFactoryService_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  26148. dojo._hasResource["com.ibm.mashups.iwidget.services.PersistentAttributesFactoryService_API"] = true;
  26149. dojo.provide("com.ibm.mashups.iwidget.services.PersistentAttributesFactoryService_API");
  26150. dojo.provide("com.ibm.mashups.iwidget.services.PersistentAttributesFactoryService");
  26151. /**
  26152. * @private
  26153. * @ibm-module iWidget2
  26154. */
  26155. dojo.declare("com.ibm.mashups.iwidget.services.PersistentAttributesFactoryService",null, {
  26156. /**
  26157. * TODO make this public at some point, ServiceManager documentation says it should be there
  26158. *
  26159. * @private
  26160. */
  26161. SERVICE_NAME : "persistentAttributesFactoryService",
  26162. /**
  26163. * Creates persistent attributes for the specified widget by honoring the current persistence mode (e.g. DOM vs. WidgetModel).
  26164. * The factory for the current persistence mode needs to be added to this service by using the <tt>addFactory</tt> method of this class.
  26165. *
  26166. * @param {com.ibm.mashups.iwidget.widget.IWidgetWrapper} widget the widget for which to create the persistent attributes
  26167. * @return {ManagedItemSet} an itemset for the specified widget using the according factory or <tt>null</tt> if no factory is available for the current mode.
  26168. */
  26169. createPersistentAttributes: function(widgetWrapper, contextAndCallback) {
  26170. },
  26171. /**
  26172. * Sets the factory for the specified persistenceMode to this service.
  26173. * @param {String} persistenceMode the mode that is supported by the specified factory
  26174. * @param {com.ibm.mashups.iwidget.services.PersistentAttributesFactory} factory the factory that creates the attributes.
  26175. * @return {void}
  26176. */
  26177. setFactory: function(persistenceMode, factory) {
  26178. },
  26179. /**
  26180. * Removes a factory for a specified persistence mode.
  26181. *
  26182. * @param {String} persistenceMode the mode to remove
  26183. *
  26184. * TODO make this public at some time
  26185. * @private
  26186. */
  26187. removeFactory: function(persistenceMode) {
  26188. }
  26189. });
  26190. com.ibm.mashups.iwidget.services.PersistentAttributesFactoryService.SERVICE_NAME = com.ibm.mashups.iwidget.services.PersistentAttributesFactoryService.prototype.SERVICE_NAME;
  26191. }
  26192. if(!dojo._hasResource["com.ibm.mm.iwidget.manageditemset.DOMPersistentAttributesFactoryImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  26193. dojo._hasResource["com.ibm.mm.iwidget.manageditemset.DOMPersistentAttributesFactoryImpl"] = true;
  26194. dojo.provide("com.ibm.mm.iwidget.manageditemset.DOMPersistentAttributesFactoryImpl");
  26195. dojo.declare("com.ibm.mm.iwidget.manageditemset.DOMPersistentAttributesFactoryImpl",com.ibm.mashups.iwidget.itemset.PersistentAttributesFactory, {
  26196. constructor: function() {
  26197. this.modes = ["DOM"];
  26198. },
  26199. createPersistentAttributes: function(widgetWrapper, persistenceMode) {
  26200. return new com.ibm.mm.iwidget.manageditemset.PersistentAttributes(widgetWrapper, true/*serverless*/);
  26201. },
  26202. getSupportedPersistenceMode: function() {
  26203. return this.modes;
  26204. }
  26205. });
  26206. }
  26207. if(!dojo._hasResource["com.ibm.mm.iwidget.services.PersistentAttributesFactoryServiceImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  26208. dojo._hasResource["com.ibm.mm.iwidget.services.PersistentAttributesFactoryServiceImpl"] = true;
  26209. dojo.provide("com.ibm.mm.iwidget.services.PersistentAttributesFactoryServiceImpl");
  26210. /*
  26211. * This is injected on the fly and not fetched through an API. Therefore we need to define the @ibm-module so that the build process is picking it up
  26212. * @ibm-module iWidget2
  26213. */
  26214. // inject this service into the ServiceManager at the end. Therefore we have to require the implementation
  26215. dojo.declare("com.ibm.mm.iwidget.services.PersistentAttributesFactoryServiceImpl", com.ibm.mashups.iwidget.services.PersistentAttributesFactoryService, {
  26216. constructor: function(){
  26217. this._factories = {};
  26218. },
  26219. createPersistentAttributes: function(widgetWrapper, contextAndCallback){
  26220. if (contextAndCallback) {
  26221. // register callback
  26222. com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.iwidget.services.ContainerService.SERVICE_NAME).registerOnChangeListener(com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_ATTRIBUTES, contextAndCallback);
  26223. }
  26224. var persistenceMode;
  26225. var wID = widgetWrapper.id;
  26226. var persistenceMode = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.iwidget.services.ContainerService.SERVICE_NAME).getPersistenceMode(com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_ATTRIBUTES);
  26227. var widgetDomNode = widgetWrapper.rootElement;
  26228. if (dojo.hasClass(widgetDomNode, com.ibm.mm.iwidget.services.PersistentAttributesFactoryServiceImpl.STANDALONE_CLASS) || !persistenceMode) {
  26229. persistenceMode = com.ibm.mm.iwidget.services.PersistentAttributesFactoryServiceImpl.DEFAULT_PERSISTENCE;
  26230. }
  26231. if (typeof persistenceMode !== "undefined" && persistenceMode == com.ibm.mashups.enabler.widget.Constants.PERSISTENCE_MODE_MODEL) {
  26232. var widgetModel = com.ibm.mashups.enabler.widget.Factory.getWidgetModel();
  26233. var navStateModel = com.ibm.mashups.enabler.model.state.NavigationStateModelFactory.getNavigationStateModel();
  26234. var spaceAccessor = com.ibm.mashups.enabler.model.state.AccessorFactory.getSpaceAccessor(navStateModel);
  26235. var pageAccessor = com.ibm.mashups.enabler.model.state.AccessorFactory.getPageAccessor(navStateModel, currentSpaceID);
  26236. var currentSpaceID = spaceAccessor.getSpaceID();
  26237. var currentPageID = pageAccessor.getPageID();
  26238. var modelID = com.ibm.mm.iwidget.Utils.getModelID(wID);
  26239. var wnd = widgetModel.findWidgetWindow(modelID, currentPageID).start();
  26240. if (!wnd) {
  26241. // we put a failsafe here to verify if the given ID is a client side ID, and if this is the case we are switching to DEFAULT PERSISTENCE
  26242. // the reason resides in a chicken and egg problem in that a not yet live preview widget may try to get the attributes
  26243. // in its onunload function, but it has already been discarded from the WidgetModel. This means that it would show an error that
  26244. // iw-Standalone is required
  26245. if (!com.ibm.mashups.enabler.services.IdentificationService.isClientID(modelID)) {
  26246. if (dojo.isFunction(widgetWrapper._getResourceBundle)) {
  26247. widgetWrapper._getResourceBundle();
  26248. }
  26249. }
  26250. persistenceMode = com.ibm.mm.iwidget.services.PersistentAttributesFactoryServiceImpl.DEFAULT_PERSISTENCE;
  26251. }
  26252. }
  26253. if (!(persistenceMode in this._factories)) {
  26254. return null;
  26255. }
  26256. return this._factories[persistenceMode].createPersistentAttributes(widgetWrapper, persistenceMode);
  26257. },
  26258. setFactory: function(persistenceMode, factory){
  26259. this._factories[persistenceMode] = factory;
  26260. },
  26261. removeFactory: function(persistenceMode) {
  26262. if(persistenceMode in this._factories) {
  26263. delete this._factories[persistenceMode];
  26264. }
  26265. }
  26266. });
  26267. com.ibm.mm.iwidget.services.PersistentAttributesFactoryServiceImpl.DEFAULT_PERSISTENCE = com.ibm.mashups.enabler.widget.Constants.PERSISTENCE_MODE_DOM;
  26268. com.ibm.mm.iwidget.services.PersistentAttributesFactoryServiceImpl.STANDALONE_CLASS = com.ibm.mm.iwidget.Constants.CSSCLASS_PREFIXED_INSTANCE.iwStandalone;
  26269. com.ibm.mashups.services.ServiceManager.setService(com.ibm.mashups.iwidget.services.PersistentAttributesFactoryService.SERVICE_NAME, new com.ibm.mm.iwidget.services.PersistentAttributesFactoryServiceImpl());
  26270. com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.iwidget.services.PersistentAttributesFactoryService.SERVICE_NAME).setFactory(com.ibm.mashups.enabler.widget.Constants.PERSISTENCE_MODE_DOM, new com.ibm.mm.iwidget.manageditemset.DOMPersistentAttributesFactoryImpl());
  26271. }
  26272. if(!dojo._hasResource["com.ibm.mashups.iwidget.services.PersistentAttributesFactoryService"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  26273. dojo._hasResource["com.ibm.mashups.iwidget.services.PersistentAttributesFactoryService"] = true;
  26274. dojo.provide("com.ibm.mashups.iwidget.services.PersistentAttributesFactoryService");
  26275. }
  26276. if(!dojo._hasResource["com.ibm.mm.iwidget.services.IWidgetFragmentServiceImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  26277. dojo._hasResource["com.ibm.mm.iwidget.services.IWidgetFragmentServiceImpl"] = true;
  26278. dojo.provide("com.ibm.mm.iwidget.services.IWidgetFragmentServiceImpl");
  26279. /*
  26280. * This is injected on the fly and not fetched through an API. Therefore we need to define the @ibm-module so that the build process is picking it up
  26281. * @ibm-module iWidget2
  26282. */
  26283. // inject this service into the ServiceManager at the end. Therefore we have to require the implementation
  26284. dojo.declare("com.ibm.mm.iwidget.services.IWidgetFragmentServiceImpl", null, {
  26285. /**
  26286. This function creates an Item in microformat as defined by iWidget spec.<p/>
  26287. If defaultValue is provided and no defaultLanguage is provided, following element will be created.<br/>
  26288. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code> &lt;a class="iw-Item" href="#{itemName}" &gt;{defaultValue} &lt;/a&gt; </code><br/>
  26289. If defaultLanguage is provided, following element will be created.</br>
  26290. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code> &lt;a class="iw-Item" href="#{itemName}" lang="{defaultLang}"&gt; &lt;/a&gt; </code><br/>
  26291. @param{String } itemName name of the item. Must never be NULL.
  26292. @param{String } defaultValue default value of the item. May be NULL.
  26293. @param{String } defaultLang default language of a localized item .May be NULL.
  26294. @param{String } prefix optional. namespace of the class, default is "iw-".
  26295. @type DOMElement
  26296. @returns{DOMElement } DOMElement of the new item.
  26297. */
  26298. createItem: function(itemName, defaultValue, defaultLang, ns) {
  26299. if (!ns) {
  26300. ns = "iw-";
  26301. }
  26302. var item = document.createElement("a");
  26303. dojo.addClass(item, ns + iwConstants.CSSCLASS_INSTANCE.iwItem);
  26304. dojo.style(item, "visibility", "hidden");
  26305. dojo.style(item, "display", "none");
  26306. item.setAttribute("href", "#" + itemName);
  26307. if (defaultLang) {
  26308. item.setAttribute("lang", defaultLang);
  26309. }
  26310. if (defaultValue && !defaultLang) {
  26311. item.innerHTML = defaultValue;
  26312. }
  26313. return item;
  26314. },
  26315. /**
  26316. This function creates an ItemSet in microformat as defined by iWidget spec.<p/>
  26317. Following element will be created.<br/>
  26318. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code> &lt;span class="iw-ItemSet" title="{setName}"&gt;&lt;/span&gt;</code><br/>
  26319. @param{String } itemSetName name of the itemset. Must never be NULL.
  26320. @param{String } prefix optional. namespace of the class, default is "iw-".
  26321. @type DOMElement
  26322. @returns{DOMElement } DOMElement of the new itemset.
  26323. */
  26324. createItemSet: function(itemSetName, ns) {
  26325. if (!ns) {
  26326. ns = "iw-";
  26327. }
  26328. var param = document.createElement("span");
  26329. dojo.addClass(param, ns + iwConstants.CSSCLASS_INSTANCE.iwItemSet);
  26330. param.setAttribute("title", itemSetName);
  26331. dojo.style(param, "visibility", "hidden");
  26332. dojo.style(param, "display", "none");
  26333. return param;
  26334. },
  26335. /**
  26336. This function creates an anchor link that points to url to load widget definition.<p/>
  26337. Following element will be created.<br/>
  26338. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code> &lt;a class="iw-Definition" href="{uri}" /&gt;&lt;/code&gt;<br/>
  26339. @param{String } widgetDefUrl url to load widget definition xml. Must never be NULL.
  26340. @param{String } prefix optional. namespace of the class, default is "iw-".
  26341. @type DOMElement
  26342. @returns{DOMElement } DOMElement of the new anchor link.
  26343. */
  26344. createWidgetDefRef: function(widgetDefUrl, ns) {
  26345. if (!ns) {
  26346. ns = "iw-";
  26347. }
  26348. var aTag = document.createElement("a");
  26349. dojo.addClass(aTag, ns + iwConstants.CSSCLASS_INSTANCE.iwDefinition);
  26350. aTag.setAttribute("href", widgetDefUrl);
  26351. dojo.style(aTag, "visibility", "hidden");
  26352. dojo.style(aTag, "display", "none");
  26353. return aTag;
  26354. },
  26355. /**
  26356. This function returns the required itemset with the given iwidget id.<br/>
  26357. @param{String } iwidgetId iwidget id. Must never be NULL.
  26358. @param{String } name name of the required ItemSet. Must never be NULL.
  26359. @param{String } prefix optional. namespace of the class, default is "iw-".
  26360. @type DOMElement
  26361. @returns{DOMElement } DOMElement of the itemset.
  26362. */
  26363. getItemSet: function(iwidgetId, name, ns) {
  26364. if (!ns) {
  26365. ns = "iw-";
  26366. }
  26367. var rc = null;
  26368. var widgetSpan = dojo.byId(iwidgetId);
  26369. var itemsets = dojo.query("." + ns + iwConstants.CSSCLASS_INSTANCE.iwItemSet, widgetSpan);
  26370. for (var i = 0; i < itemsets.length; i++) {
  26371. var anItemSet = itemsets[i];
  26372. var title = anItemSet.getAttribute("title");
  26373. if (name == title) {
  26374. rc = anItemSet;
  26375. break;
  26376. }
  26377. }
  26378. return rc;
  26379. },
  26380. /**
  26381. This function returns the required item with the given parent.<br/>
  26382. item element is a nested element within itemset element.<br/>
  26383. @param{DOMElement } parent parent element. Must never be NULL.
  26384. @param{String } name name of the required item. Must never be NULL.
  26385. @param{String } prefix optional. namespace of the class, default is "iw-".
  26386. @type DOMElement
  26387. @returns{DOMElement } DOMElement of the item.
  26388. */
  26389. getItem: function(parent, name, ns) {
  26390. if (!ns) {
  26391. ns = "iw-";
  26392. }
  26393. var rc = null;
  26394. var items = dojo.query("." + ns + iwConstants.CSSCLASS_INSTANCE.iwItem, parent);
  26395. for (var i = 0; i < items.length; i++) {
  26396. var anItem = items[i];
  26397. var title = this.getKeyFromHref(anItem);
  26398. if (title && title == name) {
  26399. rc = anItem;
  26400. break;
  26401. }
  26402. }
  26403. return rc;
  26404. },
  26405. /**
  26406. This function returns the all the items within the given parent itemset.<br/>
  26407. item element is a nested element within itemset element.<br/>
  26408. @param{DOMElement } parent parent element. Must never be NULL.
  26409. @param{String } prefix optional. namespace of the class, default is "iw-".
  26410. @type DOMElement[]
  26411. @returns{DOMElement []} list of DOMElements.
  26412. */
  26413. getItems: function(parent, ns) {
  26414. if (!ns) {
  26415. ns = "iw-";
  26416. }
  26417. var items = dojo.query("." + ns + iwConstants.CSSCLASS_INSTANCE.iwItem, parent);
  26418. if (typeof items == "undefined" || items === null || items.length === 0) {
  26419. items = null;
  26420. }
  26421. return items;
  26422. },
  26423. /**
  26424. This function returns the reference to the widget definition.<br/>
  26425. Widget definition reference is defined within anchor link.<br/>
  26426. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code> &lt;a class="iw-Definition" href="{uri}" /&gt;&lt;/code&gt;<br/>
  26427. @param{String } iwidgetId id of the iWidget. Must never be NULL.
  26428. @param{String } prefix optional. namespace of the class, default is "iw-".
  26429. @type String
  26430. @returns{ String } uri to download the iWidget definition.
  26431. */
  26432. getWidgetDefRef: function(iwidgetId, ns) {
  26433. if (!ns) {
  26434. ns = "iw-";
  26435. }
  26436. var rc = null;
  26437. var widgetSpan = dojo.byId(iwidgetId);
  26438. var def = dojo.query("." + ns + iwConstants.CSSCLASS_INSTANCE.iwDefinition, widgetSpan)[0];
  26439. var ref = def.getAttribute("href");
  26440. if (ref) {
  26441. rc = ref;
  26442. }
  26443. return rc;
  26444. },
  26445. /**
  26446. This function provides a convenience function to get the real value defined with an "href" attribute.<br/>
  26447. Per iWidget spec, several items are defined by using anchor link. <br/>
  26448. For example, item element or sourceEvent within a ReceivedEvent.<br/>
  26449. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code> &lt;a class="iw-Item" href="#{itemName}" &gt;{value} &lt;/a&gt; </code><br/>
  26450. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code>&lt;a class="iw-SourceEvent" href="#{sourceWidgetID}"&gt;{sourceEventName} &lt;/a &gt;</code><br/>
  26451. This function will return itemname if it's an item node.<br/>
  26452. This function will return id of source iWidget if it's an sourceevent node within a ReceivedEvent.<br/>
  26453. @param{DOMNode } node DOMNode which is an item. Must never be NULL.
  26454. @type String
  26455. @returns{ String } .
  26456. */
  26457. getKeyFromHref: function(node) {
  26458. var hrefValue = node.getAttribute("href");
  26459. if (!hrefValue) {
  26460. return null;
  26461. }
  26462. var pos = hrefValue.indexOf("#");
  26463. if (pos < 0) {
  26464. return null;
  26465. }
  26466. return hrefValue.substring(pos + 1);
  26467. }
  26468. });
  26469. com.ibm.mashups.services.ServiceManager.setService("iwidgetFragmentService", new com.ibm.mm.iwidget.services.IWidgetFragmentServiceImpl());
  26470. }
  26471. if(!dojo._hasResource["com.ibm.mm.enabler.EndpointUtilsExtendedImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  26472. dojo._hasResource["com.ibm.mm.enabler.EndpointUtilsExtendedImpl"] = true;
  26473. dojo.provide("com.ibm.mm.enabler.EndpointUtilsExtendedImpl");
  26474. /*
  26475. * This is injected on the fly and not fetched through an API. Therefore we need to define the @ibm-module so that the build process is picking it up
  26476. * @ibm-module iWidget
  26477. *
  26478. * This value defines the order in which the packages should be printed out into the dojo profile. Default is 100.
  26479. * Any number that is smaller causes this class to be written out before any other with a higher number
  26480. * @ibm-dojo-profile-level 40
  26481. */
  26482. dojo.declare("com.ibm.mm.enabler.EndpointUtilsExtendedImpl", com.ibm.mm.enabler.EndpointUtilsDefaultImpl, {
  26483. constructor: function(){
  26484. },
  26485. checkForEndpoints: function(/*String*/url){
  26486. if (!url) {
  26487. return null;
  26488. }
  26489. var result = url.toString();
  26490. if (result) {
  26491. var index = result.indexOf("endpoint://", 0);
  26492. if (index === 0) {
  26493. var relativeIndex = result.indexOf("/", 11);
  26494. if (relativeIndex > 0) {
  26495. var endpoint = result.substring(11, relativeIndex);
  26496. var relativeURL = result.substring(relativeIndex + 1);
  26497. var resolvedEndpoint = this._resolveEndpoint(endpoint);
  26498. if (resolvedEndpoint) {
  26499. if (resolvedEndpoint.charAt(resolvedEndpoint.length - 1) == '/') {
  26500. result = resolvedEndpoint + relativeURL;
  26501. }
  26502. else {
  26503. result = resolvedEndpoint + '/' + relativeURL;
  26504. }
  26505. return result;
  26506. }
  26507. else {
  26508. return null;
  26509. }
  26510. }
  26511. }
  26512. else
  26513. if (index > 0) {
  26514. var origUrl = result.substring(0, index);
  26515. var endpointPortion = result.substring(index);
  26516. var endpointPortion2 = this.checkForEndpoints(endpointPortion);
  26517. if (endpointPortion2) {
  26518. //return origUrl + endpointPortion2.substring(1);
  26519. return endpointPortion2.substring(0);
  26520. }
  26521. }
  26522. }
  26523. return url;
  26524. },
  26525. _resolveEndpoint: function(/*String*/endpoint){
  26526. if (!this.co) {
  26527. this._init();
  26528. }
  26529. var decodedEndpoint = decodeURIComponent(endpoint);
  26530. var url = this.co.getValue(decodedEndpoint + ".url");
  26531. if (!url) {
  26532. if (decodedEndpoint == "{contenthandler}") {
  26533. url = this.urlContentHandler;
  26534. }
  26535. else
  26536. if (decodedEndpoint == "{webdavroot}") {
  26537. url = this.urlWebDavRoot;
  26538. }
  26539. else {
  26540. return null;
  26541. }
  26542. }
  26543. if ((url) && (url.charAt(0) != "/") && (url.substr(0, 4) != "http")) {
  26544. url = "/" + url;
  26545. }
  26546. return url;
  26547. },
  26548. _init: function(){
  26549. this.cs = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);
  26550. this.co = this.cs.getConfigObject(com.ibm.mashups.enabler.services.ConfigConstants.ENDPOINT_CONFIG_PROVIDER);
  26551. this.urlContentHandler = "";
  26552. // add the contextroot
  26553. this.urlContentHandler += this.cs.getValue(com.ibm.mashups.enabler.services.ConfigConstants.CONTEXT_ROOT);
  26554. // add the public contenthandler url
  26555. var anonymousUser = this.cs.getValue(com.ibm.mashups.enabler.services.ConfigConstants.ANONYMOUS_USER);
  26556. var contenthandlerPath;
  26557. if (anonymousUser) {
  26558. contenthandlerPath = this.cs.getValue(com.ibm.mashups.enabler.services.ConfigConstants.CONTENTHANDLER_PUBLIC);
  26559. }
  26560. else {
  26561. contenthandlerPath = this.cs.getValue(com.ibm.mashups.enabler.services.ConfigConstants.CONTENTHANDLER_PRIVATE);
  26562. }
  26563. this.urlContentHandler += contenthandlerPath;
  26564. if (com.ibm.mm.enabler.remote && com.ibm.mm.enabler.remote.WebDavUrlFactory) {
  26565. this.urlWebDavRoot = com.ibm.mm.enabler.remote.WebDavUrlFactory.createUrl() + "/";
  26566. }
  26567. else {
  26568. this.urlWebDavRoot = null;
  26569. }
  26570. }
  26571. });
  26572. com.ibm.mm.enabler.EndpointUtils = new com.ibm.mm.enabler.EndpointUtilsExtendedImpl();
  26573. }
  26574. if(!dojo._hasResource["com.ibm.mm.iwidget.payloadDef"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  26575. dojo._hasResource["com.ibm.mm.iwidget.payloadDef"] = true;
  26576. dojo.provide("com.ibm.mm.iwidget.payloadDef");
  26577. dojo.declare("com.ibm.mm.iwidget.payloadDef", null, {
  26578. constructor: function(name, type, defaultValue, description, attributes) {
  26579. this.name = name;
  26580. this.attributes = attributes || null;
  26581. if (!this.attributes) {
  26582. this.attributes = {};
  26583. }
  26584. if (typeof type != "undefined" && type !== null) {
  26585. this.attributes.type = type;
  26586. }
  26587. if (typeof defaultValue != "undefined" && defaultValue !== null) {
  26588. this.attributes.defaultValue = defaultValue;
  26589. }
  26590. if (typeof description != "undefined" && description !== null) {
  26591. this.attributes.description = description;
  26592. }
  26593. this.attributeNames = [];
  26594. this.attributeNames.push("type");
  26595. this.attributeNames.push("defaultValue");
  26596. this.attributeNames.push("description");
  26597. var aName;
  26598. for (aName in attributes) {
  26599. if (Object.prototype.hasOwnProperty.call(attributes,aName)) {
  26600. this.attributeNames.push(aName);
  26601. }
  26602. }
  26603. this.children = new com.ibm.mm.enabler.ArrayMap();/*an array of payloadDef*/
  26604. },
  26605. setAttribute: function(name, defaultValue) {
  26606. this.attributes[name] = defaultValue;
  26607. if (typeof(this.attributeNames[name]) != "undefined") {
  26608. this.attributeNames.push(name);
  26609. }
  26610. },
  26611. getAttribute: function(name) {
  26612. var defaultValue = this.attributes[name];
  26613. if (typeof defaultValue == "undefined") {
  26614. defaultValue = null;
  26615. }
  26616. return defaultValue;
  26617. },
  26618. getAttributeNames: function() {
  26619. return this.attributeNames;
  26620. },
  26621. getChildren: function() {
  26622. return this.children.values();
  26623. },
  26624. getChild: function(name) {
  26625. return this.children.get(name);
  26626. },
  26627. setChild: function(name,/*object*/ payloadDef) {
  26628. this.children.put(name, payloadDef);
  26629. },
  26630. getChildrenNames: function() {
  26631. this.children.keySet();
  26632. },
  26633. getName: function() {
  26634. return this.name;
  26635. },
  26636. getType: function() {
  26637. return this.attributes.type;
  26638. },
  26639. getDefaultValue: function() {
  26640. return this.attributes.defaultValue;
  26641. },
  26642. getDescription: function() {
  26643. return this.attributes.description;
  26644. }
  26645. });
  26646. }
  26647. if(!dojo._hasResource["com.ibm.mm.iwidget.UtilsExtended"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  26648. dojo._hasResource["com.ibm.mm.iwidget.UtilsExtended"] = true;
  26649. dojo.provide("com.ibm.mm.iwidget.UtilsExtended");
  26650. /*
  26651. * This is injected on the fly and not fetched through an API. Therefore we need to define the @ibm-module so that the build process is picking it up
  26652. * @ibm-module iWidget
  26653. *
  26654. * This value defines the order in which the packages should be printed out into the dojo profile. Default is 100.
  26655. * Any number that is smaller causes this class to be written out before any other with a higher number
  26656. * @ibm-dojo-profile-level 40
  26657. */
  26658. dojo.declare("com.ibm.mm.iwidget.UtilsExtendedImpl", com.ibm.mm.iwidget.UtilsDefaultImpl, {
  26659. getPayloadDef: function(aNode) {
  26660. var name = aNode.getAttribute("name");
  26661. var payloadDef = new com.ibm.mm.iwidget.payloadDef(name);
  26662. var attributes = aNode.attributes;
  26663. //var attributesArr = [];
  26664. for (var i = 0; i < attributes.length; i++) {
  26665. var anAttribute = attributes[i];
  26666. if (anAttribute.name != "name") {
  26667. payloadDef.setAttribute(anAttribute.name, anAttribute.value);
  26668. }
  26669. }
  26670. var children = aNode.childNodes;
  26671. for (var j = 0; j < children.length; j++) {
  26672. var child = children[j];
  26673. if (child.nodeType == 1) {
  26674. var aChildPayloadDef = this.getPayloadDef(child);
  26675. payloadDef.setChild(aChildPayloadDef.name, aChildPayloadDef);
  26676. }
  26677. }
  26678. return payloadDef;
  26679. }
  26680. });
  26681. //IMPORTANT
  26682. //ibmConfig.enablerLayerModules is a comma separated string of all supported modules at runtime
  26683. //This section dynamically loads the Extended representation when the variable enablerLayerModules contains the given module
  26684. if ((ibmConfig.enablerLayerModules) && (dojo.indexOf(ibmConfig.enablerLayerModules, "CoreModel") >= 0)) {
  26685. dojo["require"]("com.ibm.mm.enabler.iwidget.UtilsModelImpl"); // JSLINT-IGNORE: This needs to be done to allow modularization and to support the layers
  26686. } else {
  26687. com.ibm.mm.iwidget.Utils = new com.ibm.mm.iwidget.UtilsExtendedImpl();
  26688. }
  26689. }
  26690. if(!dojo._hasResource["com.ibm.mm.iwidget.icontext.IContextMMExtensionImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  26691. dojo._hasResource["com.ibm.mm.iwidget.icontext.IContextMMExtensionImpl"] = true;
  26692. dojo.provide("com.ibm.mm.iwidget.icontext.IContextMMExtensionImpl");
  26693. dojo.declare("com.ibm.mm.iwidget.icontext.IContextMMExtensionImpl", null, {
  26694. constructor: function(wrapper) {
  26695. //information accessible from iwidget
  26696. this.widget = wrapper;
  26697. this.widgetId = wrapper.id;
  26698. },
  26699. getSupportedModes: function() {
  26700. var supportedModes = this.widgetwrapper.widgetDef.getSupportedModes();
  26701. return supportedModes;
  26702. },
  26703. getPayloadDef: function(name) {
  26704. var payloadDefs = this.widget.widgetDef.payloadDefs;
  26705. var payloadDef = payloadDefs[name];
  26706. if (typeof payloadDef == "undefined") {
  26707. return null;
  26708. }
  26709. return payloadDef;
  26710. },
  26711. getPayloadDefNames: function() {
  26712. var payloadDefs = this.widget.widgetDef.payloadDefs;
  26713. var arr = [];
  26714. for (var a in payloadDefs) {
  26715. if (Object.prototype.hasOwnProperty.call(payloadDefs,a)) {
  26716. arr.push(a);
  26717. }
  26718. }
  26719. return arr;
  26720. }
  26721. });
  26722. }
  26723. if(!dojo._hasResource["com.ibm.mm.iwidget.manageditemset.UserProfileImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  26724. dojo._hasResource["com.ibm.mm.iwidget.manageditemset.UserProfileImpl"] = true;
  26725. dojo.provide("com.ibm.mm.iwidget.manageditemset.UserProfileImpl");
  26726. dojo.declare("com.ibm.mm.iwidget.manageditemset.UserProfileImpl", com.ibm.mashups.iwidget.itemset.ManagedItemSet, {
  26727. constructor: function(widgetId, user) {
  26728. this.widgetId = widgetId;
  26729. this.user = user;
  26730. },
  26731. getItemValue: function(/*string*/name) {
  26732. if (!name) {
  26733. return null;
  26734. }
  26735. var value = this.user.getAttribute(name);
  26736. if (typeof value == "undefined") {
  26737. value = null;
  26738. }
  26739. return value;
  26740. },
  26741. setItemValue: function(name, value) {
  26742. //readonly
  26743. if (!name || !value) {
  26744. return null;
  26745. }
  26746. if (this.isReadOnly(name)) {
  26747. return null;
  26748. }
  26749. this.user.setAttribute(name, value);
  26750. return this;
  26751. },
  26752. isReadOnly: function(name) {
  26753. if (typeof name == "undefined" || name === null) {
  26754. return false;
  26755. }
  26756. var readOnlyAttributes = this.user.getReadOnlyAttributeNames();
  26757. var rc = this._contains(readOnlyAttributes, name);
  26758. return rc;
  26759. },
  26760. _contains: function(array, attribute) {
  26761. if (!attribute) {
  26762. return false;
  26763. }
  26764. if (!array) {
  26765. return false;
  26766. }
  26767. if (array && !dojo.isArray(array)) {
  26768. return false;
  26769. }
  26770. for (var i = 0; i < array.length; i++) {
  26771. if (array[i] && array[i] == attribute) {
  26772. return true;
  26773. }
  26774. }
  26775. return false;
  26776. },
  26777. removeItem: function(name) {
  26778. if (!name) {
  26779. return null;
  26780. }
  26781. if (this.isReadOnly(name)) {
  26782. return null;
  26783. }
  26784. this.user.removeAttribute(name);
  26785. return this;
  26786. },
  26787. getAllNames: function() {
  26788. var configService = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);
  26789. var hideLookaside = configService.getValue("com.ibm.mashups.hideLookaside");
  26790. if (dojo.isString(hideLookaside) && hideLookaside.toLowerCase() == "true") {
  26791. return this.user.getReadOnlyAttributeNames();
  26792. }
  26793. return this.user.getAttributeNames();
  26794. },
  26795. save: function(cb) {
  26796. return this.commit(cb);
  26797. },
  26798. commit: function(cb) {
  26799. var userModel = null;
  26800. if (com.ibm.mashups.enabler.user.Factory.getUserModel) {
  26801. userModel = com.ibm.mashups.enabler.user.Factory.getUserModel();
  26802. }
  26803. if (userModel) {
  26804. var deferred = userModel.commit();
  26805. var fn = function(resource, statusCode, param) {
  26806. if (cb) {
  26807. var rc = false;
  26808. var itemName = iwConstants.USERPROFILE;
  26809. if (statusCode && statusCode == iwConstants.status.SUCCESS) {
  26810. rc = true;
  26811. }
  26812. cb(itemName, rc);
  26813. }
  26814. };
  26815. deferred.setFinishedCallback(fn);
  26816. deferred.start();
  26817. }
  26818. },
  26819. addListener: function(/*obj*/fn) {
  26820. var widget = this._getWidget();
  26821. if (!widget) {
  26822. return null;
  26823. }
  26824. var listenerId = widget._registerListener(iwConstants.USERPROFILE, fn);
  26825. return listenerId;
  26826. },
  26827. removeListener: function(/*String*/listenerId) {
  26828. var widget = this._getWidget();
  26829. if (!widget) {
  26830. return null;
  26831. }
  26832. return widget._removeListener(iwConstants.USERPROFILE, listenerId);
  26833. },
  26834. _getWidget: function() {
  26835. var widgetModel = com.ibm.mashups.iwidget.model.Factory.getGlobalModel();
  26836. return widgetModel.find(this.widget) || null;
  26837. }
  26838. });
  26839. }
  26840. if(!dojo._hasResource["com.ibm.mm.iwidget.widget.ResourceImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  26841. dojo._hasResource["com.ibm.mm.iwidget.widget.ResourceImpl"] = true;
  26842. dojo.provide("com.ibm.mm.iwidget.widget.ResourceImpl");
  26843. dojo.declare("com.ibm.mm.iwidget.widget.ResourceImpl", null, {
  26844. constructor: function(/*JSON object*/obj) {
  26845. if (obj) {
  26846. for (var i in obj) {
  26847. if (Object.prototype.hasOwnProperty.call(obj,i)) {
  26848. this[i] = obj[i];
  26849. }
  26850. }
  26851. }
  26852. },
  26853. IMAGE: {
  26854. "bmp": "bmp",
  26855. "cod": "cod",
  26856. "gif": "gif",
  26857. "ief": "ief",
  26858. "jpe": "jpe",
  26859. "jpeg": "jpeg",
  26860. "jpg": "jpg",
  26861. "jfif": "jfif",
  26862. "svg": "svg",
  26863. "tif": "tif",
  26864. "tiff": "tiff",
  26865. "ras": "ras",
  26866. "cmx": "cmx",
  26867. "ico": "ico",
  26868. "pnm": "pnm",
  26869. "pbm": "pbm",
  26870. "pgm": "pgm",
  26871. "ppm": "ppm",
  26872. "rgb": "rgb",
  26873. "xbm": "xbm",
  26874. "xpm": "xpm",
  26875. "xwd": "xwd"
  26876. },
  26877. isCSS: function() {
  26878. var rc = false;
  26879. var extension = this._getExtension();
  26880. if (extension && extension == "css") {
  26881. rc = true;
  26882. }
  26883. if (!rc && this.getMimeType()) {
  26884. if (this.getMimeType() == "text/stylesheet" || this.getMimeType() == "text/css") {
  26885. rc = true;
  26886. }
  26887. }
  26888. return rc;
  26889. },
  26890. isImage: function() {
  26891. var rc = false;
  26892. var extension = this._getExtension();
  26893. if (extension && extension in this.IMAGE) {
  26894. rc = true;
  26895. }
  26896. if (!rc && this.getMimeType()) {
  26897. if (this.getMimeType().indexOf("image/") === 0) {
  26898. rc = true;
  26899. }
  26900. }
  26901. return rc;
  26902. },
  26903. isJS: function() {
  26904. var rc = false;
  26905. var extension = this._getExtension();
  26906. if (extension && extension == "js") {
  26907. rc = true;
  26908. }
  26909. if (!rc && this.getMimeType()) {
  26910. var mimetype = this.getMimeType();
  26911. if (mimetype == "text/javascript" || mimetype == "application/x-javascript" || mimetype == "application/javascript") {
  26912. rc = true;
  26913. }
  26914. }
  26915. return rc;
  26916. },
  26917. getGlobalId: function() {
  26918. var id = this[iwConstants.RESOURCE.globalid];
  26919. if (!id) {
  26920. id= this[iwConstants.RESOURCE.id];
  26921. }
  26922. if (!id) {
  26923. id = null;
  26924. }
  26925. return id;
  26926. },
  26927. getSrc: function() {
  26928. return this[iwConstants.RESOURCE.src];
  26929. },
  26930. getMimeType: function() {
  26931. var mimeType = this[iwConstants.RESOURCE.mimeType];
  26932. if (!mimeType) {
  26933. mimeType = null;
  26934. }
  26935. return mimeType;
  26936. },
  26937. _getExtension: function() {
  26938. var uri = this.getSrc();
  26939. if (!uri) {
  26940. return null;
  26941. }
  26942. var extension = uri.substring(uri.lastIndexOf(".") + 1, uri.length);
  26943. if (!extension) {
  26944. return null;
  26945. }
  26946. return extension;
  26947. }
  26948. });
  26949. }
  26950. if(!dojo._hasResource["com.ibm.mm.iwidget.icontext.IContextExtendedImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  26951. dojo._hasResource["com.ibm.mm.iwidget.icontext.IContextExtendedImpl"] = true;
  26952. dojo.provide("com.ibm.mm.iwidget.icontext.IContextExtendedImpl");
  26953. /*
  26954. * This is injected on the fly and not fetched through an API. Therefore we need to define the @ibm-module so that the build process is picking it up
  26955. * @ibm-module iWidget
  26956. *
  26957. * This value defines the order in which the packages should be printed out into the dojo profile. Default is 100.
  26958. * Any number that is smaller causes this class to be written out before any other with a higher number
  26959. * @ibm-dojo-profile-level 40
  26960. */
  26961. dojo.declare("com.ibm.mm.iwidget.icontext.IContextExtendedImpl", com.ibm.mm.iwidget.icontext.IContextDefaultImpl, {
  26962. _initEvents: function() {
  26963. this.iEvents = new com.ibm.mm.iwidget.icontext.IContextIEventsImpl(this.widgetwrapper);
  26964. },
  26965. _initIO: function() {
  26966. this.io = new com.ibm.mm.iwidget.icontext.IContextIOImpl(this.widgetwrapper);
  26967. },
  26968. _initMMExtension: function() {
  26969. this._mm = new com.ibm.mm.iwidget.icontext.IContextMMExtensionImpl(this.widgetwrapper);
  26970. },
  26971. getUserProfile: function() {
  26972. var userModel = null;
  26973. if (com.ibm.mashups.enabler.user.Factory.getUserModel) {
  26974. userModel = com.ibm.mashups.enabler.user.Factory.getUserModel();
  26975. }
  26976. var user = null;
  26977. if (userModel) {
  26978. user = userModel.findCurrentUser().start();
  26979. }
  26980. var userProfile = null;
  26981. if (user) {
  26982. userProfile = new com.ibm.mm.iwidget.manageditemset.UserProfileImpl(this.widgetId, user);
  26983. }
  26984. return userProfile;
  26985. },
  26986. requires: function(/*String*/requiredItem,/*String*/ version,/*String*/ uri,/*function*/ cb, mimeType) {
  26987. //Summery: provides means for iWidget to declare dependency on set of non-required items:
  26988. // "io"...
  26989. // no uri should be specified for above
  26990. // shared resources can be loaded just once for all iwidgets like dojo.js
  26991. // version support?
  26992. // support dynamic loads in asynchronous manner
  26993. mimeType = mimeType || null;
  26994. if (!mimeType) {
  26995. mimeType = "text/plain";
  26996. }
  26997. uri = uri || null;
  26998. if (uri) {
  26999. var obj = {};
  27000. obj[iwConstants.RESOURCE.mimeType] = mimeType;
  27001. obj[iwConstants.RESOURCE.id] = requiredItem;
  27002. obj[iwConstants.RESOURCE.version] = version;
  27003. obj[iwConstants.RESOURCE.src] = uri;
  27004. obj[iwConstants.RESOURCE.callback] = cb;
  27005. var resource = new com.ibm.mm.iwidget.widget.ResourceImpl(obj);
  27006. com.ibm.mashups.services.ServiceManager.getService("resourceLoadService").loadResource(resource, this.widgetId);
  27007. }
  27008. },
  27009. processiWidgets: function(/*domnode*/root) {
  27010. dojo.publish("/com/ibm/mashups/livetext/livetextchanged", [root, true]);
  27011. },
  27012. getShareableItemSet: function(/*String*/name) {
  27013. name = name || null;
  27014. if (!name) {
  27015. return null;
  27016. }
  27017. var itemSet = this.widgetwrapper._getShareableItemSet(name);
  27018. return itemSet;
  27019. }
  27020. });
  27021. com.ibm.mm.iwidget.icontext.IContextImpl = com.ibm.mm.iwidget.icontext.IContextExtendedImpl;
  27022. }
  27023. if(!dojo._hasResource["com.ibm.mm.iwidget.manageditemset.IDescriptorExtendedImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  27024. dojo._hasResource["com.ibm.mm.iwidget.manageditemset.IDescriptorExtendedImpl"] = true;
  27025. dojo.provide("com.ibm.mm.iwidget.manageditemset.IDescriptorExtendedImpl");
  27026. /*
  27027. * This is injected on the fly and not fetched through an API. Therefore we need to define the @ibm-module so that the build process is picking it up
  27028. * @ibm-module iWidget
  27029. *
  27030. * This value defines the order in which the packages should be printed out into the dojo profile. Default is 100.
  27031. * Any number that is smaller causes this class to be written out before any other with a higher number
  27032. * @ibm-dojo-profile-level 40
  27033. */
  27034. dojo.declare("com.ibm.mm.iwidget.manageditemset.IDescriptorExtendedImpl",com.ibm.mm.iwidget.manageditemset.IDescriptorDefaultImpl,{
  27035. _getWindowState:function(){
  27036. if (this.widget) {
  27037. var accessor = com.ibm.mashups.enabler.model.state.AccessorFactory.getWidgetAccessor(this.navStateModel,this.widget.id);
  27038. value = accessor.getWindowState();
  27039. } else {
  27040. value = 'normal';
  27041. }
  27042. return value;
  27043. }
  27044. });
  27045. com.ibm.mm.iwidget.manageditemset.IDescriptorImpl = com.ibm.mm.iwidget.manageditemset.IDescriptorExtendedImpl;
  27046. }
  27047. if(!dojo._hasResource["com.ibm.mm.iwidget.services.ResourceLoadServiceImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  27048. dojo._hasResource["com.ibm.mm.iwidget.services.ResourceLoadServiceImpl"] = true;
  27049. dojo.provide("com.ibm.mm.iwidget.services.ResourceLoadServiceImpl");
  27050. /*
  27051. * This is injected on the fly and not fetched through an API. Therefore we need to define the @ibm-module so that the build process is picking it up
  27052. * @ibm-module iWidget
  27053. */
  27054. // inject this service into the ServiceManager at the end. Therefore we have to require the implementation
  27055. dojo.declare("com.ibm.mm.iwidget.services.ResourceLoadServiceImpl", null, {
  27056. constructor: function() {
  27057. //loadModelus to keep track that if a resource has been loaded already
  27058. this.modules = {};
  27059. this.LOADING_TOKEN = 0;
  27060. this.LOADING_ERROR_TOKEN = 1;
  27061. this.LOADED_TOKEN = 2;
  27062. this.waitingqueue = {};// resource is under loading,however callback might be different, waiting to be loaded
  27063. this.evalqueue = {}; // js loaded within one resource will be evaluated in order
  27064. this.callbackQueue = {};
  27065. var cs = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);
  27066. if (cs) {
  27067. var registeredLoadedResources = cs.getValue(com.ibm.mashups.enabler.services.ConfigConstants.REGISTER_LOADEDRESOURCES);
  27068. if (registeredLoadedResources) {
  27069. if (dojo.isString(registeredLoadedResources)) {
  27070. try {
  27071. registeredLoadedResources = dojo.fromJson(registeredLoadedResources);
  27072. }
  27073. catch (e) {
  27074. //invalid configuration
  27075. }
  27076. }
  27077. if (dojo.isArray(registeredLoadedResources)) {
  27078. this.registeredLoadedResources = registeredLoadedResources;
  27079. }
  27080. }
  27081. }
  27082. },
  27083. executeCallbackQueue: function(widgetId) {
  27084. if (this.callbackQueue[widgetId]) {
  27085. var cbElems = this.callbackQueue[widgetId];
  27086. var widget = com.ibm.mashups.iwidget.model.Factory.getGlobalWidgetModel().find(widgetId);
  27087. if (widget) {
  27088. for (var i = 0; i < cbElems.length; i++) {
  27089. if (cbElems[i]) {
  27090. var scope = widget._getHandlerScope(cbElems[i].cb);
  27091. if (scope) {
  27092. var cb = dojo.hitch(scope, cbElems[i].cb);
  27093. cb(cbElems[i].id, cbElems[i].src, cbElems[i].status);
  27094. cbElems[i] = null;
  27095. }
  27096. }
  27097. }
  27098. }
  27099. }
  27100. },
  27101. loadResource: function(resourceElem, widgetId, cb2) {
  27102. var internalId = resourceElem.getGlobalId(); //could be globalid or path
  27103. var uri = resourceElem.getSrc();
  27104. var path = null;
  27105. if (resourceElem.isJS()) {
  27106. path = this._rewriteUrl(uri, widgetId, true);
  27107. }
  27108. else {
  27109. path = this._rewriteUrl(uri, widgetId, false);
  27110. }
  27111. if (!internalId) {
  27112. internalId = path;
  27113. }
  27114. if (!internalId) {
  27115. return; //if there's no id and no path, invalid request
  27116. }
  27117. //add each resource to eval queue so it will be evaluated based on order
  27118. this.evalqueue[widgetId] = this.evalqueue[widgetId] ? this.evalqueue[widgetId] : [];
  27119. this.evalqueue[widgetId].push({
  27120. _id: internalId, // used to check if resource is loaded
  27121. resourceElem: resourceElem,
  27122. cb2: cb2,
  27123. widgetId: widgetId,
  27124. isReady: false
  27125. });
  27126. //check skipLoad if available
  27127. var skipLoad = resourceElem[iwConstants.RESOURCE.skipLoad];
  27128. if (skipLoad) {
  27129. var rc = false;
  27130. try {
  27131. // we cannot use the internal eval function here as the IE eval does not return a value. We have to have it here though
  27132. rc = dojo.eval(skipLoad); // JSLINT-IGNORE: Its ok here
  27133. }
  27134. catch (e) {
  27135. rc = false;
  27136. }
  27137. if (rc) {
  27138. this._handleLoadedResource(internalId, widgetId, null, status.OTHER);
  27139. return;
  27140. }
  27141. }
  27142. //check if it's already loaded
  27143. var registeredLoadedResources = this.registeredLoadedResources;
  27144. if (dojo.isArray(registeredLoadedResources)) {
  27145. for (var j = 0; j < registeredLoadedResources.length; j++) {
  27146. if (registeredLoadedResources[j].globalid && registeredLoadedResources[j].globalid == internalId) {
  27147. if (registeredLoadedResources[j].version) {
  27148. var version = resourceElem[iwConstants.RESOURCE.version];
  27149. //don't load if specific version is not required or specific version matches the loaded version
  27150. if (!version || (version && version == registeredLoadedResources[j].version)) {
  27151. this._handleLoadedResource(internalId, widgetId, null, status.OTHER);
  27152. return;
  27153. }
  27154. }
  27155. else {
  27156. this._handleLoadedResource(internalId, widgetId, null, status.OTHER);
  27157. return;
  27158. }
  27159. }
  27160. }
  27161. }
  27162. var resourceData = this.modules[internalId]; //two widgets may have same globalid but different path
  27163. var me = this;
  27164. if (resourceData && resourceData !== null) {
  27165. var type = resourceData.type;
  27166. switch (type) {
  27167. case 0: //loading
  27168. this.waitingqueue[resourceData._id] = (this.waitingqueue[resourceData._id]) ? this.waitingqueue[resourceData._id] : [];
  27169. this.waitingqueue[resourceData._id].push({
  27170. resourceElem: resourceElem,
  27171. widgetId: widgetId,
  27172. cb2: cb2
  27173. });
  27174. return; //break; // not needed after return
  27175. case 1: //error
  27176. this._handleLoadedResource(internalId, widgetId, null, resourceData.status, resourceData.data);
  27177. return; //break; // not needed after return
  27178. case 2: //loaded
  27179. this._handleLoadedResource(internalId, widgetId, null, resourceData.status);
  27180. return; //break; // not needed after return
  27181. }
  27182. }
  27183. resourceData = {};
  27184. resourceData.type = this.LOADING_TOKEN;
  27185. resourceData._id = internalId;
  27186. resourceData._path = path;
  27187. this.modules[internalId] = resourceData;
  27188. if (internalId != path) {
  27189. this.modules[path] = this.modules[internalId];
  27190. }
  27191. var retVal = null;
  27192. if (resourceElem.isCSS()) {
  27193. retVal = this._loadCSS(path);
  27194. this.modules[internalId].type = this.LOADED_TOKEN;
  27195. this.modules[internalId].status = iwConstants.status.OTHER;
  27196. this._handleLoadedResource(internalId, widgetId, null, iwConstants.status.OTHER);
  27197. return;
  27198. }
  27199. if (resourceElem.isImage()) {
  27200. retVal = this._loadImage(path);
  27201. this.modules[internalId].type = this.LOADED_TOKEN;
  27202. this.modules[internalId].status = iwConstants.status.OTHER;
  27203. this._handleLoadedResource(internalId, widgetId, null, iwConstants.status.OTHER);
  27204. return;
  27205. }
  27206. var jsPath = path;
  27207. if (dojo.isIE == 6 && path.indexOf("/") === 0) { //ie6 doesn't like "/mum/proxy", it will throw obj error.
  27208. var schema = window.location.protocol;
  27209. var host = window.location.hostname;
  27210. var port = window.location.port;
  27211. jsPath = schema + "//" + host + ":" + port + path;
  27212. }
  27213. var mpHandler1 = com.ibm.mashups.enabler.io.XHRMultipartFactory.create();
  27214. var isSync = !mpHandler1.isTransaction();
  27215. // Required to make dojotest run synchronously
  27216. if (ibmConfig.dojotest) {
  27217. isSync = true;
  27218. }
  27219. var args = {
  27220. url: jsPath,
  27221. sync: isSync,
  27222. load: function(data, ioArgs) {
  27223. //status is 0 if it's a local file system resource
  27224. var contents = null;
  27225. if (ioArgs.xhr.status == 200 || ioArgs.xhr.status === 0) {
  27226. var oldContents = ioArgs.xhr.responseText;
  27227. contents = oldContents.replace(/_IWID_/g, "_" + widgetId + "_");
  27228. }
  27229. me.modules[internalId].type = me.LOADED_TOKEN;
  27230. me.modules[internalId].status = iwConstants.status.SUCCESS;
  27231. me._handleLoadedResource(internalId, widgetId, contents, iwConstants.status.SUCCESS);
  27232. var queue = me.waitingqueue[internalId];
  27233. if (queue) {
  27234. for (var j = 0; j < queue.length; j++) {
  27235. var req = queue[j];
  27236. me._handleLoadedResource(internalId, req.widgetId, null, iwConstants.status.SUCCESS);
  27237. }
  27238. }
  27239. me.waitingqueue[internalId] = null;
  27240. },
  27241. error: function(data, ioArgs) {
  27242. me.modules[internalId].type = me.LOADING_ERROR_TOKEN;
  27243. me.modules[internalId].data = data;
  27244. me.modules[internalId].status = ioArgs.xhr.status;
  27245. me._handleLoadedResource(internalId, widgetId, null, ioArgs.xhr.status, data);
  27246. var queue = me.waitingqueue[internalId];
  27247. if (queue) {
  27248. for (var h = 0; h < queue.length; h++) {
  27249. var req = queue[h];
  27250. me._handleLoadedResource(internalId, req.widgetId, null, ioArgs.xhr.status, data);
  27251. }
  27252. }
  27253. me.waitingqueue[internalId] = null;
  27254. }
  27255. };
  27256. dojo.xhrGet(args);
  27257. },
  27258. _rewriteUrl: function(uri, id, isXhr) {
  27259. var widget = com.ibm.mashups.iwidget.model.Factory.getGlobalWidgetModel().find(id);
  27260. return widget._rewriteURI(uri, isXhr);
  27261. },
  27262. _getExtension: function(uri) {
  27263. return uri.substring(uri.lastIndexOf(".") + 1, uri.length);
  27264. },
  27265. _loadCSS: function(path) {
  27266. var link = document.createElement("link");
  27267. link.setAttribute("rel", "stylesheet");
  27268. link.setAttribute("type", "text/css");
  27269. link.setAttribute("href", path);
  27270. document.getElementsByTagName("head")[0].appendChild(link);
  27271. },
  27272. _loadImage: function(path) {
  27273. com.ibm.mm.enabler.utils.Misc.preloadImage(url);
  27274. },
  27275. _evalCallback: function(cb, widgetId, resourceElem, status) {
  27276. //now call the callback for this resource
  27277. if (cb) {
  27278. //need to resolve as other event function
  27279. if (dojo.isString(cb)) {
  27280. var widget = com.ibm.mashups.iwidget.model.Factory.getGlobalWidgetModel().find(widgetId);
  27281. if (widget) {
  27282. var scope = widget._getHandlerScope(cb);
  27283. if (scope) {
  27284. cb = dojo.hitch(scope, cb);
  27285. }
  27286. }
  27287. }
  27288. var id = resourceElem.getGlobalId();
  27289. var src = resourceElem.getSrc();
  27290. if (!status) {
  27291. status = iwConstants.status.SUCCESS;
  27292. }
  27293. if (dojo.isFunction(cb)) {
  27294. dojo.partial(cb)(id, src, status);
  27295. }
  27296. else {
  27297. this.callbackQueue[widgetId] = this.callbackQueue[widgetId] ? this.callbackQueue[widgetId] : [];
  27298. var cbElem = {
  27299. cb: cb,
  27300. id: id,
  27301. src: src,
  27302. status: status
  27303. };
  27304. this.callbackQueue[widgetId].push(cbElem);
  27305. }
  27306. }
  27307. },
  27308. _evalFn: function(contents) {
  27309. if (window.execScript) { // JSLINT-IGNORE: We have to use eval here
  27310. window.execScript(contents, "JavaScript"); // JSLINT-IGNORE: We have to use eval here
  27311. }
  27312. else {
  27313. dojo.eval(contents); // JSLINT-IGNORE: Its ok here
  27314. }
  27315. },
  27316. _loadedFC: function(resourceElem, widgetId, cb2, data, status) {
  27317. var cb = resourceElem[iwConstants.RESOURCE.callback];
  27318. if (cb) {
  27319. this._evalCallback(cb, widgetId, resourceElem, status);
  27320. }
  27321. if (cb2) {
  27322. // suspend the transaction in order to avoid feeds/other sensitive data
  27323. // from being part of the MP transaction
  27324. var mpHandler = com.ibm.mashups.enabler.io.XHRMultipartFactory.create();
  27325. mpHandler.suspendTransaction();
  27326. if (data && status) {
  27327. cb2(data, status);
  27328. }
  27329. else {
  27330. cb2();
  27331. }
  27332. mpHandler.resumeTransaction();
  27333. }
  27334. },
  27335. _handleLoadedResource: function(internalId, widgetId, contents, status, statusData) {
  27336. var anEntry;
  27337. var queue = this.evalqueue[widgetId];
  27338. if (queue) {
  27339. if (queue[0] && queue[0]._id && queue[0]._id == internalId) {
  27340. if (contents) {
  27341. this._evalFn(contents);
  27342. }
  27343. //invoke callback
  27344. anEntry = queue.shift();//remove that resource from that queue
  27345. this._loadedFC(anEntry.resourceElem, widgetId, anEntry.cb2, statusData, status);
  27346. //if will never be here if this is the last resource in the widget loading list
  27347. var arr = queue;
  27348. var continueExec = true;
  27349. while (continueExec && queue.length > 0) {
  27350. if (queue[0].isReady) {
  27351. var theContents = queue[0].contents;
  27352. if (contents) {
  27353. this._evalFn(contents);
  27354. }
  27355. this._loadedFC(queue[0].resourceElem, widgetId, queue[0].cb2, queue[0].statusData, queue[0].status);
  27356. queue.shift();
  27357. }
  27358. else {
  27359. continueExec = false;
  27360. }
  27361. }
  27362. }
  27363. else if (queue[0] && queue[0]._id && queue[0]._id != internalId) {
  27364. for (var i = 0; i < queue.length; i++) {
  27365. anEntry = queue[i];
  27366. if (anEntry._id && anEntry._id == internalId) {
  27367. queue[i].contents = contents;
  27368. queue[i].isReady = true;
  27369. queue[i].status = status;
  27370. queue[i].statusData = statusData;
  27371. }
  27372. }
  27373. }
  27374. }
  27375. }
  27376. });
  27377. com.ibm.mashups.services.ServiceManager.setService("resourceLoadService", new com.ibm.mm.iwidget.services.ResourceLoadServiceImpl());
  27378. }
  27379. if(!dojo._hasResource["com.ibm.mm.iwidget.parser.WidgetParser"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  27380. dojo._hasResource["com.ibm.mm.iwidget.parser.WidgetParser"] = true;
  27381. dojo.provide("com.ibm.mm.iwidget.parser.WidgetParser");
  27382. dojo.declare("com.ibm.mm.iwidget.parser.WidgetParser", null, {
  27383. parseWidgetDefinition: function() {
  27384. return null;
  27385. }
  27386. });
  27387. }
  27388. if(!dojo._hasResource["com.ibm.mm.enabler.xslt"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  27389. dojo._hasResource["com.ibm.mm.enabler.xslt"] = true;
  27390. dojo.provide("com.ibm.mm.enabler.xslt");
  27391. //---------------------------------------------------------------------- xml related utility methods
  27392. /*
  27393. * loadXml(sUrl) - returns oDomDoc. parses xml from the url into DOM document object.
  27394. * loadXmlString() - returns oDomDoc. parses xml from the contents of the string into DOM document object.
  27395. * loadXsl()
  27396. * transform()
  27397. */
  27398. com.ibm.mm.enabler.xslt.ie = {};
  27399. com.ibm.mm.enabler.xslt.gecko = {};
  27400. com.ibm.mm.enabler.xslt.getXmlHttpRequest = function() {
  27401. var oXml = null;
  27402. if (typeof window.ActiveXObject != "undefined" || dojo.isIE == 11 || dojo.isIE == 10) {
  27403. oXml = new ActiveXObject("Microsoft.XMLHTTP");
  27404. }
  27405. else {
  27406. oXml = new XMLHttpRequest();
  27407. }
  27408. return oXml;
  27409. };
  27410. com.ibm.mm.enabler.xslt.loadXml = function(sUrl) {
  27411. if (typeof window.ActiveXObject != "undefined" || dojo.isIE == 11 || dojo.isIE == 10) {
  27412. return com.ibm.mm.enabler.xslt.ie.loadXml(sUrl);
  27413. }
  27414. else {
  27415. return com.ibm.mm.enabler.xslt.gecko.loadXml(sUrl);
  27416. }
  27417. };
  27418. com.ibm.mm.enabler.xslt.loadXmlString = function(sXml) {
  27419. if (typeof window.ActiveXObject != "undefined" || dojo.isIE == 11 || dojo.isIE == 10) {
  27420. return com.ibm.mm.enabler.xslt.ie.loadXmlString(sXml);
  27421. }
  27422. else {
  27423. var parser = new DOMParser();
  27424. return com.ibm.mm.enabler.xslt.gecko.loadXmlString(sXml);
  27425. }
  27426. };
  27427. com.ibm.mm.enabler.xslt.loadXsl = function(sUrl) {
  27428. if (typeof window.ActiveXObject != "undefined" || dojo.isIE == 11 || dojo.isIE == 10) {
  27429. return com.ibm.mm.enabler.xslt.ie.loadXsl(sUrl);
  27430. }
  27431. else {
  27432. return com.ibm.mm.enabler.xslt.gecko.loadXsl(sUrl);
  27433. }
  27434. };
  27435. com.ibm.mm.enabler.xslt.transform = function(xml, xsl, sXslMode, aXslParams, bReturnString) {
  27436. if (typeof window.ActiveXObject != "undefined" || dojo.isIE == 11 || dojo.isIE == 10) {
  27437. return com.ibm.mm.enabler.xslt.ie.transform(xml, xsl, sXslMode, aXslParams, bReturnString);
  27438. }
  27439. else {
  27440. return com.ibm.mm.enabler.xslt.gecko.transform(xml, xsl, sXslMode, aXslParams, bReturnString);
  27441. }
  27442. };
  27443. com.ibm.mm.enabler.xslt.transformAndUpdate = function(/*HTMLElement*/nodeToUpdate, /*XMLDocument*/ xml, /*XMLDocument*/ xsl, /*String?*/ sXslMode, /*Map*/ aXslParams) {
  27444. var results;
  27445. if (typeof window.ActiveXObject != "undefined" || dojo.isIE == 11 || dojo.isIE == 10) {
  27446. results = com.ibm.mm.enabler.xslt.ie.transform(xml, xsl, sXslMode, aXslParams, true);
  27447. //Don't really want to use innerHTML here, but seems to be the only way IE will
  27448. //take the update.
  27449. nodeToUpdate.innerHTML += results;
  27450. }
  27451. else {
  27452. results = com.ibm.mm.enabler.xslt.gecko.transform(xml, xsl, sXslMode, aXslParams, false);
  27453. var toAppend = results.documentElement;
  27454. if (results.documentElement.tagName == "transformiix:result") {
  27455. toAppend = results.documentElement.childNodes;
  27456. com.ibm.mm.enabler.utils.Dom.copyChildren(results.documentElement, nodeToUpdate, true);
  27457. }
  27458. else {
  27459. nodeToUpdate.appendChild(toAppend);
  27460. }
  27461. }
  27462. };
  27463. //---------------------------------------------------------------------- IE xml related utility methods
  27464. com.ibm.mm.enabler.xslt.ie.loadXml = function(sUrl) {
  27465. var oXmlDoc = new ActiveXObject("MSXML2.DOMDocument");
  27466. oXmlDoc.async = 0;
  27467. oXmlDoc.resolveExternals = 0;
  27468. if (!oXmlDoc.load(sUrl)) {
  27469. //Callers should catch this and can substitute their own error message
  27470. throw new Error("Error loading xml file " + sUrl);
  27471. }
  27472. return oXmlDoc;
  27473. };
  27474. com.ibm.mm.enabler.xslt.ie.loadXmlString = function(sXml) {
  27475. var oXmlDoc = new ActiveXObject("MSXML2.DOMDocument");
  27476. oXmlDoc.async = 0;
  27477. oXmlDoc.resolveExternals = 0;
  27478. if (!oXmlDoc.loadXML(sXml)) {
  27479. //Callers should catch this and can substitute their own error message
  27480. throw new Error("Error loading xml string " + sXml);
  27481. }
  27482. return oXmlDoc;
  27483. };
  27484. com.ibm.mm.enabler.xslt.ie.loadXsl = function(sUrl) {
  27485. //we need to use MSXML2.FreeThreadedDOMDocument interface in order to support
  27486. //mode and parameters in XSL transformation.
  27487. var oXslDoc = new ActiveXObject("MSXML2.FreeThreadedDOMDocument");
  27488. oXslDoc.async = 0;
  27489. oXslDoc.resolveExternals = 0;
  27490. if (!oXslDoc.load(sUrl)) {
  27491. //Callers should catch this and can substitute their own error message
  27492. throw new Error("Error loading xsl file " + sUrl);
  27493. }
  27494. return oXslDoc;
  27495. };
  27496. com.ibm.mm.enabler.xslt.ie.transform = function(xmlDoc, xsl, sXslMode, aXslParams, bReturnString) {
  27497. var oXml = xmlDoc;
  27498. var oXsl = xsl;
  27499. try {
  27500. if (!oXsl.documentElement) {
  27501. oXsl = this.loadXsl(xsl);
  27502. }
  27503. }
  27504. catch (e) {
  27505. var sMsg = e.message;
  27506. throw new Error("" + sMsg, "" + sMsg);
  27507. }
  27508. //create the xsl processor and apply the transformation
  27509. var oXslt = new ActiveXObject("Msxml2.XSLTemplate");
  27510. oXslt.stylesheet = oXsl;
  27511. var oXslProc = oXslt.createProcessor();
  27512. oXslProc.input = oXml;
  27513. //set paramaters if any
  27514. if (aXslParams) {
  27515. com.ibm.mm.enabler.utils.Misc.forIn(aXslParams, function(value,key,obj) {
  27516. this.addParameter(key,value);
  27517. },oXslProc);
  27518. }
  27519. if (sXslMode) {
  27520. oXslProc.addParameter("mode", sXslMode);
  27521. }
  27522. if (bReturnString) {
  27523. if (!oXslProc.transform()) {
  27524. //Callers should catch this and can substitute their own error message
  27525. throw new Error("Error transforming xml doc " + oXml);
  27526. }
  27527. return oXslProc.output;
  27528. }
  27529. else {
  27530. var oHtmlDoc = new ActiveXObject("MSXML2.DOMDocument");
  27531. oHtmlDoc.async = 0;
  27532. oHtmlDoc.validateOnParse = 1;
  27533. oXml.transformNodeToObject(oXsl, oHtmlDoc);
  27534. return oHtmlDoc;
  27535. }
  27536. };
  27537. //---------------------------------------------------------------------- GECKO xml related utility methods
  27538. com.ibm.mm.enabler.xslt.gecko.loadXml = function(sUrl) {
  27539. //var oXmlResponse = NG.ServerRequest.postRequest(sUrl);
  27540. // if (oXmlResponse) return xmlLoadString(oXmlResponse.responseText);
  27541. // else return null;
  27542. };
  27543. com.ibm.mm.enabler.xslt.gecko.loadXmlString = function(sXml) {
  27544. var parser = new DOMParser();
  27545. var oXmlDoc;
  27546. try {
  27547. oXmlDoc = parser.parseFromString(sXml, "text/xml");
  27548. }
  27549. catch (exc) {
  27550. //Callers should catch this and can substitute their own error message
  27551. throw new Error("Error loading xml string " + sXml);
  27552. }
  27553. return oXmlDoc;
  27554. };
  27555. com.ibm.mm.enabler.xslt.gecko.loadXsl = function(sUrl) {
  27556. //This is done through createDocument because of anchor(#) we have in portal url.
  27557. //Do not change the code without testing the case.
  27558. var oDomDoc = document.implementation.createDocument('', '', null);
  27559. oDomDoc.async = 0; // this is the important part
  27560. oDomDoc.load(sUrl);
  27561. return oDomDoc;
  27562. };
  27563. com.ibm.mm.enabler.xslt.gecko.transform = function(xmlDoc, xsl, sXslMode, aXslParams, bReturnString) {
  27564. try {
  27565. var xslDoc = xsl;
  27566. if (!xslDoc.documentElement) {
  27567. xslDoc = this.loadXsl(xsl);
  27568. }
  27569. var proc = new XSLTProcessor();
  27570. proc.importStylesheet(xslDoc);
  27571. //set parameters if any
  27572. if (aXslParams) {
  27573. com.ibm.mm.enabler.utils.Misc.forIn(aXslParams, function(value,key,obj) {
  27574. this.setParameter(null, key,value);
  27575. },proc);
  27576. }
  27577. if (sXslMode) {
  27578. proc.setParameter(null, "mode", sXslMode);
  27579. }
  27580. var resultDoc = proc.transformToDocument(xmlDoc);
  27581. if (!bReturnString) {
  27582. return resultDoc;
  27583. }
  27584. resultStr = resultDoc.documentElement.childNodes[0].textContent;
  27585. }
  27586. catch (exc) {
  27587. //Callers should catch this and can substitute their own error message
  27588. throw new Error("Error transforming xml doc " + exc);
  27589. }
  27590. return resultStr;
  27591. };
  27592. /* This method sets the content of a layer within the HTML page
  27593. * to the result of transforming the xml parameter by the xsl
  27594. * parameter. The xml and xsl parameters may be of any form
  27595. * supported by the transformXml() method. The layer parameter
  27596. * may be either a DOM object or the name of a DOM object that
  27597. * can be found using the findObject() method.
  27598. */
  27599. com.ibm.mm.enabler.xslt.setLayerContentByXml = function(layer, xml, xsl, xslparam, bReturnString) {
  27600. var result = com.ibm.mm.enabler.xslt.transform(xml, xsl, null, xslparam, bReturnString);
  27601. if (layer.innerHTML) {
  27602. layer.innerHTML = result;
  27603. }
  27604. else {
  27605. var obj = document.getElementById(layer);
  27606. obj.innerHTML = result;
  27607. }
  27608. };
  27609. }
  27610. if(!dojo._hasResource["com.ibm.mm.iwidget.widget.IWidgetDefinitionLegacyImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  27611. dojo._hasResource["com.ibm.mm.iwidget.widget.IWidgetDefinitionLegacyImpl"] = true;
  27612. dojo.provide("com.ibm.mm.iwidget.widget.IWidgetDefinitionLegacyImpl");
  27613. dojo.declare("com.ibm.mm.iwidget.widget.IWidgetDefinitionLegacyImpl", com.ibm.mashups.iwidget.widget.IWidgetDefinition, {
  27614. //unfortunately sametime iwidget is still not spec 1.0 compliant
  27615. constructor: function( /*object*/name, /*String*/ markup,/*String*/ iScope,/*object[]*/ itemSetsArr,/*object*/ widgetEvents,/*String*/ uri,/*[]*/ supportedModes,/*[]*/ publishedEvents,/*[]*/ handledEvents,/*[]*/ resources,/*[]*/ payloadDefs, iDescriptor) {
  27616. var arg1 = name;
  27617. //todo:fix me
  27618. if (dojo.isString(arg1)) {
  27619. this.name = name;
  27620. this.markup = markup;
  27621. this.iScope = iScope;
  27622. this.itemSetsArr = itemSetsArr;
  27623. this.uri = uri;
  27624. this.widgetEvents = widgetEvents;
  27625. this.publishedEvents = publishedEvents;
  27626. this.handledEvents = handledEvents;
  27627. this.supportedModes = supportedModes;
  27628. this.resources = resources;
  27629. this.payloadDefs = payloadDefs;
  27630. this.iDescriptor = iDescriptor;
  27631. }
  27632. else {
  27633. this.name = arg1.name;
  27634. this.markup = arg1.markup;
  27635. this.metaData = arg1.metaData;
  27636. this.events = arg1.events;
  27637. this.itemSets = arg1.itemSets;
  27638. this.resources = arg1.resources;
  27639. this.payloadDefs = arg1.payloadDefs;
  27640. this.iScope = this.metaData.iScope;
  27641. this.supportedModes = this.metaData.supportedModes;
  27642. this.uri = this.metaData.contentURI;
  27643. var anEvent;
  27644. this.widgetEvents = {};
  27645. for (anEvent in this.metaData) {
  27646. if (anEvent.indexOf("on") === 0) {
  27647. this.widgetEvents[anEvent] = this.metaData[anEvent];
  27648. }
  27649. }
  27650. var publishedEventsData = arg1.events.publishedEvents;
  27651. this.publishedEvents = {};
  27652. this.handledEvents = {};
  27653. var anEventName;
  27654. var iEventDescription;
  27655. for (anEventName in publishedEventsData) {
  27656. if (Object.prototype.hasOwnProperty.call(publishedEventsData,anEventName)) {
  27657. anEvent = publishedEventsData[anEventName];
  27658. iEventDescription = new com.ibm.mm.iwidget.IEventDescriptionImpl(anEvent.eventName, anEvent.payloadType, anEvent.description, anEvent.onEvent);
  27659. if (!this.publishedEvents[anEventName]) {
  27660. this.publishedEvents[anEventName] = [];
  27661. }
  27662. this.publishedEvents[anEventName].push(iEventDescription);
  27663. }
  27664. }
  27665. var handledEventsData = arg1.events.handledEvents;
  27666. for (anEventName in handledEventsData) {
  27667. if (Object.prototype.hasOwnProperty.call(handledEventsData,anEventName)) {
  27668. anEvent = handledEventsData[anEventName];
  27669. iEventDescription = new com.ibm.mm.iwidget.IEventDescriptionImpl(anEvent.eventName, anEvent.payloadType, anEvent.description, anEvent.onEvent);
  27670. if (!this.handledEvents[anEventName]) {
  27671. this.handledEvents[anEventName] = [];
  27672. }
  27673. this.handledEvents[anEventName].push(iEventDescription);
  27674. }
  27675. }
  27676. var anItemSetName;
  27677. this.itemSetsArr = {};
  27678. for (anItemSetName in arg1.itemSets) {
  27679. if (Object.prototype.hasOwnProperty.call(arg1.itemSets,anItemSetName)) {
  27680. var anItemSetData = arg1.itemSets[anItemSetName];
  27681. var anItemSet;
  27682. if (anItemSetName == "attributes") {
  27683. anItemSet = new com.ibm.mm.iwidget.itemset.ItemSetDefaultImpl(anItemSetData.name, anItemSetData.onItemSetChanged);
  27684. }
  27685. else {
  27686. anItemSet = new com.ibm.mm.iwidget.itemset.ItemSetDefaultImpl(anItemSetData.name, anItemSetData.onItemSetChanged);
  27687. }
  27688. //set data to the internal data field("items") in ItemSet
  27689. anItemSet.itemLists.items = anItemSetData.itemLists;
  27690. this.itemSetsArr[anItemSetName] = anItemSet;
  27691. }
  27692. }
  27693. }
  27694. },
  27695. _getPublishedEvents: function() {
  27696. return this.publishedEvents; // an associative array
  27697. },
  27698. _getHandledEvents: function() {
  27699. return this.handledEvents;
  27700. },
  27701. getPublishedEvents: function() {
  27702. //return a real array
  27703. var arr = [];
  27704. for (var i in this.publishedEvents) {
  27705. if (Object.prototype.hasOwnProperty.call(this.publishedEvents,i)) {
  27706. arr.push(this.publishedEvents[i]);
  27707. }
  27708. }
  27709. return arr;
  27710. },
  27711. getHandledEvents: function() {
  27712. //return a real array
  27713. var arr = [];
  27714. for (var i in this.handledEvents) {
  27715. if (Object.prototype.hasOwnProperty.call(this.handledEvents,i)) {
  27716. arr.push(this.handledEvents[i]);
  27717. }
  27718. }
  27719. return arr;
  27720. },
  27721. getAttributes: function() { // need to implement SPI
  27722. //var itemSetWrapper = {name:name,onItemSetChanged:onItemSetChanged,isPrivate:isPrivate};
  27723. // itemSetWrapper.items = [];
  27724. //var anItem = {id:id,value:value,readOnly:isReadOnly};
  27725. var attributes = this.itemSetsArr.attributes;
  27726. if (!attributes) {
  27727. attributes = {
  27728. name: "attributes",
  27729. items: {}
  27730. };
  27731. }
  27732. if (typeof(this.uri) != "undefined" && attributes) {
  27733. attributes.items.contentURI = {
  27734. id: "contentURI",
  27735. value: this.uri,
  27736. readOnly: false
  27737. };
  27738. }
  27739. if (typeof(this.supportedModes) != "undefined" && attributes) {
  27740. attributes.items.supportedModes = {
  27741. id: "supportedModes",
  27742. value: this.uri,
  27743. readOnly: false
  27744. };
  27745. }
  27746. return attributes;
  27747. },
  27748. getAllItemSetNames: function() {
  27749. var names = [];
  27750. if (!this.itemSetsArr) {
  27751. return names;
  27752. }
  27753. var i = 0;
  27754. for (var itemName in this.itemSetsArr) {
  27755. if (Object.prototype.hasOwnProperty.call(this.itemSetsArr,itemName)) {
  27756. var itemSetWrapper = this.itemSetsArr[itemName];
  27757. if (typeof(itemSetWrapper) != "undefined") {
  27758. names[i] = itemSetWrapper.name;
  27759. }
  27760. i++;
  27761. }
  27762. }
  27763. return names;
  27764. },
  27765. getItemSet: function(/*String*/name) {
  27766. if (name == "attributes") {
  27767. return this.getAttributes();
  27768. }
  27769. var itemSetWrapper = this.itemSetsArr[name];
  27770. if (typeof(itemSetWrapper) != "undefined") {
  27771. return itemSetWrapper;
  27772. }
  27773. return null;
  27774. },
  27775. getPublishedEventsNames: function() {
  27776. if (!this.publishedEvents) {
  27777. return null;
  27778. }
  27779. var eventNames = [];
  27780. var aEventName;
  27781. for (aEventName in this.publishedEvents) {
  27782. if (Object.prototype.hasOwnProperty.call(this.publishedEvents,aEventName)) {
  27783. eventNames.push(aEventName);
  27784. }
  27785. }
  27786. return eventNames;
  27787. },
  27788. getHandledEventsNames: function() {
  27789. if (!this.handledEvents) {
  27790. return null;
  27791. }
  27792. var eventNames = [];
  27793. var aEventName;
  27794. for (aEventName in this.handledEvents) {
  27795. if (Object.prototype.hasOwnProperty.call(this.handledEvents,aEventName)) {
  27796. eventNames.push(aEventName);
  27797. }
  27798. }
  27799. return eventNames;
  27800. },
  27801. getPublishedEvent: function(/*String*/eventName) {
  27802. if (!this.publishedEvents) {
  27803. return null;
  27804. }
  27805. //return an instance of iEventDescription
  27806. return this.publishedEvents[eventName];
  27807. },
  27808. getHandledEvent: function(/*String*/eventName) {
  27809. if (!this.handledEvents) {
  27810. return null;
  27811. }
  27812. //return an instance of iEventDescription
  27813. return this.handledEvents[eventName];
  27814. },
  27815. getWidgetName: function() {
  27816. return this.name;
  27817. },
  27818. getPayloadDefs: function() {
  27819. return this.payloadDefs;
  27820. },
  27821. getPayloadDef: function(name) {
  27822. var payloadDef = this.payloadDefs[name];
  27823. if (typeof payloadDef == "undefined") {
  27824. return null;
  27825. }
  27826. return payloadDef;
  27827. },
  27828. getPayloadDefNames: function() {
  27829. var arr = [];
  27830. var a;
  27831. for (a in this.payloadDefs) {
  27832. if (Object.prototype.hasOwnProperty.call(this.payloadDefs,a)) {
  27833. arr.push(a);
  27834. }
  27835. }
  27836. return arr;
  27837. },
  27838. getSupportedModes: function() {
  27839. var temp = this.supportedModes;
  27840. if (!temp) {
  27841. return null;
  27842. }
  27843. var arr = temp.split(" ");
  27844. return arr;
  27845. },
  27846. getIDescriptorItems: function() {
  27847. return null;
  27848. },
  27849. getMarkupByMode: function(mode) {
  27850. return this.markup;
  27851. },
  27852. getWidgetEvents: function() {
  27853. return this.widgetEvents;
  27854. },
  27855. getIScope: function() {
  27856. return this.iScope;
  27857. },
  27858. getResources: function() {
  27859. return this.resources;
  27860. },
  27861. getDefaultLanguage: function() {
  27862. return "en";
  27863. },
  27864. getMarkup: function() {
  27865. return this.markup;
  27866. },
  27867. getAllowInstanceContent: function() {
  27868. return false;
  27869. },
  27870. _getShareableItemSets: function() {
  27871. return null;
  27872. },
  27873. _getManagedItemSetListener: function(itemsetname) {
  27874. return null;
  27875. },
  27876. getXmlBase: function() {
  27877. return null;
  27878. }
  27879. });
  27880. }
  27881. if(!dojo._hasResource["com.ibm.mm.iwidget.parser.LegacyXMLParser"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  27882. dojo._hasResource["com.ibm.mm.iwidget.parser.LegacyXMLParser"] = true;
  27883. dojo.provide("com.ibm.mm.iwidget.parser.LegacyXMLParser");
  27884. dojo.declare("com.ibm.mm.iwidget.parser.LegacyXMLParser", com.ibm.mm.iwidget.parser.WidgetParser, {
  27885. constructor: function(responseText) {
  27886. this.xmlStr = responseText;
  27887. },
  27888. namespaces: {
  27889. "iw": "http://www.ibm.com/iWidget"
  27890. },
  27891. parseWidgetDefinition: function() {
  27892. var xmlData = com.ibm.mm.enabler.xslt.loadXmlString(this.xmlStr);
  27893. var markup = this.readMarkup(xmlData);
  27894. var itemSetsArr = this.readItemSets(xmlData);
  27895. var uri = this.readContentURI(xmlData);
  27896. var widgetEvents = this.readWidgetEvents(xmlData);
  27897. var name = this.readName(xmlData);
  27898. var iScope = this.readiScope(xmlData);
  27899. var supportedModes = this.readSupportedModes(xmlData);
  27900. var handledEvents = this.readPublicEvents(xmlData, "iw:handledEvents");
  27901. var publishedEvents = this.readPublicEvents(xmlData, "iw:publishedEvents");
  27902. var resources = this.readResources(xmlData);
  27903. var payloadDefs = this.readPayloadDefs(xmlData);
  27904. var iDescriptor = this.readIDescriptor(xmlData);
  27905. return new com.ibm.mm.iwidget.widget.IWidgetDefinitionLegacyImpl(name, markup, iScope, itemSetsArr, widgetEvents, uri, supportedModes, publishedEvents, handledEvents, resources, payloadDefs, iDescriptor);
  27906. },
  27907. readMarkup: function( /*XMLDocument*/xmlData) {
  27908. var contentsXPath = "/iw:iwidget/iw:content";
  27909. //we support html fragment only in iw:content
  27910. var rootNode = com.ibm.mashups.enabler.xml.XPath.evaluateEntry(contentsXPath, xmlData, this.namespaces);
  27911. var defaultContent = "";
  27912. if (rootNode) {
  27913. var child = rootNode.childNodes;
  27914. for (var j = 0, l = child.length; j < l; j++) {
  27915. var aNode = child[j];
  27916. //if this is CDATAsection
  27917. if (aNode.nodeType == 4) {
  27918. defaultContent = defaultContent.concat(aNode.nodeValue);
  27919. }
  27920. else if (aNode.nodeType == 3) {//textNode
  27921. defaultContent = defaultContent.concat(aNode.nodeValue);
  27922. }
  27923. }
  27924. }
  27925. // exit trace
  27926. return defaultContent;
  27927. },
  27928. readSupportedModes: function(/*XMLDocument*/xmlData) {
  27929. // read the iwidget's "supportedModes" attribute and store
  27930. // the string (no further parding here)
  27931. var root = xmlData.documentElement;
  27932. var modes = root.getAttribute("supportedModes");
  27933. // return null if not found
  27934. if (typeof modes == "undefined" || modes === null) {
  27935. return null;
  27936. }
  27937. return modes;
  27938. },
  27939. readItemSets: function( /*XMLDocument*/xmlData) {
  27940. var itemSetsArr = {};
  27941. var contentsXPath = "/iw:iwidget/iw:itemSet";
  27942. var nodes = com.ibm.mashups.enabler.xml.XPath.evaluateXPath(contentsXPath, xmlData, this.namespaces);
  27943. for (var i = 0, l = nodes.length; i < l; i++) {
  27944. var aNode = nodes[i];
  27945. var id = aNode.getAttribute("name");
  27946. var onItemSetChanged = aNode.getAttribute("onItemSetChanged");
  27947. var itemSetWrapper = {
  27948. id: id,
  27949. onItemSetChanged: onItemSetChanged
  27950. };
  27951. itemSetWrapper.items = {};
  27952. var child = aNode.childNodes;
  27953. for (var j = 0, l2 = child.length; j < l2; j++) {
  27954. var aItemNode = child[j];
  27955. if (aItemNode.nodeType == 1) {
  27956. var isReadOnly = aItemNode.getAttribute("readOnly");
  27957. var anItem = {
  27958. id: aItemNode.getAttribute("name"),
  27959. value: aItemNode.getAttribute("value"),
  27960. readOnly: isReadOnly
  27961. };
  27962. itemSetWrapper.items[anItem.id] = anItem;
  27963. }
  27964. }
  27965. itemSetsArr[id] = itemSetWrapper;
  27966. }
  27967. // exit trace
  27968. return itemSetsArr;
  27969. },
  27970. readPayloadDefs: function( /*XMLDocument*/xmlData) {
  27971. var payloadDefsArr = {};
  27972. var contentsXPath = "/iw:iwidget/iw:payloadDef";
  27973. var nodes = com.ibm.mashups.enabler.xml.XPath.evaluateXPath(contentsXPath, xmlData, this.namespaces);
  27974. for (var i = 0, l = nodes.length; i < l; i++) {
  27975. var aNode = nodes[i];
  27976. var payloadDef = com.ibm.mm.iwidget.Utils.getPayloadDef(aNode);
  27977. payloadDefsArr[payloadDef.name] = payloadDef;
  27978. }
  27979. // exit trace
  27980. return payloadDefsArr;
  27981. },
  27982. readName: function(/*XMLDocument*/xmlData) {
  27983. var root = xmlData.documentElement;
  27984. var name = root.getAttribute("name");
  27985. if (typeof name == "undefined" || name === null) {
  27986. return null;
  27987. }
  27988. return name;
  27989. },
  27990. //this attribute is a convenience for an extremely common iwidget attribute, if specifies a URI which the iwidget will use to fetch data or markup which it will present to the user
  27991. readContentURI: function(/*XMLDocument*/xmlData) {
  27992. var root = xmlData.documentElement;
  27993. var uri = root.getAttribute("contentURI");
  27994. if (typeof uri == "undefined" || uri === null) {
  27995. return null;
  27996. }
  27997. return uri;
  27998. },
  27999. readiScope: function(/*XMLDocument*/xmlData) {
  28000. var root = xmlData.documentElement;
  28001. var iScope = root.getAttribute("iScope");
  28002. if (typeof iScope == "undefined" || iScope === null) {
  28003. return null;
  28004. }
  28005. return iScope;
  28006. },
  28007. readWidgetEvents: function(/*XMLDocument*/xmlData) {
  28008. //read all teh onSth event
  28009. var root = xmlData.documentElement;
  28010. var widgetEvents = {};
  28011. var attributes = root.attributes;
  28012. for (var i = 0; i < attributes.length; i++) {
  28013. var event = attributes[i];
  28014. if (event.name.indexOf("on") === 0) {
  28015. var handler = event.value;
  28016. if (typeof handler != "undefined" && handler !== null) {
  28017. widgetEvents[event.name] = handler;
  28018. }
  28019. }
  28020. }
  28021. return widgetEvents;
  28022. },
  28023. readPublicEvents: function(/*XMLDocument*/xmlData,/*String*/ eventType) {
  28024. //returns iEventDescriptionImpl(name,onEvent,payloadType,description)
  28025. var contentsXPath = "/iw:iwidget/" + eventType;
  28026. var node = com.ibm.mashups.enabler.xml.XPath.evaluateEntry(contentsXPath, xmlData, this.namespaces);
  28027. var events = {};
  28028. if (node) {
  28029. dojo.forEach(node.childNodes, function(eventNode) {
  28030. if (eventNode.nodeType == 1) {
  28031. //todo. handle aliases
  28032. var iEventDescription = new com.ibm.mm.iwidget.IEventDescriptionImpl(eventNode.getAttribute("eventName"), eventNode.getAttribute("onEvent"), eventNode.getAttribute("payloadType"), eventNode.getAttribute("description"));
  28033. events[eventNode.getAttribute("eventName")] = iEventDescription;
  28034. }
  28035. },this);
  28036. }
  28037. if (!events) {
  28038. return null;
  28039. }
  28040. return events;
  28041. },
  28042. readResources: function(/*XMLDocument*/xmlData) {
  28043. var resourcePath = "/iw:iwidget/iw:resource";
  28044. var resources = [];
  28045. var nodes = com.ibm.mashups.enabler.xml.XPath.evaluateXPath(resourcePath, xmlData, this.namespaces);
  28046. if (nodes && nodes.length > 0) {
  28047. dojo.forEach(nodes,function(node) {
  28048. var resource = {};
  28049. resource.name = node.getAttribute("resourceName");
  28050. resource.src = node.getAttribute("uri");
  28051. resource.version = node.getAttribute("version");
  28052. resource.callback = node.getAttribute("callback");
  28053. resource.mimetype = node.getAttribute("mimetype");
  28054. resources[i] = resource;
  28055. },this);
  28056. }
  28057. return resources;
  28058. },
  28059. readIDescriptor: function(/*XMLDocument*/xmlData) {
  28060. //don't support this in legacy
  28061. return null;
  28062. }
  28063. });
  28064. }
  28065. if(!dojo._hasResource["com.ibm.mm.iwidget.parser.StandardXMLParser"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  28066. dojo._hasResource["com.ibm.mm.iwidget.parser.StandardXMLParser"] = true;
  28067. dojo.provide("com.ibm.mm.iwidget.parser.StandardXMLParser");
  28068. dojo.declare("com.ibm.mm.iwidget.parser.StandardXMLParser", com.ibm.mm.iwidget.parser.WidgetParser, {
  28069. constructor: function(responseText) {
  28070. this.xmlStr = responseText;
  28071. },
  28072. namespaces: {
  28073. "iw": "http://www.ibm.com/xmlns/prod/iWidget"
  28074. },
  28075. reservedAttributes: {
  28076. iScope: "iScope",
  28077. supportedModes: "supportedModes",
  28078. id: "id",
  28079. allowInstanceContent: "allowInstanceContent",
  28080. lang: "lang",
  28081. "xmlns:iw": "xmlns:iw",
  28082. supportedWindowStates: "supportedWindowStates",
  28083. "xml:lang": "xml:lang",
  28084. "xml:base":"xml:base"
  28085. },
  28086. parseWidgetDefinition: function() {
  28087. var xmlData = com.ibm.mm.enabler.xslt.loadXmlString(this.xmlStr);
  28088. var widgetDef = this.readRootElement(xmlData);
  28089. widgetDef.markup = this.readMarkup(xmlData);
  28090. widgetDef.itemSetsArr = this.readItemSets(xmlData, widgetDef); // it also sets the .shareableItemSetsArr
  28091. //widgetDef.handledEvents = this.readPublicEvents(xmlData,"handled");
  28092. //widgetDef.publishedEvents = this.readPublicEvents(xmlData,"published");
  28093. widgetDef.publicEvents = this.readPublicEvents(xmlData);
  28094. widgetDef.resources = this.readResources(xmlData);
  28095. var payloadDefs = this.readPayloadDefs(xmlData);
  28096. if (payloadDefs) {
  28097. widgetDef.payloadDefs = payloadDefs;
  28098. }
  28099. widgetDef.eventDescriptions = this.readEventDescriptions(xmlData);
  28100. widgetDef.xmlStr = this.xmlStr;
  28101. return new com.ibm.mm.iwidget.widget.IWidgetDefinitionImpl(widgetDef, this.xmlStr);
  28102. },
  28103. readRootElement: function( /*XMLDocument*/xmlData) {
  28104. var widgetDef = {};
  28105. var root = xmlData.documentElement;
  28106. var modes = root.getAttribute("supportedModes");
  28107. // return null if not found
  28108. if (!modes) {
  28109. modes = "view";
  28110. }
  28111. widgetDef.supportedModes = modes;
  28112. var value;
  28113. var name = root.getAttribute("id");
  28114. if (!name) {
  28115. name = null;
  28116. }
  28117. widgetDef.id = name;
  28118. widgetDef.name = name;
  28119. var temp = root.getAttribute("allowInstanceContent");
  28120. var allowInstanceContent = false;
  28121. if (temp && temp == "true") {
  28122. allowInstanceContent = true;
  28123. }
  28124. widgetDef.allowInstanceContent = allowInstanceContent;
  28125. var lang = root.getAttribute("lang");
  28126. if (!lang) {
  28127. lang = root.getAttribute("xml:lang");
  28128. }
  28129. if (!lang) {
  28130. lang = "en";
  28131. }
  28132. widgetDef.lang = lang;
  28133. var widgetEvents = {};
  28134. var attributes = root.attributes;
  28135. var i;
  28136. for (i = 0; i < attributes.length; i++) {
  28137. var event = attributes[i];
  28138. if (event.name.indexOf("on") === 0) {
  28139. var handler = event.value;
  28140. if (handler) {
  28141. widgetEvents[event.name] = handler;
  28142. }
  28143. }
  28144. }
  28145. widgetDef.widgetEvents = widgetEvents;
  28146. var iScope = root.getAttribute("iScope");
  28147. if (!iScope) {
  28148. iScope = null;
  28149. }
  28150. widgetDef.iScope = iScope;
  28151. var iDescriptorItems = iwConstants.iDescriptorItems;
  28152. var iDescriptor = {};
  28153. for (var j in iDescriptorItems) {
  28154. if (Object.prototype.hasOwnProperty.call(iDescriptorItems,j)) {
  28155. name = iDescriptorItems[j];
  28156. value = root.getAttribute(name);
  28157. iDescriptor[name] = value;
  28158. }
  28159. }
  28160. widgetDef.iDescriptor = iDescriptor;
  28161. var simpleAttributes = {};
  28162. attributes = root.attributes;
  28163. for (i = 0; i < attributes.length; i++) {
  28164. var att = attributes[i];
  28165. if (att.name.indexOf("on") !== 0 && !iwConstants.iDescriptorItems[att.name] && !this.reservedAttributes[att.name]) {
  28166. value = att.value;
  28167. if (typeof value != "undefined" && value !== null) {
  28168. simpleAttributes[att.name] = value;
  28169. }
  28170. }
  28171. }
  28172. widgetDef.simpleAttributes = simpleAttributes;
  28173. var windowStates = root.getAttribute("supportedWindowStates");
  28174. // return null if not found
  28175. if (!windowStates) {
  28176. windowStates = "normal";
  28177. }
  28178. widgetDef.supportedWindowStates = windowStates;
  28179. var xmlBase = root.getAttribute("xml:base");
  28180. if (xmlBase) {
  28181. widgetDef.xmlBase = xmlBase;
  28182. }
  28183. return widgetDef;
  28184. },
  28185. readMarkup: function( /*XMLDocument*/xmlData) {
  28186. var contentsXPath = "/iw:iwidget/iw:content";
  28187. //we support html fragment only in iw:content
  28188. var nodes = com.ibm.mashups.enabler.xml.XPath.evaluateXPath(contentsXPath, xmlData, this.namespaces);
  28189. var contents = {};
  28190. var defaultContent = "";
  28191. var mode = null;
  28192. if (nodes && nodes.length > 0) {
  28193. for (var i = 0, l = nodes.length; i < l; i++) {
  28194. var rootNode = nodes[i];
  28195. var child = rootNode.childNodes;
  28196. for (var j = 0, l2 = child.length; j < l2; j++) {
  28197. var aNode = child[j];
  28198. //if this is CDATAsection
  28199. if (aNode.nodeType == 4) {
  28200. defaultContent = defaultContent.concat(aNode.nodeValue);
  28201. }
  28202. else if (aNode.nodeType == 3) {//textNode
  28203. defaultContent = defaultContent.concat(aNode.nodeValue);
  28204. }
  28205. }
  28206. mode = rootNode.getAttribute("mode");
  28207. if (!mode) {
  28208. mode = "view"; //assign default mode
  28209. break;
  28210. }
  28211. uri = rootNode.getAttribute("uri");
  28212. contents[mode] = {};
  28213. if (uri) {
  28214. contents[mode].uri = uri;
  28215. }
  28216. contents[mode].content = defaultContent;
  28217. defaultContent = "";
  28218. }
  28219. }
  28220. // exit trace
  28221. return contents;
  28222. },
  28223. /**
  28224. * Return json object, each itemset
  28225. * {
  28226. * id:{id},
  28227. * items:{}, --> for each item: {id:{id},name:{name},readOnly:{readOnly},value:{value},defaultLocale:{defaultLocale},values:{}}
  28228. * onItemSetChanged:{handler}
  28229. * }
  28230. */
  28231. readItemSets: function( /*XMLDocument*/xmlData, widgetDef) {
  28232. var shareableItemSetsArr = {};
  28233. var itemSetsArr = {};
  28234. var contentsXPath = "/iw:iwidget/iw:itemSet";
  28235. var nodes = com.ibm.mashups.enabler.xml.XPath.evaluateXPath(contentsXPath, xmlData, this.namespaces);
  28236. for (var i = 0, l = nodes.length; i < l; i++) {
  28237. var aNode = nodes[i];
  28238. var itemSetId = aNode.getAttribute("id");
  28239. //alias if optiontal
  28240. var alias = aNode.getAttribute("alias")?aNode.getAttribute("alias"):null;
  28241. if (!alias){
  28242. alias = aNode.getAttribute("globalid") ? aNode.getAttribute("globalid") : null;
  28243. }
  28244. var onItemSetChanged = aNode.getAttribute("onItemSetChanged");
  28245. var temp = aNode.getAttribute("private");
  28246. var isPrivate = true;
  28247. if (temp && temp == "false") {
  28248. isPrivate = false;
  28249. }
  28250. var descriptionRef = aNode.getAttribute("description");
  28251. var itemSetWrapper = {
  28252. id: itemSetId,
  28253. onItemSetChanged: onItemSetChanged,
  28254. isPrivate: isPrivate
  28255. };
  28256. if (alias) {
  28257. itemSetWrapper.alias = alias;
  28258. }
  28259. itemSetWrapper.items = {};
  28260. var itemNodes = aNode.childNodes; // WARNING: this assumes that an itemset only contains items !
  28261. for (var j = 0, jL = itemNodes.length; j < jL; j++) {
  28262. var aItemNode = itemNodes[j];
  28263. if (aItemNode.nodeType == 1) {
  28264. var readOnly = false;
  28265. var readOnlyAtt = aItemNode.getAttribute("readOnly");
  28266. if (readOnlyAtt && readOnlyAtt == "true") {
  28267. readOnly = true;
  28268. }
  28269. var id = aItemNode.getAttribute("id");
  28270. var alias1 = aItemNode.getAttribute("alias")?aItemNode.getAttribute("alias"):null;
  28271. if (!alias1){
  28272. alias1 = aItemNode.getAttribute("globalid") ? aItemNode.getAttribute("globalid") : null;
  28273. }
  28274. var value = aItemNode.getAttribute("value");
  28275. var lang = aItemNode.getAttribute("lang");
  28276. if (!lang) {
  28277. lang = aItemNode.getAttribute("xml:lang");
  28278. }
  28279. var anItem = {};
  28280. anItem.id = id;
  28281. if (alias1) {
  28282. anItem.alias = alias1;
  28283. }
  28284. anItem.readOnly = readOnly;
  28285. if (!lang && (typeof value != "undefined" && value !== null)) { // "" is also allowed
  28286. anItem.value = value; //a value without locale
  28287. }
  28288. if (lang) {
  28289. anItem.defaultLocale = lang;
  28290. }
  28291. if (lang && (typeof value != "undefined" && value !== null)){
  28292. anItem.values = {};
  28293. anItem.values[lang] = value;
  28294. }
  28295. //value with locale
  28296. var valueNodes = aItemNode.childNodes;
  28297. if (valueNodes.length > 0 || (lang && value)) {
  28298. for (var v = 0, vL = valueNodes.length; v < vL; v++) {
  28299. var valueNode = valueNodes[v];
  28300. if (valueNode.nodeType == 1) {
  28301. var locale = valueNode.getAttribute("lang");
  28302. if (!locale) {
  28303. locale = valueNode.getAttribute("xml:lang");
  28304. }
  28305. if (!locale) {
  28306. locale = "en";
  28307. }
  28308. var localeValue = valueNode.getAttribute("value");
  28309. anItem.values = anItem.values?anItem.values:{};
  28310. anItem.values[locale] = localeValue;
  28311. }
  28312. }
  28313. }
  28314. itemSetWrapper.items[id] = anItem;
  28315. }
  28316. }
  28317. if (isPrivate) {
  28318. itemSetsArr[itemSetId] = itemSetWrapper;
  28319. }
  28320. else {
  28321. shareableItemSetsArr[itemSetId] = itemSetWrapper;
  28322. }
  28323. }
  28324. widgetDef.shareableItemSetsArr = shareableItemSetsArr;
  28325. // exit trace
  28326. return itemSetsArr;
  28327. },
  28328. readPayloadDefs: function( /*XMLDocument*/xmlData) {
  28329. var payloadDefsArr = {};
  28330. var contentsXPath = "/iw:iwidget/iw:payloadDef";
  28331. var nodes = com.ibm.mashups.enabler.xml.XPath.evaluateXPath(contentsXPath, xmlData, this.namespaces);
  28332. for (var i = 0, l = nodes.length; i < l; i++) {
  28333. var aNode = nodes[i];
  28334. var payloadDef = com.ibm.mm.iwidget.Utils.getPayloadDef(aNode);
  28335. payloadDefsArr[payloadDef.name] = payloadDef;
  28336. }
  28337. if (com.ibm.mm.enabler.utils.Misc.isEmpty(payloadDefsArr) === true) {
  28338. payloadDefsArr = null;
  28339. }
  28340. // exit trace
  28341. return payloadDefsArr;
  28342. },
  28343. readPublicEvents: function(/*XMLDocument*/xmlData,/*String*/ eventType) {
  28344. //return empty object if no events is defined
  28345. //var contentsXPath = "/iw:iwidget/iw:event[@"+eventType+"]";
  28346. var events = {};
  28347. var contentsXPath = "/iw:iwidget/iw:event";
  28348. var nodes = com.ibm.mashups.enabler.xml.XPath.evaluateXPath(contentsXPath, xmlData, this.namespaces);
  28349. if (nodes && nodes.length !== 0) {
  28350. for (var j = 0, l = nodes.length; j < l; j++) {
  28351. var eventNode = nodes[j];
  28352. if (eventNode.nodeType == 1) {
  28353. //todo. handler attributes
  28354. var iEvent = {};
  28355. var attributes = eventNode.attributes;
  28356. for (var i = 0; i < attributes.length; i++) {
  28357. var att = attributes[i];
  28358. var name = att.name;
  28359. var value = att.value;
  28360. if (name == "eventDescName") {
  28361. name = "description"; //backward compatibility
  28362. }
  28363. if (name == "handled") {
  28364. name = "isHandled"; //align with js representation
  28365. }
  28366. if (name == "published") {
  28367. name = "isPublished"; //align with js representation
  28368. }
  28369. if (value) {
  28370. iEvent[name] = value;
  28371. }
  28372. }
  28373. events[iEvent.id] = iEvent;
  28374. }
  28375. }
  28376. }
  28377. return events;
  28378. },
  28379. readResources: function(/*XMLDocument*/xmlData) {
  28380. var resourcePath = "/iw:iwidget/iw:resource";
  28381. var resources = [];
  28382. var nodes = com.ibm.mashups.enabler.xml.XPath.evaluateXPath(resourcePath, xmlData, this.namespaces);
  28383. if (nodes && nodes.length !== 0) {
  28384. for (var i = 0, l = nodes.length; i < l; i++) {
  28385. var node = nodes[i];
  28386. var resource = {};
  28387. var id = node.getAttribute("id");
  28388. if (!id) {
  28389. id = node.getAttribute("globalid");
  28390. }
  28391. resource[iwConstants.RESOURCE.id] = id;
  28392. resource[iwConstants.RESOURCE.globalid] = node.getAttribute("globalid")?node.getAttribute("globalid"):null;
  28393. var src = node.getAttribute("src");
  28394. if (!src) {
  28395. src = node.getAttribute("uri");
  28396. //todo warning
  28397. }
  28398. resource[iwConstants.RESOURCE.src] = src;
  28399. resource[iwConstants.RESOURCE.version] = node.getAttribute("version");
  28400. resource[iwConstants.RESOURCE.blockInit] = node.getAttribute("blockInit");
  28401. resource[iwConstants.RESOURCE.callback] = node.getAttribute("callback");
  28402. resource[iwConstants.RESOURCE.mimeType] = node.getAttribute("mimeType");
  28403. resource[iwConstants.RESOURCE.skipLoad] = node.getAttribute("skipLoad");
  28404. if (!resource[iwConstants.RESOURCE.skipLoad]) {
  28405. var childNodes = node.childNodes;
  28406. var aNode = null;
  28407. for (var j = 0; j < childNodes.length; j++) {
  28408. aNode = childNodes[j];
  28409. if (aNode.nodeType == 1) {//skipLoad section //CDATA section
  28410. break;
  28411. }
  28412. }
  28413. if (aNode) {
  28414. childNodes = aNode.childNodes;
  28415. for (var h = 0; h < childNodes.length; h++) {
  28416. if (childNodes[h].nodeType == 4) {//skipLoad section //CDATA section
  28417. resource[iwConstants.RESOURCE.skipLoad] = childNodes[h].nodeValue;
  28418. }
  28419. }
  28420. }
  28421. }
  28422. resources[i] = resource;
  28423. }
  28424. }
  28425. return resources;
  28426. },
  28427. readEventDescriptions: function(/*XMLDocument*/xmlData) {
  28428. var eventDescriptionpath = "iw:iwidget/iw:eventDescription";
  28429. var eventDescriptions = {};
  28430. var nodes = com.ibm.mashups.enabler.xml.XPath.evaluateXPath(eventDescriptionpath, xmlData, this.namespaces);
  28431. if (nodes && nodes.length !== 0) {
  28432. for (var i = 0, l = nodes.length; i < l; i++) {
  28433. var node = nodes[i];
  28434. var eventDescription = {};
  28435. var id = node.getAttribute("id");
  28436. eventDescription.id = id;
  28437. eventDescription.payloadType = node.getAttribute("payloadType");
  28438. eventDescription.description = node.getAttribute("description");
  28439. eventDescription.title = node.getAttribute("title");
  28440. eventDescription.descriptionURI = node.getAttribute("descriptionURI");
  28441. var lang = node.getAttribute("lang");
  28442. if (!lang) {
  28443. lang = node.getAttribute("xml:lang");
  28444. }
  28445. eventDescription.lang = lang;
  28446. eventDescription.aliases = node.getAttribute("aliases");
  28447. eventDescription.descriptions = {};
  28448. var children = node.childNodes;
  28449. for (var j = 0, jL = children.length; j < jL; j++) {
  28450. var aNode = children[j];
  28451. if (aNode.nodeType == 1) {
  28452. var temp = {};
  28453. var lang2 = aNode.getAttribute("lang");
  28454. if (!lang2) {
  28455. lang2 = aNode.getAttribute("xml:lang");
  28456. }
  28457. temp.description = aNode.getAttribute("description");
  28458. temp.title = aNode.getAttribute("title");
  28459. temp.descriptionURI = aNode.getAttribute("descriptionURI");
  28460. eventDescription.descriptions[lang2] = temp;
  28461. }
  28462. }
  28463. eventDescriptions[id] = eventDescription;
  28464. }
  28465. }
  28466. return eventDescriptions;
  28467. }
  28468. });
  28469. }
  28470. if(!dojo._hasResource["com.ibm.mm.iwidget.parser.OpenSocialXMLParser"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  28471. dojo._hasResource["com.ibm.mm.iwidget.parser.OpenSocialXMLParser"] = true;
  28472. dojo.provide("com.ibm.mm.iwidget.parser.OpenSocialXMLParser");
  28473. dojo.declare("com.ibm.mm.iwidget.parser.OpenSocialXMLParser", com.ibm.mm.iwidget.parser.WidgetParser, {
  28474. constructor: function(responseText) {
  28475. this.xmlStr = responseText;
  28476. },
  28477. namespaces: {},
  28478. reservedAttributes: {
  28479. iScope: "iScope",
  28480. supportedModes: "supportedModes",
  28481. id: "id",
  28482. allowInstanceContent: "allowInstanceContent",
  28483. lang: "lang",
  28484. "xmlns:iw": "xmlns:iw",
  28485. supportedWindowStates: "supportedWindowStates",
  28486. "xml:lang": "xml:lang",
  28487. "xml:base": "xml:base"
  28488. },
  28489. parseWidgetDefinition: function() {
  28490. var xmlData = com.ibm.mm.enabler.xslt.loadXmlString(this.xmlStr);
  28491. var widgetDef = this.readRootElement(xmlData);
  28492. this.readAllChildNodes(xmlData, widgetDef); // sets shareableItemSetsArr and itemSetsArr
  28493. widgetDef.publicEvents = this.readPublicEvents(xmlData);
  28494. widgetDef.resources = this.readResources(xmlData);
  28495. var payloadDefs = this.readPayloadDefs(xmlData);
  28496. if (payloadDefs) {
  28497. widgetDef.payloadDefs = payloadDefs;
  28498. }
  28499. widgetDef.eventDescriptions = this.readEventDescriptions(xmlData);
  28500. widgetDef.xmlStr = this.xmlStr;
  28501. return new com.ibm.mm.iwidget.widget.IWidgetDefinitionImpl(widgetDef, this.xmlStr);
  28502. },
  28503. readRootElement: function( /*XMLDocument*/xmlData) {
  28504. var widgetDef = {};
  28505. var root = xmlData.documentElement;
  28506. // TBD in gadgets, read mode as part of the Content tag
  28507. var modes = "view";
  28508. widgetDef.supportedModes = modes;
  28509. var value;
  28510. var name = null;
  28511. widgetDef.id = name; // TBD widget id needs to be set up with something else?
  28512. widgetDef.name = name; // // TBD widget name needs to be set up with something else?
  28513. var temp = null;
  28514. var allowInstanceContent = false; // TBD is this the right value for gadgets?
  28515. widgetDef.allowInstanceContent = allowInstanceContent;
  28516. var lang = "en"; // TBD how to determine the default language for the gadget? read Locale nodes?
  28517. widgetDef.lang = lang;
  28518. widgetDef.getType = dojo.hitch(widgetDef, function () { return com.ibm.mm.iwidget.Constants.OSGADGET_DEFINITION_TYPE; });
  28519. var widgetEvents = {};
  28520. widgetDef.widgetEvents = widgetEvents; // OS gadgets 1.0 do not have any "on" Events in its spec
  28521. var iScope = null;
  28522. widgetDef.iScope = iScope;
  28523. var iDescriptor = {};
  28524. widgetDef.iDescriptor = iDescriptor;
  28525. var simpleAttributes = {};
  28526. widgetDef.simpleAttributes = simpleAttributes;
  28527. var windowStates = "normal";
  28528. widgetDef.supportedWindowStates = windowStates;
  28529. return widgetDef;
  28530. },
  28531. readAllChildNodes: function( /*XMLDocument*/xmlData, widgetDef) {
  28532. var root = xmlData.documentElement;
  28533. if (root.children) {
  28534. var childrenNodes = root.children;
  28535. for (var j = 0; j < childrenNodes.length; j++) {
  28536. if (childrenNodes[j].nodeName) {
  28537. if (childrenNodes[j].nodeName === "ModulePrefs") {
  28538. this.readModulePrefs(childrenNodes[j], widgetDef);
  28539. }
  28540. else if (childrenNodes[j].nodeName === "UserPref") {
  28541. }
  28542. else if (childrenNodes[j].nodeName === "Content") {
  28543. widgetDef.markup = this.readContent(childrenNodes[j]);
  28544. }
  28545. }
  28546. }
  28547. }
  28548. },
  28549. readContent: function( /*XMLDocument*/documentElement) {
  28550. var contents = {};
  28551. var nodes = documentElement.childNodes;
  28552. var defaultContent = "";
  28553. var mode = "view";
  28554. for (var j = 0; j < nodes.length; j++) {
  28555. var aNode = nodes[j];
  28556. //if this is CDATAsection
  28557. if (aNode.nodeType == 4) {
  28558. defaultContent = defaultContent.concat(aNode.nodeValue);
  28559. }
  28560. else if (aNode.nodeType == 3) {//textNode
  28561. defaultContent = defaultContent.concat(aNode.nodeValue);
  28562. }
  28563. }
  28564. contents[mode] = {};
  28565. contents[mode].content = defaultContent;
  28566. return contents;
  28567. },
  28568. readMarkup: function( /*XMLDocument*/xmlData) {
  28569. return {};
  28570. },
  28571. readItemSets: function( /*XMLDocument*/xmlData, widgetDef) {
  28572. return {};
  28573. },
  28574. readModulePrefs: function( /*XMLDocument*/documentElement, widgetDef) {
  28575. // iterate through attributes to get title and then parse it with Locale info
  28576. var iDescriptor = {};
  28577. iDescriptor.mode = "view";
  28578. iDescriptor.name = ""; // TBD how to get the gadget name or id here?
  28579. widgetDef.iDescriptor = iDescriptor;
  28580. var itemSetsArr = {};
  28581. var shareableItemSetsArr = {};
  28582. var itemSetId = "idescriptor";
  28583. if (documentElement.attributes && documentElement.attributes !== null) {
  28584. var modAttributes = documentElement.attributes;
  28585. for (var j = 0; j < modAttributes.length; j++) {
  28586. if (modAttributes[j]) {
  28587. var isPrivate = true;
  28588. if (modAttributes[j].name && modAttributes[j].name === "title") { // parses only title item
  28589. var title = modAttributes[j].name;
  28590. var isTitleTranslatable = false;
  28591. var itemSetWrapper = {
  28592. id: itemSetId,
  28593. onItemSetChanged: null,
  28594. isPrivate: isPrivate
  28595. };
  28596. itemSetWrapper.items = {};
  28597. var readOnly = false;
  28598. var id = modAttributes[j].name;
  28599. var alias1 = null;
  28600. var value = modAttributes[j].value;
  28601. var lang = "en"; // TBD get default language from the browser
  28602. var anItem = {};
  28603. anItem.id = id;
  28604. if (alias1) {
  28605. anItem.alias = alias1;
  28606. }
  28607. anItem.readOnly = readOnly;
  28608. if (title.indexOf("__MSG_") >= 0) {
  28609. isTitleTranslatable = true;
  28610. anItem.defaultLocale = lang;
  28611. // anItem.values = {};
  28612. // anItem.values[lang] = value;
  28613. }
  28614. else {
  28615. anItem.value = value; //a value without locale
  28616. }
  28617. itemSetWrapper.items[id] = anItem;
  28618. if (isPrivate) {
  28619. itemSetsArr[itemSetId] = itemSetWrapper;
  28620. }
  28621. else {
  28622. shareableItemSetsArr[itemSetId] = itemSetWrapper;
  28623. }
  28624. }
  28625. }
  28626. }
  28627. }
  28628. // TBD - iterate through children nodes
  28629. // TBD - ignore Require elements for the moment(in opensocial 1.1 parse events metadata)
  28630. // TBD - parse Locale nodes and add to Items values (parse title)
  28631. widgetDef.shareableItemSetsArr = shareableItemSetsArr;
  28632. widgetDef.itemSetsArr = itemSetsArr;
  28633. },
  28634. readPayloadDefs: function( /*XMLDocument*/xmlData) {
  28635. return {};
  28636. },
  28637. readPublicEvents: function(/*XMLDocument*/xmlData,/*String*/ eventType) {
  28638. return {};
  28639. },
  28640. readResources: function(/*XMLDocument*/xmlData) {
  28641. return [];
  28642. },
  28643. readEventDescriptions: function(/*XMLDocument*/xmlData) {
  28644. return {};
  28645. }
  28646. });
  28647. }
  28648. if(!dojo._hasResource["com.ibm.mm.iwidget.parser.WidgetParserFactory"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  28649. dojo._hasResource["com.ibm.mm.iwidget.parser.WidgetParserFactory"] = true;
  28650. dojo.provide("com.ibm.mm.iwidget.parser.WidgetParserFactory");
  28651. dojo.declare("com.ibm.mm.iwidget.parser.WidgetParserFactory",null, {
  28652. getWidgetParser: function(responseText){
  28653. var xmlStr = responseText.replace(/^\s+/, "").replace(/\s+$/, "");
  28654. var isXML = this._isXML(xmlStr);
  28655. var isLegacy = this._isLegacy(xmlStr);
  28656. var isOpenSocialGadget = this._isOpenSocialGadget(xmlStr);
  28657. if ( isXML && isLegacy && !isOpenSocialGadget) {
  28658. return new com.ibm.mm.iwidget.parser.LegacyXMLParser(xmlStr);
  28659. } else if ( isXML && !isLegacy && !isOpenSocialGadget) {
  28660. return new com.ibm.mm.iwidget.parser.StandardXMLParser(xmlStr);
  28661. } else if ( isXML && isOpenSocialGadget) {
  28662. return new com.ibm.mm.iwidget.parser.OpenSocialXMLParser(xmlStr);
  28663. }
  28664. return null;
  28665. },
  28666. _isOpenSocialGadget: function(responseText) {
  28667. var isGadget = true;
  28668. var index = responseText.indexOf("<Module>");
  28669. if (index === -1) {
  28670. isGadget = false;
  28671. }
  28672. return isGadget;
  28673. },
  28674. _isXML: function(responseText){
  28675. var isXML = true;
  28676. var index = responseText.indexOf("=\"http://www.w3.org/1999/xhtml\"");
  28677. if (index != -1) {
  28678. isXML = false;
  28679. }
  28680. return isXML;
  28681. },
  28682. _isLegacy: function(responseText){
  28683. var isLegacy = true;
  28684. var index = responseText.indexOf("=\"http://www.ibm.com/xmlns/prod/iWidget\"");
  28685. if (index != -1) {
  28686. isLegacy = false;
  28687. }
  28688. return isLegacy;
  28689. }
  28690. });
  28691. com.ibm.mm.iwidget.parser.WidgetParserFactory = new com.ibm.mm.iwidget.parser.WidgetParserFactory();
  28692. }
  28693. if(!dojo._hasResource["com.ibm.mm.iwidget.services.WidgetLoadServiceImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  28694. dojo._hasResource["com.ibm.mm.iwidget.services.WidgetLoadServiceImpl"] = true;
  28695. dojo.provide("com.ibm.mm.iwidget.services.WidgetLoadServiceImpl");
  28696. /*
  28697. * This is injected on the fly and not fetched through an API. Therefore we need to define the @ibm-module so that the build process is picking it up
  28698. * @ibm-module iWidget
  28699. * TODO: Why not for sandbox ?
  28700. */
  28701. dojo.provide("com.ibm.mm.iwidget.services.WidgetLoadServiceImpl");
  28702. // inject this service into the ServiceManager at the end. Therefore we have to require the implementation
  28703. dojo.declare("com.ibm.mm.iwidget.services.WidgetLoadServiceImpl", null, {
  28704. constructor: function() {
  28705. //loadModelus to keep track that if a resource has been loaded already
  28706. this.widgetDef = {}; //cached as url-widgetdefinition
  28707. this.LOADING_TOKEN = "LOADING_TOKEN";
  28708. this.LOADING_ERROR_TOKEN = "LOADING_ERROR_TOKEN";
  28709. this.waitingqueue = {};
  28710. },
  28711. getWidgetXML: function( /*String*/widgetUrl,/*boolean*/ sync, callbackfn,/*String*/ widgetId) {
  28712. // summary: Retrieves the WidgetInfo for the given widget url.
  28713. // widgetUrl: a widget URL, should come directly from the microformat or from alias
  28714. // Required to make dojotest run synchronously
  28715. if (ibmConfig.dojotest) {
  28716. sync = true;
  28717. }
  28718. var wInfo = this.widgetDef[widgetUrl];
  28719. if (wInfo && wInfo == this.LOADING_TOKEN) {
  28720. if (!this.waitingqueue[widgetUrl]) {
  28721. this.waitingqueue[widgetUrl] = [];
  28722. }
  28723. var entry = {
  28724. id: widgetId,
  28725. cb: callbackfn
  28726. };
  28727. this.waitingqueue[widgetUrl].push(entry);
  28728. return;
  28729. }
  28730. else if (wInfo && wInfo.error && wInfo.error == this.LOADING_ERROR_TOKEN) {
  28731. return this.handleCallback(callbackfn, wInfo.data, wInfo.status);
  28732. }
  28733. else if (wInfo) {
  28734. return this.handleCallback(callbackfn, wInfo, "200");
  28735. }
  28736. this.widgetDef[widgetUrl] = this.LOADING_TOKEN;
  28737. var me = this;
  28738. var contentUrl = widgetUrl;
  28739. if ((contentUrl.indexOf("http") === 0) || (contentUrl.indexOf("https") === 0) || (contentUrl.indexOf("endpoint") === 0)) {
  28740. contentUrl = com.ibm.mm.enabler.utils.URLHelper.rewriteURL(contentUrl);
  28741. }
  28742. var args = {
  28743. url: contentUrl,
  28744. load: function(data, ioArgs) {
  28745. var xhr = ioArgs.xhr;
  28746. var parser = com.ibm.mm.iwidget.parser.WidgetParserFactory.getWidgetParser(xhr.responseText);
  28747. var wInfo = parser.parseWidgetDefinition();
  28748. me.widgetDef[widgetUrl] = wInfo;
  28749. me.handleCallback(callbackfn, wInfo, xhr.status, xhr);
  28750. //check waiting queue
  28751. var queue = me.waitingqueue[widgetUrl];
  28752. if (queue) {
  28753. for (var i in queue) {
  28754. if (Object.prototype.hasOwnProperty.call(queue,i)) {
  28755. me.handleCallback(queue[i].cb, wInfo, xhr.status, xhr);
  28756. }
  28757. }
  28758. me.waitingqueue[widgetUrl] = null;
  28759. }
  28760. },
  28761. error: function(data, ioArgs) {
  28762. var xhr = ioArgs.xhr;
  28763. me.widgetDef[widgetUrl] = {
  28764. error: me.LOADING_ERROR_TOKEN,
  28765. data: data,
  28766. status: xhr.status
  28767. };
  28768. me.handleCallback(callbackfn, data, xhr.status, xhr);
  28769. var queue = me.waitingqueue[widgetUrl];
  28770. if (queue) {
  28771. for (var i in queue) {
  28772. if (Object.prototype.hasOwnProperty.call(queue,i)) {
  28773. me.handleCallback(queue[i].cb, data, xhr.status, xhr);
  28774. }
  28775. }
  28776. me.waitingqueue[widgetUrl] = null;
  28777. }
  28778. },
  28779. handleAs: "text", //tells framework this is an text document
  28780. sync: sync //default is false, set to true if it's a blocking synchronous request
  28781. };
  28782. dojo.xhrGet(args);
  28783. return;
  28784. },
  28785. handleCallback: function(callbackfn, data, statuscode, xhr) {
  28786. if (callbackfn) {
  28787. callbackfn(data, statuscode, xhr);
  28788. }
  28789. }
  28790. });
  28791. com.ibm.mashups.services.ServiceManager.setService("widgetLoadService", new com.ibm.mm.iwidget.services.WidgetLoadServiceImpl());
  28792. }
  28793. if(!dojo._hasResource["com.ibm.mashups.iwidget.widget.Wire_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  28794. dojo._hasResource["com.ibm.mashups.iwidget.widget.Wire_API"] = true;
  28795. dojo.provide("com.ibm.mashups.iwidget.widget.Wire_API");
  28796. dojo.provide("com.ibm.mashups.iwidget.widget.Wire");
  28797. /**
  28798. * Wire interface defines functions that expose information of a Wire
  28799. * @ibm-spi
  28800. * @ibm-module iWidget
  28801. */
  28802. dojo.declare("com.ibm.mashups.iwidget.widget.Wire", null, {
  28803. /**
  28804. * @private
  28805. */
  28806. constructor: function() {
  28807. },
  28808. /**
  28809. This method returns id of the source iWidget that's connected to.
  28810. @type String
  28811. @returns{String } id of the source iWidget
  28812. */
  28813. getSourceWidgetID: function() {
  28814. },
  28815. /**
  28816. This method returns name of the event in the source iWidget.
  28817. @type String
  28818. @returns{String } name of the source event
  28819. */
  28820. getSourceEventName: function() {
  28821. //summary: This method returns an object that contains instance level attribute items
  28822. },
  28823. /**
  28824. This method returns id of the source iWidget that's connected to.
  28825. @type String
  28826. @returns{String } id of the source iWidget
  28827. */
  28828. getTargetWidgetID: function() {
  28829. },
  28830. /**
  28831. This method returns name of the event in the source iWidget
  28832. @type String
  28833. @returns{String } name of the source event
  28834. */
  28835. getTargetEventName: function() {
  28836. //summary: This method returns an object that contains instance level attribute items
  28837. }
  28838. });
  28839. }
  28840. if(!dojo._hasResource["com.ibm.mashups.iwidget.widget.Wire"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  28841. dojo._hasResource["com.ibm.mashups.iwidget.widget.Wire"] = true;
  28842. dojo.provide("com.ibm.mashups.iwidget.widget.Wire");
  28843. }
  28844. if(!dojo._hasResource["com.ibm.mm.iwidget.widget.WireImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  28845. dojo._hasResource["com.ibm.mm.iwidget.widget.WireImpl"] = true;
  28846. dojo.provide("com.ibm.mm.iwidget.widget.WireImpl");
  28847. dojo.declare("com.ibm.mm.iwidget.widget.WireImpl",com.ibm.mashups.iwidget.widget.Wire,{
  28848. constructor:function(widgetid,/*JSON object*/obj){
  28849. //"SourceWidget","SourceEvent","TargetEvent"
  28850. if(obj){
  28851. this.SourceWidget = obj.SourceWidget;
  28852. this.SourceEvent = obj.SourceEvent;
  28853. this.TargetEvent = obj.TargetEvent;
  28854. }
  28855. this.TargetWidget = widgetid;
  28856. this._isDirty = false;
  28857. this._type = null;
  28858. },
  28859. TYPE_NEW:"NEW",
  28860. TYPE_DELETE:"DELETE",
  28861. getID:function() {
  28862. return this.SourceWidget +"_"+ this.SourceEvent +"_"+ this.TargetWidget+"_"+this.TargetEvent;
  28863. },
  28864. getSourceWidgetID:function(){
  28865. return this.SourceWidget;
  28866. },
  28867. getSourceEventName:function(){
  28868. return this.SourceEvent;
  28869. },
  28870. getTargetWidgetID:function(){
  28871. return this.TargetWidget;
  28872. },
  28873. getTargetEventName:function(){
  28874. return this.TargetEvent;
  28875. },
  28876. setDirty:function(isDirty){
  28877. this._isDirty = isDirty;
  28878. },
  28879. isDirty:function(){
  28880. return this._isDirty;
  28881. },
  28882. setType:function(type){
  28883. this._type = type;
  28884. },
  28885. getType:function(){
  28886. return this._type;
  28887. },
  28888. setSubHandler:function(subHandle){
  28889. this._subHandle = subHandle;
  28890. },
  28891. getSubHandler:function(){
  28892. return this._subHandle;
  28893. },
  28894. toString: function(){
  28895. return this.getID();
  28896. }
  28897. });
  28898. }
  28899. if(!dojo._hasResource["com.ibm.mm.iwidget.widget.IWidgetWrapperStubImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  28900. dojo._hasResource["com.ibm.mm.iwidget.widget.IWidgetWrapperStubImpl"] = true;
  28901. dojo.provide("com.ibm.mm.iwidget.widget.IWidgetWrapperStubImpl");
  28902. dojo.declare("com.ibm.mm.iwidget.widget.IWidgetWrapperStubImpl", null, {
  28903. // available from IWidgetWrapperDefaultImpl:
  28904. // this.rootElement,this.id,this.loaded,this.ns,this.iwMessages
  28905. // RenderController will set this.widgetDef
  28906. PREFIX_STUB: "_stub_",
  28907. getID: function() {
  28908. return this.id; //need to implement all the method defined by IWidgetWrapper otherwise mixin will take the default impl in the interface!
  28909. },
  28910. getIWidgetInstance: function() {
  28911. if (this.widgetInstance) {
  28912. return this.widgetInstance;
  28913. }
  28914. this.widgetInstance = new com.ibm.mm.iwidget.widget.IWidgetInstanceImpl(this, this.rootElement, this.id);
  28915. return this.widgetInstance;
  28916. },
  28917. setIWidgetDefinition: function(widgetDef) {
  28918. this.widgetDef = widgetDef;
  28919. },
  28920. getIWidgetDefinition: function() {
  28921. if (this.loaded) {
  28922. return new com.ibm.mm.iwidget.DeferredLoadImpl(this.getIWidgetInstance().widgetXMLUrl, this.id, this.widgetDef);
  28923. }
  28924. else {
  28925. return new com.ibm.mm.iwidget.DeferredLoadImpl(this.getIWidgetInstance().widgetXMLUrl, this.id);
  28926. }
  28927. },
  28928. getMarkup: function() {
  28929. //return new com.ibm.mm.iwidget.DeferredLiveTextUnprocessImpl(this);
  28930. //to do need to fix this...
  28931. return new com.ibm.mm.iwidget.DeferredLiveTextUnprocessStubImpl(this);
  28932. },
  28933. _getInstanceMarkupFromDOM: function() {
  28934. return this.getIWidgetInstance()._getInstanceMarkup();
  28935. },
  28936. _deepFind: function(widgetModel, layoutModel, container, id) {
  28937. ret = null;
  28938. var children = layoutModel.getChildren(container);
  28939. while(children.hasNext()) {
  28940. var child = children.next();
  28941. if (layoutModel.hasChildren(child)) {
  28942. ret = this._deepFind(widgetModel, layoutModel, child, id);
  28943. }
  28944. else if (child.getLayoutNodeType() == com.ibm.mashups.enabler.layout.Constants.LAYOUT_CONTROL) {
  28945. var window = widgetModel.getWidgetWindow(child).start();
  28946. if (window && window.getID() == id) {
  28947. return child;
  28948. }
  28949. }
  28950. }
  28951. return ret;
  28952. },
  28953. _getInstanceMarkup: function(callback) {
  28954. var isAlienID = com.ibm.mashups.enabler.services.IdentificationService.isAlienID(this.id);
  28955. // if the id is neither client side, nor backend
  28956. if (isAlienID) {
  28957. // now we assume that we can use the DOM to render the widget
  28958. callback(this._getInstanceMarkupFromDOM());
  28959. return;
  28960. }
  28961. var isClientID = com.ibm.mashups.enabler.services.IdentificationService.isClientID(this.id);
  28962. // at this point we know that we are a widget in the page canvas area and can rely on using models to retrieve the content
  28963. var widgetModel = com.ibm.mashups.enabler.widget.Factory.getWidgetModel();
  28964. var navStateModel = com.ibm.mashups.enabler.model.state.NavigationStateModelFactory.getNavigationStateModel();
  28965. var spaceAccessor = com.ibm.mashups.enabler.model.state.AccessorFactory.getSpaceAccessor(navStateModel);
  28966. var currentSpaceID = spaceAccessor.getSpaceID();
  28967. var pageAccessor = com.ibm.mashups.enabler.model.state.AccessorFactory.getPageAccessor(navStateModel, currentSpaceID);
  28968. var currentPageID = pageAccessor.getPageID();
  28969. var navModel = com.ibm.mashups.enabler.navigation.Factory.getNavigationModel();
  28970. var navNode = navModel.find(currentPageID).start();
  28971. var layoutModel = navModel.getLayoutModel(navNode);
  28972. var control = null;
  28973. //var wnd = widgetModel.findWidgetWindow(this.id, currentPageID).start();
  28974. // we are doing a performance optimization here for normal rendering
  28975. if (isClientID) {
  28976. // if it is a client id then we need to walk the whole model
  28977. control = this._deepFind(widgetModel, layoutModel, layoutModel.getRoot().start(), this.id);
  28978. }
  28979. else {
  28980. // else we can assume that the window id is the same as the layout id and a find is sufficient
  28981. control = layoutModel.find(this.id).start();
  28982. }
  28983. if (control) {
  28984. var dfr = control.getWidgetBody();
  28985. dfr.setFinishedCallback(callback);
  28986. dfr.start(false);
  28987. }
  28988. },
  28989. doRender: function() {
  28990. try {
  28991. //update the title
  28992. this._updateTitle();
  28993. // initialize wires so that the callback handlers are registered
  28994. this.getWires();
  28995. this.subHandler = {};
  28996. this.eventSvr = com.ibm.mashups.services.ServiceManager.getService("eventService");
  28997. //subscribe general event channel for the wrapper stub, this channel could be used to accept events distributed to stub
  28998. //should be used for stub -- impl communication
  28999. //widgetevents._stub_myrealid
  29000. //console.info("subscribe #2",this.eventSvr.WIDGETEVENT_PREFIX + this.PREFIX_STUB + this.id, this, "handleEvent");
  29001. var subHandler2 = this.eventSvr.subscribeEvent(this.eventSvr.WIDGETEVENT_PREFIX + this.PREFIX_STUB + this.id, this, "handleEvent"); //subscribe eventHandler for _stub_realwidgetid
  29002. this.subHandler[this.PREFIX_STUB + this.id] = [];
  29003. this.subHandler[this.PREFIX_STUB + this.id].push(subHandler2);
  29004. this._getInstanceMarkup(dojo.hitch(this,"doRenderContinue"));
  29005. }
  29006. catch (e) {
  29007. }
  29008. },
  29009. doRenderContinue: function(instancedata) {
  29010. if (instancedata === null || instancedata === undefined) {
  29011. return;
  29012. }
  29013. //get default mode
  29014. var aMode = this._getDefaultMode();
  29015. if (!aMode) {
  29016. aMode = iwConstants.mode_view;
  29017. }
  29018. this.currentMode = aMode;
  29019. if (this._handleSaveMode) {
  29020. this._handleSaveMode();
  29021. }
  29022. //get root to render iframe
  29023. var tempDiv = document.createElement("div");
  29024. tempDiv.className = this.ns + "Content";
  29025. this.rootElement.appendChild(tempDiv);
  29026. var contentDiv = this.rootElement.lastChild;
  29027. dojo.addClass(contentDiv, this.currentMode);
  29028. contentDiv.visibility = "hidden";
  29029. //use instance id to create iframe for default view
  29030. this.windowManager[this.currentMode] = {
  29031. id: this.id,
  29032. root: contentDiv,
  29033. active: true,
  29034. main: true
  29035. };
  29036. var navigationStateModel = com.ibm.mashups.enabler.model.state.NavigationStateModelFactory.getNavigationStateModel();
  29037. var widgetAccessor = com.ibm.mashups.enabler.model.state.AccessorFactory.getWidgetAccessor(navigationStateModel, this.id);
  29038. var customParams = null;
  29039. if (widgetAccessor) {
  29040. customParams = widgetAccessor.getWidgetState("cp");
  29041. }
  29042. this._createIframe(instancedata, contentDiv, this.id, "false", this, customParams);
  29043. },
  29044. destroy: function() {
  29045. //return subdomain
  29046. this.eventSvr._getHubAdapter(this.id).returnSubDomain(this._getSubDomain());
  29047. var wireModel = this.getIWidgetInstance().getWireModel();
  29048. //remove any wires coming into this widget (any wires that this widget is a target of)
  29049. if (wireModel) {
  29050. var myWires = wireModel.getWires();
  29051. while (myWires.length > 0) {
  29052. var wireSourceID = myWires[0].getSourceWidgetID();
  29053. wireModel.removeWire(wireSourceID);
  29054. this.commit();
  29055. myWires = wireModel.getWires();
  29056. }
  29057. }
  29058. //remove any wires going out of this widget (any wires that this widget is a source of)
  29059. var targets = null;
  29060. if (wireModel) {
  29061. targets = wireModel.getTargets();
  29062. }
  29063. if (targets) {
  29064. var widgetModel = com.ibm.mashups.iwidget.model.Factory.getGlobalWidgetModel();
  29065. for (var i in targets) {
  29066. if (Object.prototype.hasOwnProperty.call(targets,i)) {
  29067. var widget = widgetModel.find(i);
  29068. if (widget) {
  29069. var wires = widget.getIWidgetInstance().getWireModel();
  29070. wires.removeWire(this.id); // remove all the wires that contains "this.id" as source
  29071. widget.commit();
  29072. }
  29073. }
  29074. }
  29075. }
  29076. //this.eventSvr.unsubscribeEvent(this.eventServiceHandler);
  29077. for (var i2 in this.subHandler) {
  29078. if (Object.prototype.hasOwnProperty.call(this.subHandler,i2)) {
  29079. for (var j in this.subHandler[i2]) {
  29080. if (Object.prototype.hasOwnProperty.call(this.subHandler[i2],j)) {
  29081. this.eventSvr.unsubscribeEvent(this.subHandler[i2][j]);
  29082. }
  29083. }
  29084. }
  29085. }
  29086. //this will remove hubclient and container and destroy all the subscription on the client--remove the window for default view
  29087. this.eventSvr._getHubAdapter(this.id).removeIframeHubContainer(this.id);
  29088. if (this.windowManager) {
  29089. this.windowManager = null;
  29090. }
  29091. },
  29092. update2: function(span) {
  29093. return;
  29094. },
  29095. _getParent: function() {
  29096. if (!this.parent) {
  29097. this.parent = com.ibm.mm.iwidget.Utils.getWidgetParent(this.rootElement);
  29098. }
  29099. this.parent = this.parent || null;
  29100. return this.parent;
  29101. },
  29102. _setParent: function(parent) {
  29103. this.parent = parent;
  29104. },
  29105. _getPublishedEvents: function() {
  29106. //Todo:should remove once widgetstub is removed,backward compatibility as part of queryservice
  29107. //return an associative array, with reference
  29108. var publishedEvents = this.getWidgetPublishedEvents();
  29109. var arr = {};
  29110. if (dojo.isArray(publishedEvents)) {
  29111. for (var i = 0, l = publishedEvents.length; i < l; i++) {
  29112. arr[publishedEvents[i].name] = publishedEvents[i];
  29113. }
  29114. }
  29115. return arr;
  29116. },
  29117. _getHandledEvents: function() {
  29118. //Todo: should remove once widgetStub is removed,backward compatibility as part of queryservice
  29119. var handledEvents = this.getWidgetHandledEvents();
  29120. var arr = {};
  29121. if (dojo.isArray(handledEvents)) {
  29122. for (var i = 0, l = handledEvents.length; i < l; i++) {
  29123. arr[handledEvents[i].name] = handledEvents[i];
  29124. }
  29125. }
  29126. return arr;
  29127. },
  29128. getWidgetPublishedEvents: function() {
  29129. //return a reference of event description for backward compatibility so it won't break the use case below
  29130. var eventModel = this._getPublicEvents();
  29131. if (eventModel) {
  29132. var condition = {};
  29133. condition.isPublished = "true";
  29134. return eventModel.getEvents(condition);
  29135. }
  29136. return null;
  29137. },
  29138. getWidgetHandledEvents: function() {
  29139. //return a reference of events array
  29140. var eventModel = this._getPublicEvents();
  29141. if (eventModel) {
  29142. var condition = {};
  29143. condition.isHandled = "true";
  29144. return eventModel.getEvents(condition);
  29145. }
  29146. return null;
  29147. },
  29148. getWires: function() {
  29149. return this.getIWidgetInstance().getWires();
  29150. },
  29151. handleEvent: function(payload) {
  29152. var scope = payload.scope;
  29153. if (scope) {
  29154. if (scope == "instance") {
  29155. scope = this.getIWidgetInstance();
  29156. }
  29157. else if (scope == "eventmodel") {
  29158. scope = this._getPublicEvents();
  29159. }
  29160. }
  29161. else {
  29162. scope = this;
  29163. }
  29164. var methodname = payload.methodname;
  29165. if (methodname && scope[methodname] && dojo.isFunction(scope[methodname])) {
  29166. scope[methodname].apply(scope, payload.params);
  29167. }
  29168. },
  29169. _handleOnModeChange: function(payload) {
  29170. //change the mode to the new mode and create dialog in mode
  29171. var isHandled = false;
  29172. var oldMode = this.currentMode;
  29173. if (!payload) {
  29174. return false;
  29175. }
  29176. if (dojo.isString(payload)) {
  29177. payload = dojo.fromJson(payload);
  29178. }
  29179. if (!payload) {
  29180. return false;
  29181. }
  29182. var newMode = payload.newMode || null;
  29183. var newRoot = payload.rootElementId || null;
  29184. // support one active mode only, thus don't support this operation
  29185. if (newMode !== null && newMode == this.currentMode) {
  29186. return false;
  29187. }
  29188. if (newMode === null) {
  29189. return false;
  29190. }
  29191. var payloadObj = {};
  29192. var currentModeWindow = this.windowManager[this.currentMode];
  29193. if (currentModeWindow && currentModeWindow.main && newRoot === null) {
  29194. //sendover to iframe and switch mode there, not popular usecase
  29195. payloadObj.methodname = "_handleOnModeChange";//refresh
  29196. //var aEvent = new com.ibm.mm.iwidget.IEventImpl(iwConstants.EVENTS.onModeChanged,null,{newMode:newMode});
  29197. payloadObj.params = [newMode];
  29198. this.eventSvr._publishEvent("widgetevents." + this.id, payloadObj);
  29199. // an extra widget mode change event is also required so theme updates contextual menu options appropriately (16928)
  29200. var payload2 = {};
  29201. payload2.id = this.id;
  29202. payload2.oldMode = oldMode;
  29203. payload2.newMode = newMode;
  29204. this.eventSvr._publishEvent(com.ibm.mashups.iwidget.Constants.WIDGET_MODECHANGED, payload2, this.hubId);
  29205. return;
  29206. }
  29207. //switch from default mode to custom mode like edit mode
  29208. if (currentModeWindow && currentModeWindow.main && newRoot !== null) {
  29209. //create iframe
  29210. this._getInstanceMarkup(dojo.hitch(this, function(instancedata) {
  29211. //add custom mode as iDescriptor
  29212. instancedata = this._getInstanceMarkupForMode(instancedata, newMode);
  29213. //get state data from main frame and create new iframe with id realwidgetid_newmode
  29214. this._createIframe(instancedata, newRoot, this.id + "_" + newMode, "true", this);
  29215. oldMode = this.currentMode;
  29216. this.currentMode = newMode;
  29217. if (this._handleSaveMode) {
  29218. this._handleSaveMode();
  29219. }
  29220. this.windowManager[this.currentMode] = {
  29221. id: this.id + "_" + newMode,
  29222. root: newRoot,
  29223. active: true,
  29224. main: false
  29225. };
  29226. //tell the default mode wrapper the new mode
  29227. payloadObj.methodname = "_handleOnModeUpdated";
  29228. payloadObj.params = [newMode];
  29229. this.eventSvr._publishEvent("widgetevents." + this.id, payloadObj);
  29230. dojo.publish(iwConstants.EVENTS.modeChanged, [this.id, oldMode, newMode]);
  29231. payload = {};
  29232. payload.id = this.id;
  29233. payload.oldMode = oldMode;
  29234. payload.newMode = newMode;
  29235. this.eventSvr._publishEvent(com.ibm.mashups.iwidget.Constants.WIDGET_MODECHANGED, payload, this.hubId);
  29236. }));
  29237. return;
  29238. }
  29239. //switch from custom mode to default mode (like view mode)
  29240. var newModeOldWindow = this.windowManager[newMode];
  29241. if (newModeOldWindow && newModeOldWindow.main ) {
  29242. //call onView
  29243. payloadObj = {};
  29244. payloadObj.methodname = "_handleOnModeChange";//refresh
  29245. //var aEvent = new com.ibm.mm.iwidget.IEventImpl(iwConstants.EVENTS.onModeChanged,null,{newMode:newMode});
  29246. payloadObj.params = [newMode];
  29247. try {
  29248. this.eventSvr._publishEvent("widgetevents." + this.id, payloadObj);
  29249. }
  29250. catch (e1) {
  29251. console.log("catching exception!!!" + e1);
  29252. }
  29253. //remove the hubcontainer for edit mode
  29254. this.eventSvr._getHubAdapter(this.id).removeIframeHubContainer(this.id + "_" + this.currentMode);
  29255. //unsubscribe any event related to edit dialog
  29256. try {
  29257. var x = this.id + "_" + this.currentMode;
  29258. for (var j in this.subHandler[x]) {
  29259. if (Object.prototype.hasOwnProperty.call(this.subHandler[x],j)) {
  29260. this.eventSvr.unsubscribeEvent(this.subHandler[x][j]);
  29261. }
  29262. }
  29263. }
  29264. catch (e2) {
  29265. console.log("IWidgetWrapperStub:_handleOnModeChange unsubscribe exception:" + e2);
  29266. }
  29267. delete this.windowManager[this.currentMode]; //delete any window that's not main window
  29268. oldMode = this.currentMode;
  29269. this.currentMode = newMode;
  29270. if (this._handleSaveMode) {
  29271. this._handleSaveMode();
  29272. }
  29273. //todo, verify how it's used with builder
  29274. dojo.publish(iwConstants.EVENTS.modeChanged, [this.id, oldMode, newMode]);
  29275. payload = {};
  29276. payload.id = this.id;
  29277. payload.oldMode = oldMode;
  29278. payload.newMode = newMode;
  29279. this.eventSvr._publishEvent(com.ibm.mashups.iwidget.Constants.WIDGET_MODECHANGED, payload, this.hubId);
  29280. }
  29281. return;
  29282. },
  29283. commit: function(noSync) {
  29284. //need to commit any change in iframe
  29285. var widgetInstance = this.getIWidgetInstance();
  29286. // need to check attribute properties and idescriptor attributes
  29287. var instanceAttributes = widgetInstance.getAttributes();
  29288. var instanceIDescriptor = widgetInstance.getIDescriptorItems();
  29289. var wiremodel = widgetInstance.getWireModel();
  29290. var params = {};
  29291. if (instanceAttributes && instanceAttributes._isDirty()) {
  29292. params.attributes = instanceAttributes;
  29293. }
  29294. if (instanceIDescriptor && instanceIDescriptor._isDirty()) {
  29295. params.idescriptors = instanceIDescriptor;
  29296. }
  29297. if (wiremodel && wiremodel.isDirty()) {
  29298. params.wiremodel = wiremodel.toJson();
  29299. }
  29300. // send events to widget main view to handle data Sync ...
  29301. if (!noSync) {
  29302. this.eventSvr._publishEvent(this.eventSvr.WIDGETEVENT_PREFIX + this.id, {
  29303. "methodname": "_handleDataSync",
  29304. "params": [params]
  29305. }, this.id);
  29306. }
  29307. if (instanceAttributes && instanceAttributes._isDirty()) {
  29308. this._writePropertiesToDOM(this, "attributes", instanceAttributes);
  29309. instanceAttributes._setDirty(false);
  29310. }
  29311. if (instanceIDescriptor && instanceIDescriptor._isDirty()) {
  29312. this._writePropertiesToDOM(this, "idescriptor", instanceIDescriptor);
  29313. instanceIDescriptor._setDirty(false);
  29314. }
  29315. //check wires
  29316. if (wiremodel && wiremodel.isDirty()) {
  29317. wiremodel.commit();
  29318. }
  29319. },
  29320. getPublicEvent: function(name) {
  29321. var eventModel = this._getPublicEvents();
  29322. return eventModel.find(name);
  29323. },
  29324. _getInstanceMarkupForMode: function(markup, mode) {
  29325. var newDiv = document.createElement("div");
  29326. newDiv.innerHTML = markup;
  29327. var root = newDiv.firstChild;
  29328. root.id = this.id;
  29329. //root.id = this.id+"_"+mode; //don't change widget id , keep it in sync so less widgets will break,widgets do cache id
  29330. // query the markup for the given itemSetName
  29331. var iDescriptors = dojo.query('span.' + this.ns + 'ItemSet[title="' + iwConstants.IDESCRIPTOR + '"]', root);
  29332. var newItemSet = null;
  29333. if (iDescriptors.length === 0) {
  29334. newItemSet = document.createElement("span");
  29335. newItemSet.className = this.ns + 'ItemSet';
  29336. newItemSet.title = iwConstants.IDESCRIPTOR;
  29337. newItemSet.style.display = "none";
  29338. newItemSet.style.visibility = "hidden";
  29339. // append it to the newDiv
  29340. root.appendChild(newItemSet);
  29341. }
  29342. else {
  29343. newItemSet = iDescriptors[0];
  29344. }
  29345. var items = dojo.query('.' + this.ns + 'Item[href="#' + 'mode' + '"]', newItemSet);
  29346. for (var i = 0, l = items.length; i < l; i++) {
  29347. var item = items[i];
  29348. if (newItemSet == item.parentNode) {
  29349. newItemSet.removeChild(item);
  29350. }
  29351. }
  29352. //create new one
  29353. var newItem = document.createElement("a");
  29354. newItem.className = this.ns + 'Item';
  29355. newItem.style.visibility = "hidden";
  29356. newItem.style.display = "none";
  29357. newItem.href = "#" + "mode";
  29358. newItem.appendChild(document.createTextNode(mode));
  29359. newItemSet.appendChild(newItem);
  29360. //console.log("MarkupWithMode:"+newDiv.innerHTML);
  29361. return newDiv.innerHTML;
  29362. },
  29363. _createIframe: function(instancedata, root, id, isModal, wrapper, stateData) {
  29364. //console.log(instancedata);
  29365. //render iframe here
  29366. var that = wrapper;
  29367. var cssUrl = wrapper.getCSSUrl();
  29368. wrapper.subHandler[id] = [];
  29369. function eventCallback(payload) {
  29370. function eventCallbackContinue(instancedata) {
  29371. var navStateModel = com.ibm.mashups.enabler.model.state.NavigationStateModelFactory.getNavigationStateModel();
  29372. var obj = {"html": instancedata,
  29373. "xml": that.widgetDef.widgetDef,//original parsed data
  29374. "isModal": isModal,
  29375. "hubId": id,
  29376. "cssUrl": cssUrl,
  29377. "navState": navStateModel._state};
  29378. if (stateData) {
  29379. obj.stateData = stateData;
  29380. }
  29381. if ( !(isModal && isModal == "false")){
  29382. var mainframeId = id.slice(0,id.lastIndexOf("_"));
  29383. var mainIframeContainer = that.eventSvr._getHubAdapter().getContainer(mainframeId,true);
  29384. mainframeId = mainIframeContainer.getIframe().id;
  29385. obj.mainframeId = mainframeId;
  29386. }
  29387. that.eventSvr._publishEvent(that.eventSvr.WIDGETEVENT_PREFIX + id + "." + "onWidgetLoading",obj );
  29388. var subHandler3 = that.eventSvr.subscribeEvent(com.ibm.mashups.iwidget.Constants.WIDGET_LOADED + "." + id, null, function(payload) { /*onData*/
  29389. if (isModal == "false") {
  29390. that.loaded = true;
  29391. dojo.query("> ." + that.ns + "loading", that.rootElement).forEach(function(elem) {
  29392. com.ibm.mm.enabler.utils.Dom.destroyNode(elem);
  29393. });
  29394. dojo.query("." + that.currentMode, that.rootElement).style({
  29395. "visibility": "" //display:"none" will make mode selector not displaying properly
  29396. //set visible will work funny in FF, the node will be visible even parent node is set to be invisible
  29397. });
  29398. }
  29399. });
  29400. that.subHandler[id].push(subHandler3);
  29401. var eventHandler = that.eventSvr.subscribeEvent(com.ibm.mashups.iwidget.Constants.RESIZE_WIDGET + "." + that.id, that, "handleSizeChanged");
  29402. that.subHandler[id].push(eventHandler);
  29403. }
  29404. //sometime, iframe will automatically reloaded, in these paricular cases, we need to update instance markup so we don't lose any updates after widget is loaded eg. wires, attributes
  29405. if (wrapper.isLoaded() && isModal && isModal == "false") {
  29406. wrapper.loaded = false;
  29407. wrapper._getInstanceMarkup(eventCallbackContinue);
  29408. }
  29409. else {
  29410. eventCallbackContinue(instancedata);
  29411. }
  29412. }
  29413. var subHandler1 = wrapper.eventSvr.subscribeEvent(wrapper.eventSvr.WIDGETEVENT_PREFIX + id + "." + "onFrameLoaded", null, eventCallback);
  29414. wrapper.subHandler[id].push(subHandler1);
  29415. var configService = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);
  29416. var url = window.location.protocol;
  29417. var host = window.location.hostname;
  29418. var serverdomain = configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.SERVERDOMAIN);
  29419. if (serverdomain && serverdomain != "null") {
  29420. host = serverdomain;
  29421. }
  29422. var port = window.location.port;
  29423. var path = window.location.pathname; // for example "/mum/enabler"
  29424. var startOfRealUrl = configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.CONTEXT_ROOT);//get Mashup context root.. "/mum"
  29425. var junction = null;
  29426. if (path.indexOf(startOfRealUrl) > 0) { //there's junciton point like http://host:8080/jp/mum/enabler
  29427. junction = path.slice(0, path.indexOf(startOfRealUrl)); //it will be "/jp"
  29428. }
  29429. if (wrapper._getSubDomain()) {
  29430. var subdomain = wrapper._getSubDomain() + "." + host;
  29431. // support for tomcat developer mode. Disable subdomains in case the system has no SSO
  29432. if (configService.getValue("sandbox.disable.subdomains")) {
  29433. subdomain = host;
  29434. }
  29435. if (port != "") {
  29436. url += "//" + subdomain + ":" + port;
  29437. }
  29438. else {
  29439. url += "//" + subdomain;
  29440. }
  29441. if (junction) {
  29442. url += junction;
  29443. }
  29444. url += configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.CONTEXT_ROOT_ENABLER);
  29445. url += "/widgetsandbox";
  29446. wrapper.eventSvr._getHubAdapter().createIframeHubContainer(id, root, url,isModal,null,null,dojo.hitch(this,"_onSecurityAlert"));
  29447. }
  29448. else {
  29449. //throw error message
  29450. var subDomainSize = wrapper.eventSvr._getHubAdapter().getSubDomainSize();
  29451. var wTitle = unescape(wrapper.getIWidgetInstance().getIDescriptorItems().getItemValue("title", dojo.locale));
  29452. if (!wTitle) {
  29453. wTitle = wrapper.getID();
  29454. }
  29455. var reuseSubDomain = configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.SUBDOMAINREUSE);
  29456. var fmt = wrapper.iwMessages.E_SUBDOMAIN_NOTAVAILABLE1_2;
  29457. if (reuseSubDomain) {
  29458. fmt = wrapper.iwMessages.E_SUBDOMAIN_NOTAVAILABLE_2;
  29459. }
  29460. var message = dojo.string.substitute(fmt, [wTitle, subDomainSize]);
  29461. var nodes = [];
  29462. com.ibm.mm.iwidget.Utils.findElementByAttribute("query", "> ."+wrapper.ns + "loading", wrapper.rootElement, nodes, false);
  29463. if (nodes.length > 0) {
  29464. aNode = nodes[0];
  29465. aNode.innerHTML = "";
  29466. }
  29467. }
  29468. },
  29469. _onSecurityAlert:function(container,securityAlert){
  29470. //handle unexpected iframe unload here
  29471. if (securityAlert&& securityAlert == "OpenAjax.hub.SecurityAlert.FramePhish" ){
  29472. var me=this;
  29473. setTimeout( function () {
  29474. me._handleIframeMove( container );
  29475. }, 0 );
  29476. }
  29477. },
  29478. _handleIframeMove:function(container){
  29479. //unsubscribe
  29480. this.eventSvr._getHubAdapter(this.id).returnSubDomain(this._getSubDomain());
  29481. var currentWindowState= this.windowManager[this.currentMode];
  29482. var id = currentWindowState.id;
  29483. var root = currentWindowState.root || null;
  29484. // if root is not specified try loading the default root
  29485. // this is needed in case that the mode was switched inside the widget but not on the stub
  29486. if (root === null) {
  29487. var aMode = this._getDefaultMode() || iwConstants.mode_view;
  29488. var mainWindowState = this.windowManager[aMode] || null;
  29489. if (mainWindowState !== null) {
  29490. root = mainWindowState.root || null;
  29491. }
  29492. }
  29493. //unsubscribe any event
  29494. try{
  29495. for (var j in this.subHandler[id]) {
  29496. if (Object.prototype.hasOwnProperty.call(this.subHandler[id], j)) {
  29497. this.eventSvr.unsubscribeEvent(this.subHandler[id][j]);
  29498. }
  29499. }
  29500. }catch(e){
  29501. }
  29502. this.eventSvr._getHubAdapter(id).removeIframeHubContainer(id);
  29503. //need to create a new one, main iframe only
  29504. this._getInstanceMarkup(dojo.hitch(this, function(instancedata) {
  29505. this._createIframe(instancedata,root,id,"false",this);
  29506. }));
  29507. },
  29508. _getSubDomain: function() {
  29509. if (!this.subDomain) {
  29510. this.subDomain = this.eventSvr._getHubAdapter().getSubDomain();
  29511. }
  29512. return this.subDomain;
  29513. },
  29514. _handleDataSync: function(payload) {
  29515. //for now it's just attributes, handle any received data....
  29516. //any sub window may have changed data these updates need to be sent to stub widget
  29517. if (payload && payload.attributes) {
  29518. var attributes = payload.attributes;
  29519. // we leave that line here for backwards compatibility
  29520. this._syncModifiableProperties(attributes, this.getIWidgetInstance().getAttributes());
  29521. // now we use our common abstraction layer to write it as well, this will cause the model to be used if enabled
  29522. this._syncAttributes(attributes, this.getAttributes());
  29523. }
  29524. if (payload && payload.wiremodel) {
  29525. var wiremodel = payload.wiremodel;
  29526. this._syncWireModel(wiremodel, this.getIWidgetInstance().getWireModel());
  29527. }
  29528. this.commit(true); //commit any change in the stub
  29529. },
  29530. _syncWireModel: function(wiremodel, instanceWireModel) {
  29531. var wires = wiremodel._wires;
  29532. for (var i in wires) {
  29533. if (Object.prototype.hasOwnProperty.call(wires,i)) {
  29534. var aWire = wires[i];
  29535. if (aWire._isDirty && aWire._type && aWire._type == "NEW") {
  29536. instanceWireModel.addWire(aWire.SourceWidget, aWire.SourceEvent, aWire.TargetEvent);
  29537. } else if (aWire._isDirty && aWire._type && aWire._type == "DELETE") {
  29538. instanceWireModel.removeWire(aWire.SourceWidget, aWire.SourceEvent, aWire.TargetEvent);
  29539. }
  29540. }
  29541. }
  29542. var targets = wiremodel._targets;
  29543. instanceWireModel._targets = targets;//simple replacement of array.
  29544. },
  29545. _syncModifiableProperties: function(properties, instanceProperties) {
  29546. instanceProperties._updateProperties(properties);
  29547. },
  29548. _syncAttributes: function(sandboxAttributes, mainAttributes) {
  29549. var TYPE_NEW = "newItem";
  29550. var TYPE_UPDATE = "updatedValue";
  29551. var TYPE_REMOVE = "removedItem";
  29552. for (var att in sandboxAttributes) {
  29553. if (Object.prototype.hasOwnProperty.call(sandboxAttributes,att)) {
  29554. var item = sandboxAttributes[att];
  29555. if (item._dirty) {
  29556. if (item._change.changeType == TYPE_REMOVE) {
  29557. mainAttributes.removeItem(item.id);
  29558. }
  29559. else {
  29560. mainAttributes.setItemValue(item.id, item.value, item.readOnly);
  29561. }
  29562. }
  29563. /*
  29564. att._change.changeType
  29565. att.id
  29566. att.value
  29567. att.values
  29568. att.readOnly
  29569. att._dirty
  29570. */
  29571. }
  29572. }
  29573. mainAttributes.commit();
  29574. },
  29575. handleSizeChanged: function(payload) {
  29576. var currentModeWindow = this.windowManager[this.currentMode];
  29577. var id = this.id;
  29578. if (!currentModeWindow.main) {
  29579. id = this.id + "_" + this.currentMode;
  29580. }
  29581. var root = currentModeWindow.root;
  29582. var iframeNode = root.childNodes[0];
  29583. if (payload.newWidth) {
  29584. var width = parseInt(payload.newWidth,10);
  29585. width = width - 5;
  29586. dojo.style(iframeNode, "width", width + "px");
  29587. }
  29588. if (payload.newHeight) {
  29589. var height = parseInt(payload.newHeight,10);
  29590. height = height - 5;
  29591. dojo.style(iframeNode, "height", height + "px");
  29592. }
  29593. //publish event to current active iframe, either view iframe or edit iframe
  29594. this.eventSvr._publishEvent(com.ibm.mashups.iwidget.Constants.RESIZE_WIDGET + id, payload);
  29595. },
  29596. getCSSUrl: function() {
  29597. var that = this;
  29598. if (this.themeCSS) {
  29599. return this.themeCSS;
  29600. }
  29601. //gather all the css link elements and find theme.css or theme_rtl.css
  29602. dojo.forEach(document.getElementsByTagName("link"), function(cssNode) {
  29603. if (cssNode.href && cssNode.href.indexOf("theme.css") != -1) {
  29604. var index1 = cssNode.href.length - 9;
  29605. if (cssNode.href.indexOf("theme.css") == index1) {
  29606. that.themeCSS = cssNode.href;
  29607. }
  29608. }
  29609. else if (cssNode.href && cssNode.href.indexOf("theme_rtl.css") != -1) {
  29610. var index2 = cssNode.href.length - 13;
  29611. if (cssNode.href.indexOf("theme_rtl.css") == index2) {
  29612. that.themeCSS = cssNode.href;
  29613. }
  29614. }
  29615. });
  29616. return this.themeCSS;
  29617. },
  29618. _handleOnNavStateChanged: function(iEvent) {
  29619. var state = iEvent.payload;
  29620. if (state) {
  29621. //call navstate api
  29622. var navigationStateModel = com.ibm.mashups.enabler.model.state.NavigationStateModelFactory.getNavigationStateModel();
  29623. var widgetAccessor = com.ibm.mashups.enabler.model.state.AccessorFactory.getWidgetAccessor(navigationStateModel, this.id);
  29624. widgetAccessor.setWidgetState("cp", state);
  29625. var deferred = navigationStateModel.commit();
  29626. deferred.start();
  29627. }
  29628. }
  29629. });
  29630. }
  29631. if(!dojo._hasResource["com.ibm.mm.iwidget.RenderController"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  29632. dojo._hasResource["com.ibm.mm.iwidget.RenderController"] = true;
  29633. dojo.provide("com.ibm.mm.iwidget.RenderController");
  29634. dojo.declare("com.ibm.mm.iwidget.RenderController", null, {
  29635. constructor: function(widgetwrapper) {
  29636. this.widgetwrapper = widgetwrapper;
  29637. this.widgetXMLUrl = this.widgetwrapper.getIWidgetInstance().widgetXMLUrl;
  29638. this.iwStr = dojo.i18n.getLocalization("com.ibm.mm.enabler", "iwStr");
  29639. this.iwMessages = dojo.i18n.getLocalization("com.ibm.mm.enabler", "iwMessages");
  29640. },
  29641. render: function() {
  29642. this._loadWidgetDefinition();
  29643. },
  29644. _resourceBaseURL: new dojo.moduleUrl("com.ibm.mm.iwidget", "image/"),
  29645. _setLoading: function() {
  29646. //create div tag and set image
  29647. var tempDiv = document.createElement("div");
  29648. tempDiv.className = this.widgetwrapper.ns + "loading";
  29649. if (ibmConfig && ibmConfig.loadingHTML) {
  29650. tempDiv.innerHTML = ibmConfig.loadingHTML;
  29651. }
  29652. else if (ibmConfig && ibmConfig["loadingHTML.imageURL"]) {
  29653. tempDiv.innerHTML = "<img alt='" + this.iwStr.LOAD + "' src='" + ibmConfig["loadingHTML.imageURL"] + "' />&nbsp;" + this.iwStr.LOAD;
  29654. }
  29655. else {
  29656. tempDiv.innerHTML = "<img alt='" + this.iwStr.LOAD + "' src='" + this._resourceBaseURL + "progress-anim.gif' />&nbsp;" + this.iwStr.LOAD;
  29657. }
  29658. this.widgetwrapper.rootElement.appendChild(tempDiv);
  29659. },
  29660. _loadWidgetDefinition: function() {
  29661. var widgetSpan = this.widgetwrapper.rootElement;
  29662. if (this.widgetwrapper.loaded) {
  29663. return false;
  29664. }
  29665. this._setLoading();
  29666. if (this.widgetXMLUrl !== null) {
  29667. var iWidgetService = com.ibm.mashups.services.ServiceManager.getService("widgetLoadService");
  29668. iWidgetService.getWidgetXML(this.widgetXMLUrl, false, dojo.hitch(this, "handleWidgetInfoRetrieved"), this.widgetwrapper.id);
  29669. }
  29670. else {
  29671. return false;
  29672. } // no io is involved
  29673. return true;
  29674. },
  29675. handleWidgetInfoRetrieved: function(data, statuscode, xhr) {
  29676. var wTitle;
  29677. if (statuscode == "200" || statuscode == "0") {
  29678. this.widgetwrapper.setIWidgetDefinition(data); //save widget definition
  29679. this.widgetDef = data;
  29680. }
  29681. else {
  29682. if (!this._isWidgetInstalled()) {
  29683. //handle widget not installed
  29684. this._handleInlineWidgetNotInstalledMessage(this.iwStr.WIDGET_NOT_INSTALLED, this.iwStr.WIDGET_NOT_INSTALLED_SUB, data.message);
  29685. }
  29686. else {
  29687. //handle error
  29688. wTitle = unescape(this.widgetwrapper.getIWidgetInstance().getIDescriptorItems().getItemValue("title", dojo.locale));
  29689. if (!wTitle) {
  29690. wTitle = this.widgetXMLUrl;
  29691. }
  29692. this._handleInlineMessage("error", dojo.string.substitute(this.iwMessages.E_IWIDGETDEF_NOTAVAILABLE_1, [wTitle]), data.message);
  29693. }
  29694. return;
  29695. }
  29696. var isSandboxed = this.isSandboxed();
  29697. if (dojo.isIE < 7 && isSandboxed) {
  29698. wTitle = unescape(this.widgetwrapper.getIWidgetInstance().getIDescriptorItems().getItemValue("title", dojo.locale));
  29699. if (!wTitle) {
  29700. wTitle = this.widgetXMLUrl;
  29701. }
  29702. this._handleInlineMessage("error", dojo.string.substitute(this.iwMessages.E_NODISPLAY_UNSECUREWIDGET_1, [wTitle]));
  29703. return;
  29704. }
  29705. this._doRender(isSandboxed);
  29706. },
  29707. _isWidgetInstalled: function() {
  29708. try {
  29709. var catalogData = com.ibm.mashups.enabler.catalog.Factory.getCatalogCategoryModel();
  29710. catalogData.setStrategy(new com.ibm.mashups.enabler.strategy.ListLoadAheadStrategy(25));
  29711. var entryModel = null;
  29712. var entryURL = null;
  29713. // root category
  29714. var rootNode = catalogData.getRoot().start();
  29715. var catIterator = catalogData.getChildren(rootNode);
  29716. // iterate through categories
  29717. while (catIterator.hasNext()) {
  29718. var category = catIterator.next();
  29719. entryModel = catalogData.getCatalogEntryModel(category);
  29720. // catalog entries iterator
  29721. var elemIterator = entryModel.iterator();
  29722. elemIterator.setCursorPosition(0);
  29723. while (elemIterator.hasNext()) {
  29724. var entry = elemIterator.next();
  29725. var widgetIWidgetDefinition = decodeURIComponent(this.widgetXMLUrl);
  29726. if (widgetIWidgetDefinition.indexOf(entry.getDefinitionURL(false)) >= 0) {
  29727. return true;
  29728. }
  29729. }
  29730. }
  29731. }
  29732. catch (e) {
  29733. // if no access to the palette such as with enabler core or something unexpected goes wrong,
  29734. // then assume the widget is installed so the user will get more detail on the error
  29735. return true;
  29736. }
  29737. return false;
  29738. },
  29739. isSandboxed: function() {
  29740. var configService = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);
  29741. var isSandboxed = configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.SANDBOXENABLED);
  29742. if (!isSandboxed) {
  29743. return false;
  29744. }
  29745. var myLocation = document.location + "";
  29746. // check if it's embedding usecase, no sandbox needed if it's embedding
  29747. /*if (myLocation.indexOf("widget:html") > -1) {
  29748. return false;
  29749. }*/
  29750. isSandboxed = false;
  29751. var attributes = this.widgetDef.getAttributes() || null;
  29752. if (attributes) {
  29753. var value = attributes.getItemValue("sandbox");
  29754. if (typeof value != "undefined" && value !== null) {
  29755. if (value == "true") {
  29756. isSandboxed = true;
  29757. }
  29758. }
  29759. }
  29760. if (!isSandboxed) {
  29761. //check attribute at instance level, deprecated
  29762. if (this.widgetwrapper.rootElement.getAttribute("sandbox") !== null && this.widgetwrapper.rootElement.getAttribute("sandbox") == "true") {
  29763. isSandboxed = true;
  29764. }
  29765. }
  29766. //check if there's iw-sandbox defined
  29767. if (!isSandboxed) {
  29768. //check attribute at instance level, deprecated
  29769. if (this.widgetwrapper.rootElement.className.indexOf(iwConstants.CSSCLASS_INSTANCE.iwSandbox) > 0) {
  29770. isSandboxed = true;
  29771. }
  29772. }
  29773. //check disable flag
  29774. if (isSandboxed) {
  29775. if (this._isSandboxDisabledWidget(this.widgetXMLUrl)) {
  29776. isSandboxed = false;
  29777. }
  29778. }
  29779. return isSandboxed;
  29780. },
  29781. _isSandboxDisabledWidget: function(widgetDefUrl) {
  29782. var configService = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);
  29783. var temp = configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.WIDGETDEFID_SANDBOX_DISABLED);
  29784. var disabledWidgetsList = temp;
  29785. if (dojo.isString(disabledWidgetsList)) {
  29786. disabledWidgetsList = [temp];
  29787. }
  29788. if (disabledWidgetsList.length === 0) {
  29789. return false;
  29790. }
  29791. for (var i = 0; i < disabledWidgetsList.length; i++) {
  29792. if (dojo.string.trim(widgetDefUrl) === dojo.string.trim(disabledWidgetsList[i])) {
  29793. return true;
  29794. }
  29795. else if (dojo.string.trim(widgetDefUrl).indexOf(dojo.string.trim(disabledWidgetsList[i])) != -1 && dojo.string.trim(disabledWidgetsList[i]).indexOf("/") !== 0) {//check relative path like dataEditor/dataEditor.xml
  29796. return true;
  29797. }
  29798. else if (dojo.string.trim(widgetDefUrl).indexOf(dojo.string.trim(disabledWidgetsList[i])) != -1 && dojo.string.trim(disabledWidgetsList[i]).indexOf("/") === 0 && dojo.string.trim(widgetDefUrl).indexOf(":") != -1) { //check absolute path like /dataEditor/dataEditor.xml
  29799. //make sure protocol, hostname,port match to window.location.
  29800. var buf = widgetDefUrl.split("//");
  29801. var protocol = buf[0];
  29802. var buf2 = buf[1].split("/");
  29803. var host = buf2[0];
  29804. if (protocol == window.location.protocol && window.location.host == host) {
  29805. return true;
  29806. }
  29807. else if (protocol == window.location.protocol && protocol == "http:" && host.indexOf(window.location.host) === 0) {
  29808. if (host.substr(host.indexOf(":") + 1) == "80") {
  29809. return true;
  29810. }
  29811. }
  29812. else if (protocol == window.location.protocol && protocol == "https:" && host.indexOf(window.location.host) === 0) {
  29813. if (host.substr(host.indexOf(":") + 1) == "443") {
  29814. return true;
  29815. }
  29816. }
  29817. }
  29818. }
  29819. return false;
  29820. },
  29821. _handleInlineMessage: function(type, message, details) {
  29822. var nodes = [];
  29823. com.ibm.mm.iwidget.Utils.findElementByAttribute("query", "> ."+this.widgetwrapper.ns + "loading", this.widgetwrapper.rootElement, nodes, false);
  29824. var aNode = nodes[0];
  29825. aNode.innerHTML = "";
  29826. },
  29827. _handleInlineWidgetNotInstalledMessage: function(message, submessage, details) {
  29828. var nodes = [];
  29829. com.ibm.mm.iwidget.Utils.findElementByAttribute("query", "> ."+this.widgetwrapper.ns + "loading", this.widgetwrapper.rootElement, nodes, false);
  29830. var aNode = nodes[0];
  29831. var msg = [];
  29832. msg[msg.length] = "<div style=\"margin:15px\">";
  29833. msg[msg.length] = "<div class=\"widgetNotInstalledImage\">";
  29834. msg[msg.length] = "</div>";
  29835. msg[msg.length] = "<div class=\"widgetNotInstalledText\">";
  29836. msg[msg.length] = message;
  29837. msg[msg.length] = "</div>";
  29838. if (submessage && submessage.length > 0) {
  29839. msg[msg.length] = "<div class=\"widgetNotInstalledSubText\">";
  29840. msg[msg.length] = submessage;
  29841. msg[msg.length] = "</div>";
  29842. }
  29843. msg[msg.length] = "</div>";
  29844. aNode.innerHTML = msg.join("");
  29845. },
  29846. _doRender: function(isSandboxed) {
  29847. var eventSvr = com.ibm.mashups.services.ServiceManager.getService("eventService");
  29848. if (isSandboxed) {
  29849. dojo.mixin(this.widgetwrapper, new com.ibm.mm.iwidget.widget.IWidgetWrapperStubImpl());
  29850. }
  29851. else {
  29852. eventSvr._getHubAdapter().createInlineHubContainer(this.widgetwrapper.id);
  29853. eventSvr._getHubAdapter().createInlineHubClient(this.widgetwrapper.id);
  29854. }
  29855. this.widgetwrapper.doRender();
  29856. }
  29857. });
  29858. }
  29859. if(!dojo._hasResource["com.ibm.mm.iwidget.model.WidgetModelExtended"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  29860. dojo._hasResource["com.ibm.mm.iwidget.model.WidgetModelExtended"] = true;
  29861. dojo.provide("com.ibm.mm.iwidget.model.WidgetModelExtended");
  29862. /*
  29863. * This is injected on the fly and not fetched through an API. Therefore we need to define the @ibm-module so that the build process is picking it up
  29864. * @ibm-module iWidget
  29865. *
  29866. * This value defines the order in which the packages should be printed out into the dojo profile. Default is 100.
  29867. * Any number that is smaller causes this class to be written out before any other with a higher number
  29868. * @ibm-dojo-profile-level 40
  29869. */
  29870. //moved here from ServiceManagerImpl:
  29871. dojo.declare("com.ibm.mm.iwidget.model.WidgetModelExtendedImpl",com.ibm.mm.iwidget.model.WidgetModelDefaultImpl,{
  29872. _onWindowUnload:function(){
  29873. //set pagemode to be "unload"
  29874. var navigationStateModel = com.ibm.mashups.enabler.model.state.NavigationStateModelFactory.getNavigationStateModel();
  29875. if (navigationStateModel){
  29876. var pageModeAccessor = com.ibm.mashups.enabler.model.state.AccessorFactory.getPageModeAccessor(navigationStateModel);
  29877. pageModeAccessor.setPageMode("unload");
  29878. }
  29879. try {
  29880. var arr = [];
  29881. for (var i in this.widgetArr){
  29882. if (Object.prototype.hasOwnProperty.call(this.widgetArr,i)) {
  29883. this._unloadWidget(i); //use _unloadWidget to avoid publish event com.ibm.mashups.iwidget.Constants.WIDGETS_UNLOADED
  29884. }
  29885. }
  29886. }
  29887. catch(e){
  29888. console.log("_onWindowUnload "+ e.message);
  29889. }
  29890. },
  29891. renderWidget: function(/*Object*/iWidget)
  29892. {
  29893. if (typeof iWidget == "undefined") {
  29894. return;
  29895. }
  29896. if (iWidget.loaded || iWidget.loading) {
  29897. return;
  29898. }
  29899. iWidget.loading = true;
  29900. var renderController = new com.ibm.mm.iwidget.RenderController(iWidget);
  29901. renderController.render();
  29902. },
  29903. getWidgetById: function(/*String*/id)
  29904. { //deprecated
  29905. return this.find(id);
  29906. }
  29907. });
  29908. com.ibm.mm.iwidget.model.WidgetModelImpl = com.ibm.mm.iwidget.model.WidgetModelExtendedImpl;
  29909. }
  29910. if(!dojo._hasResource["com.ibm.mm.iwidget.services.EventServiceExtended"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  29911. dojo._hasResource["com.ibm.mm.iwidget.services.EventServiceExtended"] = true;
  29912. dojo.provide("com.ibm.mm.iwidget.services.EventServiceExtended");
  29913. /*
  29914. * This is injected on the fly and not fetched through an API. Therefore we need to define the @ibm-module so that the build process is picking it up
  29915. * @ibm-module iWidget
  29916. *
  29917. * This value defines the order in which the packages should be printed out into the dojo profile. Default is 100.
  29918. * Any number that is smaller causes this class to be written out before any other with a higher number
  29919. * @ibm-dojo-profile-level 40
  29920. */
  29921. // inject this service into the ServiceManager at the end. Therefore we have to require the implementation
  29922. dojo.declare("com.ibm.mm.iwidget.services.EventServiceExtendedImpl", com.ibm.mm.iwidget.services.EventServiceDefaultImpl, {
  29923. registerExtServices: function(){
  29924. var event = com.ibm.mashups.iwidget.Constants.WIDGET_WINDOWSTATECHANGED;
  29925. var me = this;
  29926. var eventCallback = function(payload){
  29927. var widgetId = payload.id;
  29928. var newWindowState = payload.newWindowState;
  29929. var oldWindowState = payload.oldWindowState;
  29930. me.fireEvent(widgetId, "onWindowStateChanged", {
  29931. newWindowState: newWindowState,
  29932. oldWindowState: oldWindowState
  29933. });
  29934. };
  29935. this.subscribeEvent(event, null, eventCallback, null, null);
  29936. },
  29937. subscribeWire: function(/*String*/sourceWidget,/*String*/ sourceEvent,/*String*/ targetWidget,/*String*/ targetEvent){
  29938. if (typeof sourceWidget == "undefined" || sourceWidget === null) {
  29939. return false;
  29940. }
  29941. if (typeof sourceEvent == "undefined" || sourceEvent === null) {
  29942. return false;
  29943. }
  29944. if (typeof targetWidget == "undefined" || targetWidget === null) {
  29945. return false;
  29946. }
  29947. if (typeof targetEvent == "undefined" || targetEvent === null) {
  29948. return false;
  29949. }
  29950. var rc = true;
  29951. var that = this;
  29952. // should be subHandle, topic, payload ( as defined in publishWire...)
  29953. function eventCallback(topic, message, subscribeData){
  29954. that.fireEvent(targetWidget, targetEvent, message.payload, message.payloadType, sourceWidget);
  29955. }
  29956. function callback(item, success, error){
  29957. if (!success) {
  29958. console.log("eventService.subscribeWire subscribe failed " + "source:" + sourceWidget + " sourceEvent:" + sourceEvent + " targetWidget:" + targetWidget + " targetEvent:" + targetEvent);
  29959. }
  29960. }
  29961. // do real subscription only if it's an inline iwidget
  29962. var payload;
  29963. var hubClient = this.hubAdapter._getInlineHubClient(targetWidget);
  29964. if (hubClient) {
  29965. var wireId = this._generateWireId(sourceWidget, sourceEvent, targetWidget, targetEvent);
  29966. // failsafe implementation. In case the same wire has already been created we will not create it again
  29967. if (this.subMgr[wireId]) {
  29968. return true;
  29969. }
  29970. var subHandler = hubClient.subscribe(this.WIDGETEVENT_PREFIX + sourceWidget + "." + sourceEvent, eventCallback, null, callback);
  29971. this.subMgr[wireId] = subHandler;
  29972. //notify source iWidget -- onNewWire
  29973. payload = {};
  29974. payload.targetWidget = targetWidget;
  29975. payload.sourceEvent = sourceEvent;
  29976. payload.sourceWidget = sourceWidget;
  29977. payload.targetEvent = targetEvent;
  29978. this.fireEvent(sourceWidget, "onNewWire", payload);
  29979. }
  29980. //if target widget is an iframe widget, we need to delegate the job to iframed widget
  29981. var isInlineClient = this.hubAdapter.isInlineClient(targetWidget);
  29982. //send message to
  29983. if (!isInlineClient) {
  29984. // Eventname:eventservice.widgetid
  29985. // methodname:subscribeWire
  29986. // params:{}
  29987. // hubclient:hubclientid
  29988. var eventname = "eventservice." + targetWidget;
  29989. payload = {};
  29990. payload.methodname = "subscribeWire";
  29991. payload.sourceWidget = sourceWidget;
  29992. payload.sourceEvent = sourceEvent;
  29993. payload.targetWidget = targetWidget;
  29994. payload.targetEvent = targetEvent;
  29995. payload.hubclient = "main";
  29996. this._publishEvent(eventname, payload);
  29997. rc = true;
  29998. }
  29999. return rc;
  30000. },
  30001. publishWire: function(/*String*/sourceWidget,/*String*/ sourceEvent,/*object*/ payload,/*String*/ payloadType){
  30002. payload = this._serializePayload(payload);
  30003. //allow widget to fire a event
  30004. if (typeof sourceWidget == "undefined" || sourceWidget === null) {
  30005. return false;
  30006. }
  30007. if (typeof sourceEvent == "undefined" || sourceEvent === null) {
  30008. return false;
  30009. }
  30010. var hubClient = this.hubAdapter._getInlineHubClient(sourceWidget);
  30011. //publish wire only if it's an inline iwidget
  30012. if (hubClient) {
  30013. hubClient.publish(this.WIDGETEVENT_PREFIX + sourceWidget + "." + sourceEvent, {
  30014. "payload": payload,
  30015. "payloadType": payloadType
  30016. });
  30017. }
  30018. return true;
  30019. },
  30020. _serializePayload: function(payload){
  30021. // complex payload objects must be serialized to json for case when widgets are sandboxed
  30022. // to be serializable, complex payload objects must implement toJson method that returns json in format {"className":"x","json":"y"}
  30023. // to be deserializable, complex payload objects must have a constructor with an argument that accepts the "y" json value returned from toJson
  30024. if (typeof payload == 'object' && payload.toJson) {
  30025. payload = payload.toJson();
  30026. }
  30027. return payload;
  30028. },
  30029. unSubscribeWire: function(sourceWidget, sourceEvent, targetWidget, targetEvent){
  30030. if (typeof sourceWidget == "undefined" || sourceWidget === null) {
  30031. return false;
  30032. }
  30033. if (typeof sourceEvent == "undefined" || sourceEvent === null) {
  30034. return false;
  30035. }
  30036. if (typeof targetWidget == "undefined" || targetWidget === null) {
  30037. return false;
  30038. }
  30039. if (typeof targetEvent == "undefined" || targetEvent === null) {
  30040. return false;
  30041. }
  30042. var payload;
  30043. var hubClient = this.hubAdapter._getInlineHubClient(targetWidget);
  30044. if (hubClient) {
  30045. //unsubscribe only if it's an inline widget
  30046. var wireId = this._generateWireId(sourceWidget, sourceEvent, targetWidget, targetEvent);
  30047. var subHandler = this.subMgr[wireId];
  30048. if (subHandler) {
  30049. this.unsubscribeEvent(subHandler, targetWidget);
  30050. delete this.subMgr[wireId];
  30051. }
  30052. //onRemoveWire-- notify target widget
  30053. payload = {};
  30054. payload.targetWidget = targetWidget;
  30055. payload.targetEvent = targetEvent;
  30056. payload.sourceWidget = sourceWidget;
  30057. payload.sourceEvent = sourceEvent;
  30058. this.fireEvent(targetWidget, "onRemoveWire", payload);
  30059. this.fireEvent(sourceWidget, "onRemoveWire", payload);
  30060. //todo:remove
  30061. this.publishEvent(iwConstants.EVENTS.unSubscribeWire, {
  30062. wires: [payload]
  30063. });
  30064. //notify source widget
  30065. }
  30066. //if target widget is an iframe widget, we need to delegate the job to iframed widget
  30067. var isInlineClient = this.hubAdapter.isInlineClient(targetWidget);
  30068. //send message to
  30069. if (!isInlineClient) {
  30070. // Eventname:eventservice.widgetid
  30071. // methodname:subscribeWire
  30072. // params:{}
  30073. // hubclient:hubclientid
  30074. var eventname = "eventservice." + targetWidget;
  30075. payload = {};
  30076. payload.methodname = "unSubscribeWire";
  30077. payload.sourceWidget = sourceWidget;
  30078. payload.sourceEvent = sourceEvent;
  30079. payload.targetWidget = targetWidget;
  30080. payload.targetEvent = targetEvent;
  30081. payload.hubclient = "main";
  30082. this._publishEvent(eventname, payload);
  30083. rc = true;
  30084. }
  30085. return true;
  30086. },
  30087. addWire: function(sourceWidget, sourceEvent, targetWidget, targetEvent){
  30088. //SPI support, deprecated, should remove, no sandboxed support
  30089. if (typeof sourceWidget == "undefined" || sourceWidget === null) {
  30090. return false;
  30091. }
  30092. if (typeof sourceEvent == "undefined" || sourceEvent === null) {
  30093. return false;
  30094. }
  30095. if (typeof targetWidget == "undefined" || targetWidget === null) {
  30096. return false;
  30097. }
  30098. if (typeof targetEvent == "undefined" || targetEvent === null) {
  30099. return false;
  30100. }
  30101. var rc = false;
  30102. //if target widget is an iframe widget, we need to delegate the job to iframed widget
  30103. var isInlineClient = this.hubAdapter.isInlineClient(targetWidget);
  30104. //send message to
  30105. if (!isInlineClient) {
  30106. // Eventname:eventservice.widgetid
  30107. // methodname:addWire
  30108. // params:{}
  30109. // hubclient:hubclientid
  30110. var eventname = "eventservice." + targetWidget;
  30111. var payload = {};
  30112. payload.methodname = "addWire";
  30113. payload.params = arguments;
  30114. payload.hubclient = "main";
  30115. this._publishEvent(eventname, payload);
  30116. rc = true;
  30117. }
  30118. else {
  30119. //update js object and subscribe wire
  30120. rc = this.subscribeWire(sourceWidget, sourceEvent, targetWidget, targetEvent);
  30121. if (rc) {
  30122. var widget = com.ibm.mashups.iwidget.model.Factory.getGlobalWidgetModel().getWidgetById(targetWidget);
  30123. if (typeof widget != "undefined" && widget !== null) {
  30124. var aWire = {};
  30125. aWire.SourceWidget = sourceWidget;
  30126. aWire.SourceEvent = sourceEvent;
  30127. aWire.TargetEvent = targetEvent;
  30128. var instance = widget.getIWidgetInstance();
  30129. var wireObj = new com.ibm.mm.iwidget.widget.WireImpl(targetWidget, aWire);
  30130. instance._addWire(wireObj);
  30131. }
  30132. }
  30133. }
  30134. return rc;
  30135. },
  30136. removeWire: function(sourceWidget, sourceEvent, targetWidget, targetEvent){
  30137. //SPI support, deprecated, remove , no sandboxed support
  30138. if (typeof sourceWidget == "undefined" || sourceWidget === null) {
  30139. return false;
  30140. }
  30141. if (typeof sourceEvent == "undefined" || sourceEvent === null) {
  30142. return false;
  30143. }
  30144. if (typeof targetWidget == "undefined" || targetWidget === null) {
  30145. return false;
  30146. }
  30147. if (typeof targetEvent == "undefined" || targetEvent === null) {
  30148. return false;
  30149. }
  30150. var rc = false;
  30151. //if target widget is an iframe widget, we need to delegate the job to iframed widget
  30152. var isInlineClient = this.hubAdapter.isInlineClient(targetWidget);
  30153. //send message to
  30154. if (!isInlineClient) {
  30155. // Eventname:eventservice.widgetid
  30156. // methodname:addWire
  30157. // params:{}
  30158. // hubclient:hubclientid
  30159. var eventname = "eventservice." + targetWidget;
  30160. var payload = {};
  30161. payload.methodname = "removeWire";
  30162. payload.params = arguments;
  30163. payload.hubclient = "main";
  30164. this._publishEvent(eventname, payload);
  30165. rc = true;
  30166. }
  30167. else {
  30168. rc = this.unSubscribeWire(sourceWidget, sourceEvent, targetWidget, targetEvent);
  30169. if (rc) {
  30170. var widget = com.ibm.mashups.iwidget.model.Factory.getGlobalWidgetModel().getWidgetById(targetWidget);
  30171. if (typeof widget != "undefined" && widget !== null) {
  30172. var aWire = {};
  30173. aWire.SourceWidget = sourceWidget;
  30174. aWire.SourceEvent = sourceEvent;
  30175. aWire.TargetEvent = targetEvent;
  30176. var instance = widget.getIWidgetInstance();
  30177. var wireObj = new com.ibm.mm.iwidget.widget.WireImpl(targetWidget, aWire);
  30178. instance._removeWire(wireObj.getID());
  30179. }
  30180. }
  30181. }
  30182. return rc;
  30183. }
  30184. });
  30185. if (!ibmConfig.insideSandbox) {
  30186. com.ibm.mashups.services.ServiceManager.setService("eventService", "com.ibm.mm.iwidget.services.EventServiceExtendedImpl");
  30187. }
  30188. //IMPORTANT
  30189. //ibmConfig.enablerLayerModules is a comma separated string of all supported modules at runtime
  30190. //This section dynamically loads the Model representation when the variable enablerLayerModules contains the given module
  30191. if ((ibmConfig.enablerLayerModules) && (dojo.indexOf(ibmConfig.enablerLayerModules, "CoreModel") >= 0)) {
  30192. dojo["require"]("com.ibm.mm.enabler.iwidget.services.EventServiceModel"); // JSLINT-IGNORE: This needs to be done to allow modularization and to support the layers
  30193. }
  30194. }
  30195. if(!dojo._hasResource["com.ibm.mm.iwidget.services.IFrameEventServiceImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  30196. dojo._hasResource["com.ibm.mm.iwidget.services.IFrameEventServiceImpl"] = true;
  30197. dojo.provide("com.ibm.mm.iwidget.services.IFrameEventServiceImpl");
  30198. /*
  30199. * This is injected on the fly and not fetched through an API. Therefore we need to define the @ibm-module so that the build process is picking it up
  30200. * @ibm-module iWidget
  30201. *
  30202. * This value defines the order in which the packages should be printed out into the dojo profile. Default is 100.
  30203. * Any number that is smaller causes this class to be written out before any other with a higher number
  30204. * @ibm-dojo-profile-level 40
  30205. */
  30206. // inject this service into the ServiceManager at the end. Therefore we have to require the implementation
  30207. // make sure extended loaded before this one
  30208. dojo.declare("com.ibm.mm.iwidget.services.IFrameEventServiceImpl", com.ibm.mashups.iwidget.services.EventService, {
  30209. constructor: function() {
  30210. this.subMgr = {}; //save all the subscription on this widget
  30211. this.eventQueue = [];
  30212. this._hubClient = null;
  30213. this.getHubClient();//initialize connection
  30214. },
  30215. getType: function() {
  30216. return com.ibm.mm.iwidget.Constants.eventservice.type.IFRAME;
  30217. },
  30218. PREFIX_IFRAME: "_iframe_",
  30219. getHubClient: function() {
  30220. //console.log("getHubClient");
  30221. if (this._hubClient) {
  30222. return this._hubClient;
  30223. }
  30224. var that = this;
  30225. //create hub client and connect to hub
  30226. function onHubClientSecurityAlert(source, alertType) {
  30227. }
  30228. var hubClient = new OpenAjax.hub.IframeHubClient({
  30229. HubClient: {
  30230. onSecurityAlert: onHubClientSecurityAlert
  30231. }
  30232. });
  30233. function onHubClientConnect2(client, success, error) {
  30234. var id = client.getClientID();
  30235. id = id.slice(8);
  30236. that.setId(id);
  30237. that._hubClient = client;
  30238. that._subscribeEventService();
  30239. for (var i in that.eventQueue) {
  30240. if (Object.prototype.hasOwnProperty.call(that.eventQueue,i)) {
  30241. var args = that.eventQueue[i];
  30242. args[0] = "widgetevents." + id + args[0];
  30243. that._subscribeEvent.apply(that, args);
  30244. }
  30245. }
  30246. }
  30247. function onHubClientDisconnect(client, success, error) {
  30248. client.connect(onHubClientConnect2);
  30249. }
  30250. hubClient.connect(onHubClientConnect2);
  30251. return null;
  30252. },
  30253. disconnectHubClient: function() {
  30254. if (!this._hubClient) {
  30255. return;
  30256. }
  30257. this._hubClient.disconnect();
  30258. this._hubClient = null;
  30259. },
  30260. setId: function(id) {
  30261. this.id = id;
  30262. },
  30263. getId: function() {
  30264. return this.id;
  30265. },
  30266. _subscribeEventService: function() {
  30267. //dispatch event to each method....for now, just fireEvent
  30268. //in future, broadcastEvent... has security concern though
  30269. var that = this;
  30270. // message should contain
  30271. // methodname:fireEvent
  30272. // params:{}
  30273. // hubclient:hubclientid
  30274. function eventCallback(topic, message, subscribeData) {
  30275. //(targetWidget,targetEvent,message.payload,message.payloadType,sourceWidget)
  30276. var methodname = message.methodname;
  30277. if ((methodname == "subscribeWire") || (methodname == "unSubscribeWire")) {
  30278. var fn = that[message.methodname];
  30279. if (fn) {
  30280. fn.apply(that, [message.sourceWidget, message.sourceEvent, message.targetWidget, message.targetEvent]);
  30281. }
  30282. }
  30283. else if (methodname) {
  30284. var fn = that[message.methodname];
  30285. if (fn) {
  30286. fn.apply(that, message.params);
  30287. }
  30288. }
  30289. }
  30290. this._hubClient.subscribe("eventservice." + this.getId(), eventCallback, this, this._subscribeCallback);
  30291. },
  30292. _subscribeCallback: function(subHandle, success,/*OpenAjax.hub.Error*/ error) {
  30293. if (!success) {
  30294. //console.log("subscribe failed "+subHandle);
  30295. }
  30296. },
  30297. WIDGETEVENT_PREFIX: iwConstants.WIDGETEVENT_PREFIX,
  30298. WILDCARD_PREFIX: iwConstants.WILDCARD_PREFIX,
  30299. subscribeWire: function(/*String*/sourceWidget,/*String*/ sourceEvent,/*String*/ targetWidget,/*String*/ targetEvent) {
  30300. //called within iframe, target widget is the sandboxed iwidget
  30301. if (typeof sourceWidget == "undefined" || sourceWidget === null) {
  30302. return false;
  30303. }
  30304. if (typeof sourceEvent == "undefined" || sourceEvent === null) {
  30305. return false;
  30306. }
  30307. if (typeof targetWidget == "undefined" || targetWidget === null) {
  30308. return false;
  30309. }
  30310. if (typeof targetEvent == "undefined" || targetEvent === null) {
  30311. return false;
  30312. }
  30313. var rc = true;
  30314. var that = this;
  30315. // should be subHandle, topic, payload ( as defined in publishWire...)
  30316. function eventCallback(topic, message, subscribeData) {
  30317. //that.fireEvent(targetWidget, targetEvent, message.payload, message.payloadType, sourceWidget);
  30318. //distribute event directly to iwidgetwrapper
  30319. that.fireEvent(targetWidget, targetEvent, message.payload, message.payloadType, sourceWidget);
  30320. }
  30321. function callback(item, success, error) {
  30322. }
  30323. var subHandler = this._hubClient.subscribe(this.WIDGETEVENT_PREFIX + sourceWidget + "." + sourceEvent, eventCallback, null, callback);
  30324. var wireId = this._generateWireId(sourceWidget, sourceEvent, targetWidget, targetEvent);
  30325. this.subMgr[wireId] = subHandler;
  30326. //notify source iWidget -- onNewWire
  30327. var payload = {};
  30328. payload.targetWidget = targetWidget;
  30329. payload.sourceEvent = sourceEvent;
  30330. payload.sourceWidget = sourceWidget;
  30331. payload.targetEvent = targetEvent;
  30332. this.fireEvent(sourceWidget, "onNewWire", payload);
  30333. return rc;
  30334. },
  30335. publishWire: function(/*String*/sourceWidget,/*String*/ sourceEvent,/*object*/ payload,/*String*/ payloadType) {
  30336. payload = this._serializePayload(payload);
  30337. //allow widget to fire a event
  30338. if (typeof sourceWidget == "undefined" || sourceWidget === null) {
  30339. return false;
  30340. }
  30341. if (typeof sourceEvent == "undefined" || sourceEvent === null) {
  30342. return false;
  30343. }
  30344. this._hubClient.publish(this.WIDGETEVENT_PREFIX + sourceWidget + "." + sourceEvent, {
  30345. "payload": payload,
  30346. "payloadType": payloadType
  30347. });
  30348. return true;
  30349. },
  30350. _serializePayload: function(payload) {
  30351. // complex payload objects must be serialized to json for case when widgets are sandboxed
  30352. // to be serializable, complex payload objects must implement toJson method that returns json in format {"className":"x","json":"y"}
  30353. // to be deserializable, complex payload objects must have a constructor with an argument that accepts the "y" json value returned from toJson
  30354. if (typeof payload == 'object' && payload.toJson) {
  30355. payload = payload.toJson();
  30356. }
  30357. return payload;
  30358. },
  30359. unSubscribeWire: function(sourceWidget, sourceEvent, targetWidget, targetEvent) {
  30360. if (typeof sourceWidget == "undefined" || sourceWidget === null) {
  30361. return false;
  30362. }
  30363. if (typeof sourceEvent == "undefined" || sourceEvent === null) {
  30364. return false;
  30365. }
  30366. if (typeof targetWidget == "undefined" || targetWidget === null) {
  30367. return false;
  30368. }
  30369. if (typeof targetEvent == "undefined" || targetEvent === null) {
  30370. return false;
  30371. }
  30372. //unsubscribe from OAHub
  30373. var wireId = this._generateWireId(sourceWidget, sourceEvent, targetWidget, targetEvent);
  30374. var subHandler = this.subMgr[wireId];
  30375. if (subHandler) {
  30376. this._unsubscribeEvent(subHandler, targetEvent);
  30377. delete this.subMgr[wireId];
  30378. }
  30379. //onRemoveWire-- notify target widget
  30380. var payload = {};
  30381. payload.targetWidget = targetWidget;
  30382. payload.targetEvent = targetEvent;
  30383. payload.sourceWidget = sourceWidget;
  30384. payload.sourceEvent = sourceEvent;
  30385. this.fireEvent(targetWidget, "onRemoveWire", payload);
  30386. this.fireEvent(sourceWidget, "onRemoveWire", payload);
  30387. //builder is listening on this event
  30388. this._publishEvent(iwConstants.EVENTS.unSubscribeWire, {
  30389. wires: [payload]
  30390. });
  30391. },
  30392. fireEvent: function(targetWidget, targetEvent, payload, payloadType, sourceWidget) {
  30393. var aEvent = new com.ibm.mm.iwidget.IEventImpl(targetEvent, payloadType, payload, sourceWidget);
  30394. // this._publishEvent(this.WIDGETEVENT_PREFIX+targetWidget,aEvent,sourceWidget);
  30395. var widgetModel = com.ibm.mashups.iwidget.model.Factory.getGlobalWidgetModel();
  30396. var widget = widgetModel.find(targetWidget);
  30397. if (typeof widget != "undefined" && widget !== null) {
  30398. if (widget.isLoaded()) {
  30399. //if widget isEventsReady
  30400. widget.handleEvent(aEvent);
  30401. }
  30402. else {
  30403. var subID = dojox.uuid.generateRandomUuid();
  30404. var cb = function(eventSvr, wrapper, aEvent) {
  30405. wrapper.handleEvent(aEvent);
  30406. var subHandler = eventSvr.subMgr[subID];
  30407. if (subHandler) {
  30408. eventSvr._unsubscribeEvent(subHandler);
  30409. }
  30410. };
  30411. var subHandle = this._subscribeEvent(com.ibm.mashups.iwidget.Constants.WIDGET_LOADED + "." + widget.id, null, dojo.partial(cb, this, widget, aEvent));
  30412. this.subMgr[subID] = subHandle;
  30413. }
  30414. }
  30415. else { //if widget doesn't belong to iframe delegate the job to main eventservice since it can check if widget is loaded or not
  30416. //build payload methodname:fireEvent params:[] hubclient:hubclientid
  30417. var payloadObj = {};
  30418. payloadObj.methodname = "fireEvent";
  30419. payloadObj.hubclient = this.getId();
  30420. payloadObj.params = [targetWidget, targetEvent, payload, payloadType];
  30421. this._publishEvent("eventservice.main", payloadObj);
  30422. }
  30423. },
  30424. //support pagechanged event and widget deleted event
  30425. publishEvent: function(sourceEvent, payload, payloadType, sourceid) {
  30426. return;
  30427. },
  30428. _publishEvent: function(event, payload, sourceid) {
  30429. /*payload; need to be json object if it's openajax hub, for now, it's dojo, so it need to be array*/
  30430. if (typeof payload == "undefined" || payload === null) {
  30431. this._hubClient.publish(event, "");
  30432. }
  30433. else {
  30434. this._hubClient.publish(event, payload);
  30435. }
  30436. },
  30437. broadcastEvent: function(targetEvent, payload, payloadType, sourceid, pageid, spaceid) {
  30438. // untrusted widgets are not trusted to broadcast events
  30439. return;
  30440. },
  30441. broadcastEvents: function(eventsArray, sourceid, pageid, spaceid) {
  30442. // untrusted widgets are not trusted to broadcast events
  30443. return;
  30444. },
  30445. _handleBroadcastEventsCache: function() {
  30446. // pass to main event service
  30447. var payloadObj = {};
  30448. payloadObj.methodname = "_handleBroadcastEventsCache";
  30449. payloadObj.hubclient = this.getId();
  30450. payloadObj.params = [];
  30451. this._publishEvent("eventservice.main", payloadObj);
  30452. },
  30453. subscribeEvent: function(event, object, eventCallback, subscribeCallback, sourceid) {
  30454. return;
  30455. },
  30456. _subscribeEvent: function(event, object, eventCallback, subscribeCallback, sourceid) {
  30457. //internal use only for subscription managed by container
  30458. //widgets should not use this at all.
  30459. if (!this._hubClient) {
  30460. this.eventQueue.push(arguments);
  30461. return;
  30462. }
  30463. var subHandle1 = this._hubClient.subscribe(event, function(topic, data, subscriberData) { /*onData*/
  30464. if (object && eventCallback) {
  30465. eventCallback = dojo.hitch(object, eventCallback);
  30466. }
  30467. //Deserialize data,not necessary
  30468. if (eventCallback) {
  30469. eventCallback.apply(this, [data]);
  30470. }
  30471. }, null /* scope */, function(subID, success, error) { /*onComplete*/
  30472. if (object && subscribeCallback ) {
  30473. subscribeCallback = dojo.hitch(object, subscribeCallback);
  30474. }
  30475. if (subscribeCallback) {
  30476. subscribeCallback.apply(this, [subID, success, error]);
  30477. }
  30478. if (!success) {
  30479. return;
  30480. }
  30481. });
  30482. return subHandle1;
  30483. },
  30484. _unsubscribeEvent: function(subscriptionHandler, sourceid) {
  30485. if (!subscriptionHandler) {
  30486. return;
  30487. }
  30488. this._hubClient.unsubscribe(subscriptionHandler);
  30489. },
  30490. unsubscribeEvent: function(subscriptionHandler, sourceid) {
  30491. return;
  30492. },
  30493. _generateWireId: function(sourceWidget, sourceEvent, targetWidget, targetEvent) {
  30494. return sourceWidget + "_" + sourceEvent + "_" + targetWidget + "_" + targetEvent;
  30495. }
  30496. });
  30497. if (ibmConfig.insideSandbox) {
  30498. com.ibm.mashups.services.ServiceManager.setService("eventService", "com.ibm.mm.iwidget.services.IFrameEventServiceImpl");
  30499. }
  30500. }
  30501. if(!dojo._hasResource["com.ibm.mm.iwidget.widget.IWidgetDefinitionExtendedImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  30502. dojo._hasResource["com.ibm.mm.iwidget.widget.IWidgetDefinitionExtendedImpl"] = true;
  30503. dojo.provide("com.ibm.mm.iwidget.widget.IWidgetDefinitionExtendedImpl");
  30504. /*
  30505. * This is injected on the fly and not fetched through an API. Therefore we need to define the @ibm-module so that the build process is picking it up
  30506. * @ibm-module iWidget
  30507. *
  30508. * This value defines the order in which the packages should be printed out into the dojo profile. Default is 100.
  30509. * Any number that is smaller causes this class to be written out before any other with a higher number
  30510. * @ibm-dojo-profile-level 40
  30511. */
  30512. dojo.declare("com.ibm.mm.iwidget.widget.IWidgetDefinitionExtendedImpl", com.ibm.mm.iwidget.widget.IWidgetDefinitionDefaultImpl, {
  30513. getResources: function() {
  30514. if (!this.resources) {
  30515. this.resources = dojo.map(this.widgetDef.resources, function(resource) {
  30516. return new com.ibm.mm.iwidget.widget.ResourceImpl(resource);
  30517. });
  30518. }
  30519. return this.resources;
  30520. },
  30521. getPublishedEventsNames: function() {
  30522. var eventNames = [];
  30523. if (this.widgetDef.publicEvents) {
  30524. com.ibm.mm.enabler.utils.Misc.forIn(this.widgetDef.publicEvents, function(temp, aEventName) {
  30525. if (!temp.isPublished || (temp.isPublished && temp.isPublished == "true")) {
  30526. eventNames.push(aEventName);
  30527. }
  30528. });
  30529. }
  30530. return eventNames;
  30531. },
  30532. getHandledEventsNames: function() {
  30533. var eventNames = [];
  30534. if (this.widgetDef.publicEvents) {
  30535. com.ibm.mm.enabler.utils.Misc.forIn(this.widgetDef.publicEvents, function(temp, aEventName) {
  30536. if (temp.onEvent) {
  30537. // it's a valid handledEvent only when onEvent is defined
  30538. eventNames.push(aEventName);
  30539. }
  30540. });
  30541. }
  30542. return eventNames;
  30543. },
  30544. getPublishedEvent: function(/*String*/eventName) {
  30545. //generate a copy of ieventDescription object
  30546. if (!this.widgetDef.publicEvents) {
  30547. return null;
  30548. }
  30549. var event = this.getPublicEvent(eventName) || null;
  30550. if (event) {
  30551. if (!event.isPublished || (event.isPublished && event.isPublished == "false")) {
  30552. event = null;
  30553. }
  30554. }
  30555. return event;
  30556. },
  30557. getHandledEvent: function(/*String*/eventName) {
  30558. //generate a copy of iEventDescription object
  30559. if (!this.widgetDef.publicEvents) {
  30560. return null;
  30561. }
  30562. var event = this.getPublicEvent(eventName) || null;
  30563. if (event) {
  30564. if (!event.onEvent) {
  30565. event = null;
  30566. }
  30567. }
  30568. return event;
  30569. },
  30570. getPublicEvent: function(eventName) {
  30571. //generate a copy of iEventDescription object , following json object should be created passinto iEventDescription
  30572. if (!this.widgetDef.publicEvents) {
  30573. return null;
  30574. }
  30575. if (this.eventsCache && this.eventsCache[eventName]) {
  30576. return new com.ibm.mm.iwidget.IEventDescriptionImpl(this.eventsCache[eventName]);
  30577. }
  30578. var data = this.widgetDef.publicEvents[eventName];
  30579. var event = null;
  30580. var obj = {};
  30581. if (data) {
  30582. //mapping into json format defined by iwidget spec.
  30583. obj.name = data.id;
  30584. if (data.onEvent) {
  30585. obj.handlingFn = data.onEvent; //"String"-pass by value
  30586. obj.isHandled = true;
  30587. }
  30588. else {
  30589. obj.isHandled = false;
  30590. }
  30591. obj.isPublished = !!data.isPublished;
  30592. obj.attributes = {};
  30593. obj.localizedAttributes = {};
  30594. var descriptionId = null;
  30595. com.ibm.mm.enabler.utils.Misc.forIn(data, function(d, i) {
  30596. if (i == "description") {
  30597. descriptionId = d;
  30598. }
  30599. else if (i != "id" && i != "onEvent") {
  30600. obj.attributes[i] = d; // save onNewWire/onRemoveWire, potentially other attributes, all are string
  30601. }
  30602. });
  30603. var description = null;
  30604. if (descriptionId) {
  30605. description = this._getEventDescription(descriptionId) || null;
  30606. if (description) {
  30607. var defaultLang = description.lang;
  30608. if (!defaultLang) {
  30609. defaultLang = this.getDefaultLanguage();
  30610. if (!defaultLang) {
  30611. defaultLang = "en";
  30612. }
  30613. }
  30614. obj.lang = defaultLang;
  30615. if (description.payloadType) {
  30616. obj.type = description.payloadType;
  30617. }
  30618. //todo: save more attributes && localized attributes.
  30619. if (description.aliases) {
  30620. obj.attributes.aliases = description.aliases;
  30621. }
  30622. var localizedAttributes = description.descriptions;
  30623. /*if (typeof localizedAttributes != "undefined" && localizedAttributes != null){
  30624. obj.localizedAttributes= dojo.clone(description.descriptions);
  30625. }*/
  30626. if (localizedAttributes) { //performance improvement
  30627. obj.localizedAttributes = description.descriptions;
  30628. }
  30629. if (typeof(obj.localizedAttributes[defaultLang]) == "undefined") {
  30630. obj.localizedAttributes[defaultLang] = {};
  30631. }
  30632. //backward compatibility
  30633. if (description.title) {
  30634. obj.localizedAttributes[defaultLang].title = description.title;
  30635. }
  30636. if (description.description) {
  30637. obj.localizedAttributes[defaultLang].description = description.description;
  30638. }
  30639. if (description.descriptionURI) {
  30640. obj.localizedAttributes[defaultLang].descriptionURI = description.descriptionURI;
  30641. }
  30642. }
  30643. }
  30644. if (!this.eventsCache) {
  30645. this.eventsCache = {};
  30646. }
  30647. this.eventsCache[eventName] = obj;
  30648. event = new com.ibm.mm.iwidget.IEventDescriptionImpl(obj);
  30649. }
  30650. return event;
  30651. },
  30652. _getEventDescription: function(id) {
  30653. var eventDescription = null;
  30654. if (this.widgetDef.eventDescriptions) {
  30655. eventDescription = this.widgetDef.eventDescriptions[id];
  30656. }
  30657. return eventDescription;
  30658. },
  30659. _getPublicEvents: function() {
  30660. //return associative array, each eventdescription is identified by it's name
  30661. //return an empty object if there's no public Events;
  30662. //pass by data
  30663. var publicEvents = {};
  30664. com.ibm.mm.enabler.utils.Misc.forIn(this.widgetDef.publicEvents, function(k, aEventName) {
  30665. var eventDescription = this.getPublicEvent(aEventName) || null;
  30666. if (eventDescription) {
  30667. publicEvents[aEventName] = eventDescription;
  30668. }
  30669. }, this);
  30670. return publicEvents;
  30671. },
  30672. getWidgetPublishedEvents: function() {
  30673. return this.getPublishedEvents();
  30674. },
  30675. getWidgetHandledEvents: function() {
  30676. return this.getHandledEvents();
  30677. },
  30678. getPublishedEvents: function() {
  30679. //return an array of new generated eventDescription
  30680. //pass by data
  30681. var publishedEvents = [];
  30682. dojo.forEach(this.getPublishedEventsNames(), function(publishedEventName) {
  30683. var eventDescription = this.getPublicEvent(publishedEventName) || null;
  30684. if (eventDescription) {
  30685. publishedEvents.push(eventDescription); //todo, remove array
  30686. }
  30687. }, this);
  30688. return publishedEvents;
  30689. },
  30690. getHandledEvents: function() {
  30691. //save as above
  30692. var handledEvents = [];
  30693. dojo.forEach(this.getHandledEventsNames(), function(handledEventName) {
  30694. var eventDescription = this.getPublicEvent(handledEventName) || null;
  30695. if (eventDescription) {
  30696. handledEvents.push(eventDescription); //todo, remove array
  30697. }
  30698. }, this);
  30699. return handledEvents;
  30700. },
  30701. getPayloadDefs: function() {
  30702. return this.widgetDef.payloadDefs;
  30703. },
  30704. getPayloadDef: function(name) {
  30705. var payloadDef = this.widgetDef.payloadDefs[name];
  30706. return (typeof payloadDef == "undefined") ? null : payloadDef;
  30707. },
  30708. getPayloadDefNames: function() {
  30709. var arr = [];
  30710. com.ibm.mm.enabler.utils.Misc.forIn(this.widgetDef.payloadDefs, function(a) {
  30711. arr.push(a);
  30712. });
  30713. return arr;
  30714. },
  30715. _getShareableItemSets: function() {
  30716. // return Shareable ItemSets that's saved, based on old widgetDef format
  30717. // returns an Objectof sharedItemSet or return null
  30718. var shareableItemSetsArr = this.widgetDef.shareableItemSetsArr;
  30719. if (shareableItemSetsArr) {
  30720. for (var i in shareableItemSetsArr) {
  30721. if (Object.prototype.hasOwnProperty.call(shareableItemSetsArr, i)) {
  30722. return shareableItemSetsArr;
  30723. }
  30724. }
  30725. }
  30726. return null;
  30727. },
  30728. toSpecObject: function() {
  30729. if (this.specObject) {
  30730. return this.specObject;
  30731. }
  30732. var outputJSON = {};
  30733. //no support within sandbox
  30734. if (!this.xmlStr) {
  30735. return outputJSON;
  30736. }
  30737. var xmlData = com.ibm.mm.enabler.xslt.loadXmlString(this.xmlStr);
  30738. var expr = "/iw:iwidget";
  30739. var rootNode = com.ibm.mashups.enabler.xml.XPath.evaluateEntry(expr, xmlData, this.namespaces);
  30740. if (rootNode) {
  30741. this._addAttributesToJson(rootNode, outputJSON);
  30742. var conditionArray = [];
  30743. conditionArray.push({
  30744. elementName: "eventDescription",
  30745. keyNames: ["id"]
  30746. });
  30747. conditionArray.push({
  30748. elementName: "alt",
  30749. keyNames: ["lang", "xml:lang"]
  30750. });
  30751. this._addElements(rootNode, conditionArray, outputJSON);
  30752. conditionArray = [];
  30753. conditionArray.push({
  30754. elementName: "event",
  30755. keyNames: ["id"]
  30756. });
  30757. this._addElements(rootNode, conditionArray, outputJSON);
  30758. //this._addElements(rootNode, "itemSetDescription", ["id"], "alt", ["lang","xml:lang"], outputJSON);
  30759. //this._addElements(rootNode, "itemDescription", ["id"], "alt", ["lang","xml:lang"], outputJSON);
  30760. conditionArray = [];
  30761. conditionArray.push({
  30762. elementName: "itemSet",
  30763. keyNames: ["id"]
  30764. });
  30765. conditionArray.push({
  30766. elementName: "item",
  30767. keyNames: ["id"]
  30768. });
  30769. conditionArray.push({
  30770. elementName: "alt",
  30771. keyNames: ["lang", "xml:lang"]
  30772. });
  30773. this._addElements(rootNode, conditionArray, outputJSON);
  30774. conditionArray = [];
  30775. //if no skipLoad attribute, check if there's skipLoad element
  30776. conditionArray.push({
  30777. elementName: "resource",
  30778. keyNames: ["uri", "src"],
  30779. elemsAsAtt: ["skipLoad"]
  30780. });
  30781. this._addElements(rootNode, conditionArray, outputJSON);
  30782. conditionArray = [];
  30783. conditionArray.push({
  30784. elementName: "content",
  30785. keyNames: ["mode"]
  30786. });
  30787. this._addElements(rootNode, conditionArray, outputJSON, true);
  30788. }
  30789. this.specObject = outputJSON;
  30790. return outputJSON;
  30791. },
  30792. _addAttributesToJson: function(node, jsonNode) {
  30793. dojo.forEach(node.attributes, function(att) {
  30794. jsonNode["_" + att.nodeName.replace(":", "_")] = att.nodeValue;
  30795. });
  30796. },
  30797. _addElements: function(node, conditionArray,/*elementName, keyNames, subElement, subElementKeyNames,*/ jsonNode, isContentNode) {
  30798. if (!dojo.isArray(conditionArray) || conditionArray.length === 0) {
  30799. return;
  30800. }
  30801. var elementName = conditionArray[0].elementName;
  30802. var keyNames = conditionArray[0].keyNames;
  30803. var elemsAsAtt = conditionArray[0].elemsAsAtt;
  30804. var subElement = null;
  30805. var subElementKeyNames = null;
  30806. if (conditionArray.length > 1) {
  30807. subElement = conditionArray[1].elementName;
  30808. subElementKeyNames = conditionArray[1].keyNames;
  30809. }
  30810. var elements = jsonNode[elementName + "s"] = {}; // do plural notation
  30811. var nodes = com.ibm.mashups.enabler.xml.XPath.evaluateXPath("iw:" + elementName, node, this.namespaces);
  30812. if (nodes) {
  30813. dojo.forEach(nodes, function(node) {
  30814. var keyValue;
  30815. for (var j = 0, kL = keyNames.length; j < kL; j++) {
  30816. // first match wins
  30817. keyValue = node.getAttribute(keyNames[j]);
  30818. if (keyValue) {
  30819. break;
  30820. }
  30821. }
  30822. if (keyValue) {
  30823. var subNode = elements[keyValue] = {};
  30824. this._addAttributesToJson(node, subNode);
  30825. if (elemsAsAtt) {
  30826. dojo.forEach(elemsAsAtt, function(elemAsAtt) {
  30827. var elemAsAttKey = "_" + elemAsAtt;
  30828. if (!(elemAsAttKey in subNode) || !subNode[elemAsAttKey]) {
  30829. var node2 = com.ibm.mashups.enabler.xml.XPath.evaluateEntry("iw:" + elemAsAtt, node, this.namespaces);
  30830. if (node2) {
  30831. dojo.forEach(node2.childNodes, function(child) {
  30832. if (child.nodeType == 4 && child.nodeValue) {
  30833. subNode[elemAsAttKey] = child.nodeValue;
  30834. }
  30835. });
  30836. }
  30837. }
  30838. }, this);
  30839. }
  30840. // if there is also a subelement do one recursion
  30841. if (subElement) {
  30842. var nextLevelArr = conditionArray.slice(1);
  30843. this._addElements(node, nextLevelArr, subNode);
  30844. }
  30845. // if this is a content node also add the content as "value"
  30846. if (isContentNode) {
  30847. subNode.value = dojo.map(node.childNodes || [], function(child) {
  30848. return (child.nodeType === 4 || child.nodeType === 3) ? child.nodeValue : "";
  30849. }).join("");
  30850. }
  30851. }
  30852. }, this);
  30853. }
  30854. }
  30855. });
  30856. com.ibm.mm.iwidget.widget.IWidgetDefinitionImpl = com.ibm.mm.iwidget.widget.IWidgetDefinitionExtendedImpl;
  30857. }
  30858. if(!dojo._hasResource["com.ibm.mashups.iwidget.services.WireProviderFactoryService_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  30859. dojo._hasResource["com.ibm.mashups.iwidget.services.WireProviderFactoryService_API"] = true;
  30860. dojo.provide("com.ibm.mashups.iwidget.services.WireProviderFactoryService_API");
  30861. dojo.provide("com.ibm.mashups.iwidget.services.WireProviderFactoryService");
  30862. /**
  30863. * @private
  30864. * @ibm-module iWidget
  30865. */
  30866. dojo.declare("com.ibm.mashups.iwidget.services.WireProviderFactoryService",null, {
  30867. /**
  30868. * TODO make this public at some point, ServiceManager documentation says it should be there
  30869. *
  30870. * @private
  30871. */
  30872. SERVICE_NAME : "WireProviderFactoryService",
  30873. /**
  30874. * Creates event model for the specified widget by honoring the current persistence mode (e.g. DOM vs. Model).
  30875. * The factory for the current persistence mode needs to be added to this service by using the <tt>addFactory</tt> method of this class.
  30876. *
  30877. * @param {com.ibm.mashups.iwidget.widget.IWidgetInstance} widgetInstance the widget for which to create the wire provider
  30878. * @param {Object} contextAndCallback an optional JSON object with a context and callback property to provide as a callback
  30879. * @return {com.ibm.mashups.iwidget.widget.WireProvider} an event model for the specified widget using the according factory or <tt>null</tt> if no factory is available for the current mode.
  30880. */
  30881. createWireProvider: function(widgetWrapper, contextAndCallback) {
  30882. },
  30883. /**
  30884. * Sets the factory for the specified persistenceMode to this service.
  30885. * @param {String} persistenceMode the mode that is supported by the specified factory
  30886. * @param {com.ibm.mashups.iwidget.services.WireProviderFactory} factory the factory that creates the provider.
  30887. * @return {void}
  30888. */
  30889. setFactory: function(persistenceMode, factory) {
  30890. },
  30891. /**
  30892. * Removes a factory for a specified persistence mode.
  30893. *
  30894. * @param {String} persistenceMode the mode to remove
  30895. *
  30896. * TODO make this public at some time
  30897. * @private
  30898. */
  30899. removeFactory: function(persistenceMode) {
  30900. }
  30901. });
  30902. }
  30903. if(!dojo._hasResource["com.ibm.mashups.iwidget.services.WireProviderFactoryService"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  30904. dojo._hasResource["com.ibm.mashups.iwidget.services.WireProviderFactoryService"] = true;
  30905. dojo.provide("com.ibm.mashups.iwidget.services.WireProviderFactoryService");
  30906. com.ibm.mashups.iwidget.services.WireProviderFactoryService.SERVICE_NAME = com.ibm.mashups.iwidget.services.WireProviderFactoryService.prototype.SERVICE_NAME;
  30907. }
  30908. if(!dojo._hasResource["com.ibm.mashups.iwidget.widget.WireProviderFactory"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  30909. dojo._hasResource["com.ibm.mashups.iwidget.widget.WireProviderFactory"] = true;
  30910. dojo.provide("com.ibm.mashups.iwidget.widget.WireProviderFactory");
  30911. /**
  30912. * @private
  30913. * @ibm-module iWidget
  30914. */
  30915. dojo.declare("com.ibm.mashups.iwidget.widget.WireProviderFactory",null, {
  30916. /**
  30917. * Creates wire provider for the specified widget and persistence mode.
  30918. *
  30919. * @param {com.ibm.mashups.iwidget.widget.IWidgetInstance} widgetInstance the widget for which to create the persistent attributes
  30920. * @param {String} persistenceMode the persistence mode for which to create the attributes
  30921. * @return {com.ibm.mashups.iwidget.widget.WireProvider} wire provider the given widget / mode.
  30922. * If the specified mode is not supported by this method <tt>null</tt> will be returned.
  30923. */
  30924. createWireProvider: function(widgetInstance, persistenceMode) {
  30925. },
  30926. /**
  30927. * Returns the persistence modes that are supported by this factory.
  30928. * @return {String[]} the supported persistence modes.
  30929. */
  30930. getSupportedPersistenceMode: function() {
  30931. }
  30932. });
  30933. }
  30934. if(!dojo._hasResource["com.ibm.mm.iwidget.widget.ModifiableWireModelImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  30935. dojo._hasResource["com.ibm.mm.iwidget.widget.ModifiableWireModelImpl"] = true;
  30936. dojo.provide("com.ibm.mm.iwidget.widget.ModifiableWireModelImpl");
  30937. dojo.declare("com.ibm.mm.iwidget.widget.ModifiableWireModelImpl", null, {
  30938. constructor: function(widgetInstance) {
  30939. this._dirty = false;
  30940. this._instance = widgetInstance;
  30941. this.svc = com.ibm.mashups.services.ServiceManager.getService("eventService");
  30942. },
  30943. toJson:function(){
  30944. var returnObj = {};
  30945. returnObj._dirty = this._dirty;
  30946. if(this._wires) {
  30947. returnObj._wires = dojo.clone(this._wires);
  30948. }
  30949. if(this._targets) {
  30950. returnObj._targets = dojo.clone(this._targets );
  30951. }
  30952. return returnObj;
  30953. },
  30954. isDirty: function() {
  30955. return this._dirty;
  30956. },
  30957. setDirty: function(isDirty) {
  30958. this._dirty = isDirty;
  30959. },
  30960. registerTargets:function(tw,te,se){
  30961. if (!this._targets) {
  30962. this._targets = {};
  30963. }
  30964. if (!this._targets[tw]) {
  30965. this._targets[tw] = [];
  30966. }
  30967. var wire = {tw:tw,te:te,sw:this._instance.id,se:se};
  30968. this._targets[tw].push(wire);
  30969. this._dirty = true;
  30970. },
  30971. getTargets:function(){
  30972. if(! this._targets) {
  30973. return null;
  30974. }
  30975. return this._targets;
  30976. },
  30977. removeTargets:function(tw,te,se){
  30978. if(this._targets){
  30979. if (this._targets[tw]) {
  30980. if(!te && !se){
  30981. delete(this._targets[tw]);
  30982. this._dirty = true;
  30983. }
  30984. //todo,very rare case te,se will be available
  30985. }
  30986. }
  30987. },
  30988. _addWire:function(wire,loadFromDom) {
  30989. var wire2 = this._findWire(wire.getID()) || null;
  30990. if (wire2 === null) {
  30991. if (!this._wires) {
  30992. this._wires = [];
  30993. }
  30994. if (!(loadFromDom && loadFromDom === true)) {
  30995. wire.setDirty(true);
  30996. wire.setType(wire.TYPE_NEW);
  30997. this._dirty = true;
  30998. }
  30999. this._wires.push(wire);
  31000. this.svc.subscribeWire(wire.SourceWidget, wire.SourceEvent, this._instance.id, wire.TargetEvent);
  31001. }
  31002. },
  31003. _removeWire:function(id) {
  31004. var wire = this._findWire(id) || null;
  31005. if (wire !== null) {
  31006. // unsubscribe wire
  31007. for ( var i in this._wires) {
  31008. if (typeof this._wires[i].getID === "function" && this._wires[i].getID() == id) {
  31009. // remove wire from wire array
  31010. //this._wires.splice(j-1,1);
  31011. if(this._wires[i].setDirty === "function" ){
  31012. this._wires[i].setDirty(true);
  31013. }
  31014. if(typeof this._wires[i].setType === "function"){
  31015. this._wires[i].setType(this._wires[i].TYPE_DELETE);
  31016. }
  31017. this.svc.unSubscribeWire(wire.SourceWidget, wire.SourceEvent, this._instance.id, wire.TargetEvent);
  31018. this._dirty=true;
  31019. break;
  31020. }
  31021. }
  31022. }
  31023. },
  31024. addWire:function(sourceWidget,sourceEvent,targetEvent) {
  31025. var aWire = {};
  31026. aWire.SourceWidget = sourceWidget;
  31027. aWire.SourceEvent = sourceEvent;
  31028. aWire.TargetEvent = targetEvent;
  31029. var wire = new com.ibm.mm.iwidget.widget.WireImpl(this._instance.id, aWire);
  31030. this._addWire(wire);
  31031. },
  31032. removeWire:function(sourceWidget,sourceEvent,targetEvent) {
  31033. var aWire = {};
  31034. sourceWidget = sourceWidget || null;
  31035. sourceEvent = sourceEvent || null;
  31036. targetEvent = targetEvent || null;
  31037. if (sourceWidget !== null&& sourceEvent !== null && targetEvent !== null) {
  31038. aWire.SourceWidget = sourceWidget;
  31039. aWire.SourceEvent = sourceEvent;
  31040. aWire.TargetEvent = targetEvent;
  31041. var wireObj = new com.ibm.mm.iwidget.widget.WireImpl(this._instance.id, aWire);
  31042. this._removeWire(wireObj.getID());
  31043. }else if (sourceWidget !== null){
  31044. //delete all the wires that has this widget as source
  31045. for (var w in this._wires) {
  31046. if (typeof this._wires[w].getSourceWidgetID === "function" && this._wires[w].getSourceWidgetID() == sourceWidget) {
  31047. if(typeof this._wires[w].setDirty === "function"){
  31048. this._wires[w].setDirty(true);
  31049. }
  31050. if(typeof this._wires[w].setType === "function"){
  31051. this._wires[w].setType(this._wires[w].TYPE_DELETE);
  31052. }
  31053. }
  31054. var wire = this._wires[w];
  31055. this.svc.unSubscribeWire(sourceWidget, wire.SourceEvent, wire.TargetWidget, wire.TargetEvent);
  31056. this._dirty=true;
  31057. }
  31058. }
  31059. },
  31060. // find Wire by id
  31061. _findWire: function(id) {
  31062. this._wires = this._wires || null;
  31063. var wire = null;
  31064. if (this._wires !== null) {
  31065. for (var w in this._wires) {
  31066. if (typeof this._wires[w].getID === "function" && this._wires[w].getID() == id) {
  31067. wire = this._wires[w]; //commit the change
  31068. if (wire.isDirty() && wire.getType() !== null && wire.getType() == wire.TYPE_DELETE) {
  31069. this._removeFromDOM(wire);
  31070. delete this._wires[w];
  31071. wire = null;
  31072. }
  31073. else {
  31074. break;
  31075. }
  31076. }
  31077. }
  31078. }
  31079. return wire || null;
  31080. },
  31081. getWires:function(){
  31082. if (!this._wires) {
  31083. this._loadWires();
  31084. }
  31085. var arr = [];
  31086. for (var i in this._wires){
  31087. if (Object.prototype.hasOwnProperty.call(this._wires,i)) {
  31088. var aWire = this._wires[i];
  31089. if (!(aWire.isDirty() === true && (aWire.getType() !== null && aWire.getType() == aWire.TYPE_DELETE))) {
  31090. arr.push(aWire);
  31091. }
  31092. }
  31093. }
  31094. //if (arr.length == 0 ) return null;
  31095. return arr;
  31096. },
  31097. _loadWires:function(){
  31098. this._wires = [];
  31099. var ns = this._instance.ns;
  31100. var className="ReceivedEvent";
  31101. var nodes=[];
  31102. com.ibm.mm.iwidget.Utils.findElementByAttribute("query","> ."+ns+className,this._instance.rootElement,nodes,true);
  31103. var names = ["SourceWidget","SourceEvent","TargetEvent"];
  31104. var classes = ["SourceEvent","TargetEvent"];
  31105. for (var i=0;i<nodes.length;i++){
  31106. var aNode = nodes[i];
  31107. var aWire = {};
  31108. var isValid = true;
  31109. for (var j=0;j<2;j++){
  31110. var element=[];
  31111. com.ibm.mm.iwidget.Utils.findElementByAttribute("query","> ."+ns+classes[j],aNode,element,false);
  31112. if (element.length === 0 ){ isValid = false; }
  31113. else{
  31114. if ( j===0 ) {
  31115. var temp = element[0].getAttribute("href") || null;
  31116. if (temp !== null) {
  31117. var index = temp.indexOf ("#");
  31118. if (index != -1) {
  31119. temp=temp.substring(index+1);
  31120. }
  31121. aWire[names[0]] = temp;
  31122. aWire[names[1]] = element[0].innerHTML;
  31123. }
  31124. }
  31125. else{
  31126. aWire[names[2]] = element[0].innerHTML;
  31127. }
  31128. }
  31129. }
  31130. if (isValid) {
  31131. this._addWire(new com.ibm.mm.iwidget.widget.WireImpl(this._instance.id,aWire),true);
  31132. // com.ibm.mashups.services.ServiceManager.getService("eventService").subscribeWire(aWire.SourceWidget,aWire.SourceEvent,this._instance.id,aWire.TargetEvent);
  31133. }
  31134. }
  31135. },
  31136. commit:function(){
  31137. //update dom for ADD and Delete
  31138. if (this.isDirty() === true){
  31139. for (var i in this._wires){
  31140. if (Object.prototype.hasOwnProperty.call(this._wires,i)) {
  31141. var aWire = this._wires[i];
  31142. if (aWire.isDirty() && aWire.getType() !== null && aWire.getType() == aWire.TYPE_NEW) {
  31143. this._addToDOM(aWire);
  31144. aWire.setDirty(false);
  31145. aWire.setType(null);
  31146. }
  31147. else
  31148. if (aWire.isDirty() && aWire.getType() !== null && aWire.getType() == aWire.TYPE_DELETE) {
  31149. this._removeFromDOM(aWire);
  31150. //delete this._wires[i];
  31151. this._wires.splice(i, 1);
  31152. }
  31153. }
  31154. }
  31155. this.setDirty(false);
  31156. }
  31157. },
  31158. _addToDOM:function(aWire){
  31159. var sourceId = aWire.getSourceWidgetID();
  31160. var sourceEvent = aWire.getSourceEventName();
  31161. var targetEvent = aWire.getTargetEventName();
  31162. var recEvent = document.createElement("span");
  31163. recEvent.className = this._instance.ns+"ReceivedEvent";
  31164. var srcWidget = document.createElement("a");
  31165. srcWidget.className = this._instance.ns+"SourceEvent";
  31166. srcWidget.setAttribute("href", "#" + sourceId);
  31167. srcWidget.innerHTML = sourceEvent;
  31168. var tarEvent = document.createElement("span");
  31169. tarEvent.className = this._instance.ns+"TargetEvent";
  31170. tarEvent.innerHTML = targetEvent;
  31171. recEvent.appendChild(srcWidget);
  31172. recEvent.appendChild(tarEvent);
  31173. this._instance.rootElement.appendChild(recEvent);
  31174. },
  31175. _removeFromDOM:function(aWire){
  31176. var sourceId = aWire.getSourceWidgetID();
  31177. var sourceEvent = aWire.getSourceEventName();
  31178. var targetEvent = aWire.getTargetEventName();
  31179. var widgetSpan = this._instance.rootElement;
  31180. var allWireSpans = dojo.query("." + this._instance.ns+"ReceivedEvent", widgetSpan);
  31181. var fragmentService = com.ibm.mashups.services.ServiceManager.getService("iwidgetFragmentService");
  31182. for (var i = 0; i < allWireSpans.length; i++) {
  31183. var wireSpan = allWireSpans[i];
  31184. var srcWidgetSpan = dojo.query("."+this._instance.ns+"SourceEvent", wireSpan)[0];
  31185. var srcEvent = srcWidgetSpan.innerHTML;
  31186. var tarEventSpan = dojo.query("."+this._instance.ns+"TargetEvent", wireSpan)[0];
  31187. if (fragmentService.getKeyFromHref(srcWidgetSpan) == sourceId && srcEvent == sourceEvent && tarEventSpan.innerHTML == targetEvent) {
  31188. //widgetSpan.removeChild(wireSpan);
  31189. // use dojo.destroy() instead to avoid orphan nodes
  31190. dojo.destroy(wireSpan);
  31191. break;
  31192. }
  31193. }
  31194. }
  31195. });
  31196. }
  31197. if(!dojo._hasResource["com.ibm.mm.iwidget.widget.DOMWireProviderFactoryImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  31198. dojo._hasResource["com.ibm.mm.iwidget.widget.DOMWireProviderFactoryImpl"] = true;
  31199. dojo.provide("com.ibm.mm.iwidget.widget.DOMWireProviderFactoryImpl");
  31200. // TODO
  31201. dojo.declare("com.ibm.mm.iwidget.widget.DOMWireProviderFactoryImpl", com.ibm.mashups.iwidget.widget.WireProviderFactory, {
  31202. constructor: function() {
  31203. this.modes = ["DOM"]; //just make it consistent with other model like attributes model
  31204. },
  31205. createWireProvider: function(widgetInstance, persistenceMode) {
  31206. return new com.ibm.mm.iwidget.widget.ModifiableWireModelImpl(widgetInstance);
  31207. },
  31208. getSupportedPersistenceMode: function() {
  31209. return this.modes;
  31210. }
  31211. });
  31212. }
  31213. if(!dojo._hasResource["com.ibm.mm.iwidget.services.WireProviderFactoryServiceImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  31214. dojo._hasResource["com.ibm.mm.iwidget.services.WireProviderFactoryServiceImpl"] = true;
  31215. dojo.provide("com.ibm.mm.iwidget.services.WireProviderFactoryServiceImpl");
  31216. /*
  31217. * This is injected on the fly and not fetched through an API. Therefore we need to define the @ibm-module so that the build process is picking it up
  31218. * @ibm-module iWidget
  31219. */
  31220. // inject this service into the ServiceManager at the end. Therefore we have to require the implementation
  31221. dojo.declare("com.ibm.mm.iwidget.services.WireProviderFactoryServiceImpl", com.ibm.mashups.iwidget.services.WireProviderFactoryService, {
  31222. constructor: function(){
  31223. this._factories = {};
  31224. },
  31225. createWireProvider: function(widgetInstance, contextAndCallback) {
  31226. if (contextAndCallback) {
  31227. // register callback
  31228. com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.iwidget.services.ContainerService.SERVICE_NAME).registerOnChangeListener(com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_WIRES, contextAndCallback);
  31229. }
  31230. var persistenceMode;
  31231. var wID = widgetInstance.id;
  31232. persistenceMode = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.iwidget.services.ContainerService.SERVICE_NAME).getPersistenceMode(com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_WIRES);
  31233. var widgetDomNode = widgetInstance.rootElement;
  31234. if (dojo.hasClass(widgetDomNode, com.ibm.mm.iwidget.services.WireProviderFactoryServiceImpl.STANDALONE_CLASS) || !persistenceMode) {
  31235. persistenceMode = com.ibm.mm.iwidget.services.WireProviderFactoryServiceImpl.DEFAULT_PERSISTENCE;
  31236. }
  31237. if (typeof persistenceMode !== "undefined" && persistenceMode == com.ibm.mashups.enabler.widget.Constants.PERSISTENCE_MODE_MODEL) {
  31238. var widgetModel = com.ibm.mashups.enabler.widget.Factory.getWidgetModel();
  31239. var navStateModel = com.ibm.mashups.enabler.model.state.NavigationStateModelFactory.getNavigationStateModel();
  31240. var spaceAccessor = com.ibm.mashups.enabler.model.state.AccessorFactory.getSpaceAccessor(navStateModel);
  31241. var pageAccessor = com.ibm.mashups.enabler.model.state.AccessorFactory.getPageAccessor(navStateModel, currentSpaceID);
  31242. var currentSpaceID = spaceAccessor.getSpaceID();
  31243. var currentPageID = pageAccessor.getPageID();
  31244. var modelID = com.ibm.mm.iwidget.Utils.getModelID(wID);
  31245. var wnd = widgetModel.findWidgetWindow(modelID, currentPageID).start();
  31246. if (!wnd) {
  31247. persistenceMode = com.ibm.mm.iwidget.services.WireProviderFactoryServiceImpl.DEFAULT_PERSISTENCE;
  31248. if (this.widgetWrapper && dojo.isFunction(this.widgetWrapper._getResourceBundle)) {
  31249. this.widgetWrapper._getResourceBundle();
  31250. }
  31251. }
  31252. }
  31253. if (!(persistenceMode in this._factories)) {
  31254. return null;
  31255. }
  31256. return this._factories[persistenceMode].createWireProvider(widgetInstance, persistenceMode);
  31257. },
  31258. setFactory: function(persistenceMode, factory){
  31259. this._factories[persistenceMode] = factory;
  31260. },
  31261. removeFactory: function(persistenceMode) {
  31262. if(persistenceMode in this._factories) {
  31263. delete this._factories[persistenceMode];
  31264. }
  31265. }
  31266. });
  31267. com.ibm.mm.iwidget.services.WireProviderFactoryServiceImpl.DEFAULT_PERSISTENCE = com.ibm.mashups.enabler.widget.Constants.PERSISTENCE_MODE_DOM;
  31268. com.ibm.mm.iwidget.services.WireProviderFactoryServiceImpl.STANDALONE_CLASS = com.ibm.mm.iwidget.Constants.CSSCLASS_PREFIXED_INSTANCE.iwStandalone;
  31269. com.ibm.mashups.services.ServiceManager.setService(com.ibm.mashups.iwidget.services.WireProviderFactoryService.SERVICE_NAME, new com.ibm.mm.iwidget.services.WireProviderFactoryServiceImpl());
  31270. com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.iwidget.services.WireProviderFactoryService.SERVICE_NAME).setFactory(com.ibm.mashups.enabler.widget.Constants.PERSISTENCE_MODE_DOM, new com.ibm.mm.iwidget.widget.DOMWireProviderFactoryImpl());
  31271. }
  31272. if(!dojo._hasResource["com.ibm.mm.iwidget.widget.IWidgetInstanceExtendedImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  31273. dojo._hasResource["com.ibm.mm.iwidget.widget.IWidgetInstanceExtendedImpl"] = true;
  31274. dojo.provide("com.ibm.mm.iwidget.widget.IWidgetInstanceExtendedImpl");
  31275. /*
  31276. * This is injected on the fly and not fetched through an API. Therefore we need to define the @ibm-module so that the build process is picking it up
  31277. * @ibm-module iWidget
  31278. *
  31279. * This value defines the order in which the packages should be printed out into the dojo profile. Default is 100.
  31280. * Any number that is smaller causes this class to be written out before any other with a higher number
  31281. * @ibm-dojo-profile-level 40
  31282. */
  31283. dojo.declare("com.ibm.mm.iwidget.widget.IWidgetInstanceExtendedImpl", com.ibm.mm.iwidget.widget.IWidgetInstanceDefaultImpl, {
  31284. _addWire: function(wire) {
  31285. return this.getWireModel()._addWire(wire);
  31286. },
  31287. _removeWire: function(id) {
  31288. return this.getWireModel()._removeWire(id);
  31289. },
  31290. addWire: function(sourceWidget, sourceEvent, targetEvent) {
  31291. return this.getWireModel().addWire(sourceWidget, sourceEvent, targetEvent);
  31292. },
  31293. removeWire: function(sourceWidget, sourceEvent, targetEvent) {
  31294. return this.getWireModel().removeWire(sourceWidget, sourceEvent, targetEvent);
  31295. },
  31296. getWires: function() {
  31297. return this.getWireModel().getWires();
  31298. },
  31299. getWireModel: function() {
  31300. if (!this.wiremodel) {
  31301. this.wiremodel = com.ibm.mashups.services.ServiceManager.getService("WireProviderFactoryService").createWireProvider(this, {context: this, callback: "_wireProviderModeChange",
  31302. unregister: function(handle) {
  31303. this.wrapper.unregisterArray.push(handle);
  31304. }
  31305. });
  31306. }
  31307. return this.wiremodel;
  31308. },
  31309. _wireProviderModeChange: function(provider, oldMode, newMode) {
  31310. // D18935: Store the wire model targets to transfer to the new wire model
  31311. var targets = null;
  31312. if (this.wiremodel) {
  31313. targets = this.wiremodel.getTargets();
  31314. }
  31315. this.wiremodel = com.ibm.mashups.services.ServiceManager.getService("WireProviderFactoryService").createWireProvider(this);
  31316. // D18935: Transfer the wire model targets to the new wire model
  31317. if (targets) {
  31318. for (var id in targets) {
  31319. var value=targets[id];
  31320. for (var i=0, l=value.length;i<l;i++) {
  31321. this.wiremodel.registerTargets(value[i].tw, value[i].te, value[i].se);
  31322. }
  31323. }
  31324. }
  31325. this.getWires(); // we need to initialize the model here
  31326. },
  31327. _getPublicEvents: function() {
  31328. if (!this.events) {
  31329. this.events = {};
  31330. var events = [];
  31331. com.ibm.mm.iwidget.Utils.findElementByAttribute("query", "> ."+this.ns + com.ibm.mm.iwidget.Constants.CSSCLASS_INSTANCE.iwEvent, this.rootElement, events, true);
  31332. var eventDescs = [];
  31333. com.ibm.mm.iwidget.Utils.findElementByAttribute("query", "> ."+this.ns + com.ibm.mm.iwidget.Constants.CSSCLASS_INSTANCE.iwEventDescription, this.rootElement, eventDescs, true);
  31334. if (events.length > 0) {
  31335. for (var i = 0; i < events.length; i++) {
  31336. var elem = events[i];
  31337. var anEvent = this._getEventDescription(elem, eventDescs);
  31338. var id = elem.getAttribute("title");
  31339. this.events[id] = anEvent;
  31340. }
  31341. }
  31342. }
  31343. return this.events;
  31344. },
  31345. _getEventDescription: function(elem, eventDescs) {
  31346. var id = elem.getAttribute("title");
  31347. var nodeList = dojo.query("> ." + this.ns + com.ibm.mm.iwidget.Constants.CSSCLASS_INSTANCE.iwDescRef, elem);
  31348. var descRefNode = null;
  31349. if (nodeList) {
  31350. descRefNode = nodeList[0];
  31351. }
  31352. var eventDescName = null;
  31353. if (descRefNode) {
  31354. eventDescName = descRefNode.getAttribute("href");
  31355. if (eventDescName.indexOf("#") === 0) {
  31356. eventDescName = eventDescName.slice(1);
  31357. // some browser actually escape the href that comes back so that we have to decode it so that we compare apples with apples
  31358. eventDescName = unescape(eventDescName);
  31359. }
  31360. }
  31361. var descNode = null;
  31362. for (var j = 0; j < eventDescs.length; j++) {
  31363. var temp = eventDescs[j];
  31364. if (temp.getAttribute("title") == eventDescName) {
  31365. descNode = temp;
  31366. break;
  31367. }
  31368. }
  31369. //build IEventDescriptionImpl object
  31370. var obj = {};
  31371. /*{
  31372. name: "",
  31373. alias: "",
  31374. type: "",
  31375. lang: "",
  31376. handlingFn: "" | Function,
  31377. isHandled: true | false,
  31378. isPublished: true | false,
  31379. localizedAttributes: [<locale>: {<attName>: <attValue>}, ...],
  31380. attributes: {<attName>: <attValue>, ... }
  31381. }*/
  31382. obj.name = id;
  31383. var alias = descRefNode.innerHTML;
  31384. alias = alias.replace(/^\s*/, "").replace(/\s*$/, "");
  31385. if (alias) {
  31386. obj.alias = alias;
  31387. }
  31388. var className = elem.className;
  31389. if (className.indexOf(this.ns + com.ibm.mm.iwidget.Constants.CSSCLASS_INSTANCE.iwPublished) > 0) {
  31390. obj.isPublished = true;
  31391. }
  31392. if (className.indexOf(this.ns + com.ibm.mm.iwidget.Constants.CSSCLASS_INSTANCE.iwHandled) > 0) {
  31393. obj.isHandled = true;
  31394. }
  31395. var list = [];
  31396. list.push(this.ns + com.ibm.mm.iwidget.Constants.CSSCLASS_INSTANCE.iwHandler);
  31397. list.push(this.ns + com.ibm.mm.iwidget.Constants.CSSCLASS_INSTANCE.iwNewWire);
  31398. list.push(this.ns + com.ibm.mm.iwidget.Constants.CSSCLASS_INSTANCE.iwRemoveWire);
  31399. for (var s = 0; s < list.length; s++) {
  31400. var nodesList = dojo.query("> ." + list[s], elem);
  31401. if (nodesList) {
  31402. var aNode = nodesList[0];
  31403. if (aNode) {
  31404. switch (s) {
  31405. case 0:
  31406. obj.handlingFn = aNode.innerHTML;
  31407. break;
  31408. case 1:
  31409. obj.attributes = obj.attributes ? obj.attributes : {};
  31410. obj.attributes.onNewWire = aNode.innerHTML;
  31411. break;
  31412. case 2:
  31413. obj.attributes = obj.attributes ? obj.attributes : {};
  31414. obj.attributes.onRemoveWire = aNode.innerHTML;
  31415. break;
  31416. default:
  31417. break;
  31418. }
  31419. }
  31420. }
  31421. }
  31422. //payloadtype && localizedAttributes
  31423. if (descNode) {
  31424. var payloadTypeCSS = this.ns + com.ibm.mm.iwidget.Constants.CSSCLASS_INSTANCE.iwPayloadType;
  31425. var list = dojo.query("> ." + payloadTypeCSS, descNode);
  31426. if (list && list[0]) {
  31427. obj.type = list[0].innerHTML.replace(/^\s*/, "").replace(/\s*$/, "");
  31428. }
  31429. obj.localizedAttributes = {};
  31430. var titleCSS = this.ns + com.ibm.mm.iwidget.Constants.CSSCLASS_INSTANCE.iwTitle;
  31431. var valueCSS = this.ns + com.ibm.mm.iwidget.Constants.CSSCLASS_INSTANCE.iwValue;
  31432. var titleList = dojo.query("> ." + titleCSS, descNode);
  31433. if (titleList && titleList[0]) {
  31434. dojo.query("> ." + valueCSS, titleList[0]).forEach(function(elem) {
  31435. var lang = elem.getAttribute("lang");
  31436. var value = elem.innerHTML.replace(/^\s*/, "").replace(/\s*$/, "");
  31437. if (!obj.localizedAttributes[lang]) {
  31438. obj.localizedAttributes[lang] = {};
  31439. }
  31440. obj.localizedAttributes[lang].title = value;
  31441. });
  31442. }
  31443. var descCSS = this.ns + com.ibm.mm.iwidget.Constants.CSSCLASS_INSTANCE.iwDescription;
  31444. var valueCSS = this.ns + com.ibm.mm.iwidget.Constants.CSSCLASS_INSTANCE.iwValue;
  31445. var descList = dojo.query("> ." + descCSS, descNode);
  31446. if (descList && descList[0]) {
  31447. dojo.query("> ." + valueCSS, descList[0]).forEach(function(elem) {
  31448. var lang = elem.getAttribute("lang");
  31449. var value = elem.innerHTML.replace(/^\s*/, "").replace(/\s*$/, "");
  31450. if (!obj.localizedAttributes[lang]) {
  31451. obj.localizedAttributes[lang] = {};
  31452. }
  31453. obj.localizedAttributes[lang].description = value;
  31454. });
  31455. }
  31456. }
  31457. return new com.ibm.mm.iwidget.IEventDescriptionImpl(obj);
  31458. }
  31459. });
  31460. com.ibm.mm.iwidget.widget.IWidgetInstanceImpl = com.ibm.mm.iwidget.widget.IWidgetInstanceExtendedImpl;
  31461. }
  31462. if(!dojo._hasResource["com.ibm.mashups.iwidget.services.WidgetEventModelFactoryService_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  31463. dojo._hasResource["com.ibm.mashups.iwidget.services.WidgetEventModelFactoryService_API"] = true;
  31464. dojo.provide("com.ibm.mashups.iwidget.services.WidgetEventModelFactoryService_API");
  31465. dojo.provide("com.ibm.mashups.iwidget.services.WidgetEventModelFactoryService");
  31466. /**
  31467. * @private
  31468. * @ibm-module iWidget
  31469. */
  31470. dojo.declare("com.ibm.mashups.iwidget.services.WidgetEventModelFactoryService",null, {
  31471. /**
  31472. * TODO make this public at some point, ServiceManager documentation says it should be there
  31473. *
  31474. * @private
  31475. */
  31476. SERVICE_NAME : "WidgetEventModelFactoryService",
  31477. /**
  31478. * Creates event model for the specified widget by honoring the current persistence mode (e.g. DOM vs. Model).
  31479. * The factory for the current persistence mode needs to be added to this service by using the <tt>addFactory</tt> method of this class.
  31480. *
  31481. * @param {com.ibm.mashups.iwidget.widget.IWidgetWrapper} widget the widget for which to create the event model
  31482. * @return {com.ibm.mashups.Deferred} an event model (com.ibm.mashups.iwidget.model.EventModel) for the specified widget using the according factory or <tt>null</tt> if no factory is available for the current mode.
  31483. */
  31484. createEventModel: function(widgetWrapper,contextAndCallback) {
  31485. },
  31486. /**
  31487. * Sets the factory for the specified persistenceMode to this service.
  31488. * @param {String} persistenceMode the mode that is supported by the specified factory
  31489. * @param {com.ibm.mashups.iwidget.services.WidgetEventModelFactory} factory the factory that creates the attributes.
  31490. * @return {void}
  31491. */
  31492. setFactory: function(persistenceMode, factory) {
  31493. },
  31494. /**
  31495. * Removes a factory for a specified persistence mode.
  31496. *
  31497. * @param {String} persistenceMode the mode to remove
  31498. *
  31499. * TODO make this public at some time
  31500. * @private
  31501. */
  31502. removeFactory: function(persistenceMode) {
  31503. }
  31504. });
  31505. }
  31506. if(!dojo._hasResource["com.ibm.mashups.iwidget.services.WidgetEventModelFactoryService"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  31507. dojo._hasResource["com.ibm.mashups.iwidget.services.WidgetEventModelFactoryService"] = true;
  31508. dojo.provide("com.ibm.mashups.iwidget.services.WidgetEventModelFactoryService");
  31509. // make sure we can reference this globally
  31510. com.ibm.mashups.iwidget.services.WidgetEventModelFactoryService.SERVICE_NAME = com.ibm.mashups.iwidget.services.WidgetEventModelFactoryService.prototype.SERVICE_NAME;
  31511. }
  31512. if(!dojo._hasResource["com.ibm.mashups.iwidget.model.EventModelFactory"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  31513. dojo._hasResource["com.ibm.mashups.iwidget.model.EventModelFactory"] = true;
  31514. dojo.provide("com.ibm.mashups.iwidget.model.EventModelFactory");
  31515. /**
  31516. * @private
  31517. * @ibm-module iWidget
  31518. */
  31519. dojo.declare("com.ibm.mashups.iwidget.model.EventModelFactory",null, {
  31520. /**
  31521. * Creates widget events model for the specified widget and persistence mode.
  31522. *
  31523. * @param {com.ibm.mashups.iwidget.widget.IWidgetWrapper} widget the widget for which to create the persistent attributes
  31524. * @param {String} persistenceMode the persistence mode for which to create the attributes
  31525. * @return {ManagedItemSet} the persistent attributes for the given widget / mode.
  31526. * If the specified mode is not supported by this method <tt>null</tt> will be returned.
  31527. */
  31528. createEventModel: function(widgetWrapper, persistenceMode) {
  31529. },
  31530. /**
  31531. * Returns the persistence modes that are supported by this factory.
  31532. * @return {String[]} the supported persistence modes.
  31533. */
  31534. getSupportedPersistenceMode: function() {
  31535. }
  31536. });
  31537. }
  31538. if(!dojo._hasResource["com.ibm.mashups.iwidget.model.EventModel"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  31539. dojo._hasResource["com.ibm.mashups.iwidget.model.EventModel"] = true;
  31540. dojo.provide("com.ibm.mashups.iwidget.model.EventModel");
  31541. /**
  31542. * @private
  31543. * @ibm-module iWidget
  31544. */
  31545. dojo.declare("com.ibm.mashups.iwidget.model.EventModel",null,{
  31546. // FIXME What the heck is this doing in the API?
  31547. constructor:function (wrapper) {
  31548. this.wrapper = wrapper;
  31549. },
  31550. /**
  31551. It returns event specified by given id. It returns null if event is not found.<br/>
  31552. @param{String} id event id. Must not be <code>null</code>.
  31553. @returns{com.ibm.mashups.iwidget.IEventDescription} returns an event description that matches event id.
  31554. */
  31555. find:function(id){
  31556. return null;
  31557. },
  31558. /**
  31559. It returns true if event exists. It returns false if event doesn't exist.<br/>
  31560. @param{String} id event id. Must not be <code>null</code>.
  31561. @type Boolean
  31562. @returns{Boolean} returns true if event exists. It returns false if event doesn't exist.
  31563. */
  31564. eventExists:function(id){
  31565. return false;
  31566. },
  31567. /**
  31568. This method simply creates a new event definition. <br/>
  31569. It returns true if new event is created successfully. It returns false if it fails to create new event.<br/>
  31570. @param{com.ibm.mashups.iwidget.IEventDescription} eventDesc IEventDescription object. Must not be <code>null</code>.
  31571. @type Boolean
  31572. @returns{Boolean} returns true if new event is created successfully. It returns false if it fails to create new event.
  31573. */
  31574. createEvent:function(eventDesc){
  31575. return null;
  31576. },
  31577. /**
  31578. This method removes an existing event description.It returns true if event is removed successfully or event doesn't exist, otherwise it returns false. <br/>
  31579. @param{String} eventName event name. Must not be <code>null</code>.
  31580. @type Boolean
  31581. @returns{Boolean} returns true if event is removed successfully or event doesn't exist, otherwise it returns false.
  31582. */
  31583. removeEvent:function(eventName){
  31584. },
  31585. /**
  31586. This method verifies if an update on an event is really required as it may be the same that is getting set again.<br/>
  31587. It returns true if the event is different and an update is required, otherwise false.<br/>
  31588. @param{com.ibm.mashups.iwidget.IEventDescription} eventDesc IEventDescription object. Must not be <code>null</code>.
  31589. @type Boolean
  31590. @returns{Boolean} returns true if the event is different and an update is required, otherwise false.
  31591. */
  31592. isUpdateEventRequired:function(eventDesc){
  31593. },
  31594. /**
  31595. This method updates an existing event definition. <br/>
  31596. It returns true if event is updated successfully. It returns false if it fails to update existing event.<br/>
  31597. @param{com.ibm.mashups.iwidget.IEventDescription} eventDesc IEventDescription object. Must not be <code>null</code>.
  31598. @type Boolean
  31599. @returns{Boolean} returns true if event is updated successfully. It returns false if it fails to update existing event.
  31600. */
  31601. updateEvent:function(eventDesc){
  31602. },
  31603. /**
  31604. The query method which takes a javascript object as condition, it returns a list of event descriptions which matches the given condition. <br/>
  31605. The scope of the events is limited to this iwidget instance. The returning result need to match all the conditions that's given. <br/>
  31606. For exampe, if a condition object looks like this: {type:'text', isHandled:true}<br/>
  31607. This method will return all the handled event description whose payload is text.<br/>
  31608. If no condition is provided, this method will return all the events. It returns null if no event is found for a given condition.Only predefined fields or non localized attributes should be used to define condition.
  31609. @param{Object} condition JSON object that contains the condition. Must not be <code>null</code>.
  31610. @type com.ibm.mashups.iwidget.IEventDescription
  31611. @returns{com.ibm.mashups.iwidget.IEventDescription} returns an array of event description that matches the condition. It returns null if no event is found for a given condition.
  31612. */
  31613. getEvents:function(condition){
  31614. }
  31615. });
  31616. }
  31617. if(!dojo._hasResource["com.ibm.mm.enabler.utils.EventModelHelperImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  31618. dojo._hasResource["com.ibm.mm.enabler.utils.EventModelHelperImpl"] = true;
  31619. dojo.provide("com.ibm.mm.enabler.utils.EventModelHelperImpl");
  31620. dojo.declare("com.ibm.mm.enabler.utils.EventModelHelperImpl", null, {
  31621. _PredefinedFields: {
  31622. alias: "alias",
  31623. name: "name",
  31624. type: "type",
  31625. lang: "lang",
  31626. isPublished: "isPublished",
  31627. isHandled: "isHandled",
  31628. handlingFn: "handlingFn"
  31629. },
  31630. checkMatch: function(eventDesc, condition) {
  31631. var rc = true;
  31632. var conditionArr = [];
  31633. var isPublished;
  31634. for (var i in condition) {
  31635. if (Object.prototype.hasOwnProperty.call(condition,i)) {
  31636. if (!condition[i]) {
  31637. continue; //check next condition if current condition is null
  31638. }
  31639. if (typeof(this._PredefinedFields[i]) != "undefined") {
  31640. //for predefined fields
  31641. if (i == this._PredefinedFields.isPublished && (condition[i] === true || condition[i] == "true")) {
  31642. //check if isPublished is true
  31643. //break if !(isPublished is defined and isPublished = true)
  31644. //eventDesc.isPublished returns undefined if eventDesc.isPublished = true!
  31645. isPublished = eventDesc.isPublished;
  31646. if (!(isPublished && (isPublished === true || isPublished == "true"))) {
  31647. rc = false;
  31648. break;
  31649. }
  31650. }
  31651. else if (i == this._PredefinedFields.isPublished && (condition[i] == "false" || condition[i] === false)) {
  31652. //check if isPublished is false
  31653. //break if isPublished is defined and isPublished is not "false"
  31654. isPublished = eventDesc.isPublished;
  31655. if (!(isPublished && (isPublished === false || isPublished == "false"))) {
  31656. rc = false;
  31657. break;
  31658. }
  31659. }
  31660. else if (i == this._PredefinedFields.isPublished && (condition[i] == "false" || condition[i] === false)) {
  31661. //check if isPublished is false
  31662. //break if isPublished is defined and isPublished is not "false"
  31663. if (!this._checkBoolean(dojo.toJson(eventDesc), i, "false")) {
  31664. rc = false;
  31665. break;
  31666. }
  31667. }
  31668. else if (i == this._PredefinedFields.isHandled && (condition[i] === true || condition[i] == "true")) {
  31669. //break if handlingFn is not defined or it's null
  31670. if (!eventDesc[this._PredefinedFields.handlingFn]) {
  31671. rc = false;
  31672. break;
  31673. }
  31674. }
  31675. else if (i == this._PredefinedFields.isHandled && (condition[i] == "false" || condition[i] === false)) {
  31676. //break if handlingFn is defined and it's not null
  31677. if (eventDesc[this._PredefinedFields.handlingFn]) {
  31678. rc = false;
  31679. break;
  31680. }
  31681. }
  31682. else if (!(eventDesc[i] && eventDesc[i] == condition[i])) {
  31683. //break if !(condition exists and condition match)
  31684. rc = false;
  31685. break;
  31686. }
  31687. } //for attributes
  31688. else if (!(eventDesc.attributes && eventDesc.attributes[i] && eventDesc.attributes[i] == condition[i])) {
  31689. rc = false;
  31690. break;
  31691. }
  31692. //continue with next condition, break if condition doesn't meet
  31693. }
  31694. }
  31695. return rc;
  31696. },
  31697. _checkBoolean: function(str, name, value) {
  31698. var rc = false;
  31699. var temp = "\"" + name + "\"" + ":" + value;
  31700. if (str.indexOf(temp) != -1) {
  31701. return true;
  31702. }
  31703. temp = "\"" + name + "\"" + ":\"" + value + "\"";
  31704. if (str.indexOf(temp) != -1) {
  31705. return true;
  31706. }
  31707. return false;
  31708. }
  31709. });
  31710. dojo.declare("com.ibm.mashups.enabler.utils.EventModelHelper", null, {});
  31711. com.ibm.mashups.enabler.utils.EventModelHelper = new com.ibm.mm.enabler.utils.EventModelHelperImpl();
  31712. }
  31713. if(!dojo._hasResource["com.ibm.mm.iwidget.model.DOMEventModelImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  31714. dojo._hasResource["com.ibm.mm.iwidget.model.DOMEventModelImpl"] = true;
  31715. dojo.provide("com.ibm.mm.iwidget.model.DOMEventModelImpl");
  31716. /*provide Locator and Iterator,query by condition and other convenience function*/
  31717. /*internal model for widget wrapper */
  31718. dojo.declare("com.ibm.mm.iwidget.model.DOMEventModelImpl", com.ibm.mashups.iwidget.model.EventModel, {
  31719. constructor: function(wrapper) {
  31720. //widget wrapper id
  31721. this.wrapper = wrapper;
  31722. //an associative array of eventDescription object
  31723. this.eventDescriptionPool = {};
  31724. var defEvents = wrapper.widgetDef._getPublicEvents();
  31725. var instanceEvents = wrapper.getIWidgetInstance()._getPublicEvents();
  31726. var events = defEvents?defEvents:null;
  31727. if (instanceEvents) {
  31728. for (var j in instanceEvents) {
  31729. if (Object.prototype.hasOwnProperty.call(instanceEvents, j)) {
  31730. events[j] = instanceEvents[j];
  31731. }
  31732. }
  31733. }
  31734. if (events) {
  31735. var wrapperevents = {};
  31736. for (var i in events) {
  31737. if (Object.prototype.hasOwnProperty.call(events,i)) {
  31738. wrapperevents[i] = events[i];
  31739. }
  31740. }
  31741. this.eventDescriptionPool = wrapperevents;
  31742. }
  31743. },
  31744. /*id is eventName*/
  31745. find: function(id) {
  31746. var event = this.eventDescriptionPool[id];
  31747. if (event) {
  31748. return event;
  31749. }
  31750. if (this.wrapper.handledEvents) {
  31751. if (this.wrapper.handledEvents[id]) {
  31752. return this.wrapper.handledEvents[id][0];
  31753. }
  31754. }
  31755. if (this.wrapper.publishedEvents) {
  31756. if (this.wrapper.publishedEvents[id]) {
  31757. return this.wrapper.publishedEvents[id][0];
  31758. }
  31759. }
  31760. return null;
  31761. },
  31762. eventExists: function(eventName) {
  31763. var temp = this.eventDescriptionPool[eventName];
  31764. if (temp) {
  31765. return true;
  31766. }
  31767. else {
  31768. return false;
  31769. }
  31770. },
  31771. _getEventDescObj: function(eventDesc) {
  31772. var obj = eventDesc;
  31773. var declaredClass = eventDesc.declaredClass;
  31774. if (typeof declaredClass == "undefined" || declaredClass === null) {
  31775. obj = new com.ibm.mm.iwidget.IEventDescriptionImpl(eventDesc);
  31776. }
  31777. return obj;
  31778. },
  31779. createEvent: function(eventDescData) {
  31780. var eventDesc = this._getEventDescObj(eventDescData);
  31781. var eventExists = this.eventExists(eventDesc.name);
  31782. if (eventExists) {
  31783. return false;
  31784. }
  31785. else {
  31786. this.eventDescriptionPool[eventDesc.name] = eventDesc;
  31787. return true;
  31788. }
  31789. },
  31790. removeEvent: function(eventName) {
  31791. var eventExists = this.eventExists(eventName);
  31792. if (eventExists) {
  31793. delete this.eventDescriptionPool[eventName];
  31794. return true;
  31795. }
  31796. else {
  31797. return true;
  31798. }
  31799. },
  31800. removeEvents: function(eventNames){
  31801. for (var i=0;i<eventNames.length;i++){
  31802. this.removeEvent(eventNames[i]);
  31803. }
  31804. //return true when deleted or event doesn't exist
  31805. return true;
  31806. },
  31807. isUpdateEventRequired:function(eventDescData) {
  31808. var eventDesc = this._getEventDescObj(eventDescData);
  31809. var eventExists = this.eventExists(eventDesc.name);
  31810. if (eventExists) {
  31811. var oldEventDesc = this.eventDescriptionPool[eventDesc.name];
  31812. // strip off namespace
  31813. var oldType = oldEventDesc.type || "";
  31814. oldType = (oldType.indexOf("}")==-1) ? oldType : oldType.substring(oldType.indexOf("}")+1);
  31815. var newType = eventDesc.type || "";
  31816. newType = (newType.indexOf("}")==-1) ? newType : newType.substring(newType.indexOf("}")+1);
  31817. if ((oldEventDesc.alias != eventDesc.alias) ||
  31818. (oldEventDesc.name != eventDesc.name) ||
  31819. (oldType != newType) ||
  31820. //(oldEventDesc.handlingFn != eventDesc.handlingFn) ||
  31821. //(oldEventDesc.lang != eventDesc.lang) ||
  31822. (oldEventDesc.isHandled != eventDesc.isHandled) ||
  31823. (oldEventDesc.isPublished != eventDesc.isPublished)) {
  31824. return true;
  31825. }
  31826. return false;
  31827. }
  31828. else {
  31829. return true;
  31830. }
  31831. },
  31832. updateEvent: function(eventDescData) {
  31833. var eventDesc = this._getEventDescObj(eventDescData);
  31834. var eventExists = this.eventExists(eventDesc.name);
  31835. if (eventExists) {
  31836. this.eventDescriptionPool[eventDesc.name] = eventDesc;
  31837. }
  31838. else {
  31839. return false;
  31840. }
  31841. return true;
  31842. },
  31843. setEvents:function(eventDescDatas){
  31844. var rc = true;
  31845. for (var i=0;i<eventDescDatas.length;i++){
  31846. var anEvent = eventDescDatas[i];
  31847. var result = this.createEvent(anEvent);
  31848. result = result || false;
  31849. if (result === false) {
  31850. result = this.updateEvent(anEvent);
  31851. }
  31852. result = result ||false;
  31853. if (rc === true) {
  31854. rc = result;
  31855. }
  31856. }
  31857. return rc;
  31858. },
  31859. getEvents: function(condition) {
  31860. //return an array of iEventDescription ( by reference)
  31861. //return null if no events is found
  31862. if (typeof condition == "undefined" || condition === null) {
  31863. return this._getEventsInArray(this.eventDescriptionPool);
  31864. }
  31865. //check any events from previous session
  31866. var array = [];
  31867. if (condition.isHandled && condition.isHandled == "true") {
  31868. //check if we have any events in the wrapper array
  31869. //backward compatibility
  31870. if (this.wrapper.handledEvents) {
  31871. this._addEvents(array, this.wrapper.handledEvents);
  31872. }
  31873. }
  31874. if (condition.isPublished && condition.isPublished == "true") {
  31875. //check if we have any events in the wrapper array
  31876. //backward compatibility
  31877. if (this.wrapper.publishedEvents) {
  31878. this._addEvents(array, this.wrapper.publishedEvents);
  31879. }
  31880. }
  31881. if (dojo.isString(condition)) {
  31882. try {
  31883. condition = dojo.fromJson(condition);
  31884. }
  31885. catch (e) {
  31886. return null; // invalid condition
  31887. }
  31888. }
  31889. for (var j in this.eventDescriptionPool) {
  31890. if (Object.prototype.hasOwnProperty.call(this.eventDescriptionPool,j)) {
  31891. var eventDesc = this.eventDescriptionPool[j];
  31892. var rc = com.ibm.mashups.enabler.utils.EventModelHelper.checkMatch(eventDesc._getInternalJsonObj(), condition);
  31893. if (rc) {
  31894. array.push(eventDesc);
  31895. }
  31896. }
  31897. }
  31898. if (array.length === 0) {
  31899. return null;
  31900. }
  31901. else {
  31902. return array;
  31903. }
  31904. },
  31905. /*turn associative array into real array, return null if empty*/
  31906. _getEventsInArray: function(arr) {
  31907. var returnArr = [];
  31908. for (var j in arr) {
  31909. if (Object.prototype.hasOwnProperty.call(arr,j)) {
  31910. returnArr.push(arr[j]);
  31911. }
  31912. }
  31913. if (returnArr.length === 0) {
  31914. return null;
  31915. }
  31916. else {
  31917. return returnArr;
  31918. }
  31919. },
  31920. _addEvents: function(arr, associativeArr) {
  31921. for (var i in associativeArr) {
  31922. if (Object.prototype.hasOwnProperty.call(associativeArr,i)) {
  31923. var eventDescArr = associativeArr[i];
  31924. for (var j in eventDescArr) {
  31925. if (Object.prototype.hasOwnProperty.call(eventDescArr,j)) {
  31926. arr.push(eventDescArr[j]);
  31927. }
  31928. }
  31929. }
  31930. }
  31931. }
  31932. });
  31933. }
  31934. if(!dojo._hasResource["com.ibm.mm.iwidget.model.DOMEventModelFactoryImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  31935. dojo._hasResource["com.ibm.mm.iwidget.model.DOMEventModelFactoryImpl"] = true;
  31936. dojo.provide("com.ibm.mm.iwidget.model.DOMEventModelFactoryImpl");
  31937. // TODO
  31938. dojo.declare("com.ibm.mm.iwidget.model.DOMEventModelFactoryImpl", com.ibm.mashups.iwidget.model.EventModelFactory, {
  31939. constructor: function() {
  31940. this.modes = ["DOM"]; //just make it consistent with other model like attributes model
  31941. },
  31942. createEventModel: function(widgetWrapper, persistenceMode) {
  31943. return new com.ibm.mm.iwidget.model.DOMEventModelImpl(widgetWrapper);
  31944. },
  31945. getSupportedPersistenceMode: function() {
  31946. return this.modes;
  31947. }
  31948. });
  31949. }
  31950. if(!dojo._hasResource["com.ibm.mm.iwidget.services.WidgetEventModelFactoryServiceImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  31951. dojo._hasResource["com.ibm.mm.iwidget.services.WidgetEventModelFactoryServiceImpl"] = true;
  31952. dojo.provide("com.ibm.mm.iwidget.services.WidgetEventModelFactoryServiceImpl");
  31953. /*
  31954. * This is injected on the fly and not fetched through an API. Therefore we need to define the @ibm-module so that the build process is picking it up
  31955. * @ibm-module iWidget
  31956. */
  31957. // inject this service into the ServiceManager at the end. Therefore we have to require the implementation
  31958. dojo.declare("com.ibm.mm.iwidget.services.WidgetEventModelFactoryServiceImpl", com.ibm.mashups.iwidget.services.WidgetEventModelFactoryService, {
  31959. constructor: function() {
  31960. this._factories = {};
  31961. },
  31962. // returns a deferred
  31963. createEventModel: function(widgetWrapper, contextAndCallback) {
  31964. if (contextAndCallback) {
  31965. // register callback
  31966. com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.iwidget.services.ContainerService.SERVICE_NAME).registerOnChangeListener(com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_EVENTS, contextAndCallback);
  31967. }
  31968. return new com.ibm.mm.enabler.DeferredImpl(this, function(dfr, sync){
  31969. var wID = widgetWrapper.id;
  31970. var persistenceMode = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.iwidget.services.ContainerService.SERVICE_NAME).getPersistenceMode(com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_EVENTS);
  31971. var widgetDomNode = widgetWrapper.rootElement;
  31972. if (dojo.hasClass(widgetDomNode, com.ibm.mm.iwidget.services.WidgetEventModelFactoryServiceImpl.STANDALONE_CLASS) || !persistenceMode) {
  31973. persistenceMode = com.ibm.mm.iwidget.services.WidgetEventModelFactoryServiceImpl.DEFAULT_PERSISTENCE;
  31974. }
  31975. var retVal;
  31976. if (typeof persistenceMode !== "undefined" && persistenceMode == com.ibm.mashups.enabler.widget.Constants.PERSISTENCE_MODE_MODEL) {
  31977. var widgetModel = com.ibm.mashups.enabler.widget.Factory.getWidgetModel();
  31978. var navStateModel = com.ibm.mashups.enabler.model.state.NavigationStateModelFactory.getNavigationStateModel();
  31979. var spaceAccessor = com.ibm.mashups.enabler.model.state.AccessorFactory.getSpaceAccessor(navStateModel);
  31980. var currentSpaceID = spaceAccessor.getSpaceID();
  31981. var pageAccessor = com.ibm.mashups.enabler.model.state.AccessorFactory.getPageAccessor(navStateModel, currentSpaceID);
  31982. var currentPageID = pageAccessor.getPageID();
  31983. var modelID = com.ibm.mm.iwidget.Utils.getModelID(wID);
  31984. var deferred = widgetModel.findWidgetWindow(modelID, currentPageID);
  31985. deferred.setFinishedCallback(dojo.hitch(this, function(wnd, status){
  31986. if (!wnd) {
  31987. persistenceMode = com.ibm.mm.iwidget.services.WidgetEventModelFactoryServiceImpl.DEFAULT_PERSISTENCE;
  31988. if (dojo.isFunction(widgetWrapper._getResourceBundle)) {
  31989. widgetWrapper._getResourceBundle();
  31990. }
  31991. }
  31992. if (!(persistenceMode in this._factories)) {
  31993. retVal = null;
  31994. }
  31995. else {
  31996. retVal = this._factories[persistenceMode].createEventModel(widgetWrapper, persistenceMode);
  31997. }
  31998. dfr.finish(retVal, status);
  31999. }));
  32000. deferred.start(sync);
  32001. }
  32002. else {
  32003. if (!retVal) {
  32004. if (!(persistenceMode in this._factories)) {
  32005. retVal = null;
  32006. }
  32007. else {
  32008. retVal = this._factories[persistenceMode].createEventModel(widgetWrapper, persistenceMode);
  32009. }
  32010. }
  32011. dfr.finish(retVal, 200);
  32012. }
  32013. return retVal;
  32014. });
  32015. },
  32016. setFactory: function(persistenceMode, factory) {
  32017. this._factories[persistenceMode] = factory;
  32018. },
  32019. removeFactory: function(persistenceMode) {
  32020. if (persistenceMode in this._factories) {
  32021. delete this._factories[persistenceMode];
  32022. }
  32023. }
  32024. });
  32025. com.ibm.mm.iwidget.services.WidgetEventModelFactoryServiceImpl.DEFAULT_PERSISTENCE = com.ibm.mashups.enabler.widget.Constants.PERSISTENCE_MODE_DOM;
  32026. com.ibm.mm.iwidget.services.WidgetEventModelFactoryServiceImpl.STANDALONE_CLASS = com.ibm.mm.iwidget.Constants.CSSCLASS_PREFIXED_INSTANCE.iwStandalone;
  32027. com.ibm.mashups.services.ServiceManager.setService(com.ibm.mashups.iwidget.services.WidgetEventModelFactoryService.SERVICE_NAME, new com.ibm.mm.iwidget.services.WidgetEventModelFactoryServiceImpl());
  32028. com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.iwidget.services.WidgetEventModelFactoryService.SERVICE_NAME).setFactory(com.ibm.mashups.enabler.widget.Constants.PERSISTENCE_MODE_DOM, new com.ibm.mm.iwidget.model.DOMEventModelFactoryImpl());
  32029. }
  32030. if(!dojo._hasResource["com.ibm.mashups.iwidget.itemset.ShareableItemSet"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  32031. dojo._hasResource["com.ibm.mashups.iwidget.itemset.ShareableItemSet"] = true;
  32032. dojo.provide("com.ibm.mashups.iwidget.itemset.ShareableItemSet");
  32033. /**
  32034. * Interface to a simple abstraction of a datamodel which is shared across different components.
  32035. * @ibm-api
  32036. * @ibm-module iWidget
  32037. */
  32038. dojo.declare("com.ibm.mashups.iwidget.itemset.ShareableItemSet", null, {
  32039. /**
  32040. @private
  32041. */
  32042. constructor: function() {
  32043. },
  32044. /**
  32045. This method sets an item within the ShareableItemSet, creates or replaces an existing entry as needed.
  32046. To add an additional value to any existing item, suggest to get the current value of this item and append
  32047. the new value to the list and supply the result to this method.
  32048. @param{String}itemName name of the item. Must never be <code>null</code>.
  32049. @param{String}value value of the item. Must never be <code>null</code>.
  32050. @return{com.ibm.mashups.iwidget.itemset.ShareableItemSet} return an handle of ShareableItemSet upon successful, <code>null</code> upon failure.
  32051. */
  32052. setItemValue: function( /*String*/itemName, /*String*/ value) {
  32053. return this;
  32054. },
  32055. /**
  32056. This method returns the value for the named item from the set.
  32057. @param{String}itemName name of the item. Must never be <code>null</code>.
  32058. @return{String} return the named item for the set, <code>null</code> upon failure.
  32059. */
  32060. getItemValue: function( /*String*/itemName) {
  32061. return null;
  32062. },
  32063. /**
  32064. This method returns an array of Strings, providing the name of each item.
  32065. @return{String[]} return an array of items names and return <code>null</code> if the set contains no item
  32066. */
  32067. getAllNames: function() {
  32068. return null;
  32069. },
  32070. /**
  32071. Removes the named item from the set.
  32072. @param{String}itemName name of the item that needs to be removed. Must never be <code>null</code>.
  32073. @return{com.ibm.mashups.iwidget.itemset.ShareableItemSet} return the handle to the ShareableItemSet upon successful, <code>null</code> upon failure.
  32074. */
  32075. removeItem: function(/*String*/itemName) {
  32076. return null;
  32077. },
  32078. /**
  32079. This funtions commits all the changes that's applied to ShareableItemSet. Any udpates should be distributed to client side components that has registered listener on this ShareableItemSet.
  32080. @type void
  32081. */
  32082. commit: function() {
  32083. return null;
  32084. },
  32085. /**
  32086. This function adds listener to this ShareableItemSet. So it will gets notified when this ShareableItemSet is updated.
  32087. @param{Function}listener js function that should already be properly scoped. Must never be <code>null</code>.
  32088. @return{String} return listener id if listener is registered successfully, return null if it's not.
  32089. */
  32090. addListener: function(/*Function*/listener) {
  32091. return null;
  32092. },
  32093. /**
  32094. This function removes the listener from this ShareableItemSet.
  32095. @param{String}listenerId listener id that's returned by the system when listener is added. Must never be <code>null</code>.
  32096. @return{Boolean} return true if listener is removed successfully.
  32097. */
  32098. removeListener: function(/*String*/listenerId) {
  32099. return true;
  32100. } //return true if listener is removed successfully
  32101. });
  32102. }
  32103. if(!dojo._hasResource["com.ibm.mm.iwidget.itemset.ShareableItemSetImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  32104. dojo._hasResource["com.ibm.mm.iwidget.itemset.ShareableItemSetImpl"] = true;
  32105. dojo.provide("com.ibm.mm.iwidget.itemset.ShareableItemSetImpl");
  32106. dojo.declare("com.ibm.mm.iwidget.itemset.ShareableItemSetImpl", com.ibm.mashups.iwidget.itemset.ShareableItemSet, {
  32107. constructor: function(parent, defData, name) {
  32108. //items needs to be key/value pair
  32109. this.DELETE_TOKEN = "DELETE_TOKEN";
  32110. this.parent = parent;
  32111. /* def is a json object. other localized syntax can be ignored here
  32112. * { id:localId,
  32113. * alias:alias,//optional
  32114. * isPrivate:false,
  32115. * items:{
  32116. * <id>:{id:<id>,alias:<alias>},
  32117. * <id>:{id:<id>,alias:<alias>}
  32118. * }
  32119. * }
  32120. */
  32121. if (name) {
  32122. this.id = name; //localId for new ShareableItemSet
  32123. }
  32124. if (defData) {
  32125. this.id = defData.id;
  32126. this.alias = defData.alias ? defData.alias : null;
  32127. this.defData = defData; //save the reference to the data in widgetDef
  32128. }
  32129. this.mapping = {}; //name-id mapping globalid-id
  32130. this.items = {};//id-value mapping {id:<id>,globalid:<globalid>,value:<value>}
  32131. if (defData) {
  32132. var _items = defData.items;
  32133. for (var i in _items) {
  32134. if (Object.prototype.hasOwnProperty.call(_items, i)) {
  32135. var id = i;
  32136. var alias = _items[i].alias ? _items[i].alias : null;
  32137. this.items[i] = {
  32138. id: id
  32139. };
  32140. if (alias) {
  32141. this.mapping[alias] = id;
  32142. this.items[i].alias = alias;
  32143. }
  32144. }
  32145. }
  32146. }
  32147. this.navigationStateModel = com.ibm.mashups.enabler.model.state.NavigationStateModelFactory.getNavigationStateModel();
  32148. var psid = this.alias;
  32149. if (!psid) {
  32150. psid = this.id;
  32151. }
  32152. this.shareableAccessor = com.ibm.mashups.enabler.model.state.AccessorFactory.getShareableParameterSetAccessor(this.navigationStateModel, psid, "global");
  32153. this._isDirty = false;
  32154. },
  32155. addListener: function(/*obj*/fn) {
  32156. var id = this.alias;
  32157. if (!id) {
  32158. id = this.id;
  32159. }
  32160. var me = this;
  32161. var listener = function(payload) {
  32162. //in future, we could apply filter here if necessary, right now, we always distribute event as is
  32163. //wrap up as iEvent
  32164. if (me._isSender) {
  32165. return;
  32166. }
  32167. //resolve qname into local mapping
  32168. var changes = payload.changes ? payload.changes : null;
  32169. if (changes) {
  32170. for (var i = 0; i < changes.length; i++) {
  32171. var alias = changes[i].alias; //this is globalid
  32172. if (me.mapping) {
  32173. if (me.mapping[alias]) {
  32174. var localId = me.mapping[alias];
  32175. changes[i].id = localId;
  32176. }
  32177. }
  32178. }
  32179. }
  32180. if (changes.length > 0) {
  32181. var iEvent = new com.ibm.mm.iwidget.IEventImpl("onItemSetChanged", null, payload);
  32182. if (dojo.isString(fn)) {
  32183. var scope = me.parent._getHandlerScope(fn);
  32184. if (scope) {
  32185. fn = dojo.hitch(scope, fn);
  32186. }
  32187. }
  32188. fn(iEvent);
  32189. }
  32190. };
  32191. var listenerId = this.shareableAccessor.registerListener(listener);
  32192. return listenerId;
  32193. },
  32194. removeListener: function(/*String*/listenerId) {
  32195. return this.shareableAccessor.removeListener(listenerId);
  32196. },
  32197. setItemValue: function( /*String*/itemName, /*String*/ value) {
  32198. if (!itemName) {
  32199. return null;
  32200. }
  32201. if (!value) {
  32202. return null;
  32203. }
  32204. if (typeof(this._isDirty) != "undefined" && !this._isDirty) {
  32205. this._isDirty = true;
  32206. this._changedItems = {};
  32207. }
  32208. var alias = this._resolveMapping(itemName); //localId
  32209. if (!alias) {
  32210. alias = itemName;
  32211. }
  32212. this._changedItems = this._changedItems ? this._changedItems : {};
  32213. this._changedItems[alias] = value;
  32214. return this;
  32215. },
  32216. getItemValue: function( /*String*/itemName) {
  32217. var id = this._resolveMapping(itemName);
  32218. if (!id) {
  32219. id = itemName;
  32220. }
  32221. if (this._isDirty && this._changedItems) {
  32222. if (this._changedItems[id] && this._changedItems[id] != this.DELETE_TOKEN) {
  32223. return this._changedItems[id];
  32224. } else if (this._changedItems[id] && this._changedItems[id] == this.DELETE_TOKEN) {
  32225. return null;
  32226. }
  32227. }
  32228. //call navstate api to get value
  32229. var itemSetId = this.alias;
  32230. if (!itemSetId) {
  32231. itemSetId = this.id;
  32232. }
  32233. var value = this.shareableAccessor.getItemValue(id);
  32234. if (!value) {
  32235. value = null;
  32236. }
  32237. return value;
  32238. },
  32239. getAllNames: function() {
  32240. var itemSetId = this.alias;
  32241. if (!itemSetId) {
  32242. itemSetId = this.id;
  32243. }
  32244. var names = this.shareableAccessor.getAllNames();
  32245. if (this._isDirty) {
  32246. var obj = {};
  32247. for (var i = 0; i < names.length; i++) {
  32248. var aName = names[i];
  32249. obj[aName] = aName; //globalids
  32250. }
  32251. if (this._changedItems) {
  32252. for (var j in this._changedItems) {
  32253. if (this._changedItems[j] && this._changedItems[j] == this.DELETE_TOKEN && obj[j]) {
  32254. obj[j] = null;
  32255. } else if (this._changedItems[j] && !obj[j]) {
  32256. obj[j] = j; //globalids
  32257. }
  32258. }
  32259. }
  32260. var arr = [];
  32261. for (var k in obj) {
  32262. if (Object.prototype.hasOwnProperty.call(obj, k)) {
  32263. arr.push(k);
  32264. }
  32265. }
  32266. names = arr;
  32267. }
  32268. for (var s = 0; s < names.length; s++) {
  32269. var id = names[s];//globalid
  32270. if (this.mapping[id]) {
  32271. names[s] = this.mapping[id]; //replace with local id if available
  32272. }
  32273. }
  32274. if (names.length === 0) {
  32275. return null;
  32276. }
  32277. return names;
  32278. },
  32279. removeItem: function(/*String*/itemName) {
  32280. if (typeof(this._isDirty) != "undefined" && !this._isDirty) {
  32281. this._isDirty = true;
  32282. this._changedItems = {};
  32283. }
  32284. var names = this.getAllNames();
  32285. if (names === null) {
  32286. return null;
  32287. }
  32288. var contains = false;
  32289. for (var i = 0; i < names.length; i++) {
  32290. if (names[i] == itemName) {
  32291. contains = true;
  32292. }
  32293. }
  32294. if (!contains) {
  32295. return null; //item doesn't exist
  32296. }
  32297. var id = this._resolveMapping(itemName);
  32298. if (!id) {
  32299. id = itemName;
  32300. }
  32301. this._changedItems = this._changedItems ? this._changedItems : {};
  32302. this._changedItems[id] = this.DELETE_TOKEN;
  32303. return this;
  32304. },
  32305. getItemSetDescription: function() {
  32306. return null;
  32307. },
  32308. commit: function() {
  32309. //call navstate api to send _changedItems to navigation state
  32310. if (this._isDirty) {
  32311. this._isSender = true; //synchronous code below
  32312. var itemSetId = this.alias;
  32313. if (!itemSetId) {
  32314. itemSetId = this.id;
  32315. }
  32316. this.shareableAccessor._setItems(this._changedItems);
  32317. var deferred = this.navigationStateModel.commit(); //commit the data distribution or this will trigger data persistence to url
  32318. deferred.start();
  32319. this._isSender = false;
  32320. }
  32321. this._changedItems = null;
  32322. this._isDirty = false;
  32323. },
  32324. _resolveMapping: function(name) {
  32325. if (!name) {
  32326. return null;
  32327. }
  32328. if (!this.items) {
  32329. return null;
  32330. }
  32331. if (this.items[name] && this.items[name].alias) {
  32332. return this.items[name].alias;
  32333. }
  32334. return null;
  32335. }
  32336. });
  32337. com.ibm.mm.iwidget.itemset.ShareableItemSetFactory = com.ibm.mm.iwidget.itemset.ShareableItemSetImpl;
  32338. // IMPORTANT
  32339. // ibmConfig.enablerLayerModules is a comma separated string of all supported modules at runtime
  32340. // This section dynamically loads the Extended representation when the variable enablerLayerModules contains the given module
  32341. if ((ibmConfig.enablerLayerModules) && (dojo.indexOf(ibmConfig.enablerLayerModules, "CoreModel") >= 0)) {
  32342. dojo["require"]("com.ibm.mm.iwidget.itemset.ShareableItemSetExtendedModelImpl"); // JSLINT-IGNORE: This needs to be done to allow modularization and to support the minimal layer
  32343. }
  32344. }
  32345. if(!dojo._hasResource["com.ibm.mm.iwidget.DeferredLiveTextUnprocessImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  32346. dojo._hasResource["com.ibm.mm.iwidget.DeferredLiveTextUnprocessImpl"] = true;
  32347. dojo.provide("com.ibm.mm.iwidget.DeferredLiveTextUnprocessImpl");
  32348. dojo.declare("com.ibm.mm.iwidget.DeferredLiveTextUnprocessImpl", com.ibm.mm.enabler.DeferredImpl, {
  32349. constructor: function(wrapper) {
  32350. this.wrapper = wrapper;
  32351. },
  32352. start: function(sync) {
  32353. // defaults to false
  32354. if (sync) {
  32355. return;
  32356. }
  32357. var widgetInstance = this.wrapper.getIWidgetInstance();
  32358. if (dojo.isFunction(this.wrapper.iScope._onGetMarkup)) {
  32359. this.wrapper.iScope._onGetMarkup();
  32360. }
  32361. var tempMarkup = dojo.clone(this.wrapper.rootElement);
  32362. dojo.publish("/com/ibm/mashups/livetext/livetextunchange", [tempMarkup, true, null, null, dojo.hitch(this, this._unchangeCompleteCallback), this.includeParent]);
  32363. },
  32364. setIncludeParent: function(value) {
  32365. this.includeParent = value;
  32366. },
  32367. getIncludeParent: function() {
  32368. return this.includeParent;
  32369. },
  32370. _unchangeCompleteCallback: function(node) {
  32371. if (dojo.isFunction(this.getFinishedCallback())) {
  32372. this.finish(node, 200);
  32373. }
  32374. }
  32375. });
  32376. }
  32377. if(!dojo._hasResource["com.ibm.mm.iwidget.widget.IWidgetWrapperExtendedImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  32378. dojo._hasResource["com.ibm.mm.iwidget.widget.IWidgetWrapperExtendedImpl"] = true;
  32379. dojo.provide("com.ibm.mm.iwidget.widget.IWidgetWrapperExtendedImpl");
  32380. /*
  32381. * This is injected on the fly and not fetched through an API. Therefore we need to define the @ibm-module so that the build process is picking it up
  32382. * @ibm-module iWidget
  32383. *
  32384. * This value defines the order in which the packages should be printed out into the dojo profile. Default is 100.
  32385. * Any number that is smaller causes this class to be written out before any other with a higher number
  32386. * @ibm-dojo-profile-level 40
  32387. */
  32388. // TODO remove the following four requires as soon as the meta packages have been modularized
  32389. //dojo.require("com.ibm.mm.iwidget.model.eventmodel");
  32390. // END TODO
  32391. //dojo.require("com.ibm.mm.iwidget.model.EventModelImpl");
  32392. dojo.declare("com.ibm.mm.iwidget.widget.IWidgetWrapperExtendedImpl", com.ibm.mm.iwidget.widget.IWidgetWrapperDefaultImpl, {
  32393. getMarkup: function() {
  32394. return new com.ibm.mm.iwidget.DeferredLiveTextUnprocessImpl(this);
  32395. },
  32396. destroy: function() {
  32397. if (this.widgetDef) {
  32398. var itemsets = this.widgetDef._getShareableItemSets();
  32399. if (itemsets) {
  32400. var anItemSet = null;
  32401. for (var i in itemsets) {
  32402. if (Object.prototype.hasOwnProperty.call(itemsets, i)) {
  32403. // add default listener if there's any
  32404. if (this.shareableItemSets.listeners[i]) {
  32405. for (var j = 0, l = this.shareableItemSets.listeners[i].length; j < l; ++j) {
  32406. var listenerID = this.shareableItemSets.listeners[i][j];
  32407. anItemSet = this.shareableItemSets.itemsets[i];
  32408. anItemSet.removeListener(listenerID);
  32409. }
  32410. }
  32411. }
  32412. }
  32413. }
  32414. }
  32415. this.inherited(arguments);
  32416. // perform the unregistration
  32417. for (var m = 0, total = this.unregisterArray.length; m < total; m++) {
  32418. dojo.unsubscribe(this.unregisterArray[m]);
  32419. }
  32420. },
  32421. _getResourceBundle: function() {
  32422. if (!this.iwMessages) {
  32423. this.iwMessages = dojo.i18n.getLocalization("com.ibm.mm.enabler", "iwMessages");
  32424. }
  32425. return this.iwMessages;
  32426. },
  32427. _logUpdateMarkupError: function(mode) {
  32428. this._getResourceBundle();
  32429. var error = dojo.string.substitute(this.iwMessages.E_IWIDGETDEF_CONTENTNOTAVAILABLE_1, [mode]);
  32430. },
  32431. _loadWidgetSharedResource: function(cb2) {
  32432. var resources = this.widgetDef.getResources();
  32433. this._getResourceBundle();
  32434. if (typeof resources != "undefined" && resources !== null) {
  32435. var size = resources.length - 1;
  32436. if (size == -1) {
  32437. cb2();
  32438. }
  32439. // css and images must be grouped together for multipart support
  32440. // js must be loaded first since css callback may have dependency js files
  32441. var sortedResources = [];
  32442. var temp = [];
  32443. for (var x in resources) {
  32444. if (Object.prototype.hasOwnProperty.call(resources, x)) {
  32445. var resource = resources[x];
  32446. if (resource.isImage() || resource.isCSS()) {
  32447. // sortedResources.unshift(resource);//add to beginning of array
  32448. temp.push(resource);
  32449. }
  32450. else {
  32451. sortedResources.push(resource); //we still need the order to js resources
  32452. }
  32453. }
  32454. }
  32455. for (var y = 0; y < temp.length; y++) {
  32456. sortedResources.push(temp[y]);
  32457. }
  32458. var me = this;
  32459. var mycb = function(i, resourceData, data, status) {
  32460. if (data && status && resourceData.isJS()) {
  32461. me.error = "true";
  32462. if (!me.data) {
  32463. me.data = [];
  32464. }
  32465. var msg = dojo.string.substitute(me.iwMessages.E_RESOURCE_LOAD_FAIL_2, [resourceData.src, data.message]);
  32466. me.data.push({
  32467. data: msg,
  32468. status: status
  32469. });
  32470. }
  32471. if (size == i) {
  32472. if (me.error && me.error == "true") {
  32473. dojo.query("> ." + me.ns + "loading", me.rootElement).forEach(function(elem) {
  32474. elem.innerHTML = "";
  32475. var wTitle = me.getIWidgetInstance().getIDescriptorItems().getItemValue("title", dojo.locale);
  32476. if (!wTitle) {
  32477. wTitle = "'"+me.getIWidgetInstance().widgetXMLUrl+"'";
  32478. }
  32479. else {
  32480. wTitle = "'"+unescape(wTitle)+"'";
  32481. }
  32482. if (me.widgetDef) {
  32483. var _id = me.widgetDef.getWidgetId();
  32484. if (_id) {
  32485. wTitle = "'"+_id+"' (" + wTitle + ")";
  32486. }
  32487. }
  32488. var message = "";
  32489. var _data = (dojo.isArray(me.data))?me.data[0]:me.data;
  32490. message = "";
  32491. for (var j in _data) {
  32492. if (Object.prototype.hasOwnProperty.call(_data, j)) {
  32493. if (j=="data") { // we only copy the details
  32494. message = message.concat("'"+_data[j]+"'").concat("\n");
  32495. }
  32496. }
  32497. }
  32498. });
  32499. me.error = null;
  32500. me.data = null;
  32501. }
  32502. else {
  32503. if (cb2) {
  32504. cb2(); //iContext blockInit for all the resources rather than support blockInit
  32505. }
  32506. }
  32507. }
  32508. };
  32509. for (var i = 0; i < sortedResources.length; i++) {
  32510. var resourceData = sortedResources[i];
  32511. if (typeof resourceData != "undefined" && resourceData !== null) {
  32512. com.ibm.mashups.services.ServiceManager.getService("resourceLoadService").loadResource(resourceData, this.id, dojo.partial(mycb, i, resourceData));
  32513. }
  32514. }
  32515. }
  32516. },
  32517. handleEvent: function(payload) {
  32518. //event handler that subscribes to event handler
  32519. var declaredClass = payload.declaredClass;
  32520. if (typeof declaredClass != "undefined" && declaredClass !== null && declaredClass == "com.ibm.mm.iwidget.IEventImpl") {
  32521. var eventName = payload.name;
  32522. return this._handleEvent(eventName, payload);
  32523. }
  32524. //if it's a payload other than iEvent --used for internal communication between wrapper and wrapper stub
  32525. //for example: _getMarkup(includeParent);
  32526. var scope = payload.scope;
  32527. if (typeof scope != "undefined" && scope !== null) {
  32528. if (scope == "instance") {
  32529. scope = this.getIWidgetInstance();
  32530. }
  32531. else if (scope == "eventmodel") {
  32532. scope = this._getPublicEvents();
  32533. }
  32534. }
  32535. else {
  32536. scope = this;
  32537. }
  32538. var methodname = payload.methodname;
  32539. if (typeof methodname != "undefined" && methodname !== null) {
  32540. if (scope[methodname] && dojo.isFunction(scope[methodname])) {
  32541. scope[methodname].apply(scope, payload.params);
  32542. }
  32543. }
  32544. },
  32545. _handleEvent: function(eventName, iEvent) {
  32546. iEvent = this._deserializePayload(iEvent);
  32547. //check here. it's just one payload with {eventName,iEvent}
  32548. if (typeof eventName == "undefined" || eventName === null) {
  32549. return false;
  32550. }
  32551. if (!this.loaded) {
  32552. if (!this._eventqueue) {
  32553. this._eventqueue = {};
  32554. }
  32555. this._eventqueue[eventName] = iEvent;
  32556. return;
  32557. }
  32558. //handle onModeChanged event
  32559. try {
  32560. if (eventName == iwConstants.EVENTS.onNavStateChanged) {
  32561. return this._handleOnNavStateChanged(iEvent);
  32562. }
  32563. if (eventName == iwConstants.EVENTS.onWindowStateChanged) {
  32564. //update widget and pass event to widget
  32565. var navStateModel = com.ibm.mashups.enabler.model.state.NavigationStateModelFactory.getNavigationStateModel();
  32566. var accessor = com.ibm.mashups.enabler.model.state.AccessorFactory.getWidgetAccessor(navStateModel, this.id);
  32567. var value = iEvent.payload.newWindowState;
  32568. accessor.setWindowState(value);
  32569. var widgetBox = dojo.contentBox(this.rootElement.parentNode); // .lotusWidgetBody
  32570. this.handleSizeChanged({"newWidth":Math.max(0, widgetBox.w), "newHeight":Math.max(0, widgetBox.h)});
  32571. return this._handleEventInternal(eventName, iEvent);
  32572. }
  32573. if (eventName == iwConstants.EVENTS.onModeChanged) {
  32574. if (this._inIframe()) {
  32575. //publish event to stub widget
  32576. var payloadObj = {};
  32577. payloadObj.methodname = "_handleOnModeChange";
  32578. payloadObj.hubclient = this.hubId;
  32579. payloadObj.params = [iEvent.payload];
  32580. //var id = "_stub_"+this.id.slice(0,this.id.lastIndexOf("_"));
  32581. var id = "_stub_" + this.id;
  32582. this.eventSvr._publishEvent(iwConstants.WIDGETEVENT_PREFIX + id, payloadObj, this.hubId);
  32583. return;
  32584. }
  32585. return this._handleModeChange(iEvent);
  32586. }
  32587. if (eventName == "onNewWire") {
  32588. return this._handleNewWire(iEvent);
  32589. }
  32590. if (eventName == "onRemoveWire") {
  32591. return this._handleRemoveWire(iEvent);
  32592. }
  32593. return this._handleEventInternal(eventName, iEvent);
  32594. }
  32595. catch (e) {
  32596. }
  32597. },
  32598. getPublicEventHandler: function(/*String|Function*/eventName) {
  32599. //var eventDesc = this._getHandledEvents()[eventName];
  32600. var eventModel = this._getPublicEvents() || null;
  32601. if (!eventModel) {
  32602. return null;
  32603. }
  32604. var eventDesc = eventModel.find(eventName) || null;
  32605. if (!eventDesc) {
  32606. return null;
  32607. }
  32608. var handlerFn = eventDesc.handlingFn || null;
  32609. if (!handlerFn) {
  32610. var isComplete = eventDesc.getAttribute("isComplete");
  32611. if (typeof isComplete !== "undefined" && isComplete === false) {
  32612. //distribute an iEvent to widget
  32613. var eventName1 = iwConstants.EVENTS.onIncompleteEventDescription;
  32614. var payload = {
  32615. eventDescription: eventDesc
  32616. };
  32617. var iEvent = new com.ibm.mm.iwidget.IEventImpl(eventName1, null, payload);//json format
  32618. this._handleEventInternal(eventName1, iEvent);
  32619. eventDesc = eventModel.find(eventName);
  32620. handlerFn = eventDesc.handlingFn;
  32621. }
  32622. }
  32623. var handlerObj = null;
  32624. if (handlerFn) {
  32625. if (dojo.isFunction(handlerFn)) {
  32626. handlerObj = handlerFn;
  32627. }
  32628. else {
  32629. var scope = this._getHandlerScope(handlerFn) || null;
  32630. if (scope) {
  32631. handlerObj = dojo.hitch(scope, handlerFn);
  32632. }
  32633. }
  32634. }
  32635. return handlerObj;
  32636. },
  32637. getPublishedEvents: function() {
  32638. //backwardcompatibility
  32639. if (!this.publishedEvents) {
  32640. this.publishedEvents = {};
  32641. }
  32642. return this.publishedEvents;
  32643. },
  32644. getHandledEvents: function() {
  32645. //backwardcompatibility
  32646. if (!this.handledEvents) {
  32647. this.handledEvents = {};
  32648. }
  32649. return this.handledEvents;
  32650. },
  32651. _inIframe: function() {
  32652. if (this._isInIframe) {
  32653. return this._isInIframe;
  32654. }
  32655. var inIframe = false;
  32656. var type = this.eventSvr.getType();
  32657. if (typeof type != "undefined" && type == com.ibm.mm.iwidget.Constants.eventservice.type.IFRAME) {
  32658. inIframe = true;
  32659. }
  32660. this._isInIframe = inIframe;
  32661. return this._isInIframe;
  32662. },
  32663. setMainframeId: function(mainframeId) {
  32664. this._mainframeId = mainframeId;
  32665. },
  32666. setModal: function(isModal) {
  32667. this._isModal = isModal;
  32668. },
  32669. isModal: function() {
  32670. //indicate if this is an iframe rendered in a modal dialog
  32671. return this._isModal ? this._isModal : false;
  32672. },
  32673. _handleDataSync: function(payload) {
  32674. //for now it's just attributes
  32675. //any sub window may have changed data these updates need to be sent to stub widget
  32676. if (typeof payload.attributes != "undefined" && payload.attributes !== null) {
  32677. var attributes = payload.attributes;
  32678. this._syncModifiableProperties(attributes, this.getIWidgetInstance().getAttributes());
  32679. }
  32680. if (typeof payload.idescriptors != "undefined" && payload.idescriptors !== null) {
  32681. var idescriptors = payload.idescriptors;
  32682. this._syncModifiableProperties(idescriptors, this.getIWidgetInstance().getIDescriptorItems());
  32683. }
  32684. if (typeof payload.wiremodel != "undefined" && payload.wiremodel !== null) {
  32685. var wiremodel = payload.wiremodel;
  32686. this._syncWireModel(wiremodel, this.getIWidgetInstance().getWireModel());
  32687. }
  32688. this.commit(true); //commit any data change in instance
  32689. },
  32690. _syncModifiableProperties: function(properties, instanceProperties) {
  32691. var items = properties._items;
  32692. /* for each item following json object is used
  32693. {readOnly:false,
  32694. values:{ <locale>:<value>}
  32695. }
  32696. if the whole item is removed. _items["itemname"] = deletetoken;
  32697. if only value for a particular locale is removed, _items["itemname"] [<locale>] =deletetoken;
  32698. */
  32699. if (properties._dirty) {
  32700. for (var i in items) {
  32701. if (Object.prototype.hasOwnProperty.call(items, i)) {
  32702. var name = i;
  32703. var temp = items[i];
  32704. if (dojo.isString(temp)) {
  32705. if (temp && temp == instanceProperties.DELETE_TOKEN) {
  32706. instanceProperties.removeItem(name);
  32707. }
  32708. }
  32709. else {
  32710. var readOnly = (items[i].readOnly) ? items[i].readOnly : false;
  32711. var values = items[i].values;
  32712. if (typeof values != "undefined" && values !== null) {
  32713. for (var j in values) {
  32714. if (Object.prototype.hasOwnProperty.call(values, j)) {
  32715. var value = values[j];
  32716. if (value && value == instanceProperties.DELETE_TOKEN) {
  32717. instanceProperties.removeItemValue(name, j);
  32718. }
  32719. else if (value) {
  32720. instanceProperties.setItemValue(name, value, readOnly, j);
  32721. }
  32722. }
  32723. }
  32724. }
  32725. }
  32726. }
  32727. }
  32728. }
  32729. },
  32730. _syncWireModel: function(wiremodel, instanceWireModel) {
  32731. var wires = wiremodel._wires;
  32732. for (var i in wires) {
  32733. if (Object.prototype.hasOwnProperty.call(wires, i)) {
  32734. var aWire = wires[i];
  32735. if (aWire._isDirty && aWire._type && aWire._type == "NEW") {
  32736. instanceWireModel.addWire(aWire.SourceWidget, aWire.SourceEvent, aWire.TargetEvent);
  32737. }
  32738. else if (aWire._isDirty && aWire._type && aWire._type == "DELETE") {
  32739. instanceWireModel.removeWire(aWire.SourceWidget, aWire.SourceEvent, aWire.TargetEvent);
  32740. }
  32741. }
  32742. }
  32743. var targets = wiremodel._targets;
  32744. instanceWireModel._targets = targets;//simple replacement of array.
  32745. },
  32746. setStateData: function(stateData) {
  32747. this.stateData = stateData;
  32748. //StateData includes: widgetNavigationState
  32749. },
  32750. updateState: function() {
  32751. //frameworks distribute onNavStateChanged event
  32752. //handle onNavStateChanged Event here...
  32753. //distribute onNavStateChanged event to iWidget
  32754. var iEvent;
  32755. if (!this._inIframe()) {//do this when it's not iframed
  32756. var navigationStateModel = com.ibm.mashups.enabler.model.state.NavigationStateModelFactory.getNavigationStateModel();
  32757. var widgetAccessor = com.ibm.mashups.enabler.model.state.AccessorFactory.getWidgetAccessor(navigationStateModel, this.id) || null;
  32758. if (widgetAccessor) {
  32759. var customParams = widgetAccessor.getWidgetState("cp");
  32760. if (customParams) {
  32761. //send json object to widget
  32762. iEvent = new com.ibm.mm.iwidget.IEventImpl(iwConstants.EVENTS.onNavStateChanged, "json", customParams);//json format
  32763. this._handleEventInternal(iwConstants.EVENTS.onNavStateChanged, iEvent);
  32764. }
  32765. }
  32766. }
  32767. else {
  32768. if (this.stateData) {
  32769. //find onNavStateChanged in iScope and pass data
  32770. iEvent = new com.ibm.mm.iwidget.IEventImpl(iwConstants.EVENTS.onNavStateChanged, null, this.stateData);//json format/string
  32771. this._handleEventInternal(iwConstants.EVENTS.onNavStateChanged, iEvent);
  32772. }
  32773. }
  32774. },
  32775. _handleOnNavStateChanged: function(iEvent) {
  32776. //widget fire onNavStateChanged event
  32777. if (!this._inIframe()) {
  32778. var state = iEvent.payload;
  32779. if (state) {
  32780. //call navstate api
  32781. var navigationStateModel = com.ibm.mashups.enabler.model.state.NavigationStateModelFactory.getNavigationStateModel();
  32782. var widgetAccessor = com.ibm.mashups.enabler.model.state.AccessorFactory.getWidgetAccessor(navigationStateModel, this.id);
  32783. widgetAccessor.setWidgetState("cp", state); //payload should be string
  32784. var deferred = navigationStateModel.commit();
  32785. deferred.start();
  32786. }
  32787. }
  32788. else {
  32789. var payloadObj = {};
  32790. payloadObj.methodname = "_handleOnNavStateChanged";
  32791. payloadObj.params = [iEvent];
  32792. this.eventSvr._publishEvent(this.eventSvr.WIDGETEVENT_PREFIX + "_stub_" + this.id, payloadObj);
  32793. }
  32794. },
  32795. _initialize: function(callback) {
  32796. var lang = this.widgetDef.getDefaultLanguage() || null;
  32797. if (lang) {
  32798. this.defaultLanguage = lang;
  32799. }
  32800. else {
  32801. this.defaultLanguage = "en";
  32802. }
  32803. var aMode = this._getInitDefaultMode() || null;
  32804. if (!aMode) {
  32805. aMode = iwConstants.mode_view;
  32806. }
  32807. this.currentMode = aMode;
  32808. this._handleSaveMode();
  32809. this._initManagedItemSet();
  32810. this._getShareableItemSets();
  32811. //initialize publishedEvents and handledEvents
  32812. this._getPublicEvents(dojo.hitch(this, function(publicEvents) {
  32813. //register wires
  32814. this.getWires();
  32815. if (callback) {
  32816. callback();
  32817. }
  32818. }));
  32819. },
  32820. getPublicEvent: function(name) {
  32821. var eventModel = this._getPublicEvents();
  32822. return eventModel.find(name);
  32823. },
  32824. _getPublicEvents: function(callback) {
  32825. //Initialize internal eventmodel for iWidgetWrapper, events data are loaded in event model
  32826. //An associative array is passed from widget definition to widgetwrapper
  32827. if (!this.publicEvents) {
  32828. var factory = com.ibm.mashups.services.ServiceManager.getService("WidgetEventModelFactoryService");
  32829. var dfr = factory.createEventModel(this, {context: this, callback: "_eventProviderModeChange",
  32830. unregister: function(handle) {
  32831. this.unregisterArray.push(handle);
  32832. }
  32833. });
  32834. dfr.setFinishedCallback(dojo.hitch(this, function(eventModel, status){
  32835. this.publicEvents = eventModel;
  32836. if (callback) {
  32837. callback(this.publicEvents);
  32838. }
  32839. }));
  32840. var sync = (callback)?false:true;
  32841. // Required to make dojotest run synchronously
  32842. if (ibmConfig.dojotest) {
  32843. sync = true;
  32844. }
  32845. dfr.start(sync);
  32846. }
  32847. return this.publicEvents;
  32848. },
  32849. _eventProviderModeChange: function(provider, oldMode, newMode) {
  32850. var oldEventModel = this.publicEvents;
  32851. var factory = com.ibm.mashups.services.ServiceManager.getService("WidgetEventModelFactoryService");
  32852. var dfr = factory.createEventModel(this, {context: this, callback: "_eventProviderModeChange",
  32853. unregister: function(handle) {
  32854. this.unregisterArray.push(handle);
  32855. }
  32856. });
  32857. dfr.setFinishedCallback(dojo.hitch(this, function(eventModel, status){
  32858. this.publicEvents = eventModel;
  32859. }));
  32860. dfr.start(true);
  32861. // now we need to copy all runtime information from the previous persistence layer over. e.g. handlingFunctions
  32862. var condition = {};
  32863. condition.isHandled = "true";
  32864. var oldEvents = oldEventModel.getEvents(condition);
  32865. if (oldEvents) {
  32866. for (var i=0; i < oldEvents.length; i++) {
  32867. var oldEventDesc = oldEvents[i];
  32868. var newEventDesc = this.getPublicEvent(oldEventDesc.name);
  32869. if (oldEventDesc && newEventDesc) {
  32870. newEventDesc.copyRuntimeProperties(oldEventDesc);
  32871. }
  32872. }
  32873. }
  32874. },
  32875. _getPublishedEvents: function() {
  32876. //Todo:should remove once widgetstub is removed,backward compatibility as part of queryservice
  32877. //return an associative array, with reference
  32878. var publishedEvents = this.getWidgetPublishedEvents() || null;
  32879. var arr = {};
  32880. if (publishedEvents) {
  32881. var i = 0;
  32882. for (i; i < publishedEvents.length; i++) {
  32883. arr[publishedEvents[i].name] = publishedEvents[i];
  32884. }
  32885. }
  32886. return arr;
  32887. },
  32888. _getHandledEvents: function() {
  32889. //Todo: should remove once widgetStub is removed,backward compatibility as part of queryservice
  32890. var handledEvents = this.getWidgetHandledEvents() || null;
  32891. var arr = {};
  32892. if (handledEvents) {
  32893. var i = 0;
  32894. for (i; i < handledEvents.length; i++) {
  32895. arr[handledEvents[i].name] = handledEvents[i];
  32896. }
  32897. }
  32898. return arr;
  32899. },
  32900. getWidgetPublishedEvents: function() {
  32901. //return a reference of event description for backward compatibility so it won't break the use case below
  32902. var eventModel = this._getPublicEvents();
  32903. if (eventModel) {
  32904. var condition = {};
  32905. condition.isPublished = "true";
  32906. return eventModel.getEvents(condition);
  32907. }
  32908. return null;
  32909. },
  32910. getWidgetHandledEvents: function() {
  32911. //return a reference of events array
  32912. var eventModel = this._getPublicEvents();
  32913. if (eventModel) {
  32914. var condition = {};
  32915. condition.isHandled = "true";
  32916. return eventModel.getEvents(condition);
  32917. }
  32918. return null;
  32919. },
  32920. getWires: function() {
  32921. return this.getIWidgetInstance().getWires();
  32922. },
  32923. _handleNewWire: function(iEvent) {
  32924. var payload = iEvent.payload;
  32925. //registerTargets
  32926. var wireModel = this.getIWidgetInstance().getWireModel();
  32927. wireModel.registerTargets(payload.targetWidget, payload.targetEvent, payload.sourceEvent);
  32928. this.commit(); //need to send updates to stub, if it's iframe
  32929. var eventName = payload.sourceEvent; //check if there's onNewWire defined in iEventDescription
  32930. //var event = this.publishedEvents[eventName];
  32931. var eventModel = this._getPublicEvents();
  32932. if (!eventModel) {
  32933. return false;
  32934. }
  32935. var eventDesc = eventModel.find(eventName);
  32936. //need to get original event....
  32937. if (eventDesc) {
  32938. var handler = eventDesc.getOnNewWire();
  32939. if (handler) {
  32940. var scope = this._getHandlerScope(handler);
  32941. if (scope && dojo.isFunction(scope)) {
  32942. scope(iEvent);
  32943. }
  32944. else if (scope && dojo.isObject(scope)) {
  32945. scope[handler](iEvent);
  32946. }
  32947. return true;
  32948. }
  32949. }
  32950. return false;
  32951. },
  32952. _handleRemoveWire: function(iEvent) {
  32953. var payload = iEvent.payload;
  32954. var eventName = payload.targetEvent; // check if there's onRemoveWire defined in iEventDescription
  32955. if (this.id == payload.sourceWidget) { //since it could be provided by publish event as well
  32956. eventName = payload.sourceEvent;
  32957. }
  32958. var eventModel = this._getPublicEvents() || null;
  32959. if (!eventModel) {
  32960. return false;
  32961. }
  32962. var eventDesc = eventModel.find(eventName) || null;
  32963. if (eventDesc) {
  32964. var handler = eventDesc.getOnRemoveWire();
  32965. if (handler) {
  32966. var scope = this._getHandlerScope(handler);
  32967. if (scope && dojo.isFunction(scope)) {
  32968. scope(iEvent);
  32969. }
  32970. else if (scope && dojo.isObject(scope)) {
  32971. scope[handler](iEvent);
  32972. }
  32973. return true;
  32974. }
  32975. }
  32976. return false;
  32977. },
  32978. _getShareableItemSets: function() {
  32979. if (this.shareableItemSets) {
  32980. return this.shareableItemSets;
  32981. }
  32982. this.shareableItemSets = {};
  32983. this.shareableItemSets.mapping = {};
  32984. this.shareableItemSets.itemsets = {};
  32985. this.shareableItemSets.listeners = {};
  32986. var itemsets = this.widgetDef._getShareableItemSets();
  32987. if (itemsets) {
  32988. var anItemSet = null;
  32989. for (var i in itemsets) {
  32990. if (Object.prototype.hasOwnProperty.call(itemsets, i)) {
  32991. anItemSet = new com.ibm.mm.iwidget.itemset.ShareableItemSetFactory(this, itemsets[i]);
  32992. // add default listener if there's any
  32993. var onItemSetChanged = itemsets[i].onItemSetChanged || null;
  32994. if (onItemSetChanged) {
  32995. // if there are no listeners for this itemset yet, let's add them
  32996. if (!this.shareableItemSets.listeners[i]) {
  32997. this.shareableItemSets.listeners[i] = [];
  32998. }
  32999. this.shareableItemSets.listeners[i].push(anItemSet.addListener(onItemSetChanged));
  33000. }
  33001. this.shareableItemSets.itemsets[i] = anItemSet;
  33002. //alias is optional
  33003. var alias = itemsets[i].alias || null;
  33004. if (alias) {
  33005. this.shareableItemSets.mapping[alias] = alias;
  33006. }
  33007. }
  33008. }
  33009. }
  33010. return this.shareableItemSets;
  33011. },
  33012. //it could be either local name or real id
  33013. _getShareableItemSet: function(id) {
  33014. var shareableItemSets = this._getShareableItemSets();
  33015. if (shareableItemSets && shareableItemSets.mapping[id]) { //checking alias first
  33016. var realId = shareableItemSets.mapping[id];
  33017. return shareableItemSets.itemsets[realId];
  33018. }
  33019. else if (shareableItemSets && shareableItemSets.itemsets[id]) { //check realid -- local id
  33020. return shareableItemSets.itemsets[id];
  33021. }
  33022. var itemSet = new com.ibm.mm.iwidget.itemset.ShareableItemSetFactory(this.widgetwrapper, null, name);
  33023. shareableItemSets.itemsets[id] = itemSet; //there's no global mapping
  33024. return shareableItemSets.itemsets[id];
  33025. },
  33026. _executeCallbackQueue: function() {
  33027. com.ibm.mashups.services.ServiceManager.getService("resourceLoadService").executeCallbackQueue(this.id);
  33028. },
  33029. _handleSaveMode: function() {
  33030. var navigationStateModel = com.ibm.mashups.enabler.model.state.NavigationStateModelFactory.getNavigationStateModel();
  33031. var widgetAccessor = com.ibm.mashups.enabler.model.state.AccessorFactory.getWidgetAccessor(navigationStateModel, this.id);
  33032. var oldMode = widgetAccessor.getWidgetMode();
  33033. if (oldMode != this.currentMode) {
  33034. // check special case
  33035. if (!((oldMode === null) && (this.currentMode == com.ibm.mm.iwidget.Constants.mode.VIEW))) {
  33036. widgetAccessor.setWidgetMode(this.currentMode); //payload should be string
  33037. var deferred = navigationStateModel.commit();
  33038. deferred.start();
  33039. }
  33040. }
  33041. },
  33042. _transform: function(eventName, iEvent) {
  33043. var event = this.getPublicEvent(eventName);
  33044. if (!(!event || !event.type || !iEvent.type)) {
  33045. var targetEvent = new com.ibm.mm.iwidget.IEventImpl(event.name, event.type, iEvent.payload, null);
  33046. var transformer = new com.ibm.mm.enabler.utils.EventTransformerImpl();
  33047. var newIEvent = transformer._transform(iEvent, targetEvent) || null;
  33048. if (newIEvent) {
  33049. iEvent = newIEvent;
  33050. }
  33051. }
  33052. return iEvent;
  33053. },
  33054. _getModeFromNavStateModel: function() {
  33055. var navigationStateModel = com.ibm.mashups.enabler.model.state.NavigationStateModelFactory.getNavigationStateModel();
  33056. var widgetAccessor = com.ibm.mashups.enabler.model.state.AccessorFactory.getWidgetAccessor(navigationStateModel, this.id);
  33057. return widgetAccessor.getWidgetMode();
  33058. }
  33059. });
  33060. com.ibm.mm.iwidget.widget.IWidgetWrapperImpl = com.ibm.mm.iwidget.widget.IWidgetWrapperExtendedImpl;
  33061. //IMPORTANT
  33062. //ibmConfig.enablerLayerModules is a comma separated string of all supported modules at runtime
  33063. //This section dynamically loads the Extended representation when the variable enablerLayerModules contains the given module
  33064. if ((ibmConfig.enablerLayerModules) && (dojo.indexOf(ibmConfig.enablerLayerModules, "CoreModel") >= 0)) {
  33065. dojo["require"]("com.ibm.mm.enabler.iwidget.widget.IWidgetWrapperModelImpl"); // JSLINT-IGNORE: This needs to be done to allow modularization and to support the layers
  33066. }
  33067. }
  33068. if(!dojo._hasResource["com.ibm.mashups.livetext.CallbackModel"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  33069. dojo._hasResource["com.ibm.mashups.livetext.CallbackModel"] = true;
  33070. dojo.provide("com.ibm.mashups.livetext.CallbackModel");
  33071. /**
  33072. * This API defines the various callback functions for livetext services. These callback functions should be provided by
  33073. * event publisher.
  33074. *
  33075. * @ibm-api
  33076. * @ibm-module iWidget
  33077. */
  33078. dojo.declare("com.ibm.mashups.livetext.CallbackModel", null,
  33079. {
  33080. /**
  33081. * The callback function which should be provided to livetext service by the event publisher. This
  33082. * callback function provides a means by the event publisher and for the event publisher to run some code before
  33083. * the HTML fragment is processed. <p />
  33084. * @param {DOMNode} domNode The DOM node whose decendent nodes to be parsed and processed. May be <code>null</code>.
  33085. * @param {Object[]} livetextList The list of the live text which will be processed. May be <code>null</code>.
  33086. * @param {Object} tagEntry The JSON object of the current tag entry used to match and process the returned nodes. Is never <code>null</code>.
  33087. * @type void
  33088. */
  33089. preProcessCallbackFunc: function(/* DOMNode */ domNode, /* Object[] */livetextList, /* Object */ tagEntry) {
  33090. },
  33091. /**
  33092. * The callback function which should be provided to livetext service by the event publisher. This
  33093. * callback function provides a means by the event publisher and for the event publisher to run some code
  33094. * after HTML fragment has been processed. <p />
  33095. * @param {DOMNode} domNode The DOM node whose decendent nodes to be parsed and processed. May be <code>null</code>.
  33096. * @param {Object[]} livetextList The list of the live text which will be processed. May be <code>null</code>.
  33097. * @param {Object[]} errors The list of the exceptions occurred during the parsing and node handling process. If
  33098. * there is no error, an empty array should be provided. May be <code>null</code>.
  33099. * @param {Object} tagEntry The JSON object of the current tag entry used to match and process the returned nodes. Is never <code>null</code>.
  33100. * @type void
  33101. */
  33102. postProcessCallbackFunc: function(/* DOMNode */ domNode, /* Object[] */livetextList, /* Object[] */ errors, /* Object */ tagEntry) {
  33103. }
  33104. });
  33105. }
  33106. if(!dojo._hasResource["com.ibm.mashups.livetext.ConfigEntry_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  33107. dojo._hasResource["com.ibm.mashups.livetext.ConfigEntry_API"] = true;
  33108. dojo.provide("com.ibm.mashups.livetext.ConfigEntry_API");
  33109. dojo.provide("com.ibm.mashups.livetext.ConfigEntry");
  33110. /**
  33111. * This API defines the service model configuration entry
  33112. *
  33113. * @ibm-api
  33114. * @ibm-module iWidget
  33115. */
  33116. dojo.declare("com.ibm.mashups.livetext.ConfigEntry", null, {
  33117. /**
  33118. * Creates a new instance of livetext config entry.
  33119. *
  33120. * @param {String} match the CSS3 Selection expression to match a live text. Must not be <code>null</code>.
  33121. * @param {Boolean} processEnclosedTags should all the nested live text be processed in this request. If true, then all the live text will be processed. If false,
  33122. * only the out most live text of this type will be processed. May be <code>null</code>.
  33123. * @param {String} module the module to register the implementation livetextModel under. Must not be <code>null</code>.
  33124. * @param {String} path the url to load the livetextModel implementation resource file. Must not be <code>null</code>.
  33125. * @param {String} baseClass the JavaScript class which implement the livetextModel. Must not be <code>null</code>.
  33126. * @param {Boolean} waitOnPreTag The value of true or false to determine if the service should process this entry defined tags before the process of the previous
  33127. * entry defined tags have been completed. The default value is true. <br /> Must not be <code>null</code>.
  33128. * @param {String} configId a unique id to identify the entry. This is useful in case we have same baseClass as different handlers. configId will be used to find nodes are for which matching criteria.Must not be <code>null</code>.
  33129. */
  33130. constructor : function(/* String */match, /* Boolean */
  33131. processEnclosedTags, /* String */module,
  33132. /* String */path, /* String */baseClass ,/*Boolean*/ waitOnPreTag,/* String */id) {
  33133. },
  33134. /**
  33135. * Compare if this configuration entry is same as the given entry.
  33136. *
  33137. * @param {com.ibm.mashups.livetext.ConfigEntry} entry The entry to be compared with this entry. Must not be <code>null</code>.
  33138. * @returns {Boolean} The value indicats if the two entries are the same.
  33139. */
  33140. isEqual : function(/* ConfigEntry */entry) {
  33141. }
  33142. });
  33143. }
  33144. if(!dojo._hasResource["com.ibm.mm.livetext.ConfigEntryImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  33145. dojo._hasResource["com.ibm.mm.livetext.ConfigEntryImpl"] = true;
  33146. dojo.provide("com.ibm.mm.livetext.ConfigEntryImpl");
  33147. dojo.declare("com.ibm.mm.livetext.ConfigEntryImpl", com.ibm.mashups.livetext.ConfigEntry, {
  33148. constructor: function(/* String */match, /* Boolean */ processEnclosedTags, /* String */ module, /* String */
  33149. path, /* String */ baseClass, /*Boolean*/ waitOnPreTag, /* String */id) {
  33150. this.match = match;
  33151. this.wait = waitOnPreTag;
  33152. this.procEnc = processEnclosedTags;
  33153. this.mod = module;
  33154. this.path = path;
  33155. this.baseCls = baseClass;
  33156. this.id = id;
  33157. },
  33158. isEqual: function(/* ConfigEntry */entry) { // Should not we just use configId to check if configentry are equal or not??
  33159. return entry &&
  33160. entry.match == this.match &&
  33161. entry.wait == this.wait &&
  33162. entry.procEnc == this.procEnc &&
  33163. entry.mod == this.mod &&
  33164. entry.path == this.path &&
  33165. entry.baseCls == this.baseCls &&
  33166. entry.id == this.id ;
  33167. }
  33168. });
  33169. com.ibm.mashups.livetext.ConfigEntry = com.ibm.mm.livetext.ConfigEntryImpl;
  33170. }
  33171. if(!dojo._hasResource["com.ibm.mashups.livetext.ConfigEntry"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  33172. dojo._hasResource["com.ibm.mashups.livetext.ConfigEntry"] = true;
  33173. dojo.provide("com.ibm.mashups.livetext.ConfigEntry");
  33174. }
  33175. if(!dojo._hasResource["com.ibm.mashups.livetext.Exception"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  33176. dojo._hasResource["com.ibm.mashups.livetext.Exception"] = true;
  33177. dojo.provide("com.ibm.mashups.livetext.Exception");
  33178. /**
  33179. * This API defines the exception which can be thrown by the semantic services during the parsing and processing
  33180. *
  33181. * An exceptionId should identify the current exception. It is a 7 character long string which uniquely identifies the
  33182. * current abnormal condition of the parsing and processing. <p />
  33183. *
  33184. * @ibm-api
  33185. * @ibm-module iWidget
  33186. */
  33187. dojo.declare("com.ibm.mashups.livetext.Exception", null,
  33188. {
  33189. /**
  33190. * Create new instance of livetext service exception. <p />
  33191. *
  33192. * @param {String} exceptionId The exception identifier. Must not be <code>null</code>.
  33193. * @param {Object} variable The list of the parameters to describe this error condition. May be <code>null</code>. This object must hold all the necessary
  33194. * values to populate the exception message. For example, a message may be defined as the following: <p />
  33195. *
  33196. * &nbsp;&nbsp;&nbsp;&nbsp;"The node ${id} does not have the necessary attribute ${attribute} or the attribute has unrecongnized values." <p/>
  33197. * When an exception is throw, the variable object should have members namded "id" and "attribute" respectively. Here is an example of such object <p />
  33198. *
  33199. * &nbsp;&nbsp;&nbsp;&nbsp;throw new com.ibm.mashups.livetext.exception('E000001', {'id':100, 'attribute':'DeJaWu'});
  33200. */
  33201. constructor: function(/* String */exceptionId, /* Object */ variable) {
  33202. },
  33203. /**
  33204. * Retrieve locale specific description by using the status code. This method should not cause any exception. If
  33205. * no locale specific message is found, then an empty string will be returned.
  33206. * @param {String[]} locales The list of the locales which the locale specific error should be looked up. May be <code>null</code>.
  33207. * @returns {String} The locale specific exception message.
  33208. */
  33209. getMessage: function(/* String[] */ locales) {
  33210. }
  33211. });
  33212. }
  33213. if(!dojo._hasResource["com.ibm.mashups.livetext.LivetextBatchModel"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  33214. dojo._hasResource["com.ibm.mashups.livetext.LivetextBatchModel"] = true;
  33215. dojo.provide("com.ibm.mashups.livetext.LivetextBatchModel");
  33216. /**
  33217. This is the tag processor API. When a match tag is found by the livetext service according to the configuration, the service
  33218. will hand the all DOM nodes to the tag processor which matches the criteria. Each tag processor must implement this interface. Each processor must also provide a
  33219. non-parameter constructor in addition to the processTag method. The non-parameter constructor is to ensure that the livetext service
  33220. can create an instance of the implementation class without providing any more information. <p />
  33221. @ibm-api
  33222. @ibm-module iWidget
  33223. */
  33224. dojo.declare("com.ibm.mashups.livetext.LivetextBatchModel", null,
  33225. {
  33226. /**
  33227. * The entry point of a tag processor. When a tag is found, the service will dynamically load the module which was designed to process
  33228. * that type of tags, then create an instance of that tag module class if it has not been created, then call this method and hand the
  33229. * control to the tag module.
  33230. * @param {DOMNode[]} nodes The livetext DOM nodes to be processed. Must not be <code>null</code>.
  33231. * @param {com.ibm.mashups.livetext.ConfigEntry} configEntry The configuration enrty for the handler. This will be required in case we have one hanlder for multiple matching criteria <code>null</code>.
  33232. * @type void
  33233. */
  33234. processTag: function(/*DOMNode[]*/nodes, configEntry) {
  33235. },
  33236. /**
  33237. * The entry point of a tag processor (unchanging). When a tag is found, the service will dynamically load the module which was designed to process
  33238. * that type of tags, then create an instance of that tag module class if it has not been created, then call this method and hand the
  33239. * control to the tag module.
  33240. * @param {DOMNode[]} nodes The livetext DOM node to be &quot;unprocessed&quot;. Must not be <code>null</code>.
  33241. * @type void
  33242. */
  33243. unprocessTag: function(/*DOMNode[]*/nodes) {
  33244. }
  33245. });
  33246. }
  33247. if(!dojo._hasResource["com.ibm.mashups.livetext.LivetextModel"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  33248. dojo._hasResource["com.ibm.mashups.livetext.LivetextModel"] = true;
  33249. dojo.provide("com.ibm.mashups.livetext.LivetextModel");
  33250. /**
  33251. This is the tag processor API. When a match tag is found by the livetext service according to the configuration, the service
  33252. will hand the DOM node to the tag processor. Each tag processor must implement this interface. Each processor must also provide a
  33253. non-parameter constructor in addition to the processTag method. The non-parameter constructor is to ensure that the livetext service
  33254. can create an instance of the implementation class without providing any more information. <p />
  33255. @ibm-api
  33256. @ibm-module iWidget
  33257. */
  33258. dojo.declare("com.ibm.mashups.livetext.LivetextModel", null,
  33259. {
  33260. /**
  33261. * The entry point of a tag processor. When a tag is found, the service will dynamically load the module which was designed to process
  33262. * that type of tags, then create an instance of that tag module class if it has not been created, then call this method and hand the
  33263. * control to the tag module.
  33264. * @param {DOMNode} node The livetext DOM node to be processed. Must not be <code>null</code>.
  33265. * @type void
  33266. */
  33267. processTag: function(/*DOMNode*/node) {
  33268. },
  33269. /**
  33270. * The entry point of a tag processor (unchanging). When a tag is found, the service will dynamically load the module which was designed to process
  33271. * that type of tags, then create an instance of that tag module class if it has not been created, then call this method and hand the
  33272. * control to the tag module.
  33273. * @param {DOMNode} node The livetext DOM node to be &quot;unprocessed&quot;. Must not be <code>null</code>.
  33274. * @type void
  33275. */
  33276. unprocessTag: function(/*DOMNode*/node) {
  33277. }
  33278. });
  33279. }
  33280. if(!dojo._hasResource["com.ibm.mashups.livetext.ServiceModel_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  33281. dojo._hasResource["com.ibm.mashups.livetext.ServiceModel_API"] = true;
  33282. dojo.provide("com.ibm.mashups.livetext.ServiceModel_API");
  33283. dojo.provide("com.ibm.mashups.livetext.ServiceModel");
  33284. /**
  33285. The livetext (formally known as semantic tag) service API. The implementation class of this API provides the livetext parsing services
  33286. so that tags on a page can be recognized and processed according to the tagservice.entries.cfg
  33287. configuration file. An instance of this API implementation class should be created after a page is fully loaded.
  33288. Once the instance is created, the init method should be called so that the tags will be parsed. Each tag processor
  33289. will be invoked to process the tags in order of the tags defined in the tagservices.entries.cfg file. There should be no more
  33290. than 1 instance of this class on each page.
  33291. The implementation of this API should subscribe to one of the following two event topics.<p/>
  33292. &nbsp;&nbsp;&nbsp;"/com/ibm/mashups/livetext/livetextchanged" <p />
  33293. &nbsp;&nbsp;&nbsp;"/com/ibm/mashups/livetext/livetextcontentchanged" <p />
  33294. Once an event is published to that topic, the implementation of this API should start using the given DOM node and processing all the
  33295. decendant DOM nodes of that given node. That given node itself will not be processed. Event livetextchanged will cause the passed node and
  33296. all its children to be parsed. Event livetextcontentchanged will cause only the passed node children to be parsed. <p />
  33297. If a component wishes for a piece of markup fragment being processed, that component should publish an event to that topic, that event
  33298. should also come with the DOM node which holds that piece of the markup fragment, callback functions and a flag to indicate how to proceed
  33299. when an exception is thrown. The DOM node, flag and the callback functions are referred to event data below.<p />
  33300. The event data must be an array of objects in the following format.<p />
  33301. &nbsp;&nbsp;&nbsp;[domNode, continueAfterException, preProcessCallbackFunc, postProcessCallbackFunc] <p/>
  33302. The first object in the event data array is the root node of the HTML markup fragment. If that object is not a valid DOM node, then no action
  33303. will be taken. The second object in the array is a flag to indicate if the parsing should continue when an exception is caught. The third and
  33304. the last object in the array are two callback functions. The preProcessCallbackFunc will be invoked before the parsing process starts, the
  33305. postProcessCallbackFunc will be invoked after the parsing process finished. If none callback function is provided by the array, then no function
  33306. will be invoked. The default value for continueAfterException flag is false. <p/>
  33307. If the node needs to be processed and the both pre and post process callback exist, then the call should look like this.<br /> <br />
  33308. &nbsp;&nbsp;&nbsp;dojo.publish("/com/ibm/mashups/livetext/livetextchanged", <br />
  33309. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[aDOMNode, false, callbackFunc1, callbackFunc2]); <br /><br />
  33310. If all the nodes on the page need to be processed, and no callback functions are needed, then the call should look like this.<br/><br/>
  33311. &nbsp;&nbsp;&nbsp;dojo.publish("/com/ibm/mashups/livetext/livetextchanged", <br />
  33312. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[document, true]); <br /><br />
  33313. If the node in the event data is not a valid node, then the event will be ignored. Before a given DOM node being processed,
  33314. The preProcesCallbackFunc will be called. After the given DOM node has been processed, the postProcessCallbackFunc will be called.
  33315. If preProcessCallbackFunc or postProcessCallbackFunc is not null, then the callback function is guaranteed to be invoked regardless
  33316. the status of the tag parsing process. The given DOM node is considered as the root node of given HTML fragment. All its decendent
  33317. child DOM nodes will be parsed. To make the process effecient, components should avoid passing the entire Document as the given DOM
  33318. node unless it is the very first time.<p />
  33319. Tag service configuration. <p/>
  33320. This section describes the specific implementation of the IBM Lotus Mashups livetext services implementation. The tag matching
  33321. method is not defined, it is up to the tag service implementation to define their own match method and tag processing invoke sequence.<p />
  33322. Tags can be nested, this tag service can be configured to process nested tags or leave the nested tags to the container to
  33323. process. <p />
  33324. This service is configurable by providing a configuration file. The configuration file should be located at the same location
  33325. where the tag service API implementation class is. The configuration file is simply a JSON type of code. It defines tags that this service can process. The
  33326. following is an example of this file. <p />
  33327. &nbsp;&nbsp;&nbsp;[<br/>
  33328. &nbsp;&nbsp;&nbsp;{"match":"*.iWidgetSkin[skin]","processEnclosedTags":true,'waitOnPreTag':true,<br/>
  33329. &nbsp;&nbsp;&nbsp;&nbsp;"module":"tagservices", "path":"../../tagservices", "baseClass":"tagservices.skins"},<br/>
  33330. &nbsp;&nbsp;&nbsp;{"match":"*.iw-iWidget","processEnclosedTags":false,'waitOnPreTag':false,<br/>
  33331. &nbsp;&nbsp;&nbsp;&nbsp;"module":"tagservices", "path":"../../tagservices", "baseClass":"tagservices.widgets"}<br/>
  33332. &nbsp;&nbsp;&nbsp;] <p />
  33333. Each entry in this file presents a type of tags that this service can process. The order of these entries in the configuration
  33334. file is important because the service will process the tags in this order. <p />
  33335. Each entry should have the following element. <p />
  33336. "match": The CSS3 format for tag attribute match value. The value of this element determines if a tag should be processed by the services. This can now be a comma seperated values. In case comma seperated values are specified, nodes matching each of them will be merged<br/>
  33337. "processEnclosedTags": The value of true or false to determine if the service should process the nested tag. The default value is false.<br />
  33338. "waitOnPreTag": The value of true or false to determine if the service should process this entry defined tags before the process of the previous
  33339. entry defined tags have been completed. The default value is true. <br />
  33340. "module": The implementation JavaScript module. This is required. <br />
  33341. "path": The path to the JavaScript implementation of the tag processor. This should be a URI to the JavaScript resource. This is required. <br />
  33342. "baseClass": The class which implement the tag processor API. <br />
  33343. "id" a unique id to identify the entry. This is useful in case we have same baseClass as different handlers. id will be used to find nodes are for which matching criteria.Can be <code>null</code><br />
  33344. Livetext service also provide a way for other components to dynamically add or remove a configuration entry. The addition or removal of the entries
  33345. will not be persisted. It will only affect the current session. <br />
  33346. If an entry needs to be added, then a component should publish to this topic with
  33347. an entry.<br>
  33348. &nbsp;&nbsp;&nbsp;"/com/ibm/mashups/livetext/configentryadded" <p />
  33349. If an entry needs to be removed, then a component should publish to this topic with
  33350. an entry.<br>
  33351. &nbsp;&nbsp;&nbsp;"/com/ibm/mashups/livetext/configentryremoved" <p />
  33352. @ibm-api
  33353. @ibm-module iWidget
  33354. */
  33355. dojo.declare("com.ibm.mashups.livetext.ServiceModel", null,
  33356. {
  33357. /**
  33358. * The service name to be used to fetch the service from the ServiceManager
  33359. * @type String
  33360. */
  33361. SERVICE_NAME: "livetextService",
  33362. /**
  33363. * Initiate the tag service. This should be only called once after a page is completely loaded.
  33364. * Normally it should be added to the document onload method. This method should initialize the
  33365. * tag service which includes load the tag configuration and start parsing tags for the entire page.
  33366. * @param {Object} initArgs Optional JSON object that defines initialization properties for the live text service.
  33367. * May be <code>null</code>. Currently supports these properties on the JSON object:</br>
  33368. * { <br/>
  33369. * &nbsp;&nbsp;&nbsp;&nbsp;<code>node</code>: The DOM node whose decendent nodes will be parsed and processed. Applies only to the initial parse. May be <code>null</code>.<br/>
  33370. * &nbsp;&nbsp;&nbsp;&nbsp;<code>continueAfterException</code>: The flag to indicate if the service should continue the parsing and processing after an exception is caught. Applies only to the initial parse. May be <code>null</code>.<br/>
  33371. * &nbsp;&nbsp;&nbsp;&nbsp;<code>preProcessCallbackFunc</code>: The callback function being called before nodes are processed for a particular tag. Applies only to the initial parse. May be <code>null</code>.<br/>
  33372. * &nbsp;&nbsp;&nbsp;&nbsp;<code>postProcessCallbackFunc</code>: The callback function being called after nodes are processed for a particular tag. Applies only to the initial parse. May be <code>null</code>.<br/>
  33373. * }<br/>
  33374. * @type void
  33375. */
  33376. init: function(/* Object */ initArgs) {
  33377. },
  33378. /**
  33379. * Tag changed event handler. This handler will parse the passed in tag and all its children to be parsed.
  33380. * @param {DOMNode} domNode The DOM node whose decendent nodes to be parsed and processed. May be <code>null</code>.
  33381. * @param {boolean} continueAfterException The flag to indicate if the service should continue the parsing and processing after an exception is caught.
  33382. If this parameter is missing, the default is false. May be <code>null</code>.
  33383. * @param {com.ibm.mashups.livetext.CallbackModel.preProcessCallbackFunc} preProcessCallbackFunc The callback function being called before a node being processed. May be <code>null</code>.
  33384. * @param {com.ibm.mashups.livetext.CallbackModel.postProcessCallbackFunc} postProcessCallbackFunc The callback function being called after the a node being processed. May be <code>null</code>.
  33385. * @type void
  33386. */
  33387. onTagChanged: function(/* DOMNode */ domNode,
  33388. /* boolean */ continueAfterException,
  33389. /* com.ibm.mashups.livetext.CallbackModel.preProcessCallbackFunc */ preProcessCallbackFunc,
  33390. /* com.ibm.mashups.livetext.CallbackModel.postProcessCallbackFunc */ postProcessCallbackFunc) {
  33391. },
  33392. /**
  33393. The event handler when a tag and/or its content should be removed.
  33394. @param {DOMNode} node the root node which will be parsed.
  33395. @param {Boolean} continueAfterException a flag indicate if the process should continue when error occurrs.
  33396. @param {Function} preProcessCallback the callback function which will be called before nodes being processed.
  33397. @param {Function} postProcessCallback the callback function which will be called after nodes being processed.
  33398. @param {Function} postUnProcessCallbcak the callback function which will be called after the content is unchanged.
  33399. @type void
  33400. */
  33401. onUnchangeTag: function(node, continueAfterException, preUnProcessCallback, postUnProcessCallback, unchangeCompleteCallback) {
  33402. },
  33403. /**
  33404. * Tag content changed event handler. This handle will parsed all the passed in tag content to be parsed.
  33405. * @param {DOMNode} domNode The DOM node whose decendent nodes to be parsed and processed. May be <code>null</code>.
  33406. * @param {boolean} continueAfterException The flag to indicate if the service should continue the parsing and processing after an exception is caught.
  33407. If this parameter is missing, the default is false. May be <code>null</code>.
  33408. * @param {com.ibm.mashups.livetext.CallbackModel.preProcessCallbackFunc} preProcessCallbackFunc The callback function being called before a node being processed. May be <code>null</code>.
  33409. * @param {com.ibm.mashups.livetext.CallbackModel.postProcessCallbackFunc} postProcessCallbackFunc The callback function being called after the a node being processed. May be <code>null</code>.
  33410. * @type void
  33411. */
  33412. onTagContentChanged: function(/* DOMNode */ domNode,
  33413. /* boolean */ continueAfterException,
  33414. /* com.ibm.mashups.livetext.CallbackModel.preProcessCallbackFunc */ preProcessCallbackFunc,
  33415. /* com.ibm.mashups.livetext.CallbackModel.postProcessCallbackFunc */ postProcessCallbackFunc) {
  33416. },
  33417. /**
  33418. * The method allows component dynamically add a new configuration entry so that the service can start process the tags presented
  33419. * by the entry.
  33420. * @param {com.ibm.mashups.livetext.ConfigEntry} entry The entry that should be added to the configuration. Must not be <code>null</code>.
  33421. * @param {boolean} bFront The flag to indicate if the entry should be added to the front of the configuration array or not. true for front, false for end. Default is false for end.
  33422. * @type void
  33423. */
  33424. onAddConfigEntry: function(/* com.ibm.mashups.livetext.ConfigEntry */ entry, bFront) {
  33425. },
  33426. /**
  33427. * This method allows components dynamically remove a configuration entry so that the service will not process that type of tags which
  33428. * are presented by the configuration entry.
  33429. * @param {com.ibm.mashups.livetext.ConfigEntry} entry The entry that should be removed from the configuration. Must not be <code>null</code>.
  33430. * @type void
  33431. */
  33432. onRemoveConfigEntry: function(/* com.ibm.mashups.livetext.ConfigEntry */ entry) {
  33433. }
  33434. });
  33435. com.ibm.mashups.livetext.ServiceModel.SERVICE_NAME = com.ibm.mashups.livetext.ServiceModel.prototype.SERVICE_NAME;
  33436. }
  33437. if(!dojo._hasResource["com.ibm.mm.livetext.ServiceModelImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  33438. dojo._hasResource["com.ibm.mm.livetext.ServiceModelImpl"] = true;
  33439. dojo.provide("com.ibm.mm.livetext.ServiceModelImpl");
  33440. // inject this service into the ServiceManager at the end. Therefore we have to require the implementation
  33441. dojo.declare("com.ibm.mm.livetext.ServiceModelImpl", com.ibm.mashups.livetext.ServiceModel,
  33442. {
  33443. _initialized:false,
  33444. _tagTypes:null,
  33445. _rootContainer: null,
  33446. tagChanged:"/com/ibm/mashups/livetext/livetextchanged",
  33447. unchangeTag: "/com/ibm/mashups/livetext/livetextunchange",
  33448. tagStatusChange: "/com/ibm/mashups/livetext/livetextchanged",
  33449. tagContentChanged: "/com/ibm/mashups/livetext/livetextcontentchanged",
  33450. entryAdded: "/com/ibm/mashups/livetext/configentryadded",
  33451. entryRemoved: "/com/ibm/mashups/livetext/configentryremoved",
  33452. constructor:function(){
  33453. if (com.ibm.mm.livetext.ServiceModelStatic) {
  33454. console.warn("WARNING: Do not create the LiveText Framework multiple times!");
  33455. return;
  33456. }
  33457. com.ibm.mm.livetext.ServiceModelStatic = true;
  33458. dojo.subscribe(this.entryAdded, this, "onAddConfigEntry");
  33459. dojo.subscribe(this.entryRemoved, this, "onRemoveConfigEntry");
  33460. },
  33461. /**
  33462. Initiate the tag service. This should be only called once after a page is completed loaded.
  33463. Load the livetext configuration by calling loadTags method.<b>
  33464. Subscribe to two event topics and prepare to catch events fired by other components.
  33465. Publish the content changed event and start the entire document parsing.
  33466. @returns
  33467. */
  33468. init: function(initArgs) {
  33469. if (this._initialized) {
  33470. console.warn("WARNING: Do not initialize the LiveText Framework multiple times!");
  33471. return;
  33472. }
  33473. this._initialized = true;
  33474. if(!initArgs) {
  33475. initArgs = {};
  33476. }
  33477. this._loadTags(initArgs);
  33478. dojo.subscribe(this.tagChanged, this, "onTagChanged");
  33479. dojo.subscribe(this.unchangeTag, this, "onUnchangeTag");
  33480. dojo.subscribe(this.tagContentChanged, this, "onTagContentChanged");
  33481. dojo.publish(this.tagContentChanged, [initArgs.node || document, ("continueAfterException" in initArgs) ? initArgs.continueAfterException : true, initArgs.preProcessCallbackFunc, initArgs.postProcessCallbackFunc]);
  33482. },
  33483. /**
  33484. The core method to query the match tags according to the matching condition defined as CSS3 selection expression.
  33485. If the type of the tag is defined to query the enclosed tag, then simply do one dojo query and return all the nodes.<b>
  33486. If the type of the tag is defined to query tags excluding the enclosed tags, then two query will be performed, the offset
  33487. of the two query results will be returned. The first query gets all the tags, the second query gets the tags which has nested
  33488. tag inside, then the difference of the two results will be returned.
  33489. @param {DOMNode} node the root node which will be parsed.
  33490. @param {Object} tagType a tag type which maps to one of the configuration entries.
  33491. @returns {Array} list of the matching tags.
  33492. */
  33493. _getNodes: function(node, tagType) {
  33494. var k = [];
  33495. if ( tagType == "undfined" || !tagType) {
  33496. console.error("Why are we having tagType undefined ::::");
  33497. return k;
  33498. }
  33499. // handle for tagType.match having multiple option
  33500. var aNodeList;
  33501. var a;
  33502. var matchEntry = 0;
  33503. if (tagType.processEnclosedTags != "undefined" && tagType.processEnclosedTags) {
  33504. var tagTypeMatch = tagType.match;
  33505. a = [];
  33506. aNodeList = dojo.query(tagTypeMatch, node);
  33507. aNodeList.forEach(function(node, index, nodeList){
  33508. a.push(node);
  33509. });// JSLINT-IGNORE: Enabler Team decided to keep this paradigma from dojo in tact
  33510. return a;
  33511. }
  33512. else {
  33513. var tagTypeMatchArray = tagType.match.split(",");
  33514. a = [];
  33515. var b = [];
  33516. for ( matchEntry = 0, l = tagTypeMatchArray.length; matchEntry < l ; matchEntry++ ) {
  33517. aNodeList = dojo.query(tagTypeMatchArray[matchEntry] +' ' + tagTypeMatchArray[matchEntry], node);
  33518. aNodeList.forEach(function(node, index, nodeList){
  33519. a.push(node);
  33520. });// JSLINT-IGNORE: Enabler Team decided to keep this paradigma from dojo in tact
  33521. var bNodeList = dojo.query(tagTypeMatchArray[matchEntry], node);
  33522. bNodeList.forEach(function(node, index, nodeList){
  33523. b.push(node);
  33524. });// JSLINT-IGNORE: Enabler Team decided to keep this paradigma from dojo in tact
  33525. }
  33526. var anItem, bIndex;
  33527. while (a.length > 0) {
  33528. anItem = a[0]; bIndex = 0;
  33529. while (bIndex < b.length) {
  33530. if (anItem == b[bIndex]) {
  33531. a.splice(0,1); b.splice(bIndex, 1);
  33532. break;
  33533. }
  33534. else {
  33535. bIndex++;
  33536. }
  33537. }
  33538. }
  33539. return b;
  33540. }
  33541. },
  33542. /**
  33543. The event handler when a tag and/or its content get changed.
  33544. @param {DOMNode} node the root node which will be parsed.
  33545. @param {Boolean} continueAfterException a flag indicate if the process should continue when error occurrs.
  33546. @param {Function} preProcessCallback the callback function which will be called before nodes being processed.
  33547. @param {Function} postProcessCallback the callback function which will be called after nodes being processed.
  33548. @returns
  33549. */
  33550. onTagChanged: function(node, continueAfterException, preProcessCallback, postProcessCallback) {
  33551. var tag = null;
  33552. for (var index=0, l = this._tagTypes.length; index<l;index++) {
  33553. tag = this._tagTypes[index];
  33554. this._processTypeTag(node,tag, continueAfterException, preProcessCallback, postProcessCallback, true);
  33555. }
  33556. },
  33557. /**
  33558. The event handler when a tag and/or its content should be removed.
  33559. @param {DOMNode} node the root node which will be parsed.
  33560. @param {Boolean} continueAfterException a flag indicate if the process should continue when error occurrs.
  33561. @param {Function} preProcessCallback the callback function which will be called before nodes being processed.
  33562. @param {Function} postProcessCallback the callback function which will be called after nodes being processed.
  33563. @param {Function} postUnProcessCallbcak the callback function which will be called after the content is unchanged.
  33564. @returns
  33565. */
  33566. onUnchangeTag: function(node, continueAfterException, preUnProcessCallback, postUnProcessCallback, unchangeCompleteCallback) {
  33567. var tag = null;
  33568. for (var index=0, l = this._tagTypes.length; index<l;index++) {
  33569. tag = this._tagTypes[index];
  33570. this._unprocessTypeTag(node,tag, continueAfterException, preUnProcessCallback, postUnProcessCallback, false);
  33571. }
  33572. if (dojo.isFunction(unchangeCompleteCallback)) {
  33573. unchangeCompleteCallback(node);
  33574. }
  33575. },
  33576. /**
  33577. The event handler when a tag content gets changed. The passed in DOM node will not be processed. Only its child nodes
  33578. will be processed.
  33579. @param {DOMNode} node the root node which will be parsed.
  33580. @param {Boolean} continueAfterException a flag indicate if the process should continue when error occurrs.
  33581. @param {Function} preProcessCallback the callback function which will be called before nodes being processed.
  33582. @param {Function} postProcessCallback the callback function which will be called after nodes being processed.
  33583. @returns
  33584. */
  33585. onTagContentChanged: function(node, continueAfterException, preProcessCallback, postProcessCallback){
  33586. var tag = null;
  33587. for (var index=0, l = this._tagTypes.length; index<l;index++) {
  33588. tag = this._tagTypes[index];
  33589. this._processTypeTag(node,tag, continueAfterException, preProcessCallback, postProcessCallback, false);
  33590. }
  33591. },
  33592. /**
  33593. Once a type of tags have been found, each of the same type of tags will be processed by that type of the tag processor
  33594. class defined in the configuration. If that type of the tag processor class has not been loaded, then the tag processor will
  33595. be loaded and a new instance of that class will be created.
  33596. After tag processor is created, this method will check if the passed in node should be included according to the includeRoot parameter.<b>
  33597. If the passed in node should be included, then the check the node against the matching condition. If condition is met, then the node will
  33598. be included in the list of the tags being processed individually. Otherwise, only the matching tags will be processed.<b>
  33599. Before each tag is being processed, the preProcessCallBack function will be called. All the tags found will be passed into this callback function
  33600. The loop in the middle of the method go through each tag in the list, using the tag processor to process each individual tag.<b>
  33601. After entire tags in the list get processed, the postProcessCallback function get called with exceptions which might have occurred.<b>
  33602. @param {DOMNode} node the root node which will be parsed.
  33603. @param {Object} tag the tag type entry object from the configration.
  33604. @param {Boolean} continueAfterException a flag indicate if the process should continue when error occurrs.
  33605. @param {Function} preProcessCallback the callback function which will be called before nodes being processed.
  33606. @param {Function} postProcessCallback the callback function which will be called after nodes being processed.
  33607. @param {Boolean} includeRoot the flag indicate if the passed in node should be included in the process. This flag is used to differiate
  33608. the event tag changed from tag content changed.
  33609. @returns
  33610. */
  33611. _processTypeTag:function(node, tag, continueAfterException, preProcessCallback, postProcessCallback, includeRoot) {
  33612. // if tag does not have baseClass there is no point going forward.
  33613. tag = tag || null;
  33614. if (tag === null) {
  33615. return;
  33616. }
  33617. var nodes = [];
  33618. if (includeRoot && this._checkRoot(node, tag)) {
  33619. nodes[0] = node;
  33620. }
  33621. nodes = nodes.concat(this._getNodes(node, tag));
  33622. var id = tag.id || null;
  33623. if (id === null) {
  33624. id = "";
  33625. }
  33626. var tagsforcallbackfunc = [];
  33627. tagsforcallbackfunc = tagsforcallbackfunc.concat(nodes);
  33628. if (tagsforcallbackfunc.length > 0) {
  33629. tag.loaded = tag.loaded || null;
  33630. if (tag.loaded === null){
  33631. this._loadTagHandler(tag);
  33632. }
  33633. var errors = [];
  33634. if (dojo.isFunction(preProcessCallback)) {
  33635. try {
  33636. preProcessCallback(node, tagsforcallbackfunc, tag);
  33637. } catch (error1) {
  33638. console.debug(error1);
  33639. }
  33640. }
  33641. if ( tag.tagHandler instanceof com.ibm.mashups.livetext.LivetextBatchModel ) {
  33642. try {
  33643. tag.tagHandler.processTag(nodes, tag);
  33644. } catch(error){
  33645. errors[errors.length] = error;
  33646. }
  33647. } else {
  33648. for (var index0=0, l = nodes.length; index0<l;index0++) {
  33649. try {
  33650. tag.tagHandler.processTag(nodes[index0]);
  33651. } catch (error2) {
  33652. errors[errors.length] = error2;
  33653. if (continueAfterException) {
  33654. break;
  33655. }
  33656. }
  33657. }
  33658. }
  33659. if (dojo.isFunction(postProcessCallback)) {
  33660. try {
  33661. postProcessCallback(node, tagsforcallbackfunc, errors, tag);
  33662. } catch (error3) {
  33663. console.debug(error3);
  33664. }
  33665. }
  33666. }
  33667. },
  33668. _unprocessTypeTag: function (node, tag, continueAfterException, preUnProcessCallback, postUnProcessCallback, includeRoot) {
  33669. var tags = [];
  33670. if (includeRoot && this._checkRoot(node, tag)) {
  33671. tags[0] = node;
  33672. }
  33673. tags = tags.concat(this._getNodes(node, tag));
  33674. var tagsforcallbackfunc = [];
  33675. tagsforcallbackfunc = tagsforcallbackfunc.concat(tags);
  33676. var errors = [];
  33677. if (dojo.isFunction(preUnProcessCallback)) {
  33678. try {
  33679. preUnProcessCallback(node, tagsforcallbackfunc, tag);
  33680. } catch (error1) {
  33681. console.debug(error1);
  33682. }
  33683. }
  33684. if (tagsforcallbackfunc.length > 0) {
  33685. tag.loaded = tag.loaded || null;
  33686. if (tag.loaded === null){
  33687. this._loadTagHandler(tag);
  33688. }
  33689. if (tag.tagHandler instanceof com.ibm.mashups.livetext.LivetextBatchModel) {
  33690. try {
  33691. tag.tagHandler.unprocessTag(nodes, tag);
  33692. }
  33693. catch (error2) {
  33694. errors[errors.length] = error2;
  33695. }
  33696. } else {
  33697. for (var index0=0, l = tags.length; index0<l;index0++) {
  33698. try {
  33699. tag.tagHandler.unprocessTag(tags[index0]);
  33700. } catch(error3) {
  33701. errors[errors.length] = error3;
  33702. if (continueAfterException) {
  33703. break;
  33704. }
  33705. }
  33706. }
  33707. }
  33708. }
  33709. if (dojo.isFunction(postUnProcessCallback)) {
  33710. try {
  33711. postUnProcessCallback(node, tagsforcallbackfunc, errors, tag);
  33712. } catch (error4) {
  33713. console.debug(error4);
  33714. }
  33715. }
  33716. },
  33717. /**
  33718. The method to check individual node to see if the passed in node meet a given tag matching condition. If it does, then
  33719. a value of true will be returned, otherwise a value of false will be returned.
  33720. @param {DOMNode} node the DOM node to check with
  33721. @param {Object} tag the tag type object
  33722. @returns {Boolean} the value which indicate if the node meet the matching condition.
  33723. */
  33724. _checkRoot:function(node, tag) {
  33725. var shouldInclude = false;
  33726. node = node || null;
  33727. if (node !== null && node.nodeType) {
  33728. var copy = {};
  33729. if(!this._rootContainer) {
  33730. this._rootContainer = dojo.create("div", {
  33731. style: {
  33732. display: "none"
  33733. }
  33734. }, dojo.body());
  33735. }
  33736. copy.copyNodeParent = document.createElement("div");
  33737. this._rootContainer.appendChild(copy.copyNodeParent);
  33738. copy.copyOfNode = node.cloneNode(false);
  33739. copy.copyNodeParent.appendChild(copy.copyOfNode);
  33740. copy.result = this._getNodes(copy.copyNodeParent, tag);
  33741. copy.result = copy.result || null;
  33742. if (copy.result !== null && copy.result.length > 0) {
  33743. shouldInclude = true;
  33744. }
  33745. dojo.destroy(copy.copyOfNode);
  33746. dojo.destroy(copy.copyNodeParent);
  33747. delete copy.copyOfNode;
  33748. delete copy.copyNodeParent;
  33749. delete copy.result;
  33750. }
  33751. return shouldInclude;
  33752. },
  33753. /**
  33754. This method will load the livetext framework configuration. It will first check if a livetextCfg global variable exists,
  33755. if it does, then it assume that the global variable is the list of the tag configuration entries. This is to improve the performance
  33756. and assume that the bootstrap will create a such javascript object.<b>
  33757. If it does not exist, then it will load from a configuration file. The configuration file is assumed at the same location where
  33758. this file is located. The format of this file is defined as the following
  33759. &nbsp;&nbsp;&nbsp;[<br/>
  33760. &nbsp;&nbsp;&nbsp;{"match":"*.iWidgetSkin[skin]","processEnclosedTags":true,'waitOnPreTag':true,<br/>
  33761. &nbsp;&nbsp;&nbsp;&nbsp;"module":"tagservices", "path":"../../tagservices", "baseClass":"tagservices.skins"},<br/>
  33762. &nbsp;&nbsp;&nbsp;{"match":"*.iw-iWidget","processEnclosedTags":false,'waitOnPreTag':false,<br/>
  33763. &nbsp;&nbsp;&nbsp;&nbsp;"module":"tagservices", "path":"../../tagservices", "baseClass":"tagservices.widgets"}<br/>
  33764. &nbsp;&nbsp;&nbsp;] <p />
  33765. match, the value of the match is the CSS3 selection expression which presents a tag (livetext) matching condition.<b>
  33766. processEnclosedTags, the boolean value to indicate if the enclosed same tag should be presented in this query. a value of true will cause
  33767. all the tags to be processed. a value of false will make the outmost tags to be processed.<b>
  33768. waitOnPreTag, this is not used for 1.1, it is for the future release.
  33769. module, the string value to indicate a javascript module which the tag processor should be loaded against.
  33770. path, the string value to indicate the processor javascript resources.<b>
  33771. baseClass, the javascript class for the tag processor.
  33772. @returns
  33773. */
  33774. _loadTags:function() {
  33775. this._tagTypes = this._tagTypes || null;
  33776. if (this._tagTypes === null) {
  33777. var thisObj = this;
  33778. if (ibmConfig.livetextService) {
  33779. //if we have the livetext configuration exists as a global variable which is loaded by the bootstrap,
  33780. //then we will simply use it. otherwise, we load from the configuration file.
  33781. this._tagTypes = ibmConfig.livetextService;
  33782. }
  33783. else {
  33784. dojo.xhrGet({
  33785. url: dojo.moduleUrl("com.ibm.mm.livetext", "tagservice.entries.cfg"),
  33786. handleAs: "text",
  33787. sync: true,
  33788. load:function(result) {
  33789. thisObj._tagTypes = dojo.fromJson(result);
  33790. },
  33791. error:function(data) {
  33792. console.dir(data);
  33793. }
  33794. });
  33795. }
  33796. }
  33797. },
  33798. /**
  33799. * @param {com.ibm.mashups.livetext.ConfigEntry} entry The entry that should be added to the configuration.
  33800. * @param {boolean} bFront The flag to indicate if the entry should be added to the front of the configuration array or not. true for front, false for end. Default is false for end.
  33801. * @returns
  33802. * @throws The sermantic tag service exception.
  33803. */
  33804. onAddConfigEntry: function(/* com.ibm.mashups.livetext.ConfigEntry */ cfgEntry, bFront) {
  33805. this._loadTags();
  33806. if(!dojo.some(this._tagTypes,
  33807. function(entry){
  33808. return cfgEntry.isEqual(entry);
  33809. })) {
  33810. if (bFront) {
  33811. this._tagTypes.unshift({
  33812. "match":cfgEntry.match,
  33813. "processEnclosedTags":cfgEntry.procEnc,
  33814. 'waitOnPreTag':cfgEntry.wait,
  33815. "module":cfgEntry.mod,
  33816. "path":cfgEntry.path,
  33817. "baseClass":cfgEntry.baseCls,
  33818. "id":cfgEntry.id}
  33819. );
  33820. } else {
  33821. this._tagTypes.push({
  33822. "match":cfgEntry.match,
  33823. "processEnclosedTags":cfgEntry.procEnc,
  33824. 'waitOnPreTag':cfgEntry.wait,
  33825. "module":cfgEntry.mod,
  33826. "path":cfgEntry.path,
  33827. "baseClass":cfgEntry.baseCls,
  33828. "id":cfgEntry.id}
  33829. );
  33830. }
  33831. }
  33832. },
  33833. /**
  33834. * @param {com.ibm.mashups.livetext.ConfigEntry} entry The entry that should be removed from the configuration.
  33835. * @returns
  33836. * @throws The sermantic tag service exception.
  33837. */
  33838. onRemoveConfigEntry: function(/* com.ibm.mashups.livetext.ConfigEntry */ entry) {
  33839. this._loadTags();
  33840. for(var i=0; ; i<this._tagTypes.length) {
  33841. if (entry.isEqual(this._tagTypes[i])) {
  33842. this._tagTypes[i].splice(i, 1);
  33843. }
  33844. else {
  33845. i++;
  33846. }
  33847. }
  33848. },
  33849. /**
  33850. This method is to provide a fall back for backfoward compatibility. If a component is still using the SemTagSvc.parseDom method,
  33851. this method will still ensure the correctness of that component but it is strongly recommended to use the event model.
  33852. * @param {Object} event Not used.
  33853. * @param {DOMNode} node The dom node to be processed.
  33854. @deprecated this methid has been deprecated. Use the publish event to invoke the process of the tags.
  33855. @returns
  33856. */
  33857. parseDom:function(aEvent, node) {
  33858. dojo.publish(this.tagChanged, [node]);
  33859. },
  33860. /**
  33861. This method will register the tag processor module, then load the processor module and create an instance of base class.<b>
  33862. After the tag processor is created, the flag on the tag type object will be set to true. This ensures that each tag processor will
  33863. only have one instance and the module will be loaded only once.
  33864. @param {Object} tag, the tag configuration entry.<b>
  33865. @returns
  33866. */
  33867. _loadTagHandler:function(tag) {
  33868. try {
  33869. dojo.registerModulePath(tag.module, tag.path);
  33870. dojo["require"](tag.baseClass); // JSLINT-IGNORE: array notation needed because otherwise gets stripped by shrinksafe
  33871. var jsonStr = "{create:function(){return new " + tag.baseClass + "()}}";
  33872. var classCreator = dojo.fromJson(jsonStr);
  33873. tag.tagHandler = classCreator.create();
  33874. tag.loaded = true;
  33875. } catch(e) {
  33876. }
  33877. }
  33878. });
  33879. com.ibm.mashups.services.ServiceManager.setService(com.ibm.mashups.livetext.ServiceModel.SERVICE_NAME, "com.ibm.mm.livetext.ServiceModelImpl");
  33880. }
  33881. if(!dojo._hasResource["com.ibm.mashups.livetext.ServiceModel"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  33882. dojo._hasResource["com.ibm.mashups.livetext.ServiceModel"] = true;
  33883. dojo.provide("com.ibm.mashups.livetext.ServiceModel");
  33884. }
  33885. if(!dojo._hasResource["tagservices.skins"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  33886. dojo._hasResource["tagservices.skins"] = true;
  33887. dojo.provide("tagservices.skins");
  33888. dojo.provide("com.ibm.mm.livetext.skins");
  33889. /*
  33890. * This is injected on the fly and not fetched through an API. Therefore we need to define the @ibm-module so that the build process is picking it up
  33891. * @ibm-module iWidget
  33892. */
  33893. /*
  33894. Each skin should have a skin.html and skin.js file.
  33895. skin.html file serves as a template with desirable variables. As a skin developer, you may
  33896. define any number of variables for you to use as long as you setup the variable correctly
  33897. in the process function which is defined in skin.js
  33898. skin.js file is a json string file, it defines all the variables in the skin.html and how they should be created.
  33899. In this file, function process can be defined as follows:
  33900. process:function(skinId,tagId) {
  33901. }
  33902. this function will be called to form all the variables which are used in the skin.html.
  33903. you may have variables in skin.html file like this
  33904. ${var01}
  33905. ${var02}
  33906. When you have these, you will have to define these two variables with correct values. Of course,
  33907. in process function, you have chance to set these variables to other values. Since function process
  33908. will be given two objects, one is the skinId and the other is the tagId (widget id normally), so
  33909. a lot of action can be taken to set up all necessary variables.
  33910. There are two variable that you can use in the skin.html file, but you must not provide the value for,
  33911. these two variables are
  33912. ${widgetBody}
  33913. ${skinId}
  33914. Even if you provide values for these two variables, they will be overwritten;
  33915. */
  33916. dojo.declare("tagservices.skins", null, {
  33917. skinIdPrefix: "mm_ibm_skin_",
  33918. allSkins: [],
  33919. allVars: [],
  33920. tempSkinHtmlObj: null,
  33921. tempSkinJsObj: null,
  33922. isProcessing: 0,
  33923. waitingList: [],
  33924. subscribeHandler: null,
  33925. skinAttachEvent: "/skinservice/attachEnd",
  33926. processTag: function(tag) {
  33927. this.tempSkinHtmlObj = {};
  33928. this.tempSkinJsObj = {};
  33929. if (!tag) {
  33930. return;
  33931. }
  33932. var skinId = tag.getAttribute("skin");
  33933. this._getSkinTemplate(skinId, tag);
  33934. },
  33935. unprocessTag: function(tag) {
  33936. var skinNode = this._findSkinNode(tag);
  33937. var contentNode = skinNode.parentNode;
  33938. contentNode.insertBefore(tag, skinNode);
  33939. com.ibm.mm.enabler.utils.Dom.destroyNode(skinNode);
  33940. },
  33941. _findSkinNode: function(node) {
  33942. var tempNode = node;
  33943. while (tempNode && tempNode.id != this.skinIdPrefix + node.id) {
  33944. tempNode = tempNode.parentNode;
  33945. }
  33946. return tempNode;
  33947. },
  33948. _getSkinTemplate: function(skinId, tag) {
  33949. var aSkin = this.allSkins[skinId];
  33950. if (!aSkin) {
  33951. var thisObj = this;
  33952. var skinMarkupURL = this._getSkinResourceUrl(skinId, "skin.html");
  33953. var skinVarURL = this._getSkinResourceUrl(skinId, "skin.js");
  33954. dojo.xhrGet({
  33955. url: skinMarkupURL,
  33956. handleAs: "text",
  33957. sync: true,
  33958. load: function(htmlData) {
  33959. dojo.xhrGet({
  33960. url: skinVarURL,
  33961. handleAs: "json",
  33962. sync: true,
  33963. load: function(jsData) {
  33964. // remove the copyright in the skin.html
  33965. htmlData = htmlData.replace(/<!--.*-->\s*/, "");
  33966. thisObj.allSkins[skinId] = htmlData;
  33967. thisObj.allVars[skinId] = jsData;
  33968. thisObj.startAttatchSkin(skinId, tag);
  33969. },
  33970. error: function(data) {
  33971. thisObj.allSkins[skinId] = htmlData;
  33972. thisObj.startAttatchSkin(skinId, tag);
  33973. }
  33974. });
  33975. },
  33976. error: function(data) {
  33977. }
  33978. });
  33979. }
  33980. else {
  33981. this.startAttatchSkin(skinId, tag);
  33982. }
  33983. },
  33984. startAttatchSkin: function(skinId, tag) {
  33985. if (this.isProcessing === 0) {
  33986. this.executeReplaceSkin(skinId, tag);
  33987. }
  33988. else {
  33989. this.addToWaitingList(skinId, tag);
  33990. }
  33991. },
  33992. chooseNext: function() {
  33993. if (this.waitingList.length !== 0) {
  33994. var theObject = this.waitingList.pop();
  33995. this.executeReplaceSkin(theObject.skin, theObject.tag);
  33996. }
  33997. },
  33998. addToWaitingList: function(skinId, tag) {
  33999. if (!this.subscribeHandler) {
  34000. this.subscribeHandler = dojo.subscribe(this.skinAttachEvent, this, "chooseNext");
  34001. }
  34002. var waitObj = {};
  34003. waitObj.skin = skinId;
  34004. waitObj.tag = tag;
  34005. this.waitingList.push(waitObj);
  34006. },
  34007. executeReplaceSkin: function(skinId, tag) {
  34008. this.isProcessing = 1;
  34009. var temp = this.allSkins[skinId];
  34010. if (temp) {
  34011. var nodeToReplace = this._getNodeToReplace(tag);
  34012. var parentNode = nodeToReplace.parentNode;
  34013. var anId = dojox.uuid.generateRandomUuid().replace(/\-/g, "");
  34014. var args = this._getArgs(skinId, tag, anId);
  34015. if (!args) {
  34016. return;
  34017. }
  34018. var skinCssURL = this._getSkinResourceUrl(skinId, "skin.css");
  34019. com.ibm.mm.builder.utils.htmlUtil.loadCss(skinCssURL);
  34020. if (builderConfig.isBidi) { //if language is rtl, load the rtl css
  34021. var skinRtlCssURL = this._getSkinResourceUrl(skinId, "skin_rtl.css");
  34022. com.ibm.mm.builder.utils.htmlUtil.loadCss(skinRtlCssURL);
  34023. }
  34024. var newMarkup = dojo.string.substitute(temp, args);
  34025. newMarkup = newMarkup.replace(/\/>/g, "><\/div>");
  34026. var newNode = this._getNodeFromMarkup(newMarkup);
  34027. dojo.addClass(newNode, "mumWidgetTitleBar");
  34028. parentNode.replaceChild(newNode, nodeToReplace);
  34029. var tNode = dojo.byId(anId);
  34030. tNode.parentNode.replaceChild(tag, tNode);
  34031. // fix ie6 performance defect 6909
  34032. if (!(dojo.hasClass(nodeToReplace, "iw-iWidget") || dojo.hasClass(nodeToReplace, "mm_iWidget"))) {
  34033. //dojo.destroy(nodeToReplace);
  34034. }
  34035. // end fix
  34036. var para = {};
  34037. para.widgetId = tag.id;
  34038. para.skinNodeId = newNode.id;
  34039. para.skinParam = args;
  34040. // NOTE: use enabler new SPI to getParent() can't help here, since the widget instance is created after skin creation.
  34041. com.ibm.mashups.services.ServiceManager.getService("eventService").broadcastEvent("com.ibm.mashups.builder.skinLoaded", para);
  34042. }
  34043. this.isProcessing = 0;
  34044. dojo.publish(this.skinAttachEvent, [null]);
  34045. },
  34046. _getSkinResourceUrl: function(skinId, resource) {
  34047. try {
  34048. var skinModel = com.ibm.mm.builder.utils.skinUtil._getSkinModel();
  34049. var skin = com.ibm.mm.builder.utils.skinUtil.getSkinNode(skinId) ||
  34050. com.ibm.mm.builder.utils.skinUtil.getDefaultSkin();
  34051. var url = skinModel.findResourceURL(skin, resource);
  34052. return url;
  34053. }
  34054. catch (ex) {
  34055. }
  34056. return null;
  34057. },
  34058. _getArgs: function(skinId, tag, anId) {
  34059. var args = {};
  34060. //fixme. use the skin substitution to do this.
  34061. //here we will allow users to do things.
  34062. var skinVar = this.allVars[skinId];
  34063. if (skinVar) {
  34064. dojo.mixin(args, skinVar);
  34065. }
  34066. //in case, skin defines the widgetBody and skinId, we need to overwrite.
  34067. args.widgetBody = "<div id='" + anId + "'/>";
  34068. args.skinId = this.skinIdPrefix + tag.id;
  34069. if (!args.process) {
  34070. args.process = function(skinId, tagId) {
  34071. };
  34072. }
  34073. args.process(skinId, tag.id);
  34074. return args;
  34075. },
  34076. _getNodeMarkup: function(tag) {
  34077. var newNode = document.createElement("div");
  34078. newNode.appendChild(tag.cloneNode(true));
  34079. var markup = newNode.innerHTML;
  34080. newNode.removeChild(newNode.firstChild);
  34081. return markup;
  34082. },
  34083. _getNodeFromMarkup: function(markup) {
  34084. var newNode = document.createElement("div");
  34085. newNode.innerHTML = markup;
  34086. return newNode.removeChild(newNode.firstChild);
  34087. },
  34088. _getNodeToReplace: function(tag) {
  34089. var node = dojo.byId(this.skinIdPrefix + tag.id);
  34090. if (!node) {
  34091. node = tag;
  34092. }
  34093. return node;
  34094. },
  34095. _showParent: function(node) {
  34096. var parent = node.parentNode;
  34097. while (parent) {
  34098. parent = parent.parentNode;
  34099. }
  34100. }
  34101. });
  34102. }
  34103. if(!dojo._hasResource["tagservices.widgets"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  34104. dojo._hasResource["tagservices.widgets"] = true;
  34105. dojo.provide("tagservices.widgets");
  34106. dojo.provide("com.ibm.mm.livetext.widgets");
  34107. /*
  34108. * This is injected on the fly and not fetched through an API. Therefore we need to define the @ibm-module so that the build process is picking it up
  34109. * @ibm-module iWidget
  34110. */
  34111. dojo.declare("tagservices.widgets", null, {
  34112. //20349
  34113. queue: [],
  34114. queueHandle: null,
  34115. queueRendering: true,
  34116. constructor: function() {
  34117. //20349. Load the config property to determine if perform queued rendering
  34118. var configService = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);
  34119. queueRendering = configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.QUEUE_RENDERING);
  34120. },
  34121. processTag: function(tag) {
  34122. var id = dojo.attr(tag,"id");
  34123. if (typeof id != "undefined") {
  34124. var lazyLoad = dojo.attr(tag,"lazyLoad");
  34125. var iWidget = com.ibm.mashups.iwidget.model.Factory.getGlobalWidgetModel().find(id);
  34126. if (iWidget === null) {
  34127. // create widget
  34128. iWidget = com.ibm.mashups.iwidget.model.Factory.getGlobalWidgetModel().createWidget(tag);
  34129. }
  34130. if (iWidget) {
  34131. // render widget
  34132. if (!lazyLoad || (lazyLoad && lazyLoad != "true")) {
  34133. //20349.
  34134. if ((queueRendering === true) && !dojo.hasClass(tag,"iw-Standalone")) {
  34135. this.queue.push({priority: dojo.position(tag).y, widgetId: id});
  34136. this.processQueue(false);
  34137. }
  34138. else {
  34139. com.ibm.mashups.iwidget.model.Factory.getGlobalWidgetModel().renderWidget(iWidget);
  34140. }
  34141. }
  34142. else {
  34143. iWidget.lazyLoad = true;
  34144. }
  34145. }
  34146. }
  34147. },
  34148. //20349
  34149. processQueue: function(process) {
  34150. if (this.queue.length>0) {
  34151. if (process) {
  34152. // process queue
  34153. // pick the one of the lowest number
  34154. while (this.queue.length>0) {
  34155. var json = this.queue.shift();
  34156. var iWidget = com.ibm.mashups.iwidget.model.Factory.getGlobalWidgetModel().find(json.widgetId);
  34157. if (iWidget) {
  34158. com.ibm.mashups.iwidget.model.Factory.getGlobalWidgetModel().renderWidget(iWidget);
  34159. break;
  34160. }
  34161. }
  34162. } else {
  34163. // sort
  34164. this.queue.sort(function(node1, node2) {
  34165. return node1.priority - node2.priority;
  34166. });
  34167. }
  34168. if (!this.queueHandle) {
  34169. var that = this;
  34170. this.queueHandle = setTimeout(function() { // this timeout put them in a queue effectively and allows other system/skin JS to be executed first
  34171. that.queueHandle = setTimeout(function() { // this timeout give the browser a little bit of time to render the page before executing any further
  34172. that.queueHandle = null;
  34173. dojo.hitch(that, that.processQueue)(true);
  34174. }, 5);
  34175. }, 0);
  34176. }
  34177. }
  34178. },
  34179. unprocessTag: function(tag) {
  34180. var ns = ["iw-", "mm_"];
  34181. for (var n = 0, l = ns.length; n < l; n++) {
  34182. // search the content nodes
  34183. var contentNodes = dojo.query("." + ns[n] + iwConstants.CSSCLASS_INSTANCE.iwContent, tag);
  34184. // iterate through them and delete them
  34185. for (var i = 0; i < contentNodes.length; i++) {
  34186. com.ibm.mm.enabler.utils.Dom.destroyNode(contentNodes[i]);
  34187. }
  34188. }
  34189. }
  34190. });
  34191. }
  34192. });