prototypePost.js 566 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219
  1. // 8.0.0.3382. Generated 1/14/2019 10:26:32 PM UTC
  2. //***** messagecenter.js *****//
  3. if (typeof console == 'undefined') console = {
  4. log: function () { }
  5. };
  6. // sniff chrome
  7. var CHROME_5_LOCAL = false;
  8. var CHROME = false;
  9. var SAFARI = false;
  10. var FIREFOX = false;
  11. var WEBKIT = false;
  12. var OS_MAC = false;
  13. var IOS = false;
  14. var ANDROID = false;
  15. var MOBILE_DEVICE = false;
  16. var IE = false;
  17. var IE_10_AND_BELOW = false; //ie 10 and lower
  18. var IE_11_AND_ABOVE = false; //ie 11 and above
  19. var BROWSER_VERSION = 5000;
  20. (function () {
  21. if(!window.$axure) window.$axure = function() {};
  22. var useragent = window.navigator.userAgent;
  23. var edgeRegex = /Edge\/([0-9]+)/g;
  24. var edgeMatch = edgeRegex.exec(useragent);
  25. $axure.browser = { isEdge: Boolean(edgeMatch) };
  26. if(!$axure.browser.isEdge) {
  27. var chromeRegex = /Chrome\/([0-9]+).([0-9]+)/g;
  28. var chromeMatch = chromeRegex.exec(useragent);
  29. CHROME = Boolean(chromeMatch);
  30. CHROME_5_LOCAL = chromeMatch &&
  31. Number(chromeMatch[1]) >= 5 &&
  32. location.href.indexOf('file://') >= 0;
  33. }
  34. var safariRegex = /Safari\/([0-9]+)/g;
  35. var safariMatch = safariRegex.exec(useragent);
  36. SAFARI = Boolean(safariMatch) && !CHROME; //because chrome also inserts safari string into user agent
  37. var webkitRegex = /WebKit\//g ;
  38. WEBKIT = Boolean(webkitRegex.exec(useragent));
  39. FIREFOX = useragent.toLowerCase().indexOf('firefox') > -1;
  40. var macRegex = /Mac/g ;
  41. OS_MAC = Boolean(macRegex.exec(window.navigator.platform));
  42. IOS = useragent.match(/iPhone/i) || useragent.match(/iPad/i) || useragent.match(/iPod/i);
  43. ANDROID = useragent.match(/Android/i);
  44. MOBILE_DEVICE = ANDROID || IOS
  45. || navigator.userAgent.match(/webOS/i)
  46. || navigator.userAgent.match(/BlackBerry/i)
  47. || navigator.userAgent.match(/Tablet PC/i)
  48. || navigator.userAgent.match(/Windows Phone/i);
  49. if($.browser) {
  50. if($.browser.msie) IE_10_AND_BELOW = true;
  51. else IE_11_AND_ABOVE = useragent.toLowerCase().indexOf('trident') > -1;
  52. BROWSER_VERSION = $.browser.version;
  53. }
  54. IE = IE_10_AND_BELOW || IE_11_AND_ABOVE;
  55. //Used by sitemap and variables.js getLinkUrl functions so that they know
  56. //whether to embed global variables in URL as query string or hash string
  57. //_shouldSendVars persists the value for sitemap instead of re-checking every time
  58. var _shouldSendVars;
  59. var _shouldSendVarsToServer = function(url) {
  60. if(typeof _shouldSendVars != 'undefined') {
  61. return _shouldSendVars;
  62. }
  63. if(SAFARI || (IE_10_AND_BELOW && BROWSER_VERSION < 10)) {
  64. var urlToCheck = typeof url != 'undefined' ? url : window.location.href;
  65. var serverRegex = /http:\/\/127\.0\.0\.1:[0-9]{5}/g;
  66. var serverMatch = serverRegex.exec(urlToCheck);
  67. var previewRegex = /[0-9]{2}\.[0-9]{2}\.[0-9]{2}/g;
  68. var previewMatch = previewRegex.exec(urlToCheck);
  69. if(Boolean(serverMatch) && Boolean(previewMatch)) {
  70. _shouldSendVars = true;
  71. return _shouldSendVars;
  72. }
  73. }
  74. _shouldSendVars = false;
  75. return _shouldSendVars;
  76. };
  77. $axure.shouldSendVarsToServer = _shouldSendVarsToServer;
  78. })();
  79. (function() {
  80. var _topMessageCenter;
  81. var _messageCenter = {};
  82. var _listeners = [];
  83. var _stateListeners = [];
  84. var _state = {};
  85. var _eventObject = null;
  86. var _queuedMessages = [];
  87. var _initialized = false;
  88. // this is for the non Chrome 5 local scenarios. The "top" message center will dispatch to all the bottom ones
  89. var _childrenMessageCenters = [];
  90. // create $axure if it hasn't been created
  91. if (!window.$axure) window.$axure = function() {};
  92. $axure.messageCenter = _messageCenter;
  93. // isolate scope, and initialize _topMessageCenter.
  94. (function() {
  95. if (!CHROME_5_LOCAL) {
  96. var topAxureWindow = window;
  97. try {
  98. while(topAxureWindow.parent && topAxureWindow.parent !== topAxureWindow
  99. && topAxureWindow.parent.$axure) topAxureWindow = topAxureWindow.parent;
  100. } catch(e) {}
  101. _topMessageCenter = topAxureWindow.$axure.messageCenter;
  102. }
  103. })();
  104. $(window.document).ready(function() {
  105. if (CHROME_5_LOCAL) {
  106. $('body').append("<div id='axureEventReceiverDiv' style='display:none'></div>" +
  107. "<div id='axureEventSenderDiv' style='display:none'></div>");
  108. _eventObject = window.document.createEvent('Event');
  109. _eventObject.initEvent('axureMessageSenderEvent', true, true);
  110. $('#axureEventReceiverDiv').bind('axureMessageReceiverEvent', function () {
  111. var request = JSON.parse($(this).text());
  112. _handleRequest(request);
  113. });
  114. } else {
  115. if (_topMessageCenter != _messageCenter) {
  116. _topMessageCenter.addChildMessageCenter(_messageCenter);
  117. console.log('adding from ' + window.location.toString());
  118. }
  119. }
  120. });
  121. var _handleRequest = function (request) {
  122. // route the request to all the listeners
  123. for(var i = 0; i < _listeners.length; i++) _listeners[i](request.message, request.data);
  124. // now handle the queued messages if we're initializing
  125. if (request.message == 'initialize') {
  126. _initialized = true;
  127. // send all the queued messages and return
  128. for (var i = 0; i < _queuedMessages.length; i++) {
  129. var qRequest = _queuedMessages[i];
  130. _messageCenter.postMessage(qRequest.message, qRequest.data);
  131. }
  132. _queuedMessages = [];
  133. }
  134. // and then handle the set state messages, if necessary
  135. if (request.message == 'setState') {
  136. _state[request.data.key] = request.data.value;
  137. for (var i = 0; i < _stateListeners.length; i++) {
  138. var keyListener = _stateListeners[i];
  139. // if thep passed a null or empty value, always post the message
  140. if (!keyListener.key || keyListener.key == request.data.key) {
  141. keyListener.listener(request.data.key, request.data.value);
  142. }
  143. }
  144. }
  145. };
  146. // -----------------------------------------------------------------------------------------
  147. // This method allows for dispatching messages in the non-chromelocal scenario.
  148. // Each child calls this on _topMessageCenter
  149. // -----------------------------------------------------------------------------------------
  150. _messageCenter.addChildMessageCenter = function(messageCenter) {
  151. _childrenMessageCenters[_childrenMessageCenters.length] = messageCenter;
  152. };
  153. // -----------------------------------------------------------------------------------------
  154. // This method allows for dispatching messages in the non-chromelocal scenario.
  155. // Each child calls this on _topMessageCenter
  156. // -----------------------------------------------------------------------------------------
  157. _messageCenter.dispatchMessage = function(message, data) {
  158. _handleRequest({
  159. message: message,
  160. data: data
  161. });
  162. };
  163. // -----------------------------------------------------------------------------------------
  164. // -----------------------------------------------------------------------------------------
  165. _messageCenter.dispatchMessageRecursively = function(message, data) {
  166. console.log("dispatched to " + window.location.toString());
  167. // dispatch to the top center first
  168. _messageCenter.dispatchMessage(message, data);
  169. $('iframe').each(function(index, frame) {
  170. //try,catch to handle permissions error in FF when loading pages from another domain
  171. try {
  172. if (frame.contentWindow.$axure && frame.contentWindow.$axure.messageCenter) {
  173. frame.contentWindow.$axure.messageCenter.dispatchMessageRecursively(message, data);
  174. }
  175. }catch(e) {}
  176. });
  177. };
  178. var _combineEventMessages = false;
  179. var _compositeEventMessageData = [];
  180. _messageCenter.startCombineEventMessages = function() {
  181. _combineEventMessages = true;
  182. }
  183. _messageCenter.endCombineEventMessages = function () {
  184. _messageCenter.sendCompositeEventMessage();
  185. _combineEventMessages = false;
  186. }
  187. _messageCenter.sendCompositeEventMessage = function () {
  188. _messageCenter.postMessage('axCompositeEventMessage', _compositeEventMessageData);
  189. _compositeEventMessageData = [];
  190. }
  191. _messageCenter.postMessage = function (message, data) {
  192. if(_combineEventMessages) {
  193. if(message == 'axEvent' || message == 'axCase' || message == 'axAction' || message == 'axEventComplete') {
  194. _compositeEventMessageData.push({ 'message': message, 'data': data });
  195. if(_compositeEventMessageData.length >= 10) _messageCenter.sendCompositeEventMessage();
  196. return;
  197. }
  198. }
  199. if(!CHROME_5_LOCAL) {
  200. _topMessageCenter.dispatchMessageRecursively(message, data);
  201. } else {
  202. var request = {
  203. message: message,
  204. data: data
  205. };
  206. if(_initialized) {
  207. var senderDiv = window.document.getElementById('axureEventSenderDiv');
  208. var messageText = JSON.stringify(request);
  209. // console.log('sending event: ' + messageText);
  210. senderDiv.innerText = messageText;
  211. senderDiv.dispatchEvent(_eventObject);
  212. // console.log('event sent');
  213. } else {
  214. _queuedMessages[_queuedMessages.length] = request;
  215. }
  216. }
  217. };
  218. _messageCenter.setState = function(key, value) {
  219. var data = {
  220. key: key,
  221. value: value
  222. };
  223. _messageCenter.postMessage('setState', data);
  224. };
  225. _messageCenter.getState = function(key) {
  226. return _state[key];
  227. };
  228. _messageCenter.addMessageListener = function(listener) {
  229. _listeners[_listeners.length] = listener;
  230. };
  231. _messageCenter.addStateListener = function(key, listener) {
  232. _stateListeners[_stateListeners.length] = {
  233. key: key,
  234. listener: listener
  235. };
  236. };
  237. })();
  238. //***** events.js *****//
  239. // ******* Features MANAGER ******** //
  240. $axure.internal(function($ax) {
  241. var _features = $ax.features = {};
  242. var _supports = _features.supports = {};
  243. _supports.touchstart = typeof window.ontouchstart !== 'undefined';
  244. _supports.touchmove = typeof window.ontouchmove !== 'undefined';
  245. _supports.touchend = typeof window.ontouchend !== 'undefined';
  246. _supports.mobile = _supports.touchstart && _supports.touchend && _supports.touchmove;
  247. // Got this from http://stackoverflow.com/questions/11381673/javascript-solution-to-detect-mobile-browser
  248. var check = navigator.userAgent.match(/Android/i)
  249. || navigator.userAgent.match(/webOS/i)
  250. || navigator.userAgent.match(/iPhone/i)
  251. || navigator.userAgent.match(/iPad/i)
  252. || navigator.userAgent.match(/iPod/i)
  253. || navigator.userAgent.match(/BlackBerry/i)
  254. || navigator.userAgent.match(/Tablet PC/i)
  255. || navigator.userAgent.match(/Windows Phone/i);
  256. _supports.windowsMobile = navigator.userAgent.match(/Tablet PC/i) || navigator.userAgent.match(/Windows Phone/i);
  257. if(!check && _supports.mobile) {
  258. _supports.touchstart = false;
  259. _supports.touchmove = false;
  260. _supports.touchend = false;
  261. _supports.mobile = false;
  262. }
  263. var _eventNames = _features.eventNames = {};
  264. _eventNames.mouseDownName = _supports.touchstart ? 'touchstart' : 'mousedown';
  265. _eventNames.mouseUpName = _supports.touchend ? 'touchend' : 'mouseup';
  266. _eventNames.mouseMoveName = _supports.touchmove ? 'touchmove' : 'mousemove';
  267. });
  268. // ******* EVENT MANAGER ******** //
  269. $axure.internal(function($ax) {
  270. var _objectIdToEventHandlers = {};
  271. var _jBrowserEvent = undefined;
  272. $ax.setjBrowserEvent = function(event) {
  273. _jBrowserEvent = event;
  274. };
  275. $ax.getjBrowserEvent = function() {
  276. return _jBrowserEvent;
  277. };
  278. var _event = {};
  279. $ax.event = _event;
  280. //initilize state
  281. _event.mouseOverObjectId = '';
  282. _event.mouseDownObjectId = '';
  283. _event.mouseOverIds = [];
  284. var EVENT_NAMES = ['mouseenter', 'mouseleave', 'contextmenu', 'change', 'focus', 'blur'];
  285. // Tap, double tap, and touch move, or synthetic.
  286. if(!$ax.features.supports.mobile) {
  287. EVENT_NAMES[EVENT_NAMES.length] = 'click';
  288. EVENT_NAMES[EVENT_NAMES.length] = 'dblclick';
  289. EVENT_NAMES[EVENT_NAMES.length] = 'mousemove';
  290. }
  291. // add the event names for the touch events
  292. EVENT_NAMES[EVENT_NAMES.length] = $ax.features.eventNames.mouseDownName;
  293. EVENT_NAMES[EVENT_NAMES.length] = $ax.features.eventNames.mouseUpName;
  294. for(var i = 0; i < EVENT_NAMES.length; i++) {
  295. var eventName = EVENT_NAMES[i];
  296. //we need the function here to circumvent closure modifying eventName
  297. _event[eventName] = (function(event_Name) {
  298. return function(elementId, fn) {
  299. var elementIdQuery = $jobj(elementId);
  300. var type = $ax.getTypeFromElementId(elementId);
  301. //we need specially track link events so we can enable and disable them along with
  302. //their parent widgets
  303. if(elementIdQuery.is('a')) _attachCustomObjectEvent(elementId, event_Name, fn);
  304. //see notes below
  305. else if($ax.IsTreeNodeObject(type)) _attachTreeNodeEvent(elementId, event_Name, fn);
  306. else if ($ax.IsImageFocusable(type) && (event_Name == 'focus' || event_Name == 'blur')) {
  307. var suitableChild;
  308. var imgChild = $ax.repeater.applySuffixToElementId(elementId, '_img');
  309. var divChild = $ax.repeater.applySuffixToElementId(elementId, '_div');
  310. for (var j = 0; j < elementIdQuery[0].children.length; j++) {
  311. if (elementIdQuery[0].children[j].id == imgChild) suitableChild = imgChild;
  312. if (!suitableChild && elementIdQuery[0].children[j].id == divChild) suitableChild = divChild;
  313. }
  314. if(!suitableChild) suitableChild = imgChild;
  315. _attachDefaultObjectEvent($jobj(suitableChild), elementId, event_Name, fn);
  316. } else {
  317. var inputId = $ax.INPUT(elementId);
  318. var isInput = $jobj(inputId).length != 0;
  319. var id = isInput && (event_Name == 'focus' || event_Name == 'blur') ? inputId : elementId;
  320. _attachDefaultObjectEvent($jobj(id), elementId, event_Name, fn);
  321. }
  322. };
  323. })(eventName);
  324. }
  325. var AXURE_TO_JQUERY_EVENT_NAMES = {
  326. 'onMouseOver': 'mouseenter',
  327. 'onMouseOut': 'mouseleave',
  328. 'onContextMenu': 'contextmenu',
  329. 'onChange': 'change',
  330. 'onFocus': 'focus',
  331. 'onLostFocus': 'blur'
  332. };
  333. // Tap, double tap, and touch move, or synthetic.
  334. if(!$ax.features.supports.mobile) {
  335. AXURE_TO_JQUERY_EVENT_NAMES.onClick = 'click';
  336. AXURE_TO_JQUERY_EVENT_NAMES.onDoubleClick = 'dblclick';
  337. AXURE_TO_JQUERY_EVENT_NAMES.onMouseMove = 'mousemove';
  338. }
  339. AXURE_TO_JQUERY_EVENT_NAMES.onMouseDown = $ax.features.eventNames.mouseDownName;
  340. AXURE_TO_JQUERY_EVENT_NAMES.onMouseUp = $ax.features.eventNames.mouseUpName;
  341. //for dp, if mouse entered without leaving, don't fire mouse enter again
  342. var mouseEnterGuard = {};
  343. var _attachEvents = function (diagramObject, elementId, doMouseEnterGuard) {
  344. var inputId = $ax.repeater.applySuffixToElementId(elementId, '_input');
  345. var id = $jobj(inputId).length ? inputId : elementId;
  346. for(var eventName in diagramObject.interactionMap) {
  347. var jQueryEventName = AXURE_TO_JQUERY_EVENT_NAMES[eventName];
  348. if(!jQueryEventName) continue;
  349. _event[jQueryEventName](id,
  350. //this is needed to escape closure
  351. (function(axEventObject) {
  352. return function (e) {
  353. if(e.type == 'mouseenter' && doMouseEnterGuard) {
  354. if(mouseEnterGuard[elementId]) return;
  355. else mouseEnterGuard[elementId] = true;
  356. }
  357. $ax.setjBrowserEvent(e);
  358. // console.log(axEventObject.description);
  359. var eventInfo = $ax.getEventInfoFromEvent($ax.getjBrowserEvent(), false, elementId);
  360. _handleEvent(elementId, eventInfo, axEventObject);
  361. };
  362. })(diagramObject.interactionMap[eventName])
  363. );
  364. if(jQueryEventName.toLowerCase() == 'mouseenter' && doMouseEnterGuard) {
  365. $jobj(elementId).on('mouseleave touchend', function() {
  366. mouseEnterGuard[elementId] = false;
  367. });
  368. }
  369. }
  370. };
  371. var _descriptionToKey = { 'OnFocus': 'onFocus', 'OnLostFocus': 'onLostFocus' };
  372. var _createProxies = function(diagramObject, elementId) {
  373. var createFocus = _needsProxy(diagramObject, elementId, 'onFocus');
  374. var createLostFocus = _needsProxy(diagramObject, elementId, 'onLostFocus');
  375. if(!createFocus && !createLostFocus) return;
  376. if(!diagramObject.interactionMap) diagramObject.interactionMap = {};
  377. if(createFocus) diagramObject.interactionMap.onFocus = { proxy: true, description: 'OnFocus' };
  378. if(createLostFocus) diagramObject.interactionMap.onLostFocus = { proxy: true, description: 'OnLostFocus' };
  379. }
  380. var preventDefaultEvents = ['OnContextMenu', 'OnKeyUp', 'OnKeyDown'];
  381. var allowBubble = ['OnFocus', 'OnResize', 'OnMouseOut', 'OnMouseOver'];
  382. var _canClick = true;
  383. var _startScroll = [];
  384. var _setCanClick = function(canClick) {
  385. _canClick = canClick;
  386. if(_canClick) _startScroll = [$(window).scrollLeft(), $(window).scrollTop()];
  387. };
  388. var _getCanClick = function() {
  389. if(!$ax.features.supports.mobile) return true;
  390. var endScroll = [$(window).scrollLeft(), $(window).scrollTop()];
  391. return _canClick && _startScroll[0] == endScroll[0] && _startScroll[1] == endScroll[1];
  392. };
  393. //var _notAllowedInvisible = function (type) {
  394. // $ax.getTypeFromElementId(elementId);
  395. // return !$ax.public.fn.IsReferenceDiagramObject(type) && !$ax.public.fn.IsLayer(type);
  396. //}
  397. var _notAllowedInvisible = function (id) {
  398. var type = $ax.getTypeFromElementId(id);
  399. if ($ax.public.fn.IsReferenceDiagramObject(type) || $ax.public.fn.IsLayer(type)) return false;
  400. return !($ax.public.fn.IsVector(type) && _hasCompoundImage(id));
  401. }
  402. var _hasCompoundImage = function (id) {
  403. var query = $jobj(id);
  404. return $ax.public.fn.isCompoundVectorHtml(query[0]);
  405. }
  406. var _suppressedEvents = {}; // Suppressed for next occurance.
  407. var _blockedEvents = {}; // Blocked until unblocked.
  408. _event.addSuppressedEvent = function(id, event) {
  409. if(!_suppressedEvents[id]) _suppressedEvents[id] = [];
  410. var events = _suppressedEvents[id];
  411. if(events.indexOf(event) != -1) return;
  412. events.push(event);
  413. }
  414. _event.blockEvent = function(id, event) {
  415. if(!_blockedEvents[id]) _blockedEvents[id] = {};
  416. var events = _blockedEvents[id];
  417. if(events[event]) ++events[event];
  418. else events[event] = 1;
  419. return function() { _unblockEvent(id, event); };
  420. }
  421. var _isSuppressedEvent = function(id, event) {
  422. var suppressedEvents = _suppressedEvents[id];
  423. var blockedEvents = _blockedEvents[id];
  424. return (suppressedEvents && suppressedEvents.indexOf(event) != -1) || (blockedEvents && blockedEvents[event]);
  425. }
  426. var _removeSuppressedEvent = function(id, event) {
  427. var events = _suppressedEvents[id];
  428. if(!events) return;
  429. if(events.length == 1) {
  430. delete _suppressedEvents[id];
  431. } else {
  432. var eventIndex = events.indexOf(event);
  433. for(var i = eventIndex + 1; i < events.length; i++) events[i - 1] = events[i];
  434. events.pop();
  435. }
  436. }
  437. var _unblockEvent = function(id, event) {
  438. var events = _blockedEvents[id];
  439. if(events) {
  440. if(--events[event] > 0) return;
  441. }
  442. _removeSuppressedEvent(id, event);
  443. }
  444. var _unblockEvent = function(id, event) {
  445. var events = _blockedEvents[id];
  446. if(events) {
  447. if(--events[event] > 0) return;
  448. }
  449. _removeSuppressedEvent(id, event);
  450. }
  451. var eventNesting = 0;
  452. var eventNestingTime = new Date().getTime();
  453. var _handleEvent = $ax.event.handleEvent = function (elementId, eventInfo, axEventObject, skipShowDescriptions, synthetic) {
  454. var eventDescription = axEventObject.description;
  455. if(_enteredWidgets[elementId] && eventDescription == 'OnMouseEnter') return; // Suppress entering a widget when already in widget (ie only)
  456. if(_isSuppressedEvent(elementId, eventDescription)) {
  457. _removeSuppressedEvent(elementId, eventDescription);
  458. return;
  459. }
  460. if(axEventObject.proxy) {
  461. var firingId = _widgetToFocusParent[elementId];
  462. if(firingId) {
  463. var firingObj = $obj(firingId);
  464. var nextEventObj = firingObj.interactionMap && firingObj.interactionMap[_descriptionToKey[eventDescription]];
  465. if(!nextEventObj) nextEventObj = axEventObject;
  466. _handleEvent(firingId, eventInfo, nextEventObj, skipShowDescriptions, synthetic);
  467. }
  468. return;
  469. }
  470. // var x = JSON.stringify(eventInfo);
  471. // var y = JSON.stringify(axEventObject);
  472. var fireTime = new Date().getTime();
  473. if(fireTime - eventNestingTime > 100) {
  474. eventNestingTime = fireTime;
  475. eventNesting = 0;
  476. }
  477. if(eventNesting === 0) {
  478. $ax.recording.maybeRecordEvent(elementId, eventInfo, axEventObject, fireTime);
  479. }
  480. eventNesting += 1;
  481. if(!_getCanClick() && (eventDescription == 'OnClick' || eventDescription == 'OnPageClick')) return;
  482. // If you are supposed to suppress, do that right away.
  483. if(suppressedEventStatus[eventDescription]) {
  484. return;
  485. }
  486. var currentEvent = $ax.getjBrowserEvent();
  487. if(!synthetic && currentEvent && currentEvent.originalEvent && currentEvent.originalEvent.handled && !eventInfo.isMasterEvent) return;
  488. if(!synthetic && elementId && !$ax.style.getObjVisible(elementId) && _notAllowedInvisible(elementId)) return;
  489. //if debug
  490. var axObj = $obj(elementId);
  491. var axObjLabel = axObj ? axObj.label : eventInfo.label;
  492. var axObjType = axObj ? axObj.friendlyType : eventInfo.friendlyType;
  493. if(!skipShowDescriptions || eventDescription == 'OnPageLoad') $ax.messageCenter.postMessage('axEvent', { 'label': axObjLabel, 'type': axObjType, 'event': axEventObject });
  494. var bubble = true;
  495. var showCaseDescriptions = !skipShowDescriptions && _shouldShowCaseDescriptions(axEventObject);
  496. if(!showCaseDescriptions) {
  497. //handle case descriptions
  498. var caseGroups = [];
  499. var currentCaseGroup = [];
  500. caseGroups[0] = currentCaseGroup;
  501. // Those refreshes not after a wait
  502. var guaranteedRefreshes = {};
  503. var caseGroupIndex = 0;
  504. for(var i = 0; i < axEventObject.cases.length; i++) {
  505. var currentCase = axEventObject.cases[i];
  506. if(currentCase.isNewIfGroup && i != 0) {
  507. caseGroupIndex++;
  508. currentCaseGroup = [];
  509. caseGroups[caseGroups.length] = currentCaseGroup;
  510. // Joon: Isn't caseGroups.length always equal to caseGroupIndex?
  511. }
  512. currentCaseGroup[currentCaseGroup.length] = currentCase;
  513. for(var j = 0; j < currentCase.actions.length; j++) {
  514. var action = currentCase.actions[j];
  515. if(action.action == 'wait') break;
  516. if(action.action != 'refreshRepeater') continue;
  517. for(var k = 0; k < action.repeatersToRefresh.length; k++) {
  518. var id = $ax.getElementIdsFromPath(action.repeatersToRefresh[k], eventInfo)[0];
  519. if(id) guaranteedRefreshes[id] = caseGroupIndex;
  520. }
  521. }
  522. }
  523. for(var i = 0; i < caseGroups.length; i++) {
  524. var groupRefreshes = [];
  525. for(var key in guaranteedRefreshes) {
  526. if(guaranteedRefreshes[key] == i) groupRefreshes[groupRefreshes.length] = key;
  527. }
  528. bubble = _handleCaseGroup(eventInfo, caseGroups[i], groupRefreshes) && bubble;
  529. }
  530. } else {
  531. _showCaseDescriptions(elementId, eventInfo, axEventObject, synthetic);
  532. bubble = false;
  533. }
  534. // If not handled, synthetically bubble if you can
  535. if(bubble && _widgetToFocusParent[elementId]) {
  536. firingId = _widgetToFocusParent[elementId];
  537. if(firingId) {
  538. firingObj = $obj(firingId);
  539. nextEventObj = firingObj.interactionMap && firingObj.interactionMap[_descriptionToKey[axEventObject.description]];
  540. if(!nextEventObj) nextEventObj = axEventObject;
  541. _handleEvent(firingId, eventInfo, nextEventObj, skipShowDescriptions, synthetic);
  542. }
  543. return;
  544. }
  545. // Only trigger a supression if it handled this event
  546. if(!bubble && suppressingEvents[eventDescription]) {
  547. suppressedEventStatus[suppressingEvents[eventDescription]] = true;
  548. }
  549. $ax.action.flushAllResizeMoveActions(eventInfo);
  550. // This should not be needed anymore. All refreshes should be inserted, or handled earlier.
  551. var repeaters = $ax.deepCopy($ax.action.repeatersToRefresh);
  552. while($ax.action.repeatersToRefresh.length) $ax.action.repeatersToRefresh.pop();
  553. for(i = 0; i < repeaters.length; i++) $ax.repeater.refreshRepeater(repeaters[i], eventInfo);
  554. if(currentEvent && currentEvent.originalEvent) {
  555. currentEvent.originalEvent.handled = !synthetic && !bubble && allowBubble.indexOf(eventDescription) == -1;
  556. //currentEvent.originalEvent.donotdrag = currentEvent.donotdrag || (!bubble && eventDescription == 'OnMouseDown');
  557. // Prevent default if necessary
  558. if(currentEvent.originalEvent.handled && preventDefaultEvents.indexOf(eventDescription) != -1) {
  559. currentEvent.preventDefault();
  560. }
  561. }
  562. eventNesting -= 1;
  563. if(!showCaseDescriptions) $ax.messageCenter.postMessage('axEventComplete');
  564. };
  565. var _handleScrollEvent = function (elementId, eventInfo, originalEvent, scrolledUp, scrolledDown, interactionMap, skipShowDescription, synthetic) {
  566. if (!interactionMap) return;
  567. if (interactionMap.onScroll) _handleEvent(elementId, eventInfo, interactionMap.onScroll, skipShowDescription, synthetic);
  568. var wasHandled = originalEvent.handled;
  569. if (interactionMap.onScrollUp && scrolledUp) {
  570. originalEvent.handled = false;
  571. _handleEvent(elementId, eventInfo, interactionMap.onScrollUp, skipShowDescription, synthetic);
  572. } else if (interactionMap.onScrollDown && scrolledDown) {
  573. originalEvent.handled = false;
  574. _handleEvent(elementId, eventInfo, interactionMap.onScrollDown, skipShowDescription, synthetic);
  575. }
  576. originalEvent.handled |= wasHandled;
  577. }
  578. var _showCaseDescriptions = function(elementId, eventInfo, axEventObject, synthetic) {
  579. if(axEventObject.cases.length == 0) return true;
  580. var linksId = elementId + "linkBox";
  581. $('#' + linksId).remove();
  582. var $container = $("<div class='intcases' id='" + linksId + "'></div>");
  583. if(!_isEventSimulating(axEventObject)) {
  584. var copy = $ax.eventCopy(eventInfo);
  585. for(var i = 0; i < axEventObject.cases.length; i++) {
  586. var $link = $("<div class='intcaselink'>" + axEventObject.cases[i].description + "</div>");
  587. $link.click(function(j) {
  588. return function () {
  589. var currentCase = axEventObject.cases[j];
  590. $ax.messageCenter.postMessage('axCase', { 'description': currentCase.description });
  591. for(var k = 0; k < currentCase.actions.length; k++) {
  592. $ax.messageCenter.postMessage('axAction', { 'description': currentCase.actions[k].description });
  593. }
  594. $ax.messageCenter.postMessage('axEventComplete');
  595. var bubble = $ax.action.dispatchAction(copy, axEventObject.cases[j].actions);
  596. $ax.action.flushAllResizeMoveActions(copy);
  597. $('#' + linksId).remove();
  598. return bubble;
  599. };
  600. } (i)
  601. );
  602. $container.append($link);
  603. }
  604. } else {
  605. var fullDescription = axEventObject.description + ":<br>";
  606. for(var i = 0; i < axEventObject.cases.length; i++) {
  607. var currentCase = axEventObject.cases[i];
  608. fullDescription += "&nbsp;&nbsp;" + currentCase.description.replace(/<br>/g, '<br>&nbsp;&nbsp;') + ":<br>";
  609. for(var j = 0; j < currentCase.actions.length; j++) {
  610. fullDescription += "&nbsp;&nbsp;&nbsp;&nbsp;" + currentCase.actions[j].description.replace(/<br>/g, '<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;') + "<br>";
  611. }
  612. }
  613. fullDescription = fullDescription.substring(0, fullDescription.length - 4);
  614. var $link = $("<div class='intcaselink'>" + fullDescription + "</div>");
  615. $link.click(function() {
  616. _handleEvent(elementId, eventInfo, axEventObject, true, synthetic);
  617. $ax.messageCenter.postMessage('axEventComplete');
  618. $('#' + linksId).remove();
  619. return;
  620. });
  621. $container.append($link);
  622. }
  623. $container.mouseleave(function(e) { $ax.legacy.SuppressBubble(e); });
  624. $('body').append($container);
  625. _showCaseLinks(eventInfo, linksId);
  626. };
  627. var _showCaseLinks = function(eventInfo, linksId) {
  628. var links = window.document.getElementById(linksId);
  629. links.style.top = eventInfo.pageY;
  630. var left = eventInfo.pageX;
  631. links.style.left = left;
  632. $ax.visibility.SetVisible(links, true);
  633. $ax.legacy.BringToFront(linksId, true);
  634. // Switch to using jquery if this is still needed. Really old legacy code, likely for a browser no longer supported.
  635. //$ax.legacy.RefreshScreen();
  636. };
  637. var _shouldShowCaseDescriptions = function(axEventObject) {
  638. if($ax.document.configuration.linkStyle == "alwaysDisplayTargets") return true;
  639. if($ax.document.configuration.linkStyle == "neverDisplayTargets") return false;
  640. if(axEventObject.cases.length == 0) return false;
  641. if(_isEventSimulating(axEventObject)) return false;
  642. if(axEventObject.cases.length >= 2) return true;
  643. return false;
  644. };
  645. var _isEventSimulating = function(axEventObject) {
  646. for(var i = 0; i < axEventObject.cases.length; i++) {
  647. if(axEventObject.cases[i].condition) return true;
  648. }
  649. return false;
  650. };
  651. var _handleCaseGroup = function(eventInfo, caseGroup, groupRefreshes) {
  652. for(var i = 0; i < caseGroup.length; i++) {
  653. var currentCase = caseGroup[i];
  654. if(!currentCase.condition || _processCondition(currentCase.condition, eventInfo)) {
  655. $ax.messageCenter.postMessage('axCase', { 'description': currentCase.description });
  656. for(var j = 0; j < currentCase.actions.length; j++) {
  657. if(currentCase.actions[j].action != 'refreshRepeater') $ax.messageCenter.postMessage('axAction', { 'description': currentCase.actions[j].description });
  658. }
  659. for(var j = 0; j < currentCase.actions.length; j++) {
  660. var action = currentCase.actions[j];
  661. if(action.action == 'wait') break;
  662. if(action.action != 'refreshRepeater') continue;
  663. for(var k = 0; k < action.repeatersToRefresh.length; k++) {
  664. var id = $ax.getElementIdsFromPath(action.repeatersToRefresh[i], eventInfo)[i];
  665. if(id) {
  666. var index = groupRefreshes.indexOf(id);
  667. if(index != -1) $ax.splice(groupRefreshes, index);
  668. }
  669. }
  670. }
  671. // Any guaranteed refreshes that aren't accounted for must be run still.
  672. $ax.action.tryRefreshRepeaters(groupRefreshes, eventInfo);
  673. $ax.action.dispatchAction(eventInfo, currentCase.actions);
  674. return false;
  675. }
  676. }
  677. // Any guaranteed refreshes that aren't accounted for must be run still.
  678. $ax.action.tryRefreshRepeaters(groupRefreshes, eventInfo);
  679. return true;
  680. };
  681. var _processCondition = function(expr, eventInfo) {
  682. return $ax.expr.evaluateExpr(expr, eventInfo);
  683. };
  684. var _attachTreeNodeEvent = function(elementId, eventName, fn) {
  685. //we need to set the cursor here because we want to make sure that every tree node has the default
  686. //cursor set and then it's overridden if it has a click
  687. if(eventName == 'click') window.document.getElementById(elementId).style.cursor = 'pointer';
  688. _attachCustomObjectEvent(elementId, eventName, fn);
  689. };
  690. var _attachDefaultObjectEvent = function(elementIdQuery, elementId, eventName, fn) {
  691. var func = function() {
  692. if(!$ax.style.IsWidgetDisabled(elementId)) return fn.apply(this, arguments);
  693. return true;
  694. };
  695. var bind = !elementIdQuery[eventName];
  696. if(bind) elementIdQuery.bind(eventName, func);
  697. else elementIdQuery[eventName](func);
  698. };
  699. var _attachCustomObjectEvent = function(elementId, eventName, fn) {
  700. var handlers = _objectIdToEventHandlers[elementId];
  701. if(!handlers) _objectIdToEventHandlers[elementId] = handlers = {};
  702. var fnList = handlers[eventName];
  703. if(!fnList) handlers[eventName] = fnList = [];
  704. fnList[fnList.length] = fn;
  705. };
  706. var _fireObjectEvent = function(elementId, event, originalArgs) {
  707. var element = window.document.getElementById(elementId);
  708. var handlerList = _objectIdToEventHandlers[elementId] && _objectIdToEventHandlers[elementId][event];
  709. if(handlerList) {
  710. for(var i = 0; i < handlerList.length; i++) handlerList[i].apply(element, originalArgs);
  711. }
  712. eventNesting -= 1;
  713. };
  714. var _layerToFocusableWidget = {};
  715. var _widgetToFocusParent = {};
  716. _event.layerMapFocus = function(layer, elementId) {
  717. var mainObj = layer.objs[0];
  718. // If first child non existant return
  719. if (!mainObj) return;
  720. var mainId = $ax.getElementIdFromPath([mainObj.id], { relativeTo: elementId });
  721. _widgetToFocusParent[mainId] = elementId;
  722. // If first child is a layer, call recursively
  723. if ($ax.public.fn.IsLayer(mainObj.type)) {
  724. _event.layerMapFocus(mainObj, mainId);
  725. var baseId = _layerToFocusableWidget[mainId];
  726. if(baseId) _layerToFocusableWidget[elementId] = baseId;
  727. return;
  728. }
  729. _layerToFocusableWidget[elementId] = mainId;
  730. }
  731. var _needsProxy = function(obj, id, proxyName) {
  732. // layers don't need on focus ever, proxies will handle them
  733. if ($ax.public.fn.IsLayer(obj.type)) return false;
  734. // If you already focus you don't need to force yourself to proxy.
  735. if(obj.interactionMap && obj.interactionMap[proxyName]) return false;
  736. var parentId = _widgetToFocusParent[id];
  737. if(parentId) return _needsProxyHelper(parentId, proxyName);
  738. return false;
  739. }
  740. var _needsProxyHelper = function(id, proxyName) {
  741. var obj = $obj(id);
  742. if(obj.interactionMap && obj.interactionMap[proxyName]) return true;
  743. var parentId = _widgetToFocusParent[id];
  744. if(parentId) return _needsProxyHelper(parentId, proxyName);
  745. return false;
  746. }
  747. //for button shapes and images the img is focusable instead of the div to get better outlines
  748. // For layers, we remember who their proxy is.
  749. $ax.event.getFocusableWidgetOrChildId = function (elementId) {
  750. var mappedId = _layerToFocusableWidget[elementId];
  751. if (mappedId) elementId = mappedId;
  752. var inputId = $ax.repeater.applySuffixToElementId(elementId, '_input');
  753. var inputQuery = $jobj(inputId);
  754. if(inputQuery.length > 0) return inputId;
  755. var imgId = $ax.repeater.applySuffixToElementId(elementId, '_img');
  756. var imgQuery = $jobj(imgId);
  757. if (imgQuery.length > 0) return imgId;
  758. var divId = $ax.repeater.applySuffixToElementId(elementId, '_div');
  759. var divQuery = $jobj(divId);
  760. if (divQuery.length > 0) return divId;
  761. return elementId;
  762. };
  763. var _enteredWidgets = {};
  764. // key is the suppressing event, and the value is the event that is supressed
  765. var suppressingEvents = {};
  766. // key is the event that will cancel the suppression, and value is the event that was being suppressed
  767. var cancelSuppressions = {};
  768. // suppressed event maps to true if it is supressed
  769. var suppressedEventStatus = {};
  770. var initSuppressingEvents = function () {
  771. suppressingEvents['OnLongClick'] = 'OnClick';
  772. cancelSuppressions['onMouseDown'] = 'OnClick';
  773. // Have to cancel suppressed event here. Only works for non-synthetic events currently
  774. for(var key in cancelSuppressions) {
  775. var jEventName = AXURE_TO_JQUERY_EVENT_NAMES[key];
  776. if(!jEventName) continue;
  777. $('body').bind(jEventName, function () {
  778. suppressedEventStatus[cancelSuppressions[key]] = false;
  779. });
  780. }
  781. };
  782. // TODO: It may be a good idea to split this into multiple functions, or at least pull out more similar functions into private methods
  783. var _initializeObjectEvents = function(query, refreshType) {
  784. query.each(function(dObj, elementId) {
  785. var $element = $jobj(elementId);
  786. var itemId = $ax.repeater.getItemIdFromElementId(elementId);
  787. // Focus has to be done before on focus fires
  788. // Set up focus
  789. if ($ax.public.fn.IsTextArea(dObj.type) || $ax.public.fn.IsTextBox(dObj.type) || $ax.public.fn.IsCheckBox(dObj.type) || $ax.public.fn.IsRadioButton(dObj.type) ||
  790. $ax.public.fn.IsListBox(dObj.type) || $ax.public.fn.IsComboBox(dObj.type) || $ax.public.fn.IsButton(dObj.type) ||
  791. (dObj.tabbable && ($ax.public.fn.IsImageBox(dObj.type) || $ax.public.fn.IsVector(dObj.type) || $ax.IsTreeNodeObject(dObj.type) || $ax.public.fn.IsTableCell(dObj.type)))) {
  792. var focusObj = $jobj($ax.event.getFocusableWidgetOrChildId(elementId));
  793. focusObj.focus(function() {
  794. window.lastFocusedControl = elementId;
  795. });
  796. }
  797. // [MAS: Supressing events were here]
  798. _createProxies(dObj, elementId);
  799. var isDynamicPanel = $ax.public.fn.IsDynamicPanel(dObj.type);
  800. if(dObj.interactionMap) {
  801. _attachEvents(dObj, elementId, isDynamicPanel);
  802. };
  803. if (IE || $axure.browser.isEdge) {
  804. $element.mouseenter(function() {
  805. _enteredWidgets[elementId] = true;
  806. }).mouseleave(function() {
  807. _enteredWidgets[elementId] = false;
  808. });
  809. }
  810. _attachIxStyleEvents(dObj, elementId, $element);
  811. var $axElement = $ax('#' + elementId);
  812. // Base case is set up selected disabled based on the default in the axobj, for non, repeaters and resetting repeaters
  813. var itemReset = refreshType == $ax.repeater.refreshType.reset;
  814. if(!itemId || itemReset) {
  815. //initialize disabled elements, do this first before selected, cause if a widget is disabled, we don't want to apply selected style anymore
  816. if($ax.public.fn.IsVector(dObj.type) || $ax.public.fn.IsImageBox(dObj.type) || isDynamicPanel || $ax.public.fn.IsLayer(dObj.type)) {
  817. if(dObj.disabled) $axElement.enabled(false);
  818. // Initialize selected elements
  819. if(dObj.selected) $axElement.selected(true);
  820. }
  821. } else if(refreshType == $ax.repeater.refreshType.preEval) {
  822. // Otherwise everything should be set up correctly by pre-eval, want to set up selected disabled dictionaries (and disabled status)
  823. // Disabled layer/dynamic panel don't have the disabled class, but they do have the disabled attr written out, so use that in that case
  824. if ($element.hasClass('disabled') ||
  825. (($ax.IsLayer(dObj.type) || $ax.IsDynamicPanel(dObj.type)) && $element.attr('disabled'))) $axElement.enabled(false);
  826. if($element.hasClass('selected')) $axElement.selected(true);
  827. } else {
  828. // Persist means we want to leave it as is, but we want to make sure we use selected based off of the backing data, and not some class that exists because of the reset
  829. $element.removeClass('selected');
  830. }
  831. if(OS_MAC && WEBKIT) {
  832. if ($ax.public.fn.IsComboBox(dObj.type) && dObj.disabled) {
  833. $jobj($ax.INPUT(elementId)).css('color', 'grayText');
  834. }
  835. };
  836. // Initialize Placeholders. Right now this is text boxes and text areas.
  837. // Also, the assuption is being made that these widgets with the placeholder, have no other styles (this may change...)
  838. var hasPlaceholder = dObj.placeholderText == '' ? true : Boolean(dObj.placeholderText);
  839. if(($ax.public.fn.IsTextArea(dObj.type) || $ax.public.fn.IsTextBox(dObj.type)) && hasPlaceholder) {
  840. // This is needed to initialize the placeholder state
  841. var inputJobj = $jobj($ax.INPUT(elementId));
  842. inputJobj.bind('focus', function () {
  843. if(dObj.HideHintOnFocused) {
  844. var id = this.id;
  845. var inputIndex = id.indexOf('_input');
  846. if (inputIndex == -1) return;
  847. var inputId = id.substring(0, inputIndex);
  848. if (!$ax.placeholderManager.isActive(inputId)) return;
  849. $ax.placeholderManager.updatePlaceholder(inputId, false, true);
  850. }
  851. $ax.placeholderManager.moveCaret(this.id);
  852. }).bind('mouseup', function() {
  853. $ax.placeholderManager.moveCaret(this.id);
  854. }).bind('blur', function() {
  855. var id = this.id;
  856. var inputIndex = id.indexOf('_input');
  857. if(inputIndex == -1) return;
  858. var inputId = id.substring(0, inputIndex);
  859. if($jobj(id).val()) return;
  860. $ax.placeholderManager.updatePlaceholder(inputId, true);
  861. });
  862. if(ANDROID) {
  863. //input fires before keyup, to avoid flicker, supported in ie9 and above
  864. inputJobj.bind('input', function() {
  865. if(!dObj.HideHintOnFocused) { //hide on type
  866. var id = this.id;
  867. var inputIndex = id.indexOf('_input');
  868. if(inputIndex == -1) return;
  869. var inputId = id.substring(0, inputIndex);
  870. if($ax.placeholderManager.isActive(inputId)) {
  871. $ax.placeholderManager.updatePlaceholder(inputId, false, true);
  872. } else if(!$jobj(id).val()) {
  873. $ax.placeholderManager.updatePlaceholder(inputId, true, false);
  874. $ax.placeholderManager.moveCaret(id, 0);
  875. }
  876. }
  877. });
  878. } else {
  879. inputJobj.bind('keydown', function() {
  880. if(!dObj.HideHintOnFocused) {
  881. var id = this.id;
  882. var inputIndex = id.indexOf('_input');
  883. if(inputIndex == -1) return;
  884. var inputId = id.substring(0, inputIndex);
  885. if(!$ax.placeholderManager.isActive(inputId)) return;
  886. $ax.placeholderManager.updatePlaceholder(inputId, false, true);
  887. }
  888. }).bind('keyup', function() {
  889. var id = this.id;
  890. var inputIndex = id.indexOf('_input');
  891. if(inputIndex == -1) return;
  892. var inputId = id.substring(0, inputIndex);
  893. if($ax.placeholderManager.isActive(inputId)) return;
  894. if(!dObj.HideHintOnFocused && !$jobj(id).val()) {
  895. $ax.placeholderManager.updatePlaceholder(inputId, true);
  896. $ax.placeholderManager.moveCaret(id, 0);
  897. }
  898. });
  899. }
  900. $ax.placeholderManager.registerPlaceholder(elementId, dObj.placeholderText, inputJobj.attr('type') == 'password');
  901. $ax.placeholderManager.updatePlaceholder(elementId, !($jobj($ax.repeater.applySuffixToElementId(elementId, '_input')).val()));
  902. }
  903. // Initialize assigned submit buttons
  904. if(dObj.submitButton) {
  905. $element.keyup(function(e) {
  906. if(e.keyCode == '13') {
  907. var scriptId = $ax.repeater.getScriptIdFromElementId(elementId);
  908. var path = $ax.deepCopy(dObj.submitButton.path);
  909. path[path.length] = dObj.submitButton.id;
  910. var itemNum = $ax.repeater.getItemIdFromElementId(elementId);
  911. var submitId = $ax.getScriptIdFromPath(path, scriptId);
  912. if(itemNum && $ax.getParentRepeaterFromScriptId(submitId) == $ax.getParentRepeaterFromScriptId(scriptId)) {
  913. submitId = $ax.repeater.createElementId(submitId, itemNum);
  914. }
  915. var inputId = $ax.INPUT(submitId);
  916. if($jobj(inputId).length) submitId = inputId;
  917. $ax.setjBrowserEvent(e);
  918. $ax.event.fireClick(submitId);
  919. }
  920. }).keydown(function(e) {
  921. if(e.keyCode == '13') {
  922. e.preventDefault();
  923. }
  924. });
  925. }
  926. // Don't drag after mousing down on a plain text object
  927. if ($ax.public.fn.IsTextArea(dObj.type) || $ax.public.fn.IsTextBox(dObj.type) || $ax.public.fn.IsListBox(dObj.type) ||
  928. $ax.public.fn.IsComboBox(dObj.type) || $ax.public.fn.IsCheckBox(dObj.type) || $ax.public.fn.IsRadioButton(dObj.type)) {
  929. $element.bind($ax.features.eventNames.mouseDownName, function(event) {
  930. event.originalEvent.donotdrag = true;
  931. });
  932. }
  933. if($ax.features.supports.mobile) {
  934. $element.bind($ax.features.eventNames.mouseDownName, function() { _setCanClick(true); });
  935. if (isDynamicPanel) {
  936. $element.scroll(function() { _setCanClick(false); });
  937. }
  938. }
  939. //initialize tree node cursors to default so they will override their parent
  940. if ($ax.public.fn.IsTreeNodeObject(dObj.type) && !(dObj.interactionMap && dObj.interactionMap.onClick)) {
  941. $element.css('cursor', 'default');
  942. }
  943. //initialize widgets that are clickable to have the pointer over them when hovering
  944. if($ax.event.HasClick(dObj)) {
  945. if($element) $element.css('cursor', 'pointer');
  946. }
  947. // TODO: not sure if we need this. It appears to be working without
  948. //initialize panels for DynamicPanels
  949. if (isDynamicPanel) {
  950. $element.children().each(function() {
  951. var parts = this.id.split('_');
  952. var state = parts[parts.length - 1].substring(5);
  953. if(state != 0) $ax.visibility.SetVisible(this, false);
  954. });
  955. }
  956. //initialize TreeNodes
  957. if ($ax.public.fn.IsTreeNodeObject(dObj.type)) {
  958. if($element.hasClass('treeroot')) return;
  959. var childrenId = elementId + '_children';
  960. var children = $element.children('[id="' + childrenId + '"]:first');
  961. if(children.length > 0) {
  962. var plusMinusId = 'u' + (parseInt($ax.repeater.getScriptIdFromElementId(elementId).substring(1)) + 1);
  963. if(itemId) plusMinusId = $ax.repeater.createElementId(plusMinusId, itemId);
  964. if(!$jobj(plusMinusId).children().first().is('img')) plusMinusId = '';
  965. $ax.tree.InitializeTreeNode(elementId, plusMinusId, childrenId);
  966. }
  967. $element.click(function() { $ax.tree.SelectTreeNode(elementId, true); });
  968. }
  969. //initialize submenus
  970. if ($ax.public.fn.IsMenuObject(dObj.type)) {
  971. if($element.hasClass('sub_menu')) {
  972. var tableCellElementId = $ax.getElementIdFromPath([dObj.parentCellId], { relativeTo: elementId });
  973. $ax.menu.InitializeSubmenu(elementId, tableCellElementId);
  974. }
  975. }
  976. // Attach handles for dynamic panels that propagate styles to inner items.
  977. if ((isDynamicPanel || $ax.public.fn.IsLayer(dObj.type)) && dObj.propagate) {
  978. $element.mouseenter(function() {
  979. dynamicPanelMouseOver(this.id);
  980. }).mouseleave(function() {
  981. dynamicPanelMouseLeave(this.id);
  982. }).bind($ax.features.eventNames.mouseDownName, function() {
  983. dynamicPanelMouseDown(this.id);
  984. }).bind($ax.features.eventNames.mouseUpName, function() {
  985. dynamicPanelMouseUp(this.id);
  986. });
  987. }
  988. // These are the dynamic panel functions for propagating rollover styles and mouse down styles to inner objects
  989. var dynamicPanelMouseOver = function(elementId, fromChild) {
  990. var parent = $ax.dynamicPanelManager.parentHandlesStyles(elementId);
  991. if(parent) {
  992. dynamicPanelMouseOver(parent.id, true);
  993. if(parent.direct) return;
  994. }
  995. if($.inArray(elementId, _event.mouseOverIds) != -1) return;
  996. // If this event is coming from a child, don't mark that it's actually entered.
  997. // Only mark that this has been entered if this event has naturally been triggered. (For reason see mouseleave)
  998. if(!fromChild) _event.mouseOverIds[_event.mouseOverIds.length] = elementId;
  999. if(elementId == _event.mouseOverObjectId) return;
  1000. _event.mouseOverObjectId = elementId;
  1001. $ax.dynamicPanelManager.propagateMouseOver(elementId, true);
  1002. };
  1003. var dynamicPanelMouseLeave = function(elementId, fromChild) {
  1004. var parent = $ax.dynamicPanelManager.parentHandlesStyles(elementId);
  1005. if(parent) {
  1006. dynamicPanelMouseLeave(parent.id, true);
  1007. if(parent.direct) return;
  1008. }
  1009. var index = $.inArray(elementId, _event.mouseOverIds);
  1010. // If index != -1, this has been natuarally entered. If naturally entered, then leaving child should not trigger leaving,
  1011. // but instead wait for natural mouse leave. If natural mouse enter never triggered, natural mouse leave won't so do this now.
  1012. if((index != -1) && fromChild) return;
  1013. $ax.splice(_event.mouseOverIds, index, 1);
  1014. if(elementId == _event.mouseOverObjectId) {
  1015. _event.mouseOverObjectId = '';
  1016. }
  1017. $ax.dynamicPanelManager.propagateMouseOver(elementId, false);
  1018. };
  1019. //attach handlers for button shape and tree node mouse over styles
  1020. // TODO: Can this really be removed? Trees seem to work with out (the generic hover case works for it).
  1021. // query.filter(function(obj) {
  1022. // return $ax.public.fn.IsVector(obj.type) && $ax.public.fn.IsTreeNodeObject(obj.parent.type) &&
  1023. // obj.parent.style && obj.parent.style.stateStyles &&
  1024. // obj.parent.style.stateStyles.mouseOver;
  1025. // }).mouseenter(function() {
  1026. // $ax.style.SetWidgetHover(this.id, true);
  1027. // }).mouseleave(function() {
  1028. // $ax.style.SetWidgetHover(this.id, false);
  1029. // });
  1030. //handle treeNodeObject events and prevent them from bubbling up. this is necessary because otherwise
  1031. //both a sub menu and it's parent would get a click
  1032. if ($ax.public.fn.IsTreeNodeObject(dObj.type)) {
  1033. $element.click(function() {
  1034. //todo -- this was bubbling, but then selecting a child tree node would bubble and select the parent (don't know if there is a better way)
  1035. _fireObjectEvent(this.id, 'click', arguments);
  1036. return false;
  1037. }).each(function() {
  1038. if(!this.style.cursor) {
  1039. this.style.cursor = 'default';
  1040. }
  1041. });
  1042. }
  1043. // Synthetic events
  1044. var map = dObj.interactionMap;
  1045. // Attach dynamic panel synthetic drag and swipe events
  1046. if(dObj.type == "dynamicPanel" && map && (
  1047. map.onDragStart || map.onDrag ||
  1048. map.onDragDrop || map.onSwipeLeft || map.onSwipeRight || map.onSwipeUp || map.onSwipeDown)) {
  1049. $element.bind($ax.features.eventNames.mouseDownName, function(e) { $ax.drag.StartDragWidget(e.originalEvent, elementId); });
  1050. }
  1051. // Attach dynamic panel synthetic scroll event
  1052. if (isDynamicPanel && map && (map.onScroll || map.onScrollUp || map.onScrollDown)) {
  1053. var diagrams = dObj.diagrams;
  1054. for(var i = 0; i < diagrams.length; i++) {
  1055. var panelId = $ax.repeater.applySuffixToElementId(elementId, '_state' + i);
  1056. (function(id) {
  1057. if ($('#' + id).data('lastScrollTop') == undefined) $('#' + id).data('lastScrollTop', '0');
  1058. _attachDefaultObjectEvent($('#' + id), elementId, 'scroll', function(e) {
  1059. $ax.setjBrowserEvent(e);
  1060. var currentEvent = $ax.getjBrowserEvent();
  1061. var eventInfoFromEvent = $ax.getEventInfoFromEvent(currentEvent, false, elementId);
  1062. var currentTop = $('#' + id).scrollTop();
  1063. var lastTop = $('#' + id).data('lastScrollTop');
  1064. _handleScrollEvent(elementId, eventInfoFromEvent, currentEvent.originalEvent, currentTop < lastTop, currentTop > lastTop, map);
  1065. $('#' + id).data('lastScrollTop', currentTop);
  1066. });
  1067. })(panelId);
  1068. }
  1069. }
  1070. // Attach synthetic hover event
  1071. if (map && map.onMouseHover) {
  1072. var MIN_HOVER_HOLD_TIME = 1000;
  1073. // So when the timeout fires, you know whether it is the same mouseenter that is active or not.
  1074. var hoverMouseCount = 0;
  1075. // Update eventInfo regularly, so position is accurate.
  1076. var hoverEventInfo;
  1077. $element.mouseenter(function(e) {
  1078. $ax.setjBrowserEvent(e);
  1079. hoverEventInfo = $ax.getEventInfoFromEvent($ax.getjBrowserEvent(), false, elementId);
  1080. (function(currCount) {
  1081. window.setTimeout(function() {
  1082. if(currCount == hoverMouseCount) _raiseSyntheticEvent(elementId, 'onMouseHover', false, hoverEventInfo, true);
  1083. }, MIN_HOVER_HOLD_TIME);
  1084. })(hoverMouseCount);
  1085. }).mouseleave(function(e) {
  1086. $ax.setjBrowserEvent(e);
  1087. hoverMouseCount++;
  1088. }).mousemove(function(e) {
  1089. $ax.setjBrowserEvent(e);
  1090. hoverEventInfo = $ax.getEventInfoFromEvent($ax.getjBrowserEvent(), false, elementId);
  1091. });
  1092. }
  1093. // Attach synthetic tap and hold event.
  1094. if (map && map.onLongClick) {
  1095. var MIN_LONG_CLICK_HOLD_TIME = 750;
  1096. // So when the timeout fires, you know whether it is the same mousedown that is active or not.
  1097. var longClickMouseCount = 0;
  1098. $element.bind($ax.features.eventNames.mouseDownName, function(e) {
  1099. (function(currCount) {
  1100. $ax.setjBrowserEvent(e);
  1101. var eventInfo = $ax.getEventInfoFromEvent($ax.getjBrowserEvent(), false, elementId);
  1102. window.setTimeout(function() {
  1103. if(currCount == longClickMouseCount) _raiseSyntheticEvent(elementId, 'onLongClick', false, eventInfo, true);
  1104. }, MIN_LONG_CLICK_HOLD_TIME);
  1105. if(e.preventDefault) e.preventDefault();
  1106. })(longClickMouseCount);
  1107. }).bind($ax.features.eventNames.mouseUpName, function(e) {
  1108. $ax.setjBrowserEvent(e);
  1109. longClickMouseCount++;
  1110. });
  1111. };
  1112. // Attach synthetic onSelectionChange event to droplist and listbox elements
  1113. if ($ax.event.HasSelectionChanged(dObj)) {
  1114. $element.bind('change', function(e) {
  1115. $ax.setjBrowserEvent(e);
  1116. _raiseSyntheticEvent(elementId, 'onSelectionChange');
  1117. });
  1118. };
  1119. // Highjack key up and key down to keep track of state of keyboard.
  1120. if($ax.event.HasKeyUpOrDown(dObj)) _event.initKeyEvents($element);
  1121. // Attach synthetic onTextChange event to textbox and textarea elements
  1122. if ($ax.event.HasTextChanged(dObj)) {
  1123. var element = $jobj($ax.INPUT(elementId));
  1124. $ax.updateElementText(elementId, element.val());
  1125. //Key down needed because when holding a key down, key up only fires once, but keydown fires repeatedly.
  1126. //Key up because last mouse down will only show the state before the last character.
  1127. element.bind('keydown', function(e) {
  1128. $ax.setjBrowserEvent(e);
  1129. $ax.event.TryFireTextChanged(elementId);
  1130. }).bind('keyup', function(e) {
  1131. $ax.setjBrowserEvent(e);
  1132. $ax.event.TryFireTextChanged(elementId);
  1133. });
  1134. };
  1135. // Attach synthetic onCheckedChange event to radiobutton and checkbox elements
  1136. if ($ax.public.fn.IsCheckBox(dObj.type) || $ax.public.fn.IsRadioButton(dObj.type)) {
  1137. var input = $jobj($ax.INPUT(elementId));
  1138. if ($ax.public.fn.IsRadioButton(dObj.type) && input.prop('checked')) {
  1139. $ax.updateRadioButtonSelected(input.attr('name'), elementId);
  1140. }
  1141. $element.bind('change', function(e) {
  1142. $ax.setjBrowserEvent(e);
  1143. var eTarget = e.target || e.srcElement;
  1144. _tryFireCheckedChanged(elementId, eTarget.checked);
  1145. });
  1146. };
  1147. var hasTap = map && (map.onClick || map.onDoubleClick);
  1148. var hasMove = map && map.onMouseMove;
  1149. _event.initMobileEvents(hasTap ? $element : $(),
  1150. hasMove ? $element : $(), elementId);
  1151. //attach link alternate styles
  1152. if(dObj.type == 'hyperlink') {
  1153. $element.mouseenter(function() {
  1154. var linkId = this.id;
  1155. if(_event.mouseOverIds.indexOf(linkId) != -1) return true;
  1156. _event.mouseOverIds[_event.mouseOverIds.length] = linkId;
  1157. var mouseOverObjectId = _event.mouseOverObjectId;
  1158. if(mouseOverObjectId && $ax.style.IsWidgetDisabled(mouseOverObjectId)) return true;
  1159. $ax.style.SetLinkHover(linkId);
  1160. var bubble = _fireObjectEvent(linkId, 'mouseenter', arguments);
  1161. $ax.annotation.updateLinkLocations($ax.GetParentIdFromLink(linkId));
  1162. return bubble;
  1163. }).mouseleave(function() {
  1164. var linkId = this.id;
  1165. $ax.splice(_event.mouseOverIds, _event.mouseOverIds.indexOf(linkId), 1);
  1166. var mouseOverObjectId = _event.mouseOverObjectId;
  1167. if(mouseOverObjectId && $ax.style.IsWidgetDisabled(mouseOverObjectId)) return true;
  1168. $ax.style.SetLinkNotHover(linkId);
  1169. var bubble = _fireObjectEvent(linkId, 'mouseleave', arguments);
  1170. $ax.annotation.updateLinkLocations($ax.GetParentIdFromLink(linkId));
  1171. return bubble;
  1172. }).bind($ax.features.eventNames.mouseDownName, function() {
  1173. var linkId = this.id;
  1174. var mouseOverObjectId = _event.mouseOverObjectId;
  1175. if($ax.style.IsWidgetDisabled(mouseOverObjectId)) return undefined;
  1176. if(mouseOverObjectId) $ax.style.SetWidgetMouseDown(mouseOverObjectId, true);
  1177. $ax.style.SetLinkMouseDown(linkId);
  1178. $ax.annotation.updateLinkLocations($ax.GetParentIdFromLink(linkId));
  1179. return false;
  1180. }).bind($ax.features.eventNames.mouseUpName, function() {
  1181. var linkId = this.id;
  1182. var mouseOverObjectId = _event.mouseOverObjectId;
  1183. if(mouseOverObjectId && $ax.style.IsWidgetDisabled(mouseOverObjectId)) return;
  1184. if(mouseOverObjectId) $ax.style.SetWidgetMouseDown(mouseOverObjectId, false);
  1185. $ax.style.SetLinkNotMouseDown(linkId);
  1186. $ax.annotation.updateLinkLocations($ax.GetParentIdFromLink(linkId));
  1187. }).click(function() {
  1188. var elementId = this.id;
  1189. var mouseOverObjectId = _event.mouseOverObjectId;
  1190. if(mouseOverObjectId && $ax.style.IsWidgetDisabled(mouseOverObjectId)) return undefined;
  1191. return _fireObjectEvent(elementId, 'click', arguments);
  1192. });
  1193. }
  1194. // Init inline frames
  1195. if (dObj.type == 'inlineFrame') {
  1196. var target = dObj.target;
  1197. var url = '';
  1198. if(target.includeVariables && target.url) {
  1199. var origSrc = target.url;
  1200. url = origSrc.toLowerCase().indexOf('http://') == -1 ? $ax.globalVariableProvider.getLinkUrl(origSrc) : origSrc;
  1201. } else if(target.urlLiteral) {
  1202. url = $ax.expr.evaluateExpr(target.urlLiteral, $ax.getEventInfoFromEvent(undefined, true, elementId), true);
  1203. }
  1204. if(url) $jobj($ax.INPUT(elementId)).attr('src', url);
  1205. };
  1206. });
  1207. }
  1208. $ax.initializeObjectEvents = _initializeObjectEvents;
  1209. $ax.event.updateIxStyleEvents = function(elementId) {
  1210. _dettachIxStyleEvents(elementId);
  1211. _attachIxStyleEvents($ax.getObjectFromElementId(elementId), elementId, $jobj(elementId), true);
  1212. }
  1213. function clearMouseDownIxStyle(e) {
  1214. if(_event.mouseDownObjectId) {
  1215. $('#' + _event.mouseDownObjectId).trigger(
  1216. { type: "mouseup",
  1217. checkMouseOver: e.data && e.data.checkMouseOver
  1218. }
  1219. );
  1220. }
  1221. }
  1222. var _dettachIxStyleEvents = function(elementId) {
  1223. var $element = $jobj(elementId);
  1224. $element.off('mouseenter.ixStyle')
  1225. .off('mouseleave.ixStyle')
  1226. .off($ax.features.eventNames.mouseDownName + '.ixStyle')
  1227. .off($ax.features.eventNames.mouseUpName + '.ixStyle');
  1228. }
  1229. var _attachIxStyleEvents = function(dObj, elementId, $element, ignoreHasIxStyles) {
  1230. //attach button shape alternate styles
  1231. var isDynamicPanel = $ax.public.fn.IsDynamicPanel(dObj.type);
  1232. var needsMouseFilter = (ignoreHasIxStyles || $ax.event.HasIxStyles(dObj))
  1233. && dObj.type != 'hyperlink' && !$ax.public.fn.IsLayer(dObj.type) && !isDynamicPanel && dObj.type != $ax.constants.TEXT_TYPE &&
  1234. !$ax.public.fn.IsRepeater(dObj.type) && !$ax.public.fn.IsCheckBox(dObj.type) && !$ax.public.fn.IsRadioButton(dObj.type)
  1235. && !$ax.public.fn.IsTreeNodeObject(dObj.type);
  1236. if(needsMouseFilter) {
  1237. //$element.mouseenter(function () {
  1238. $element.on('mouseenter.ixStyle', function () {
  1239. var elementId = this.id;
  1240. var parent = $ax.dynamicPanelManager.parentHandlesStyles(elementId);
  1241. if(parent && parent.direct) return;
  1242. if($.inArray(elementId, _event.mouseOverIds) != -1) return;
  1243. _event.mouseOverIds[_event.mouseOverIds.length] = elementId;
  1244. if(elementId == _event.mouseOverObjectId) return;
  1245. _event.mouseOverObjectId = elementId;
  1246. $ax.style.SetWidgetHover(elementId, true);
  1247. $ax.annotation.updateLinkLocations(elementId);
  1248. //}).mouseleave(function () {
  1249. }).on('mouseleave.ixStyle', function () {
  1250. var elementId = this.id;
  1251. var parent = $ax.dynamicPanelManager.parentHandlesStyles(elementId);
  1252. if(parent && parent.direct) return;
  1253. $ax.splice(_event.mouseOverIds, $.inArray(elementId, _event.mouseOverIds), 1);
  1254. if(elementId == _event.mouseOverObjectId) {
  1255. _event.mouseOverObjectId = '';
  1256. }
  1257. $ax.style.SetWidgetHover(elementId, false);
  1258. $ax.annotation.updateLinkLocations(elementId);
  1259. });
  1260. //$element.bind($ax.features.eventNames.mouseDownName, function () {
  1261. $element.on($ax.features.eventNames.mouseDownName + '.ixStyle', function () {
  1262. var elementId = this.id;
  1263. var parent = $ax.dynamicPanelManager.parentHandlesStyles(elementId);
  1264. if(parent) {
  1265. dynamicPanelMouseDown(parent.id);
  1266. if(parent.direct) return;
  1267. }
  1268. _event.mouseDownObjectId = elementId;
  1269. //since we don't do mouse capture, it's possible that the mouseup not get triggered later
  1270. //in that case, detect the mouseup on document and dragend
  1271. $(document).one("mouseup", {checkMouseOver: true}, clearMouseDownIxStyle);
  1272. $("#" + elementId).one("dragend", clearMouseDownIxStyle);
  1273. $ax.style.SetWidgetMouseDown(this.id, true);
  1274. $ax.annotation.updateLinkLocations(elementId);
  1275. //}).bind($ax.features.eventNames.mouseUpName, function () {
  1276. }).on($ax.features.eventNames.mouseUpName + '.ixStyle', function (e) {
  1277. var elementId = this.id;
  1278. var parent = $ax.dynamicPanelManager.parentHandlesStyles(elementId);
  1279. if(parent) {
  1280. dynamicPanelMouseUp(parent.id);
  1281. if(parent.direct) return;
  1282. }
  1283. $(document).off("mouseup", clearMouseDownIxStyle);
  1284. $("#" + _event.mouseDownObjectId).off("dragend", clearMouseDownIxStyle);
  1285. _event.mouseDownObjectId = '';
  1286. if(!$ax.style.ObjHasMouseDown(elementId)) return;
  1287. $ax.style.SetWidgetMouseDown(elementId, false, e.checkMouseOver);
  1288. $ax.annotation.updateLinkLocations(elementId);
  1289. //there used to be something we needed to make images click, because swapping out the images prevents the click
  1290. // this is a note that we can eventually delete.
  1291. });
  1292. }
  1293. };
  1294. var dynamicPanelMouseDown = function (elementId) {
  1295. var parent = $ax.dynamicPanelManager.parentHandlesStyles(elementId);
  1296. if(parent) {
  1297. dynamicPanelMouseDown(parent.id);
  1298. if(parent.direct) return;
  1299. }
  1300. _event.mouseDownObjectId = elementId;
  1301. $ax.dynamicPanelManager.propagateMouseDown(elementId, true);
  1302. };
  1303. var dynamicPanelMouseUp = function (elementId) {
  1304. var parent = $ax.dynamicPanelManager.parentHandlesStyles(elementId);
  1305. if(parent) {
  1306. dynamicPanelMouseUp(parent.id);
  1307. if(parent.direct) return;
  1308. }
  1309. _event.mouseDownObjectId = '';
  1310. $ax.dynamicPanelManager.propagateMouseDown(elementId, false);
  1311. };
  1312. // Handle key up and key down events
  1313. (function() {
  1314. var _keyState = {};
  1315. _keyState.ctrl = false;
  1316. _keyState.alt = false;
  1317. _keyState.shift = false;
  1318. _keyState.keyCode = 0;
  1319. $ax.event.keyState = function() {
  1320. return $ax.deepCopy(_keyState);
  1321. };
  1322. var modifierCodes = [16, 17, 18];
  1323. var clearKeyCode = false;
  1324. $ax.event.initKeyEvents = function($query) {
  1325. $query.keydown(function (e) {
  1326. if(clearKeyCode) {
  1327. clearKeyCode = false;
  1328. _keyState.keyCode = 0;
  1329. }
  1330. var elementId = this.id;
  1331. _keyState.ctrl = e.ctrlKey;
  1332. _keyState.alt = e.altKey;
  1333. _keyState.shift = e.shiftKey;
  1334. // If a modifier was pressed, then don't set the keyCode;
  1335. if(modifierCodes.indexOf(e.keyCode) == -1) _keyState.keyCode = e.keyCode;
  1336. $ax.setjBrowserEvent(e);
  1337. if (!elementId) fireEventThroughContainers('onKeyDown', undefined, false, [$ax.constants.PAGE_TYPE, $ax.constants.REFERENCE_DIAGRAM_OBJECT_TYPE, $ax.constants.DYNAMIC_PANEL_TYPE, $ax.constants.REPEATER],
  1338. [$ax.constants.PAGE_TYPE, $ax.constants.REFERENCE_DIAGRAM_OBJECT_TYPE, $ax.constants.LAYER_TYPE]);
  1339. else _raiseSyntheticEvent(elementId, 'onKeyDown', false, undefined, true);
  1340. });
  1341. $query.keyup(function(e) {
  1342. var elementId = this.id;
  1343. if (modifierCodes.indexOf(e.keyCode) == -1) clearKeyCode = true;
  1344. else if (clearKeyCode) {
  1345. clearKeyCode = false;
  1346. _keyState.keyCode = 0;
  1347. }
  1348. $ax.setjBrowserEvent(e);
  1349. // Fire event before updating modifiers.
  1350. if (!elementId) fireEventThroughContainers('onKeyUp', undefined, false, [$ax.constants.PAGE_TYPE, $ax.constants.REFERENCE_DIAGRAM_OBJECT_TYPE, $ax.constants.DYNAMIC_PANEL_TYPE, $ax.constants.REPEATER],
  1351. [$ax.constants.PAGE_TYPE, $ax.constants.REFERENCE_DIAGRAM_OBJECT_TYPE, $ax.constants.LAYER_TYPE]);
  1352. else _raiseSyntheticEvent(elementId, 'onKeyUp', false, undefined, true);
  1353. //_keyState.ctrl = e.ctrlKey;
  1354. //_keyState.alt = e.altKey;
  1355. //_keyState.shift = e.shiftKey;
  1356. //// If a non-modifier was lifted, clear the keycode
  1357. ///if(modifierCodes.indexOf(e.keyCode) == -1) _keyState.keyCode = 0;
  1358. });
  1359. };
  1360. })();
  1361. // Handle adding mobile events
  1362. (function() {
  1363. // NOTE: Multi touch is NOT handled currently.
  1364. var CLICK_THRESHOLD_PX = 25;
  1365. var CLICK_THRESHOLD_PX_SQ = CLICK_THRESHOLD_PX * CLICK_THRESHOLD_PX;
  1366. var DBLCLICK_THRESHOLD_MS = 500;
  1367. // Location in page cooridinates
  1368. var tapDownLoc;
  1369. var lastClickEventTime;
  1370. _event.initMobileEvents = function($tapQuery, $moveQuery, elementId) {
  1371. if(!$ax.features.supports.mobile) return;
  1372. // Handle touch start
  1373. $tapQuery.bind('touchstart', function(e) {
  1374. // We do NOT support multiple touches. This isn't necessarily the touch we want.
  1375. var touch = e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0];
  1376. if(!touch) return;
  1377. tapDownLoc = [touch.pageX, touch.pageY];
  1378. var time = (new Date()).getTime();
  1379. if(time - lastClickEventTime < DBLCLICK_THRESHOLD_MS) {
  1380. var dObj = elementId === '' ? $ax.pageData.page : $ax.getObjectFromElementId(elementId);
  1381. var axEventObject = dObj && dObj.interactionMap && dObj.interactionMap['onDoubleClick'];
  1382. if(axEventObject) e.preventDefault(); //for Chrome on Android
  1383. }
  1384. }).bind('touchend', function(e) {
  1385. var touch = e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0];
  1386. if(!touch || !tapDownLoc || $ax.style.IsWidgetDisabled(elementId)) return;
  1387. var tapUpLoc = [touch.pageX, touch.pageY];
  1388. var xDiff = tapUpLoc[0] - tapDownLoc[0];
  1389. var yDiff = tapUpLoc[1] - tapDownLoc[1];
  1390. if((xDiff * xDiff + yDiff * yDiff) < CLICK_THRESHOLD_PX_SQ) {
  1391. $ax.setjBrowserEvent(e);
  1392. _raiseSyntheticEvent(elementId, 'onClick', false, undefined, true);
  1393. var time = (new Date()).getTime();
  1394. if(time - lastClickEventTime < DBLCLICK_THRESHOLD_MS) {
  1395. _raiseSyntheticEvent(elementId, 'onDoubleClick', false, undefined, true);
  1396. if(e.originalEvent && e.originalEvent.handled) e.preventDefault(); //for iOS
  1397. }
  1398. lastClickEventTime = time;
  1399. }
  1400. });
  1401. // Handles touch move
  1402. $moveQuery.bind('touchmove', function(e) {
  1403. $ax.setjBrowserEvent(e);
  1404. _raiseSyntheticEvent(elementId, 'onMouseMove', false, undefined, true);
  1405. if(e.originalEvent && e.originalEvent.handled) e.preventDefault();
  1406. });
  1407. };
  1408. })();
  1409. // Handle adding device independent click events to non-widgets
  1410. (function() {
  1411. var CLICK_THRESHOLD_PX = 25;
  1412. var CLICK_THRESHOLD_PX_SQ = CLICK_THRESHOLD_PX * CLICK_THRESHOLD_PX;
  1413. // Location in page cooridinates
  1414. var tapDownLoc;
  1415. _event.attachClick = function(query, clickHandler) {
  1416. if(!$ax.features.supports.mobile) {
  1417. query.click(clickHandler);
  1418. return;
  1419. }
  1420. $(query).bind('touchstart', function(e) {
  1421. // We do NOT support multiple touches. This isn't necessarily the touch we want.
  1422. var touch = e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0];
  1423. if(!touch) return;
  1424. tapDownLoc = [touch.pageX, touch.pageY];
  1425. });
  1426. $(query).bind('touchend', function(e) {
  1427. var touch = e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0];
  1428. if(!touch) return;
  1429. var tapUpLoc = [touch.pageX, touch.pageY];
  1430. var xDiff = tapUpLoc[0] - tapDownLoc[0];
  1431. var yDiff = tapUpLoc[1] - tapDownLoc[1];
  1432. if((xDiff * xDiff + yDiff * yDiff) < CLICK_THRESHOLD_PX_SQ) {
  1433. clickHandler();
  1434. }
  1435. });
  1436. };
  1437. })();
  1438. // Handle firing device independent click events on widgets
  1439. (function() {
  1440. _event.fireClick = function(elementId) {
  1441. if(!$ax.features.supports.mobile) {
  1442. $('#' + elementId).click();
  1443. return;
  1444. }
  1445. _raiseSyntheticEvent(elementId, 'onClick', false, undefined, true);
  1446. };
  1447. })();
  1448. var _mouseLocation = $ax.mouseLocation = { x: 0, y: 0 };
  1449. var _lastmouseLocation = $ax.lastMouseLocation = { x: 0, y: 0 };
  1450. var _updateMouseLocation = function(e, end) {
  1451. if(!e) return;
  1452. if(IE_10_AND_BELOW && typeof (e.type) == 'unknown') return;
  1453. if(e.type != 'mousemove' && e.type != 'touchstart' && e.type != 'touchmove' && e.type != 'touchend') return;
  1454. var newX;
  1455. var newY;
  1456. if(IE_10_AND_BELOW) {
  1457. newX = e.clientX + $('html').scrollLeft();
  1458. newY = e.clientY + $('html').scrollTop();
  1459. } else {
  1460. newX = e.pageX;
  1461. newY = e.pageY;
  1462. }
  1463. //var body = $('body');
  1464. //if(body.css('position') == 'relative') newX = Math.round(newX - Number(body.css('left').replace('px', '')) - Math.max(0, ($(window).width() - body.width()) / 2));
  1465. if(_mouseLocation.x == newX && _mouseLocation.y == newY) return;
  1466. _lastmouseLocation.x = _mouseLocation.x;
  1467. _lastmouseLocation.y = _mouseLocation.y;
  1468. _mouseLocation.x = newX;
  1469. _mouseLocation.y = newY;
  1470. $ax.geometry.tick(_mouseLocation.x, _mouseLocation.y, end);
  1471. };
  1472. _event.updateMouseLocation = _updateMouseLocation;
  1473. var _leavingState = function(stateId) {
  1474. var mouseOverIds = _event.mouseOverIds;
  1475. if(mouseOverIds.length == 0) return;
  1476. var stateQuery = $jobj(stateId);
  1477. for(var i = mouseOverIds.length - 1; i >= 0; i--) {
  1478. var id = mouseOverIds[i];
  1479. if(stateQuery.find('#' + id).length) {
  1480. $ax.splice(mouseOverIds, $.inArray(id, mouseOverIds), 1);
  1481. $ax.style.SetWidgetMouseDown(id, false);
  1482. $ax.style.SetWidgetHover(id, false);
  1483. }
  1484. }
  1485. };
  1486. _event.leavingState = _leavingState;
  1487. var _raiseSelectedEvents = function(elementId, value) {
  1488. $ax.event.raiseSyntheticEvent(elementId, 'onSelectedChange');
  1489. if(value) $ax.event.raiseSyntheticEvent(elementId, 'onSelect');
  1490. else $ax.event.raiseSyntheticEvent(elementId, 'onUnselect');
  1491. };
  1492. $ax.event.raiseSelectedEvents = _raiseSelectedEvents;
  1493. var _raiseSyntheticEvent = function(elementId, eventName, skipShowDescription, eventInfo, nonSynthetic) {
  1494. // Empty string used when this is an event directly on the page.
  1495. var dObj = elementId === '' ? $ax.pageData.page : $ax.getObjectFromElementId(elementId);
  1496. var axEventObject = dObj && dObj.interactionMap && dObj.interactionMap[eventName];
  1497. if(!axEventObject) return;
  1498. eventInfo = eventInfo || $ax.getEventInfoFromEvent($ax.getjBrowserEvent(), skipShowDescription, elementId);
  1499. // $ax.recording.maybeRecordEvent(elementId, eventInfo, axEventObject, new Date().getTime());
  1500. _handleEvent(elementId, eventInfo, axEventObject, false, !nonSynthetic);
  1501. };
  1502. $ax.event.raiseSyntheticEvent = _raiseSyntheticEvent;
  1503. var _hasSyntheticEvent = function(scriptId, eventName) {
  1504. var dObj = $ax.getObjectFromScriptId(scriptId);
  1505. var axEventObject = dObj && dObj.interactionMap && dObj.interactionMap[eventName];
  1506. return Boolean(axEventObject);
  1507. };
  1508. $ax.event.hasSyntheticEvent = _hasSyntheticEvent;
  1509. var _addEvent = function (target, eventType, handler, useCapture) {
  1510. //this return value is only for debug purpose
  1511. var succeed = undefined;
  1512. if(target.attachEvent) {
  1513. if($ax.features.supports.windowsMobile) {
  1514. succeed = target.attachEvent(eventType, handler);
  1515. } else {
  1516. succeed = target.attachEvent('on' + eventType, handler);
  1517. }
  1518. } else if(target.addEventListener) {
  1519. target.addEventListener(eventType, handler, useCapture);
  1520. succeed = true;
  1521. }
  1522. return succeed;
  1523. }
  1524. $ax.event.addEvent = _addEvent;
  1525. var _removeEvent = function(target, eventType, handler, useCapture, skipCheckingWindowsMobile) {
  1526. //this return value is only for debug purpose
  1527. var succeed = undefined;
  1528. if(target.detachEvent) {
  1529. if(!skipCheckingWindowsMobile && $ax.features.supports.windowsMobile) {
  1530. succeed = target.detachEvent(eventType, handler);
  1531. } else {
  1532. succeed = target.detachEvent('on' + eventType, handler);
  1533. }
  1534. } else if(target.removeEventListener) {
  1535. target.removeEventListener(eventType, handler, useCapture);
  1536. succeed = true;
  1537. }
  1538. return succeed;
  1539. }
  1540. $ax.event.removeEvent = _removeEvent;
  1541. var _initialize = function() {
  1542. $ax.repeater.load();
  1543. // Make sure key events for page are initialized first. That way they will update the value of key pressed before any other events occur.
  1544. _event.initKeyEvents($(window));
  1545. initSuppressingEvents();
  1546. // Anything with an item id is in a repeater and should be handled by that repeater.
  1547. _initializeObjectEvents($ax(function(obj, elementId) { return !$ax.repeater.getItemIdFromElementId(elementId); }));
  1548. //finally, process the pageload
  1549. _pageLoad();
  1550. // _loadDynamicPanelsAndMasters();
  1551. // $ax.repeater.init();
  1552. // and wipe out the basic links.
  1553. $('.basiclink').click(function() {
  1554. return false;
  1555. });
  1556. };
  1557. _event.initialize = _initialize;
  1558. $ax.event.HasIxStyles = function(diagramObject) {
  1559. if(diagramObject.style.stateStyles) return true;
  1560. if(diagramObject.adaptiveStyles) {
  1561. for(var viewId in diagramObject.adaptiveStyles) {
  1562. if(diagramObject.adaptiveStyles[viewId].stateStyles) return true;
  1563. }
  1564. }
  1565. return false;
  1566. };
  1567. $ax.event.HasTextChanged = function(diagramObject) {
  1568. if (!$ax.public.fn.IsTextBox(diagramObject.type) && !$ax.public.fn.IsTextArea(diagramObject.type)) return false;
  1569. var map = diagramObject.interactionMap;
  1570. return map && map.onTextChange;
  1571. };
  1572. $ax.event.TryFireTextChanged = function(elementId) {
  1573. var query = $jobj($ax.repeater.applySuffixToElementId(elementId, '_input'));
  1574. if(!$ax.hasElementTextChanged(elementId, query.val())) return;
  1575. $ax.updateElementText(elementId, query.val());
  1576. $ax.event.raiseSyntheticEvent(elementId, 'onTextChange');
  1577. };
  1578. $ax.event.HasSelectionChanged = function(diagramObject) {
  1579. if (!$ax.public.fn.IsListBox(diagramObject.type) && !$ax.public.fn.IsComboBox(diagramObject.type)) return false;
  1580. var map = diagramObject.interactionMap;
  1581. return map && map.onSelectionChange;
  1582. };
  1583. $ax.event.HasKeyUpOrDown = function (diagramObject) {
  1584. if($ax.public.fn.IsTextBox(diagramObject.type) || $ax.public.fn.IsTextArea(diagramObject.type)) return true;
  1585. var map = diagramObject.interactionMap;
  1586. return map && (map.onKeyUp || map.onKeyDown);
  1587. };
  1588. $ax.event.HasCheckedChanged = function(diagramObject) {
  1589. if (!$ax.public.fn.IsCheckBox(diagramObject.type) && !$ax.public.fn.IsRadioButton(diagramObject.type)) return false;
  1590. var map = diagramObject.interactionMap;
  1591. return map && map.onSelectedChange;
  1592. };
  1593. $ax.event.HasClick = function (diagramObject) {
  1594. var map = diagramObject.interactionMap;
  1595. return map && map.onClick;
  1596. };
  1597. var _tryFireCheckedChanged = $ax.event.TryFireCheckChanged = function(elementId, value) {
  1598. var isRadio = $ax.public.fn.IsRadioButton($obj(elementId).type);
  1599. if(isRadio) {
  1600. if(!value) {
  1601. $ax.updateRadioButtonSelected($jobj($ax.INPUT(elementId)).attr('name'), undefined);
  1602. } else {
  1603. var last = $ax.updateRadioButtonSelected($jobj($ax.INPUT(elementId)).attr('name'), elementId);
  1604. // If no change, this should not fire
  1605. if(last == elementId) return;
  1606. // Initially selecting one, last may be undefined
  1607. if(last) {
  1608. //here last is the previouse selected elementid
  1609. $ax.event.raiseSelectedEvents(last, false);
  1610. }
  1611. }
  1612. }
  1613. $ax.event.raiseSelectedEvents(elementId, value);
  1614. };
  1615. //onload everything now, not only dp and master
  1616. var _loadDynamicPanelsAndMasters = function(objects, path, itemId) {
  1617. fireEventThroughContainers('onLoad', objects, true, [$ax.constants.PAGE_TYPE, $ax.constants.REFERENCE_DIAGRAM_OBJECT_TYPE, $ax.constants.DYNAMIC_PANEL_TYPE],
  1618. [$ax.constants.ALL_TYPE], path, itemId);
  1619. };
  1620. $ax.loadDynamicPanelsAndMasters = _loadDynamicPanelsAndMasters;
  1621. var _viewChangePageAndMasters = function(forceSwitchTo) {
  1622. fireEventThroughContainers('onAdaptiveViewChange', undefined, true, [$ax.constants.PAGE_TYPE, $ax.constants.REFERENCE_DIAGRAM_OBJECT_TYPE, $ax.constants.DYNAMIC_PANEL_TYPE],
  1623. [$ax.constants.PAGE_TYPE, $ax.constants.REFERENCE_DIAGRAM_OBJECT_TYPE]);
  1624. _postAdaptiveViewChanged(forceSwitchTo);
  1625. };
  1626. $ax.viewChangePageAndMasters = _viewChangePageAndMasters;
  1627. //if forceSwitchTo is true, we will also update the checkmark in sitemap.js
  1628. var _postAdaptiveViewChanged = function(forceSwitchTo) {
  1629. //only trigger adaptive view changed if the window is on the mainframe. Also triggered on init, even if default.
  1630. try {
  1631. if(window.name == 'mainFrame' ||
  1632. (!CHROME_5_LOCAL && window.parent.$ && window.parent.$('#mainFrame').length > 0)) {
  1633. var data = {
  1634. viewId: $ax.adaptive.currentViewId,
  1635. forceSwitchTo: forceSwitchTo
  1636. };
  1637. $axure.messageCenter.postMessage('adaptiveViewChange', data);
  1638. }
  1639. } catch(e) { }
  1640. };
  1641. $ax.postAdaptiveViewChanged = _postAdaptiveViewChanged;
  1642. var _postResize = $ax.postResize = function(e) {
  1643. $ax.setjBrowserEvent(e);
  1644. return fireEventThroughContainers('onResize', undefined, false, [$ax.constants.PAGE_TYPE, $ax.constants.REFERENCE_DIAGRAM_OBJECT_TYPE, $ax.constants.DYNAMIC_PANEL_TYPE, $ax.constants.REPEATER],
  1645. [$ax.constants.PAGE_TYPE, $ax.constants.REFERENCE_DIAGRAM_OBJECT_TYPE]);
  1646. };
  1647. //fire events for table, menu and tree, including its sub items
  1648. var _fireEventsForTableMenuAndTree = function (object, event, skipShowDescription, eventInfo, path, synthetic) {
  1649. if (!path) path = [];
  1650. var pathCopy = path.slice();
  1651. pathCopy[path.length] = object.id;
  1652. var scriptId = $ax.getScriptIdFromPath(pathCopy);
  1653. $ax.event.raiseSyntheticEvent(scriptId, event, skipShowDescription, eventInfo, !synthetic);
  1654. if(object.objects) {
  1655. for(var index = 0; index < object.objects.length; index++) {
  1656. var subObj = object.objects[index];
  1657. if ($ax.public.fn.IsTableCell(subObj.type)) {
  1658. pathCopy[path.length] = subObj.id;
  1659. scriptId = $ax.getScriptIdFromPath(pathCopy);
  1660. $ax.event.raiseSyntheticEvent(scriptId, event, skipShowDescription, eventInfo, !synthetic);
  1661. } else if ($ax.public.fn.IsTable(object.type) || $ax.public.fn.IsMenuObject(object.type) || $ax.public.fn.IsTreeNodeObject(object.type)) {
  1662. _fireEventsForTableMenuAndTree(subObj, event, skipShowDescription, eventInfo, path, synthetic);
  1663. }
  1664. }
  1665. }
  1666. }
  1667. //remember the scroll bar position, so we can detect scroll up/down
  1668. var lastScrollTop;
  1669. var fireEventForPageOrMaster = function (elementId, eventName, interactionMap, isPage, skipShowDescription, synthetic) {
  1670. if(!interactionMap) return;
  1671. var axEvent = interactionMap[eventName];
  1672. var scrolling = eventName === "onScroll";
  1673. if (scrolling && !axEvent) axEvent = interactionMap.onScrollUp || interactionMap.onScrollDown;
  1674. if (axEvent) {
  1675. var currentEvent = $ax.getjBrowserEvent();
  1676. var eventInfo = $ax.getEventInfoFromEvent(currentEvent, skipShowDescription, elementId);
  1677. if(isPage) {
  1678. eventInfo.label = $ax.pageData.page.name;
  1679. eventInfo.friendlyType = 'Page';
  1680. } else eventInfo.isMasterEvent = true;
  1681. if(scrolling) _handleScrollEvent(elementId, eventInfo, currentEvent.originalEvent, _event.windowScrollingUp, _event.windowScrollingDown, interactionMap, skipShowDescription, synthetic);
  1682. else _handleEvent(elementId, eventInfo, axEvent, skipShowDescription, synthetic);
  1683. }
  1684. }
  1685. // Filters include page, referenceDiagramObject, dynamicPanel, and repeater.
  1686. var _callFilterCheck = function(callFilter, type) {
  1687. for(var index = 0; index < callFilter.length; index++) {
  1688. var currentType = callFilter[index];
  1689. if(currentType === $ax.constants.ALL_TYPE || currentType === type) return true;
  1690. }
  1691. return false;
  1692. };
  1693. var fireEventThroughContainers = function(eventName, objects, synthetic, searchFilter, callFilter, path, itemId) {
  1694. // TODO: may want to pass in this as a parameter. At that point, may want to convert some of them to an option parameter. For now this is the only case
  1695. var skipShowDescription = eventName == 'onLoad';
  1696. // If objects undefined, load page
  1697. if(!objects) {
  1698. if(_callFilterCheck(callFilter, $ax.constants.PAGE_TYPE)) {
  1699. //if scrolling, set direction, later master will know
  1700. if(eventName === "onScroll") {
  1701. var currentScrollTop = $(window).scrollTop();
  1702. _event.windowScrollingUp = currentScrollTop < lastScrollTop;
  1703. _event.windowScrollingDown = currentScrollTop > lastScrollTop;
  1704. }
  1705. fireEventForPageOrMaster('', eventName, $ax.pageData.page.interactionMap, true, skipShowDescription, synthetic);
  1706. }
  1707. if(searchFilter.indexOf($ax.constants.PAGE_TYPE) != -1) fireEventThroughContainers(eventName, $ax.pageData.page.diagram.objects, synthetic, searchFilter, callFilter);
  1708. //reset and save scrolling info at the end
  1709. if(currentScrollTop) {
  1710. lastScrollTop = currentScrollTop;
  1711. _event.windowScrollingUp = undefined;
  1712. _event.windowScrollingDown = undefined;
  1713. }
  1714. return;
  1715. }
  1716. if(!path) path = [];
  1717. var pathCopy = [];
  1718. for(var j = 0; j < path.length; j++) pathCopy[j] = path[j];
  1719. for(var i = 0; i < objects.length; i++) {
  1720. var obj = objects[i];
  1721. pathCopy[path.length] = obj.id;
  1722. if (!$ax.public.fn.IsReferenceDiagramObject(obj.type) && !$ax.public.fn.IsDynamicPanel(obj.type) && !$ax.public.fn.IsRepeater(obj.type) && !$ax.public.fn.IsLayer(obj.type)) {
  1723. if(_callFilterCheck(callFilter)) { //fire current event for all types
  1724. if ($ax.public.fn.IsTable(obj.type) || $ax.public.fn.IsMenuObject(obj.type) || $ax.public.fn.IsTreeNodeObject(obj.type)) {
  1725. _fireEventsForTableMenuAndTree(obj, eventName, skipShowDescription, undefined, path, !synthetic);
  1726. } else {
  1727. var scriptId = $ax.getScriptIdFromPath(pathCopy);
  1728. if(scriptId && itemId) scriptId = $ax.repeater.createElementId(scriptId, itemId);
  1729. $ax.event.raiseSyntheticEvent(scriptId, eventName, skipShowDescription, undefined, !synthetic);
  1730. }
  1731. }
  1732. continue;
  1733. }
  1734. var objId = $ax.getScriptIdFromPath(pathCopy);
  1735. // If limboed, move on to next item
  1736. if(!objId) continue;
  1737. if(itemId) objId = $ax.repeater.createElementId(objId, itemId);
  1738. if($ax.public.fn.IsReferenceDiagramObject(obj.type)) {
  1739. if(_callFilterCheck(callFilter, $ax.constants.REFERENCE_DIAGRAM_OBJECT_TYPE)) {
  1740. fireEventForPageOrMaster(objId, eventName, $ax.pageData.masters[obj.masterId].interactionMap, false, skipShowDescription, synthetic);
  1741. }
  1742. if(searchFilter.indexOf($ax.constants.REFERENCE_DIAGRAM_OBJECT_TYPE) != -1) fireEventThroughContainers(eventName, $ax.pageData.masters[obj.masterId].diagram.objects, synthetic, searchFilter, callFilter, pathCopy, itemId);
  1743. } else if($ax.public.fn.IsDynamicPanel(obj.type)) {
  1744. if(_callFilterCheck(callFilter, $ax.constants.DYNAMIC_PANEL_TYPE)) $ax.event.raiseSyntheticEvent(objId, eventName, skipShowDescription, undefined, !synthetic);
  1745. if(searchFilter.indexOf($ax.constants.DYNAMIC_PANEL_TYPE) != -1) {
  1746. var diagrams = obj.diagrams;
  1747. for(var j = 0; j < diagrams.length; j++) {
  1748. fireEventThroughContainers(eventName, diagrams[j].objects, synthetic, searchFilter, callFilter, path, itemId);
  1749. }
  1750. }
  1751. } else if($ax.public.fn.IsRepeater(obj.type)) {
  1752. // TODO: possible an option for repeater item? Now fires overall for the repeater
  1753. if(_callFilterCheck(callFilter, $ax.constants.REPEATER)) $ax.event.raiseSyntheticEvent(objId, eventName, skipShowDescription, undefined, !synthetic);
  1754. if(searchFilter.indexOf($ax.constants.REPEATER) != -1) {
  1755. var itemIds = $ax.getItemIdsForRepeater(objId);
  1756. for(var j = 0; j < itemIds.length; j++) {
  1757. fireEventThroughContainers(eventName, obj.objects, synthetic, searchFilter, callFilter, path, itemIds[j]);
  1758. }
  1759. }
  1760. } else if($ax.public.fn.IsLayer(obj.type)) {
  1761. if(_callFilterCheck(callFilter, $ax.constants.LAYER_TYPE)) $ax.event.raiseSyntheticEvent(objId, eventName, skipShowDescription, undefined, !synthetic);
  1762. if(obj.objs && obj.objs.length > 0) {
  1763. fireEventThroughContainers(eventName, obj.objs, synthetic, searchFilter, callFilter, path, itemId);
  1764. }
  1765. }
  1766. }
  1767. eventNesting -= 1;
  1768. }; // FOCUS stuff
  1769. (function() {
  1770. })();
  1771. var _pageLoad = function() {
  1772. // Map of axure event names to pair of what it should attach to, and what the jquery event name is.
  1773. var PAGE_AXURE_TO_JQUERY_EVENT_NAMES = {
  1774. 'onScroll': [window, 'scroll'],
  1775. 'onScrollUp': [window, 'scrollup'],
  1776. 'onScrollDown': [window, 'scrolldown'],
  1777. //'onResize': [window, 'resize'],
  1778. 'onContextMenu': [window, 'contextmenu']
  1779. };
  1780. var $win = $(window);
  1781. if(!$ax.features.supports.mobile) {
  1782. PAGE_AXURE_TO_JQUERY_EVENT_NAMES.onClick = ['html', 'click'];
  1783. PAGE_AXURE_TO_JQUERY_EVENT_NAMES.onDoubleClick = ['html', 'dblclick'];
  1784. PAGE_AXURE_TO_JQUERY_EVENT_NAMES.onMouseMove = ['html', 'mousemove'];
  1785. } else {
  1786. _event.initMobileEvents($win, $win, '');
  1787. $win.bind($ax.features.eventNames.mouseDownName, _updateMouseLocation);
  1788. $win.bind($ax.features.eventNames.mouseUpName, function(e) { _updateMouseLocation(e, true); });
  1789. $win.scroll(function() { _setCanClick(false); });
  1790. $win.bind($ax.features.eventNames.mouseDownName, (function() {
  1791. _setCanClick(true);
  1792. }));
  1793. }
  1794. $win.bind($ax.features.eventNames.mouseMoveName, _updateMouseLocation);
  1795. $win.scroll($ax.flyoutManager.reregisterAllFlyouts);
  1796. for(key in PAGE_AXURE_TO_JQUERY_EVENT_NAMES) {
  1797. if(!PAGE_AXURE_TO_JQUERY_EVENT_NAMES.hasOwnProperty(key)) continue;
  1798. (function(axureName) {
  1799. var jqueryEventNamePair = PAGE_AXURE_TO_JQUERY_EVENT_NAMES[axureName];
  1800. var actionName = jqueryEventNamePair[1];
  1801. if(actionName == "scrollup" || actionName == "scrolldown") return;
  1802. $(jqueryEventNamePair[0])[actionName](function (e) {
  1803. $ax.setjBrowserEvent(e);
  1804. return fireEventThroughContainers(axureName, undefined, false, [$ax.constants.PAGE_TYPE, $ax.constants.REFERENCE_DIAGRAM_OBJECT_TYPE, $ax.constants.DYNAMIC_PANEL_TYPE, $ax.constants.REPEATER],
  1805. [$ax.constants.PAGE_TYPE, $ax.constants.REFERENCE_DIAGRAM_OBJECT_TYPE]);
  1806. });
  1807. })(key);
  1808. }
  1809. eventNesting -= 1;
  1810. lastScrollTop = 0;
  1811. };
  1812. _event.pageLoad = _pageLoad;
  1813. });
  1814. //***** recording.js *****//
  1815. // ******* Recording MANAGER ******** //
  1816. $axure.internal(function($ax) {
  1817. var _recording = $ax.recording = {};
  1818. $ax.recording.recordEvent = function(element, eventInfo, axEventObject, timeStamp) {
  1819. var elementHtml = $jobj(element);
  1820. var className = elementHtml.attr('class');
  1821. var inputValue;
  1822. if(className === 'ax_checkbox') {
  1823. inputValue = elementHtml.find('#' + element + '_input')[0].checked;
  1824. eventInfo.inputType = className;
  1825. eventInfo.inputValue = inputValue;
  1826. }
  1827. if(className === 'ax_text_field') {
  1828. inputValue = elementHtml.find('#' + element + '_input').val();
  1829. eventInfo.inputType = className;
  1830. eventInfo.inputValue = inputValue;
  1831. }
  1832. var scriptId = $ax.repeater.getScriptIdFromElementId(element);
  1833. var diagramObjectPath = $ax.getPathFromScriptId(scriptId);
  1834. var form = {
  1835. recordingId: $ax.recording.recordingId,
  1836. elementID: element,
  1837. eventType: axEventObject.description,
  1838. 'eventInfo': eventInfo,
  1839. // eventObject: axEventObject,
  1840. 'timeStamp': timeStamp,
  1841. 'path': diagramObjectPath
  1842. // ,
  1843. // 'trigger': function() {
  1844. // $ax.event.handleEvent(element, eventInfo, axEventObject);
  1845. // return false;
  1846. // }
  1847. };
  1848. $ax.messageCenter.postMessage('logEvent', form);
  1849. };
  1850. $ax.recording.maybeRecordEvent = function(element, eventInfo, axEventObject, timeStamp) {
  1851. };
  1852. $ax.recording.recordingId = "";
  1853. $ax.recording.recordingName = "";
  1854. $ax.messageCenter.addMessageListener(function(message, data) {
  1855. if(message === 'startRecording') {
  1856. $ax.recording.maybeRecordEvent = $ax.recording.recordEvent;
  1857. $ax.recording.recordingId = data.recordingId;
  1858. $ax.recording.recordingName = data.recordingName;
  1859. } else if(message === 'stopRecording') {
  1860. $ax.recording.maybeRecordEvent = function(element, eventInfo, axEventObject, timeStamp) {
  1861. };
  1862. }
  1863. else if(message === 'playEvent') {
  1864. var eventType = makeFirstLetterLower(data.eventType);
  1865. var inputElement;
  1866. var dObj = data.element === '' ? $ax.pageData.page : $ax.getObjectFromElementId(data.element);
  1867. if(!data.axEventObject) {
  1868. data.axEventObject = dObj && dObj.interactionMap && dObj.interactionMap[eventType];
  1869. }
  1870. data.eventInfo.thiswidget = $ax.getWidgetInfo(data.element);
  1871. data.eventInfo.item = $ax.getItemInfo(data.element);
  1872. if(data.eventInfo.inputType && data.eventInfo.inputType === 'ax_checkbox') {
  1873. inputElement = $jobj(data.element + '_input');
  1874. inputElement[0].checked = data.eventInfo.inputValue;
  1875. }
  1876. if(data.eventInfo.inputType && data.eventInfo.inputType === 'ax_text_field') {
  1877. inputElement = $jobj(data.element + '_input');
  1878. inputElement.val(data.eventInfo.inputValue);
  1879. }
  1880. $ax.event.handleEvent(data.element, data.eventInfo, data.axEventObject, false, true);
  1881. }
  1882. });
  1883. var makeFirstLetterLower = function(eventName) {
  1884. return eventName.substr(0, 1).toLowerCase() + eventName.substr(1);
  1885. };
  1886. });
  1887. //***** action.js *****//
  1888. $axure.internal(function($ax) {
  1889. var _actionHandlers = {};
  1890. var _action = $ax.action = {};
  1891. var queueTypes = _action.queueTypes = {
  1892. none: 0,
  1893. move: 1,
  1894. setState: 2,
  1895. fade: 3,
  1896. resize: 4,
  1897. rotate: 5
  1898. };
  1899. var animationQueue = {};
  1900. // using array as the key doesn't play nice
  1901. var nextAnimationId = 1;
  1902. var animationsToCount = {};
  1903. var actionToActionGroups = {};
  1904. var getAnimation = function(id, type) {
  1905. return animationQueue[id] && animationQueue[id][type] && animationQueue[id][type][0];
  1906. };
  1907. var _addAnimation = _action.addAnimation = function (id, type, func, suppressFire) {
  1908. var wasEmpty = !getAnimation(id, type);
  1909. // Add the func to the queue. Create the queue if necessary.
  1910. var idQueue = animationQueue[id];
  1911. if(!idQueue) animationQueue[id] = idQueue = {};
  1912. var queue = idQueue[type];
  1913. if(!queue) idQueue[type] = queue = [];
  1914. queue[queue.length] = func;
  1915. // If it was empty, there isn't a callback waiting to be called on this. You have to fire it manually.
  1916. // If this is waiting on something, suppress it, and it will fire when it's ready
  1917. if(wasEmpty && !suppressFire) func();
  1918. };
  1919. var _addAnimations = function (animations) {
  1920. if(animations.length == 1) {
  1921. _addAnimation(animations[0].id, animations[0].type, animations[0].func);
  1922. return;
  1923. }
  1924. var allReady = true;
  1925. var readyCount = 0;
  1926. for(var i = 0; i < animations.length; i++) {
  1927. var animation = animations[i];
  1928. var thisReady = !getAnimation(animation.id, animation.type);
  1929. allReady = allReady && thisReady;
  1930. if (thisReady) readyCount++;
  1931. else {
  1932. var typeToGroups = actionToActionGroups[animation.id];
  1933. if (!typeToGroups) actionToActionGroups[animation.id] = typeToGroups = {};
  1934. var groups = typeToGroups[animation.type];
  1935. if (!groups) typeToGroups[animation.type] = groups = [];
  1936. groups[groups.length] = animations;
  1937. }
  1938. }
  1939. for(i = 0; i < animations.length; i++) {
  1940. animation = animations[i];
  1941. _addAnimation(animation.id, animation.type, animation.func, true);
  1942. }
  1943. if (allReady) {
  1944. for (i = 0; i < animations.length; i++) animations[i].func();
  1945. } else {
  1946. animations.id = nextAnimationId++;
  1947. animationsToCount[animations.id] = readyCount;
  1948. }
  1949. }
  1950. var _fireAnimationFromQueue = _action.fireAnimationFromQueue = function (id, type) {
  1951. // Remove the function that was just fired
  1952. if (animationQueue[id] && animationQueue[id][type]) $ax.splice(animationQueue[id][type], 0, 1);
  1953. // Fire the next func if there is one
  1954. var func = getAnimation(id, type);
  1955. if(func && !_checkFireActionGroup(id, type, func)) func();
  1956. };
  1957. var _checkFireActionGroup = function(id, type, func) {
  1958. var group = actionToActionGroups[id];
  1959. group = group && group[type];
  1960. if (!group || group.length == 0) return false;
  1961. var animations = group[0];
  1962. var found = false;
  1963. for (var i = 0; i < animations.length; i++) {
  1964. var animation = animations[i];
  1965. if (animation.id == id && animation.type == type) {
  1966. found = func == animation.func;
  1967. break;
  1968. }
  1969. }
  1970. // if found then update this action group, otherwise, keep waiting for right action to fire
  1971. if(!found) return false;
  1972. $ax.splice(group, 0, 1);
  1973. var count = animationsToCount[animations.id] + 1;
  1974. if(count != animations.length) {
  1975. animationsToCount[animations.id] = count;
  1976. return true;
  1977. }
  1978. delete animationsToCount[animations.id];
  1979. // Funcs is needed because an earlier func can try to cascade right away (when no animation for example) and will kill this func and move on to the
  1980. // next one (which may not even exist). If we get all funcs before calling any, then we know they are all the func we want.
  1981. var funcs = [];
  1982. for(i = 0; i < animations.length; i++) {
  1983. animation = animations[i];
  1984. funcs.push(getAnimation(animation.id, animation.type));
  1985. }
  1986. for(i = 0; i < funcs.length; i++) {
  1987. funcs[i]();
  1988. }
  1989. return true;
  1990. }
  1991. var _refreshing = [];
  1992. _action.refreshStart = function(repeaterId) { _refreshing.push(repeaterId); };
  1993. _action.refreshEnd = function() { _refreshing.pop(); };
  1994. // TODO: [ben] Consider moving this to repeater.js
  1995. var _repeatersToRefresh = _action.repeatersToRefresh = [];
  1996. var _ignoreAction = function(repeaterId) {
  1997. for(var i = 0; i < _refreshing.length; i++) if(_refreshing[i] == repeaterId) return true;
  1998. return false;
  1999. };
  2000. var _addRefresh = function(repeaterId) {
  2001. if(_repeatersToRefresh.indexOf(repeaterId) == -1) _repeatersToRefresh.push(repeaterId);
  2002. };
  2003. var _getIdToResizeMoveState = function(eventInfo) {
  2004. if(!eventInfo.idToResizeMoveState) eventInfo.idToResizeMoveState = {};
  2005. return eventInfo.idToResizeMoveState;
  2006. }
  2007. var _queueResizeMove = function (id, type, eventInfo, actionInfo) {
  2008. if (type == queueTypes.resize || type == queueTypes.rotate) $ax.public.fn.convertToSingleImage($jobj(id));
  2009. var idToResizeMoveState = _getIdToResizeMoveState(eventInfo);
  2010. if(!idToResizeMoveState[id]) {
  2011. idToResizeMoveState[id] = {};
  2012. idToResizeMoveState[id][queueTypes.move] = { queue: [], used: 0 };
  2013. idToResizeMoveState[id][queueTypes.resize] = { queue: [], used: 0 };
  2014. idToResizeMoveState[id][queueTypes.rotate] = { queue: [], used: 0 };
  2015. }
  2016. var state = idToResizeMoveState[id];
  2017. // If this is not a type being queued (no action of it's type waiting already) then if it is an instant, fire right away.
  2018. var myOptions = type == queueTypes.resize ? actionInfo : actionInfo.options;
  2019. if(!state[type].queue.length && (!myOptions.easing || myOptions.easing == 'none' || !myOptions.duration)) {
  2020. var func = type == queueTypes.resize ? _addResize : type == queueTypes.rotate ? _addRotate : _addMove;
  2021. func(id, eventInfo, actionInfo, { easing: 'none', duration: 0, stop: { instant: true } });
  2022. return;
  2023. }
  2024. // Check other 2 types to see if either is empty, if so, we can't do anything, so just queue it up
  2025. var otherType1 = type == queueTypes.move ? queueTypes.resize : queueTypes.move;
  2026. var otherType2 = type == queueTypes.rotate ? queueTypes.resize : queueTypes.rotate;
  2027. if (!state[otherType1].queue.length || !state[otherType2].queue.length) {
  2028. state[type].queue.push({ eventInfo: eventInfo, actionInfo: actionInfo });
  2029. } else {
  2030. var duration = myOptions.duration;
  2031. var used1 = state[otherType1].used;
  2032. var used2 = state[otherType2].used;
  2033. while(state[otherType1].queue.length && state[otherType2].queue.length && duration != 0) {
  2034. var other1 = state[otherType1].queue[0];
  2035. var otherOptions1 = otherType1 == queueTypes.resize ? other1.actionInfo : other1.actionInfo.options;
  2036. // If queue up action is a non animation, then don't combo it, just queue it and move on
  2037. if(!otherOptions1.easing || otherOptions1.easing == 'none' || !otherOptions1.duration) {
  2038. func = otherType1 == queueTypes.resize ? _addResize : otherType1 == queueTypes.rotate ? _addRotate : _addMove;
  2039. func(id, eventInfo, actionInfo, { easing: 'none', duration: 0, stop: { instant: true } });
  2040. continue;
  2041. }
  2042. var other2 = state[otherType2].queue[0];
  2043. var otherOptions2 = otherType2 == queueTypes.resize ? other2.actionInfo : other2.actionInfo.options;
  2044. // If queue up action is a non animation, then don't combo it, just queue it and move on
  2045. if(!otherOptions2.easing || otherOptions2.easing == 'none' || !otherOptions2.duration) {
  2046. func = otherType2 == queueTypes.resize ? _addResize : otherType2 == queueTypes.rotate ? _addRotate : _addMove;
  2047. func(id, eventInfo, actionInfo, { easing: 'none', duration: 0, stop: { instant: true } });
  2048. continue;
  2049. }
  2050. // Other duration is what is left over. When in queue it may be partly finished already
  2051. var otherDuration1 = otherOptions1.duration - used1;
  2052. var otherDuration2 = otherOptions2.duration - used2;
  2053. var resizeInfo = type == queueTypes.resize ? actionInfo : otherType1 == queueTypes.resize ? other1.actionInfo : other2.actionInfo;
  2054. var rotateInfo = type == queueTypes.rotate ? actionInfo : otherType1 == queueTypes.rotate ? other1.actionInfo : other2.actionInfo;
  2055. var moveInfo = type == queueTypes.move ? actionInfo : otherType1 == queueTypes.move ? other1.actionInfo : other2.actionInfo;
  2056. var options = { easing: moveInfo.options.easing, duration: Math.min(duration, otherDuration1, otherDuration2) };
  2057. // Start for self is whole duration - duration left, end is start plus duration of combo to be queued, length is duration
  2058. var stop = { start: myOptions.duration - duration, len: myOptions.duration };
  2059. stop.end = stop.start + options.duration;
  2060. // Start for other is used (will be 0 after 1st round), end is start plus length is duration of combo to be queued, length is other duration
  2061. var otherStop1 = { start: used1, end: options.duration + used1, len: otherOptions1.duration };
  2062. var otherStop2 = { start: used2, end: options.duration + used2, len: otherOptions2.duration };
  2063. options.stop = type == queueTypes.resize ? stop : otherType1 == queueTypes.resize ? otherStop1 : otherStop2;
  2064. options.moveStop = type == queueTypes.move ? stop : otherType1 == queueTypes.move ? otherStop1 : otherStop2;
  2065. options.rotateStop = type == queueTypes.rotate ? stop : otherType1 == queueTypes.rotate ? otherStop1 : otherStop2;
  2066. _addResize(id, eventInfo, resizeInfo, options, moveInfo, rotateInfo);
  2067. // Update duration for this animation
  2068. duration -= options.duration;
  2069. // For others update used and remove from queue if necessary
  2070. if(otherDuration1 == options.duration) {
  2071. $ax.splice(state[otherType1].queue, 0, 1);
  2072. used1 = 0;
  2073. } else used1 += options.duration;
  2074. if(otherDuration2 == options.duration) {
  2075. $ax.splice(state[otherType2].queue, 0, 1);
  2076. used2 = 0;
  2077. } else used2 += options.duration;
  2078. }
  2079. // Start queue for new type if necessary
  2080. if(duration) {
  2081. state[type].queue.push({ eventInfo: eventInfo, actionInfo: actionInfo });
  2082. state[type].used = myOptions.duration - duration;
  2083. }
  2084. // Update used for others
  2085. state[otherType1].used = used1;
  2086. state[otherType2].used = used2;
  2087. }
  2088. };
  2089. _action.flushAllResizeMoveActions = function (eventInfo) {
  2090. var idToResizeMoveState = _getIdToResizeMoveState(eventInfo);
  2091. for(var id in idToResizeMoveState) _flushResizeMoveActions(id, idToResizeMoveState);
  2092. };
  2093. var _flushResizeMoveActions = function(id, idToResizeMoveState) {
  2094. var state = idToResizeMoveState[id];
  2095. var move = state[queueTypes.move];
  2096. var moveInfo = move.queue[0];
  2097. var resize = state[queueTypes.resize];
  2098. var resizeInfo = resize.queue[0];
  2099. var rotate = state[queueTypes.rotate];
  2100. var rotateInfo = rotate.queue[0];
  2101. while (moveInfo || resizeInfo || rotateInfo) {
  2102. var eventInfo = moveInfo ? moveInfo.eventInfo : resizeInfo ? resizeInfo.eventInfo : rotateInfo.eventInfo;
  2103. moveInfo = moveInfo && moveInfo.actionInfo;
  2104. resizeInfo = resizeInfo && resizeInfo.actionInfo;
  2105. rotateInfo = rotateInfo && rotateInfo.actionInfo;
  2106. // Resize is used by default, then rotate
  2107. if(resizeInfo) {
  2108. // Check for instant resize
  2109. if(!resizeInfo.duration || resizeInfo.easing == 'none') {
  2110. _addResize(id, resize.queue[0].eventInfo, resizeInfo, { easing: 'none', duration: 0, stop: { instant: true } });
  2111. _updateResizeMoveUsed(id, queueTypes.resize, 0, idToResizeMoveState);
  2112. resizeInfo = resize.queue[0];
  2113. continue;
  2114. }
  2115. var duration = resizeInfo.duration - resize.used;
  2116. if(moveInfo) duration = Math.min(duration, moveInfo.options.duration - move.used);
  2117. if(rotateInfo) duration = Math.min(duration, rotateInfo.options.duration - rotate.used);
  2118. var baseOptions = moveInfo ? moveInfo.options : resizeInfo;
  2119. var options = { easing: baseOptions.easing, duration: duration };
  2120. options.stop = { start: resize.used, end: resize.used + duration, len: resizeInfo.duration };
  2121. if(moveInfo) options.moveStop = { start: move.used, end: move.used + duration, len: moveInfo.options.duration };
  2122. if(rotateInfo) options.rotateStop = { start: rotate.used, end: rotate.used + duration, len: rotateInfo.options.duration };
  2123. _addResize(id, eventInfo, resizeInfo, options, moveInfo, rotateInfo);
  2124. _updateResizeMoveUsed(id, queueTypes.resize, duration, idToResizeMoveState);
  2125. resizeInfo = resize.queue[0];
  2126. if(rotateInfo) {
  2127. _updateResizeMoveUsed(id, queueTypes.rotate, duration, idToResizeMoveState);
  2128. rotateInfo = rotate.queue[0];
  2129. }
  2130. if(moveInfo) {
  2131. _updateResizeMoveUsed(id, queueTypes.move, duration, idToResizeMoveState);
  2132. moveInfo = move.queue[0];
  2133. }
  2134. } else if (rotateInfo) {
  2135. // Check for instant rotate
  2136. if(!rotateInfo.options.duration || rotateInfo.options.easing == 'none') {
  2137. _addRotate(id, rotate.queue[0].eventInfo, rotateInfo, { easing: 'none', duration: 0, stop: { instant: true } });
  2138. _updateResizeMoveUsed(id, queueTypes.rotate, 0, idToResizeMoveState);
  2139. rotateInfo = rotate.queue[0];
  2140. continue;
  2141. }
  2142. duration = rotateInfo.options.duration - rotate.used;
  2143. if(moveInfo) duration = Math.min(duration, moveInfo.options.duration - move.used);
  2144. baseOptions = moveInfo ? moveInfo.options : rotateInfo.options;
  2145. options = { easing: baseOptions.easing, duration: duration };
  2146. options.stop = { start: rotate.used, end: rotate.used + duration, len: rotateInfo.options.duration };
  2147. if(moveInfo) options.moveStop = { start: move.used, end: move.used + duration, len: moveInfo.options.duration };
  2148. _addRotate(id, eventInfo, rotateInfo, options, moveInfo);
  2149. _updateResizeMoveUsed(id, queueTypes.rotate, duration, idToResizeMoveState);
  2150. rotateInfo = rotate.queue[0];
  2151. if(moveInfo) {
  2152. _updateResizeMoveUsed(id, queueTypes.move, duration, idToResizeMoveState);
  2153. moveInfo = move.queue[0];
  2154. }
  2155. } else {
  2156. if(!moveInfo.options.duration || moveInfo.options.easing == 'none') {
  2157. _addMove(id, eventInfo, moveInfo, { easing: 'none', duration: 0, stop: { instant: true } });
  2158. _updateResizeMoveUsed(id, queueTypes.move, 0, idToResizeMoveState);
  2159. moveInfo = move.queue[0];
  2160. continue;
  2161. }
  2162. duration = moveInfo.options.duration - move.used;
  2163. options = { easing: moveInfo.options.easing, duration: duration };
  2164. options.stop = { start: move.used, end: moveInfo.options.duration, len: moveInfo.options.duration };
  2165. _addMove(id, eventInfo, moveInfo, options);
  2166. _updateResizeMoveUsed(id, queueTypes.move, duration, idToResizeMoveState);
  2167. moveInfo = move.queue[0];
  2168. }
  2169. }
  2170. };
  2171. var _updateResizeMoveUsed = function(id, type, duration, idToResizeMoveState) {
  2172. var state = idToResizeMoveState[id][type];
  2173. state.used += duration;
  2174. var options = state.queue[0].actionInfo;
  2175. if(options.options) options = options.options;
  2176. var optionDur = (options.easing && options.easing != 'none' && options.duration) || 0;
  2177. if(optionDur <= state.used) {
  2178. $ax.splice(state.queue, 0, 1);
  2179. state.used = 0;
  2180. }
  2181. }
  2182. var _dispatchAction = $ax.action.dispatchAction = function(eventInfo, actions, currentIndex) {
  2183. currentIndex = currentIndex || 0;
  2184. //If no actions, you can bubble
  2185. if(currentIndex >= actions.length) return;
  2186. //actions are responsible for doing their own dispatching
  2187. _actionHandlers[actions[currentIndex].action](eventInfo, actions, currentIndex);
  2188. };
  2189. _actionHandlers.wait = function(eventInfo, actions, index) {
  2190. var action = actions[index];
  2191. var infoCopy = $ax.eventCopy(eventInfo);
  2192. window.setTimeout(function() {
  2193. infoCopy.now = new Date();
  2194. infoCopy.idToResizeMoveState = undefined;
  2195. _dispatchAction(infoCopy, actions, index + 1);
  2196. _action.flushAllResizeMoveActions(infoCopy);
  2197. }, action.waitTime);
  2198. };
  2199. _actionHandlers.expr = function(eventInfo, actions, index) {
  2200. var action = actions[index];
  2201. $ax.expr.evaluateExpr(action.expr, eventInfo); //this should be a block
  2202. _dispatchAction(eventInfo, actions, index + 1);
  2203. };
  2204. _actionHandlers.setFunction = _actionHandlers.expr;
  2205. _actionHandlers.linkWindow = function(eventInfo, actions, index) {
  2206. linkActionHelper(eventInfo, actions, index);
  2207. };
  2208. _actionHandlers.closeCurrent = function(eventInfo, actions, index) {
  2209. $ax.closeWindow();
  2210. _dispatchAction(eventInfo, actions, index + 1);
  2211. };
  2212. _actionHandlers.linkFrame = function(eventInfo, actions, index) {
  2213. linkActionHelper(eventInfo, actions, index);
  2214. };
  2215. _actionHandlers.setAdaptiveView = function(eventInfo, actions, index) {
  2216. var action = actions[index];
  2217. var view = action.setAdaptiveViewTo;
  2218. if(view) $ax.adaptive.setAdaptiveView(view);
  2219. };
  2220. var linkActionHelper = function(eventInfo, actions, index) {
  2221. var action = actions[index];
  2222. eventInfo.link = true;
  2223. if(action.linkType != 'frame') {
  2224. var includeVars = _includeVars(action.target, eventInfo);
  2225. if(action.target.targetType == "reloadPage") {
  2226. $ax.reload(action.target.includeVariables);
  2227. } else if(action.target.targetType == "backUrl") {
  2228. $ax.back();
  2229. }
  2230. var url = action.target.url;
  2231. if(!url && action.target.urlLiteral) {
  2232. url = $ax.expr.evaluateExpr(action.target.urlLiteral, eventInfo, true);
  2233. }
  2234. if(url) {
  2235. if(action.linkType == "popup") {
  2236. $ax.navigate({
  2237. url: url,
  2238. target: action.linkType,
  2239. includeVariables: includeVars,
  2240. popupOptions: action.popup
  2241. });
  2242. } else {
  2243. $ax.navigate({
  2244. url: url,
  2245. target: action.linkType,
  2246. includeVariables: includeVars
  2247. });
  2248. }
  2249. }
  2250. } else linkFrame(eventInfo, action);
  2251. eventInfo.link = false;
  2252. _dispatchAction(eventInfo, actions, index + 1);
  2253. };
  2254. var _includeVars = function(target, eventInfo) {
  2255. if(target.includeVariables) return true;
  2256. // If it is a url literal, that is a string literal, that has only 1 sto, that is an item that is a page, include vars.
  2257. if(target.urlLiteral) {
  2258. var literal = target.urlLiteral;
  2259. var sto = literal.stos[0];
  2260. if(literal.exprType == 'stringLiteral' && literal.value.indexOf('[[') == 0 && literal.value.indexOf(']]' == literal.value.length - 2) && literal.stos.length == 1 && sto.sto == 'item' && eventInfo.item) {
  2261. var data = $ax.repeater.getData(eventInfo, eventInfo.item.repeater.elementId, eventInfo.item.index, sto.name, 'data');
  2262. if (data && $ax.public.fn.IsPage(data.type)) return true;
  2263. }
  2264. }
  2265. return false;
  2266. };
  2267. var linkFrame = function(eventInfo, action) {
  2268. for(var i = 0; i < action.framesToTargets.length; i++) {
  2269. var framePath = action.framesToTargets[i].framePath;
  2270. var target = action.framesToTargets[i].target;
  2271. var includeVars = _includeVars(target, eventInfo);
  2272. var url = target.url;
  2273. if(!url && target.urlLiteral) {
  2274. url = $ax.expr.evaluateExpr(target.urlLiteral, eventInfo, true);
  2275. }
  2276. var id = $ax.getElementIdsFromPath(framePath, eventInfo)[0];
  2277. if(id) $ax('#' + $ax.INPUT(id)).openLink(url, includeVars);
  2278. }
  2279. };
  2280. var _repeatPanelMap = {};
  2281. _actionHandlers.setPanelState = function(eventInfo, actions, index) {
  2282. var action = actions[index];
  2283. for(var i = 0; i < action.panelsToStates.length; i++) {
  2284. var panelToState = action.panelsToStates[i];
  2285. var stateInfo = panelToState.stateInfo;
  2286. var elementIds = $ax.getElementIdsFromPath(panelToState.panelPath, eventInfo);
  2287. for(var j = 0; j < elementIds.length; j++) {
  2288. var elementId = elementIds[j];
  2289. // Need new scope for elementId and info
  2290. (function(elementId, stateInfo) {
  2291. _addAnimation(elementId, queueTypes.setState, function() {
  2292. var stateNumber = stateInfo.stateNumber;
  2293. if(stateInfo.setStateType == "value") {
  2294. var oldTarget = eventInfo.targetElement;
  2295. eventInfo.targetElement = elementId;
  2296. var stateName = $ax.expr.evaluateExpr(stateInfo.stateValue, eventInfo);
  2297. eventInfo.targetElement = oldTarget;
  2298. // Try for state name first
  2299. var states = $ax.getObjectFromElementId(elementId).diagrams;
  2300. var stateNameFound = false;
  2301. for(var k = 0; k < states.length; k++) {
  2302. if(states[k].label == stateName) {
  2303. stateNumber = k + 1;
  2304. stateNameFound = true;
  2305. }
  2306. }
  2307. // Now check for index
  2308. if(!stateNameFound) {
  2309. stateNumber = Number(stateName);
  2310. var panelCount = $('#' + elementId).children().length;
  2311. // Make sure number is not NaN, is in range, and is a whole number.
  2312. // Wasn't a state name or number, so return
  2313. if(isNaN(stateNumber) || stateNumber <= 0 || stateNumber > panelCount || Math.round(stateNumber) != stateNumber) return _fireAnimationFromQueue(elementId, queueTypes.setState);
  2314. }
  2315. } else if(stateInfo.setStateType == 'next' || stateInfo.setStateType == 'previous') {
  2316. var info = $ax.deepCopy(stateInfo);
  2317. var repeat = info.repeat;
  2318. // Only map it, if repeat exists.
  2319. if(typeof (repeat) == 'number') _repeatPanelMap[elementId] = info;
  2320. return _progessPanelState(elementId, info, info.repeatSkipFirst);
  2321. }
  2322. delete _repeatPanelMap[elementId];
  2323. // If setting to current (to stop repeat) break here
  2324. if(stateInfo.setStateType == 'current') return _fireAnimationFromQueue(elementId, queueTypes.setState);
  2325. $ax('#' + elementId).SetPanelState(stateNumber, stateInfo.options, stateInfo.showWhenSet);
  2326. });
  2327. })(elementId, stateInfo);
  2328. }
  2329. }
  2330. _dispatchAction(eventInfo, actions, index + 1);
  2331. };
  2332. var _progessPanelState = function(id, info, skipFirst) {
  2333. var direction = info.setStateType;
  2334. var loop = info.loop;
  2335. var repeat = info.repeat;
  2336. var options = info.options;
  2337. var hasRepeat = typeof (repeat) == 'number';
  2338. var currentStateId = $ax.visibility.GetPanelState(id);
  2339. var stateNumber = '';
  2340. if(currentStateId != '') {
  2341. currentStateId = $ax.repeater.getScriptIdFromElementId(currentStateId);
  2342. var currentStateNumber = Number(currentStateId.substr(currentStateId.indexOf('state') + 5));
  2343. if(direction == "next") {
  2344. stateNumber = currentStateNumber + 2;
  2345. if(stateNumber > $ax.visibility.GetPanelStateCount(id)) {
  2346. if(loop) stateNumber = 1;
  2347. else {
  2348. delete _repeatPanelMap[id];
  2349. return _fireAnimationFromQueue(id, queueTypes.setState);
  2350. }
  2351. }
  2352. } else if(direction == "previous") {
  2353. stateNumber = currentStateNumber;
  2354. if(stateNumber <= 0) {
  2355. if(loop) stateNumber = $ax.visibility.GetPanelStateCount(id);
  2356. else {
  2357. delete _repeatPanelMap[id];
  2358. return _fireAnimationFromQueue(id, queueTypes.setState);
  2359. }
  2360. }
  2361. }
  2362. if(hasRepeat && _repeatPanelMap[id] != info) return _fireAnimationFromQueue(id, queueTypes.setState);
  2363. if (!skipFirst) $ax('#' + id).SetPanelState(stateNumber, options, info.showWhenSet);
  2364. else _fireAnimationFromQueue(id, queueTypes.setState);
  2365. if(hasRepeat) {
  2366. var animate = options && options.animateIn;
  2367. if(animate && animate.easing && animate.easing != 'none' && animate.duration > repeat) repeat = animate.duration;
  2368. animate = options && options.animateOut;
  2369. if(animate && animate.easing && animate.easing != 'none' && animate.duration > repeat) repeat = animate.duration;
  2370. window.setTimeout(function() {
  2371. // Either new repeat, or no repeat anymore.
  2372. if(_repeatPanelMap[id] != info) return;
  2373. _addAnimation(id, queueTypes.setState, function() {
  2374. _progessPanelState(id, info, false);
  2375. });
  2376. }, repeat);
  2377. } else delete _repeatPanelMap[id];
  2378. }
  2379. };
  2380. _actionHandlers.fadeWidget = function(eventInfo, actions, index) {
  2381. var action = actions[index];
  2382. for(var i = 0; i < action.objectsToFades.length; i++) {
  2383. var fadeInfo = action.objectsToFades[i].fadeInfo;
  2384. var elementIds = $ax.getElementIdsFromPath(action.objectsToFades[i].objectPath, eventInfo);
  2385. for(var j = 0; j < elementIds.length; j++) {
  2386. var elementId = elementIds[j];
  2387. // Need new scope for elementId and info
  2388. (function(elementId, fadeInfo) {
  2389. _addAnimation(elementId, queueTypes.fade, function() {
  2390. if(fadeInfo.fadeType == "hide") {
  2391. $ax('#' + elementId).hide(fadeInfo.options);
  2392. } else if(fadeInfo.fadeType == "show") {
  2393. $ax('#' + elementId).show(fadeInfo.options, eventInfo);
  2394. } else if(fadeInfo.fadeType == "toggle") {
  2395. $ax('#' + elementId).toggleVisibility(fadeInfo.options);
  2396. }
  2397. });
  2398. })(elementId, fadeInfo);
  2399. }
  2400. }
  2401. _dispatchAction(eventInfo, actions, index + 1);
  2402. };
  2403. _actionHandlers.setOpacity = function(eventInfo, actions, index) {
  2404. var action = actions[index];
  2405. for(var i = 0; i < action.objectsToSetOpacity.length; i++) {
  2406. var opacityInfo = action.objectsToSetOpacity[i].opacityInfo;
  2407. var elementIds = $ax.getElementIdsFromPath(action.objectsToSetOpacity[i].objectPath, eventInfo);
  2408. for(var j = 0; j < elementIds.length; j++) {
  2409. var elementId = elementIds[j];
  2410. (function(elementId, opacityInfo) {
  2411. _addAnimation(elementId, queueTypes.fade, function () {
  2412. var oldTarget = eventInfo.targetElement;
  2413. eventInfo.targetElement = elementId;
  2414. var opacity = $ax.expr.evaluateExpr(opacityInfo.opacity, eventInfo);
  2415. eventInfo.targetElement = oldTarget;
  2416. opacity = Math.min(100, Math.max(0, opacity));
  2417. $ax('#' + elementId).setOpacity(opacity/100, opacityInfo.easing, opacityInfo.duration);
  2418. })
  2419. })(elementId, opacityInfo);
  2420. }
  2421. }
  2422. _dispatchAction(eventInfo, actions, index + 1);
  2423. }
  2424. _actionHandlers.moveWidget = function(eventInfo, actions, index) {
  2425. var action = actions[index];
  2426. for(var i = 0; i < action.objectsToMoves.length; i++) {
  2427. var moveInfo = action.objectsToMoves[i].moveInfo;
  2428. var elementIds = $ax.getElementIdsFromPath(action.objectsToMoves[i].objectPath, eventInfo);
  2429. for(var j = 0; j < elementIds.length; j++) {
  2430. var elementId = elementIds[j];
  2431. _queueResizeMove(elementId, queueTypes.move, eventInfo, moveInfo);
  2432. //_addMove(eventInfo, elementId, moveInfo, eventInfo.dragInfo);
  2433. }
  2434. }
  2435. _dispatchAction(eventInfo, actions, index + 1);
  2436. };
  2437. var _compoundChildrenShallow = function (id) {
  2438. var deep = [];
  2439. var children = $ax('#' + id).getChildren()[0].children;
  2440. var piecePrefix = id + 'p';
  2441. for (var i = 0; i < children.length; i++) {
  2442. if(children[i].substring(0, id.length + 1) == piecePrefix) {
  2443. deep.push(children[i]);
  2444. }
  2445. }
  2446. return deep;
  2447. };
  2448. var _addMove = function (elementId, eventInfo, moveInfo, optionsOverride) {
  2449. var eventInfoCopy = $ax.eventCopy(eventInfo);
  2450. var idToResizeMoveState = _getIdToResizeMoveState(eventInfoCopy);
  2451. eventInfoCopy.targetElement = elementId;
  2452. var options = $ax.deepCopy(moveInfo.options);
  2453. options.easing = optionsOverride.easing;
  2454. options.duration = optionsOverride.duration;
  2455. options.dragInfo = eventInfo.dragInfo;
  2456. if($ax.public.fn.IsLayer($obj(elementId).type)) {
  2457. var childrenIds = $ax.public.fn.getLayerChildrenDeep(elementId, true);
  2458. if(childrenIds.length == 0) return;
  2459. var animations = [];
  2460. // Get move delta once, then apply to all children
  2461. animations.push({
  2462. id: elementId,
  2463. type: queueTypes.move,
  2464. func: function() {
  2465. var layerInfo = $ax.public.fn.getWidgetBoundingRect(elementId);
  2466. var deltaLoc = _getMoveLoc(elementId, moveInfo, eventInfoCopy, optionsOverride.stop, idToResizeMoveState[elementId], options, layerInfo);
  2467. // $ax.event.raiseSyntheticEvent(elementId, "onMove");
  2468. $ax.visibility.pushContainer(elementId, false);
  2469. options.onComplete = function () {
  2470. _fireAnimationFromQueue(elementId, queueTypes.move);
  2471. $ax.visibility.popContainer(elementId, false);
  2472. };
  2473. $ax('#' + elementId).moveBy(deltaLoc.x, deltaLoc.y, options);
  2474. }
  2475. });
  2476. //for(var i = 0; i < childrenIds.length; i++) {
  2477. // (function(childId) {
  2478. // animations.push({
  2479. // id: childId,
  2480. // type: queueTypes.move,
  2481. // func: function () {
  2482. // // Nop, while trying to move as container
  2483. // //$ax.event.raiseSyntheticEvent(childId, "onMove");
  2484. // //if($ax.public.fn.IsLayer($obj(childId).type)) _fireAnimationFromQueue(childId, queueTypes.move);
  2485. // //else $ax('#' + childId).moveBy(deltaLoc.x, deltaLoc.y, moveInfo.options);
  2486. // }
  2487. // });
  2488. // })(childrenIds[i]);
  2489. //}
  2490. _addAnimations(animations);
  2491. } else {
  2492. _addAnimation(elementId, queueTypes.move, function() {
  2493. var loc = _getMoveLoc(elementId, moveInfo, eventInfoCopy, optionsOverride.stop, idToResizeMoveState[elementId], options);
  2494. // $ax.event.raiseSyntheticEvent(elementId, "onMove");
  2495. if(loc.moveTo) $ax('#' + elementId).moveTo(loc.x, loc.y, options);
  2496. else $ax('#' + elementId).moveBy(loc.x, loc.y, options);
  2497. });
  2498. }
  2499. };
  2500. var _moveSingleWidget = function (elementId, delta, options, onComplete) {
  2501. if(!delta.x && !delta.y) {
  2502. $ax.action.fireAnimationFromQueue(elementId, $ax.action.queueTypes.move);
  2503. return;
  2504. }
  2505. var fixedInfo = $ax.dynamicPanelManager.getFixedInfo(elementId);
  2506. var xProp = 'left';
  2507. var xDiff = '+=';
  2508. if(fixedInfo) {
  2509. if(fixedInfo.horizontal == 'right') {
  2510. xProp = 'right';
  2511. xDiff = '-=';
  2512. } else if(fixedInfo.horizontal == 'center') {
  2513. xProp = 'margin-left';
  2514. }
  2515. }
  2516. var yProp = 'top';
  2517. var yDiff = '+=';
  2518. if(fixedInfo) {
  2519. if(fixedInfo.vertical == 'bottom') {
  2520. yProp = 'bottom';
  2521. yDiff = '-=';
  2522. } else if(fixedInfo.vertical == 'middle') {
  2523. yProp = 'margin-top';
  2524. }
  2525. }
  2526. var css = {};
  2527. css[xProp] = xDiff + delta.x;
  2528. css[yProp] = yDiff + delta.y;
  2529. var moveInfo = $ax.move.PrepareForMove(elementId, delta.x, delta.y,false, options);
  2530. $jobjAll(elementId).animate(css, {
  2531. duration: options.duration,
  2532. easing: options.easing,
  2533. queue: false,
  2534. complete: function () {
  2535. if(onComplete) onComplete();
  2536. if(moveInfo.rootLayer) $ax.visibility.popContainer(moveInfo.rootLayer, false);
  2537. $ax.action.fireAnimationFromQueue(elementId, $ax.action.queueTypes.move);
  2538. }
  2539. });
  2540. }
  2541. var _getMoveLoc = function (elementId, moveInfo, eventInfoCopy, stopInfo, comboState, options, layerInfo) {
  2542. var moveTo = false;
  2543. var moveWithThis = false;
  2544. var xValue = 0;
  2545. var yValue = 0;
  2546. var moveResult = comboState.moveResult;
  2547. var widgetDragInfo = eventInfoCopy.dragInfo;
  2548. var jobj = $jobj(elementId);
  2549. var startX;
  2550. var startY;
  2551. switch(moveInfo.moveType) {
  2552. case "location":
  2553. // toRatio is ignoring anything before start since that has already taken effect we just know whe have from start to len to finish
  2554. // getting to the location we want to get to.
  2555. var toRatio = stopInfo.instant ? 1 : (stopInfo.end - stopInfo.start) / (stopInfo.len - stopInfo.start);
  2556. // If result already caluculated, don't recalculate again, other calculate and save
  2557. if (moveResult) {
  2558. xValue = moveResult.x;
  2559. yValue = moveResult.y;
  2560. } else {
  2561. comboState.moveResult = moveResult = { x: $ax.expr.evaluateExpr(moveInfo.xValue, eventInfoCopy), y: $ax.expr.evaluateExpr(moveInfo.yValue, eventInfoCopy) };
  2562. xValue = moveResult.x;
  2563. yValue = moveResult.y;
  2564. }
  2565. // If this is final stop for this move, then clear out the result so next move won't use it
  2566. if(stopInfo.instant || stopInfo.end == stopInfo.len) comboState.moveResult = undefined;
  2567. if (layerInfo) {
  2568. startX = layerInfo.left;
  2569. startY = layerInfo.top;
  2570. //} else if ($ax.public.fn.isCompoundVectorHtml(jobj[0])) {
  2571. // var dimensions = $ax.public.fn.compoundWidgetDimensions(jobj);
  2572. // startX = dimensions.left;
  2573. // startY = dimensions.top;
  2574. } else {
  2575. startX = $ax('#' + elementId).locRelativeIgnoreLayer(false);
  2576. startY = $ax('#' + elementId).locRelativeIgnoreLayer(true);
  2577. if(jobj.css('position') == 'fixed') {
  2578. startX -= $(window).scrollLeft();
  2579. startY -= $(window).scrollTop();
  2580. }
  2581. }
  2582. xValue = xValue == '' ? 0 : (xValue - startX) * toRatio;
  2583. yValue = yValue == '' ? 0 : (yValue - startY) * toRatio;
  2584. break;
  2585. case "delta":
  2586. var ratio = stopInfo.instant ? 1 : (stopInfo.end - stopInfo.start) / stopInfo.len;
  2587. // See case location above
  2588. if(moveResult) {
  2589. xValue = moveResult.x * ratio;
  2590. yValue = moveResult.y * ratio;
  2591. } else {
  2592. comboState.moveResult = moveResult = { x: $ax.expr.evaluateExpr(moveInfo.xValue, eventInfoCopy), y: $ax.expr.evaluateExpr(moveInfo.yValue, eventInfoCopy) };
  2593. xValue = moveResult.x * ratio;
  2594. yValue = moveResult.y * ratio;
  2595. }
  2596. if (stopInfo.instant || stopInfo.end == stopInfo.len) comboState.moveResult = undefined;
  2597. break;
  2598. case "drag":
  2599. xValue = widgetDragInfo.xDelta;
  2600. yValue = widgetDragInfo.yDelta;
  2601. break;
  2602. case "dragX":
  2603. xValue = widgetDragInfo.xDelta;
  2604. yValue = 0;
  2605. break;
  2606. case "dragY":
  2607. xValue = 0;
  2608. yValue = widgetDragInfo.yDelta;
  2609. break;
  2610. case "locationBeforeDrag":
  2611. var location = widgetDragInfo.movedWidgets[eventInfoCopy.targetElement];
  2612. if (location) {
  2613. var axObj = $ax('#' + eventInfoCopy.targetElement);
  2614. xValue = location.x - axObj.left();
  2615. yValue = location.y - axObj.top();
  2616. } else {
  2617. _fireAnimationFromQueue(eventInfoCopy.srcElement, queueTypes.move);
  2618. return { x: 0, y: 0 };
  2619. }
  2620. //moveTo = true;
  2621. break;
  2622. case "withThis":
  2623. moveWithThis = true;
  2624. var widgetMoveInfo = $ax.move.GetWidgetMoveInfo();
  2625. var srcElementId = $ax.getElementIdsFromEventAndScriptId(eventInfoCopy, eventInfoCopy.srcElement)[0];
  2626. var delta = widgetMoveInfo[srcElementId];
  2627. options.easing = delta.options.easing;
  2628. options.duration = delta.options.duration;
  2629. xValue = delta.x;
  2630. yValue = delta.y;
  2631. break;
  2632. }
  2633. if (options && options.boundaryExpr) {
  2634. //$ax.public.fn.removeCompound(jobj);
  2635. if(jobj.css('position') == 'fixed') {
  2636. //swap page coordinates with fixed coordinates
  2637. options.boundaryExpr.leftExpr.value = options.boundaryExpr.leftExpr.value.replace('.top', '.topfixed').replace('.left', '.leftfixed').replace('.bottom', '.bottomfixed').replace('.right', '.rightfixed');
  2638. options.boundaryExpr.leftExpr.stos[0].leftSTO.prop = options.boundaryExpr.leftExpr.stos[0].leftSTO.prop + 'fixed';
  2639. options.boundaryStos.boundaryScope.direcval0.value = options.boundaryStos.boundaryScope.direcval0.value.replace('.top', '.topfixed').replace('.left', '.leftfixed').replace('.bottom', '.bottomfixed').replace('.right', '.rightfixed');
  2640. options.boundaryStos.boundaryScope.direcval0.stos[0].leftSTO.prop = options.boundaryStos.boundaryScope.direcval0.stos[0].leftSTO.prop + 'fixed';
  2641. }
  2642. if(moveWithThis && (xValue || yValue)) {
  2643. _updateLeftExprVariable(options.boundaryExpr, xValue.toString(), yValue.toString());
  2644. }
  2645. if(!$ax.expr.evaluateExpr(options.boundaryExpr, eventInfoCopy)) {
  2646. var boundaryStoInfo = options.boundaryStos;
  2647. if(boundaryStoInfo) {
  2648. if(moveWithThis) {
  2649. var stoScopes = boundaryStoInfo.boundaryScope;
  2650. if(stoScopes) {
  2651. for(var s in stoScopes) {
  2652. var boundaryScope = stoScopes[s];
  2653. if(!boundaryScope.localVariables) continue;
  2654. if(boundaryScope.localVariables.withx) boundaryScope.localVariables.withx.value = xValue.toString();
  2655. if(boundaryScope.localVariables.withy) boundaryScope.localVariables.withy.value = yValue.toString();
  2656. }
  2657. }
  2658. }
  2659. if(layerInfo) {
  2660. startX = layerInfo.left;
  2661. startY = layerInfo.top;
  2662. } else {
  2663. startX = $ax('#' + elementId).locRelativeIgnoreLayer(false);
  2664. startY = $ax('#' + elementId).locRelativeIgnoreLayer(true);
  2665. if(jobj.css('position') == 'fixed') {
  2666. startX -= $(window).scrollLeft();
  2667. startY -= $(window).scrollTop();
  2668. }
  2669. }
  2670. if(boundaryStoInfo.ySto) {
  2671. var currentTop = layerInfo ? layerInfo.top : startY;
  2672. var newTop = $ax.evaluateSTO(boundaryStoInfo.ySto, boundaryStoInfo.boundaryScope, eventInfoCopy);
  2673. if(moveTo) yValue = newTop;
  2674. else yValue = newTop - currentTop;
  2675. }
  2676. if(boundaryStoInfo.xSto) {
  2677. var currentLeft = layerInfo ? layerInfo.left : startX;
  2678. var newLeft = $ax.evaluateSTO(boundaryStoInfo.xSto, boundaryStoInfo.boundaryScope, eventInfoCopy);
  2679. if(moveTo) xValue = newLeft;
  2680. else xValue = newLeft - currentLeft;
  2681. }
  2682. }
  2683. }
  2684. //$ax.public.fn.restoreCompound(jobj);
  2685. }
  2686. return { x: Number(xValue), y: Number(yValue), moveTo: moveTo };
  2687. };
  2688. //we will have something like [[Target.right + withX]] for leftExpr, and this function set the value of withX
  2689. var _updateLeftExprVariable = function (exprTree, xValue, yValue) {
  2690. if(exprTree.leftExpr && !exprTree.leftExpr.op) {
  2691. var localVars = exprTree.leftExpr.localVariables;
  2692. if(localVars) {
  2693. if(localVars.withx) localVars.withx.value = xValue;
  2694. if(localVars.withy) localVars.withy.value = yValue;
  2695. }
  2696. }
  2697. //traversal
  2698. if(exprTree.op) {
  2699. if(exprTree.leftExpr) _updateLeftExprVariable(exprTree.leftExpr, xValue, yValue);
  2700. if(exprTree.rightExpr) _updateLeftExprVariable(exprTree.rightExpr, xValue, yValue);
  2701. }
  2702. }
  2703. var widgetRotationFilter = [
  2704. $ax.constants.IMAGE_BOX_TYPE, $ax.constants.IMAGE_MAP_REGION_TYPE, $ax.constants.DYNAMIC_PANEL_TYPE,
  2705. $ax.constants.VECTOR_SHAPE_TYPE, $ax.constants.VERTICAL_LINE_TYPE, $ax.constants.HORIZONTAL_LINE_TYPE
  2706. ];
  2707. _actionHandlers.rotateWidget = function(eventInfo, actions, index) {
  2708. var action = actions[index];
  2709. for(var i = 0; i < action.objectsToRotate.length; i++) {
  2710. var rotateInfo = action.objectsToRotate[i].rotateInfo;
  2711. var elementIds = $ax.getElementIdsFromPath(action.objectsToRotate[i].objectPath, eventInfo);
  2712. for(var j = 0; j < elementIds.length; j++) {
  2713. var elementId = elementIds[j];
  2714. _queueResizeMove(elementId, queueTypes.rotate, eventInfo, rotateInfo);
  2715. }
  2716. }
  2717. _dispatchAction(eventInfo, actions, index + 1);
  2718. };
  2719. var _addRotate = function (elementId, eventInfo, rotateInfo, options, moveInfo) {
  2720. var idToResizeMoveState = _getIdToResizeMoveState(eventInfo);
  2721. rotateInfo = $ax.deepCopy(rotateInfo);
  2722. rotateInfo.options.easing = options.easing;
  2723. rotateInfo.options.duration = options.duration;
  2724. var eventInfoCopy = $ax.eventCopy(eventInfo);
  2725. eventInfoCopy.targetElement = elementId;
  2726. //calculate degree value at start of animation
  2727. var rotateDegree;
  2728. var offset = {};
  2729. var eval = function(boundingRect) {
  2730. rotateDegree = parseFloat($ax.expr.evaluateExpr(rotateInfo.degree, eventInfoCopy));
  2731. offset.x = Number($ax.expr.evaluateExpr(rotateInfo.offsetX, eventInfoCopy));
  2732. offset.y = Number($ax.expr.evaluateExpr(rotateInfo.offsetY, eventInfoCopy));
  2733. if(!rotateInfo.options.clockwise) rotateDegree = -rotateDegree;
  2734. _updateOffset(offset, rotateInfo.anchor, boundingRect);
  2735. }
  2736. if(moveInfo) {
  2737. var moveOptions = { dragInfo: eventInfoCopy.dragInfo, duration: options.duration, easing: options.easing, boundaryExpr: moveInfo.options.boundaryExpr, boundaryStos: moveInfo.options.boundaryStos };
  2738. }
  2739. var obj = $obj(elementId);
  2740. if($ax.public.fn.IsLayer(obj.type)) {
  2741. var childrenIds = $ax.public.fn.getLayerChildrenDeep(elementId, true, true);
  2742. if(childrenIds.length == 0) return;
  2743. var animations = [];
  2744. //get center point of the group, and degree delta
  2745. var centerPoint, degreeDelta, moveDelta;
  2746. animations.push({
  2747. id: elementId,
  2748. type: queueTypes.rotate,
  2749. func: function () {
  2750. var boundingRect = $axure.fn.getWidgetBoundingRect(elementId);
  2751. eval(boundingRect);
  2752. centerPoint = boundingRect.centerPoint;
  2753. centerPoint.x += offset.x;
  2754. centerPoint.y += offset.y;
  2755. degreeDelta = _initRotateLayer(elementId, rotateInfo, rotateDegree, options, options.stop);
  2756. _fireAnimationFromQueue(elementId, queueTypes.rotate);
  2757. moveDelta = { x: 0, y: 0 };
  2758. if (moveInfo) {
  2759. moveDelta = _getMoveLoc(elementId, moveInfo, eventInfoCopy, options.moveStop, idToResizeMoveState[elementId], moveOptions, boundingRect);
  2760. if (moveDelta.moveTo) {
  2761. moveDelta.x -= $ax.getNumFromPx($jobj(elementId).css('left'));
  2762. moveDelta.y -= $ax.getNumFromPx($jobj(elementId).css('top'));
  2763. }
  2764. $ax.event.raiseSyntheticEvent(elementId, 'onMove');
  2765. }
  2766. }
  2767. });
  2768. for(var idIndex = 0; idIndex < childrenIds.length; idIndex++) {
  2769. var childId = childrenIds[idIndex];
  2770. (function(id) {
  2771. var childObj = $obj(id);
  2772. var rotate = $.inArray(childObj.type, widgetRotationFilter) != -1;
  2773. var isLayer = $ax.public.fn.IsLayer(childObj.type);
  2774. animations.push({
  2775. id: id,
  2776. type: queueTypes.rotate,
  2777. func: function() {
  2778. $ax.event.raiseSyntheticEvent(id, "onRotate");
  2779. if(isLayer) _fireAnimationFromQueue(id, queueTypes.rotate);
  2780. else $ax('#' + id).circularMoveAndRotate(degreeDelta, options, centerPoint.x, centerPoint.y, rotate, moveDelta);
  2781. }
  2782. });
  2783. if(!isLayer) animations.push({ id: id, type: queueTypes.move, func: function() {} });
  2784. })(childId);
  2785. }
  2786. _addAnimations(animations);
  2787. } else {
  2788. animations = [];
  2789. animations.push({
  2790. id: elementId,
  2791. type: queueTypes.rotate,
  2792. func: function () {
  2793. var jobj = $jobj(elementId);
  2794. var unrotatedDim = { width: $ax.getNumFromPx(jobj.css('width')), height: $ax.getNumFromPx(jobj.css('height')) };
  2795. eval(unrotatedDim);
  2796. var delta = { x: 0, y: 0 };
  2797. if(moveInfo) {
  2798. delta = _getMoveLoc(elementId, moveInfo, eventInfoCopy, options.moveStop, idToResizeMoveState[elementId], moveOptions);
  2799. if(delta.moveTo) {
  2800. delta.x -= $ax.getNumFromPx($jobj(elementId).css('left'));
  2801. delta.y -= $ax.getNumFromPx($jobj(elementId).css('top'));
  2802. }
  2803. }
  2804. $ax.event.raiseSyntheticEvent(elementId, 'onRotate');
  2805. if(offset.x == 0 && offset.y == 0) _rotateSingle(elementId, rotateDegree, rotateInfo.rotateType == 'location', delta, options, options.stop, true);
  2806. else _rotateSingleOffset(elementId, rotateDegree, rotateInfo.rotateType == 'location', delta, { x: offset.x, y: offset.y }, options, options.stop);
  2807. if(moveInfo) $ax.event.raiseSyntheticEvent(elementId, 'onMove');
  2808. }
  2809. });
  2810. animations.push({ id: elementId, type: queueTypes.move, func: function () { } });
  2811. _addAnimations(animations);
  2812. }
  2813. }
  2814. var _updateOffset = function(offset, anchor, boundingRect) {
  2815. if (anchor.indexOf('left') != -1) offset.x -= boundingRect.width / 2;
  2816. if (anchor.indexOf('right') != -1) offset.x += boundingRect.width / 2;
  2817. if (anchor.indexOf('top') != -1) offset.y -= boundingRect.height / 2;
  2818. if (anchor.indexOf('bottom') != -1) offset.y += boundingRect.height / 2;
  2819. }
  2820. var _rotateSingle = function(elementId, rotateDegree, rotateTo, delta, options, stop, handleMove) {
  2821. var degreeDelta = _applyRotateStop(rotateDegree, $ax.move.getRotationDegree(elementId), rotateTo, stop);
  2822. $ax('#' + elementId).rotate(degreeDelta, options.easing, options.duration, false, true);
  2823. if(handleMove) {
  2824. if (delta.x || delta.y) _moveSingleWidget(elementId, delta, options);
  2825. else $ax.action.fireAnimationFromQueue(elementId, $ax.action.queueTypes.move);
  2826. }
  2827. };
  2828. var _rotateSingleOffset = function (elementId, rotateDegree, rotateTo, delta, offset, options, stop, resizeOffset) {
  2829. var obj = $obj(elementId);
  2830. var currRotation = $ax.move.getRotationDegree(elementId);
  2831. // Need to fix offset. Want to to stay same place on widget after rotation, so need to take the offset and rotate it to where it should be.
  2832. if(currRotation) {
  2833. offset = $axure.fn.getPointAfterRotate(currRotation, offset, { x: 0, y: 0 });
  2834. }
  2835. var degreeDelta = _applyRotateStop(rotateDegree, currRotation, rotateTo, stop);
  2836. var widgetCenter = $axure.fn.getWidgetBoundingRect(elementId).centerPoint;
  2837. var rotate = $.inArray(obj.type, widgetRotationFilter) != -1;
  2838. $ax('#' + elementId).circularMoveAndRotate(degreeDelta, options, widgetCenter.x + offset.x, widgetCenter.y + offset.y, rotate, delta, resizeOffset);
  2839. }
  2840. var _applyRotateStop = function(rotateDegree, currRotation, to, stop) {
  2841. var degreeDelta;
  2842. var ratio;
  2843. if(to) {
  2844. degreeDelta = rotateDegree - currRotation;
  2845. ratio = stop.instant ? 1 : (stop.end - stop.start) / (stop.len - stop.start);
  2846. } else {
  2847. degreeDelta = rotateDegree;
  2848. ratio = stop.instant ? 1 : (stop.end - stop.start) / stop.len;
  2849. }
  2850. return degreeDelta * ratio;
  2851. }
  2852. var _initRotateLayer = function(elementId, rotateInfo, rotateDegree, options, stop) {
  2853. var layerDegree = $jobj(elementId).data('layerDegree');
  2854. if (layerDegree === undefined) layerDegree = 0;
  2855. else layerDegree = parseFloat(layerDegree);
  2856. var to = rotateInfo.rotateType == 'location';
  2857. var newDegree = to ? rotateDegree : layerDegree + rotateDegree;
  2858. var degreeDelta = newDegree - layerDegree;
  2859. var ratio = stop.instant ? 1 : (stop.end - stop.start) / (stop.len - stop.start);
  2860. degreeDelta *= ratio;
  2861. $jobj(elementId).data('layerDegree', newDegree);
  2862. $ax.event.raiseSyntheticEvent(elementId, "onRotate");
  2863. return degreeDelta;
  2864. }
  2865. _actionHandlers.setWidgetSize = function(eventInfo, actions, index) {
  2866. var action = actions[index];
  2867. for(var i = 0; i < action.objectsToResize.length; i++) {
  2868. var resizeInfo = action.objectsToResize[i].sizeInfo;
  2869. var objPath = action.objectsToResize[i].objectPath;
  2870. if(objPath == 'thisItem') {
  2871. var thisId = eventInfo.srcElement;
  2872. var repeaterId = $ax.getParentRepeaterFromElementId(thisId);
  2873. var itemId = $ax.repeater.getItemIdFromElementId(thisId);
  2874. var currSize = $ax.repeater.getItemSize(repeaterId, itemId);
  2875. var newSize = _getSizeFromInfo(resizeInfo, eventInfo, currSize.width, currSize.height);
  2876. $ax.repeater.setItemSize(repeaterId, itemId, newSize.width, newSize.height);
  2877. continue;
  2878. }
  2879. var elementIds = $ax.getElementIdsFromPath(objPath, eventInfo);
  2880. for(var j = 0; j < elementIds.length; j++) {
  2881. var elementId = elementIds[j];
  2882. _queueResizeMove(elementId, queueTypes.resize, eventInfo, resizeInfo);
  2883. //_addResize(elementId, resizeInfo);
  2884. }
  2885. }
  2886. _dispatchAction(eventInfo, actions, index + 1);
  2887. };
  2888. // Move info undefined unless this move/resize actions are being merged
  2889. var _addResize = function(elementId, eventInfo, resizeInfo, options, moveInfo, rotateInfo) {
  2890. var axObject = $obj(elementId);
  2891. resizeInfo = $ax.deepCopy(resizeInfo);
  2892. resizeInfo.easing = options.easing;
  2893. resizeInfo.duration = options.duration;
  2894. var eventInfoCopy = $ax.eventCopy(eventInfo);
  2895. eventInfoCopy.targetElement = elementId;
  2896. var moves = moveInfo || resizeInfo.anchor != "top left" || ($ax.public.fn.IsDynamicPanel(axObject.type) &&
  2897. ((axObject.fixedHorizontal && axObject.fixedHorizontal == 'center') || (axObject.fixedVertical && axObject.fixedVertical == 'middle'))) ||
  2898. (rotateInfo && (rotateInfo.offsetX || rotateInfo.offsetY));
  2899. if(moveInfo) {
  2900. var moveOptions = { dragInfo: eventInfoCopy.dragInfo, duration: options.duration, easing: options.easing, boundaryExpr: moveInfo.options.boundaryExpr, boundaryStos: moveInfo.options.boundaryStos };
  2901. }
  2902. var idToResizeMoveState = _getIdToResizeMoveState(eventInfoCopy);
  2903. var animations = [];
  2904. if($ax.public.fn.IsLayer(axObject.type)) {
  2905. moves = true; // Assume widgets will move will layer, even though not all widgets may move
  2906. var childrenIds = $ax.public.fn.getLayerChildrenDeep(elementId, true, true);
  2907. if(childrenIds.length === 0) return;
  2908. // Need to wait to calculate new size, until time to animate, but animates are in separate queues
  2909. // best option seems to be to calculate in a "animate" for the layer itself and all children will use that.
  2910. // May just have to be redundant if this doesn't work well.
  2911. var boundingRect, widthChangedPercent, heightChangedPercent, unchanged, deltaLoc, degreeDelta, resizeOffset;
  2912. animations.push({
  2913. id: elementId,
  2914. type: queueTypes.resize,
  2915. func: function () {
  2916. $ax.visibility.pushContainer(elementId, false);
  2917. boundingRect = $ax.public.fn.getWidgetBoundingRect(elementId);
  2918. var size = _getSizeFromInfo(resizeInfo, eventInfoCopy, boundingRect.width, boundingRect.height, elementId);
  2919. deltaLoc = { x: 0, y: 0 };
  2920. var stop = options.stop;
  2921. var ratio = stop.instant ? 1 : (stop.end - stop.start) / (stop.len - stop.start);
  2922. widthChangedPercent = Math.round(size.width - boundingRect.width) / boundingRect.width * ratio;
  2923. heightChangedPercent = Math.round(size.height - boundingRect.height) / boundingRect.height * ratio;
  2924. resizeOffset = _applyAnchorToResizeOffset(widthChangedPercent * boundingRect.width, heightChangedPercent * boundingRect.height, resizeInfo.anchor);
  2925. if(stop.instant || stop.end == stop.len) idToResizeMoveState[elementId].resizeResult = undefined;
  2926. unchanged = widthChangedPercent === 0 && heightChangedPercent === 0;
  2927. $ax.event.raiseSyntheticEvent(elementId, 'onResize');
  2928. _fireAnimationFromQueue(elementId, queueTypes.resize);
  2929. }
  2930. });
  2931. if(moveInfo) animations.push({
  2932. id: elementId,
  2933. type: queueTypes.move,
  2934. func: function() {
  2935. deltaLoc = _getMoveLoc(elementId, moveInfo, eventInfoCopy, options.moveStop, idToResizeMoveState[elementId], moveOptions, boundingRect);
  2936. $ax.visibility.pushContainer(elementId, false);
  2937. _fireAnimationFromQueue(elementId, queueTypes.move);
  2938. $ax.event.raiseSyntheticEvent(elementId, 'onMove');
  2939. }
  2940. });
  2941. if (rotateInfo) animations.push({
  2942. id: elementId,
  2943. type: queueTypes.rotate,
  2944. func: function () {
  2945. resizeOffset = _applyAnchorToResizeOffset(widthChangedPercent * boundingRect.width, heightChangedPercent * boundingRect.height, resizeInfo.anchor);
  2946. var rotateDegree = parseFloat($ax.expr.evaluateExpr(rotateInfo.degree, eventInfoCopy));
  2947. degreeDelta = _initRotateLayer(elementId, rotateInfo, rotateDegree, options, options.rotateStop);
  2948. _fireAnimationFromQueue(elementId, queueTypes.rotate);
  2949. $ax.event.raiseSyntheticEvent(elementId, 'onRotate');
  2950. }
  2951. });
  2952. var completeCount = childrenIds.length*2; // Because there is a resize and move complete, it needs to be doubled
  2953. for(var idIndex = 0; idIndex < childrenIds.length; idIndex++) {
  2954. // Need to use scoping trick here to make sure childId doesn't change on next loop
  2955. (function(childId) {
  2956. //use ax obj to get width and height, jquery css give us the value without border
  2957. var isLayer = $ax.public.fn.IsLayer($obj(childId).type);
  2958. var rotate = $.inArray($obj(childId).type, widgetRotationFilter) != -1;
  2959. animations.push({
  2960. id: childId,
  2961. type: queueTypes.resize,
  2962. func: function() {
  2963. //$ax.event.raiseSyntheticEvent(childId, 'onResize');
  2964. if(isLayer) {
  2965. completeCount -= 2;
  2966. _fireAnimationFromQueue(childId, queueTypes.resize);
  2967. $ax.event.raiseSyntheticEvent(childId, 'onResize');
  2968. } else {
  2969. var currDeltaLoc = { x: deltaLoc.x, y: deltaLoc.y };
  2970. var resizeDeltaMove = { x: 0, y: 0 };
  2971. var css = _getCssForResizingLayerChild(childId, resizeInfo.anchor, boundingRect, widthChangedPercent, heightChangedPercent, resizeDeltaMove);
  2972. var onComplete = function() {
  2973. if(--completeCount == 0) $ax.visibility.popContainer(elementId, false);
  2974. };
  2975. $ax('#' + childId).resize(css, resizeInfo, true, moves, onComplete);
  2976. if(rotateInfo) {
  2977. var offset = { x: Number($ax.expr.evaluateExpr(rotateInfo.offsetX, eventInfoCopy)), y: Number($ax.expr.evaluateExpr(rotateInfo.offsetY, eventInfo)) };
  2978. _updateOffset(offset, resizeInfo.anchor, boundingRect);
  2979. var centerPoint = { x: boundingRect.centerPoint.x + offset.x, y: boundingRect.centerPoint.y + offset.y };
  2980. $ax('#' + childId).circularMoveAndRotate(degreeDelta, options, centerPoint.x, centerPoint.y, rotate, currDeltaLoc, resizeOffset, resizeDeltaMove, onComplete);
  2981. } else {
  2982. currDeltaLoc.x += resizeDeltaMove.x;
  2983. currDeltaLoc.y += resizeDeltaMove.y;
  2984. _moveSingleWidget(childId, currDeltaLoc, options, onComplete);
  2985. }
  2986. }
  2987. }
  2988. });
  2989. if(!isLayer) animations.push({ id: childId, type: queueTypes.move, func: function () {} });
  2990. if(!isLayer && rotateInfo) animations.push({ id: childId, type: queueTypes.rotate, func: function () {} });
  2991. })(childrenIds[idIndex]);
  2992. }
  2993. } else {
  2994. // Not func, obj with func
  2995. animations.push({
  2996. id: elementId,
  2997. type: queueTypes.resize,
  2998. func: function() {
  2999. //textarea can be resized manully by the user, but doesn't update div size yet, so doing this for now.
  3000. //alternatively axquery get for size can account for this
  3001. var sizeId = $ax.public.fn.IsTextArea(axObject.type) ? $jobj(elementId).children('textarea').attr('id') : elementId;
  3002. var oldSize = $ax('#' + sizeId).size();
  3003. var oldWidth = oldSize.width;
  3004. var oldHeight = oldSize.height;
  3005. var stop = options.stop;
  3006. var ratio = stop.instant ? 1 : (stop.end - stop.start) / (stop.len - stop.start);
  3007. var size = _getSizeFromInfo(resizeInfo, eventInfoCopy, oldWidth, oldHeight, elementId);
  3008. var newWidth = size.width;
  3009. var newHeight = size.height;
  3010. var deltaWidth = Math.round(newWidth - oldWidth) * ratio;
  3011. var deltaHeight = Math.round(newHeight - oldHeight) * ratio;
  3012. newWidth = oldWidth + deltaWidth;
  3013. newHeight = oldHeight + deltaHeight;
  3014. var delta = { x: 0, y: 0 };
  3015. if(moveInfo) {
  3016. delta = _getMoveLoc(elementId, moveInfo, eventInfoCopy, options.moveStop, idToResizeMoveState[elementId], moveOptions);
  3017. if (delta.moveTo) {
  3018. delta.x -= $ax.getNumFromPx($jobj(elementId).css('left'));
  3019. delta.y -= $ax.getNumFromPx($jobj(elementId).css('top'));
  3020. }
  3021. }
  3022. var rotateHandlesMove = false;
  3023. var offset = { x: 0, y: 0 };
  3024. if(rotateInfo) {
  3025. offset.x = Number($ax.expr.evaluateExpr(rotateInfo.offsetX, eventInfoCopy));
  3026. offset.y = Number($ax.expr.evaluateExpr(rotateInfo.offsetY, eventInfoCopy));
  3027. _updateOffset(offset, rotateInfo.anchor, $axure.fn.getWidgetBoundingRect(elementId));
  3028. rotateHandlesMove = Boolean(rotateInfo && (offset.x || offset.y || rotateInfo.anchor != 'center'));
  3029. $ax.event.raiseSyntheticEvent(elementId, 'onRotate');
  3030. }
  3031. var css = null;
  3032. var rootLayer = null;
  3033. if(deltaHeight != 0 || deltaWidth != 0) {
  3034. rootLayer = $ax.move.getRootLayer(elementId);
  3035. if(rootLayer) $ax.visibility.pushContainer(rootLayer, false);
  3036. css = _getCssForResizingWidget(elementId, eventInfoCopy, resizeInfo.anchor, newWidth, newHeight, oldWidth, oldHeight, delta, options.stop, !rotateHandlesMove);
  3037. idToResizeMoveState[elementId].resizeResult = undefined;
  3038. }
  3039. if(rotateInfo) {
  3040. var rotateDegree = parseFloat($ax.expr.evaluateExpr(rotateInfo.degree, eventInfoCopy));
  3041. if(rotateHandlesMove) {
  3042. var resizeOffset = _applyAnchorToResizeOffset(deltaWidth, deltaHeight, rotateInfo.anchor);
  3043. _rotateSingleOffset(elementId, rotateDegree, rotateInfo.rotateType == 'location', delta, offset, options, options.rotateStop, resizeOffset);
  3044. } else {
  3045. // Not handling move so pass in nop delta
  3046. _rotateSingle(elementId, rotateDegree, rotateInfo.rotateType == 'location', { x: 0, y: 0 }, options, options.rotateStop);
  3047. if (moves) _fireAnimationFromQueue(elementId, queueTypes.move);
  3048. }
  3049. } else if(!css && moves) _moveSingleWidget(elementId, delta, options);
  3050. // Have to do it down here to make sure move info is registered
  3051. if(moveInfo) $ax.event.raiseSyntheticEvent(elementId, 'onMove');
  3052. //$ax.event.raiseSyntheticEvent(elementId, 'onResize');
  3053. if (css) {
  3054. $ax('#' + elementId).resize(css, resizeInfo, true, moves, function () {
  3055. if(rootLayer) $ax.visibility.popContainer(rootLayer, false);
  3056. });
  3057. } else {
  3058. _fireAnimationFromQueue(elementId, queueTypes.resize);
  3059. $ax.event.raiseSyntheticEvent(elementId, 'onResize');
  3060. }
  3061. }
  3062. });
  3063. // Nop move (move handled by resize)
  3064. if(rotateInfo) animations.push({ id: elementId, type: queueTypes.rotate, func: function () { } });
  3065. if(moves) animations.push({ id: elementId, type: queueTypes.move, func: function () { } });
  3066. }
  3067. _addAnimations(animations);
  3068. };
  3069. var _applyAnchorToResizeOffset = function (deltaWidth, deltaHeight, anchor) {
  3070. var offset = {};
  3071. if (anchor.indexOf('left') != -1) offset.x = -deltaWidth / 2;
  3072. else if (anchor.indexOf('right') != -1) offset.x = deltaWidth / 2;
  3073. if (anchor.indexOf('top') != -1) offset.y = -deltaHeight / 2;
  3074. else if (anchor.indexOf('bottom') != -1) offset.y = deltaHeight / 2;
  3075. return offset;
  3076. }
  3077. //var _getOldAndNewSize = function (resizeInfo, eventInfo, targetElement) {
  3078. // var axObject = $obj(targetElement);
  3079. // var oldWidth, oldHeight;
  3080. // //textarea can be resized manully by the user, use the textarea child to get the current size
  3081. // //because this new size may not be reflected on its parents yet
  3082. // if ($ax.public.fn.IsTextArea(axObject.type)) {
  3083. // var jObject = $jobj(elementId);
  3084. // var textObj = $ax('#' + jObject.children('textarea').attr('id'));
  3085. // //maybe we shouldn't use ax obj to get width and height here anymore...
  3086. // oldWidth = textObj.width();
  3087. // oldHeight = textObj.height();
  3088. // } else {
  3089. // oldWidth = $ax('#' + elementId).width();
  3090. // oldHeight = $ax('#' + elementId).height();
  3091. // }
  3092. // var size = _getSizeFromInfo(resizeInfo, eventInfo, oldHeight, oldWidth, elementId);
  3093. // return { oldWidth: oldWidth, oldHeight: oldHeight, newWidth: size.width, newHeight: size.height, change: oldWidth != size.width || oldHeight != size.height };
  3094. //}
  3095. var _getSizeFromInfo = function(resizeInfo, eventInfo, oldWidth, oldHeight, targetElement) {
  3096. var oldTarget = eventInfo.targetElement;
  3097. eventInfo.targetElement = targetElement;
  3098. var state = _getIdToResizeMoveState(eventInfo)[targetElement];
  3099. if(state && state.resizeResult) return state.resizeResult;
  3100. var width = $ax.expr.evaluateExpr(resizeInfo.width, eventInfo);
  3101. var height = $ax.expr.evaluateExpr(resizeInfo.height, eventInfo);
  3102. eventInfo.targetElement = oldTarget;
  3103. // If either one is not a number, use the old value
  3104. width = width != "" ? Number(width) : oldWidth;
  3105. height = height != "" ? Number(height) : oldHeight;
  3106. width = isNaN(width) ? oldWidth : width;
  3107. height = isNaN(height) ? oldHeight : height;
  3108. // can't be negative
  3109. var result = { width: Math.max(width, 0), height: Math.max(height, 0) };
  3110. if(state) state.resizeResult = result;
  3111. return result;
  3112. }
  3113. //var _queueResize = function (elementId, css, resizeInfo) {
  3114. // var resizeFunc = function() {
  3115. // $ax('#' + elementId).resize(css, resizeInfo, true);
  3116. // //$ax.public.fn.resize(elementId, css, resizeInfo, true);
  3117. // };
  3118. // var obj = $obj(elementId);
  3119. // var moves = resizeInfo.anchor != "top left" || ($ax.public.fn.IsDynamicPanel(obj.type) && ((obj.fixedHorizontal && obj.fixedHorizontal == 'center') || (obj.fixedVertical && obj.fixedVertical == 'middle')))
  3120. // if(!moves) {
  3121. // _addAnimation(elementId, queueTypes.resize, resizeFunc);
  3122. // } else {
  3123. // var animations = [];
  3124. // animations[0] = { id: elementId, type: queueTypes.resize, func: resizeFunc };
  3125. // animations[1] = { id: elementId, type: queueTypes.move, func: function() {}}; // Nop func - resize handles move and firing from queue
  3126. // _addAnimations(animations);
  3127. // }
  3128. //};
  3129. //should clean this function and
  3130. var _getCssForResizingWidget = function (elementId, eventInfo, anchor, newWidth, newHeight, oldWidth, oldHeight, delta, stop, handleMove) {
  3131. var ratio = stop.instant ? 1 : (stop.end - stop.start) / (stop.len - stop.start);
  3132. var deltaWidth = (newWidth - oldWidth) * ratio;
  3133. var deltaHeight = (newHeight - oldHeight) * ratio;
  3134. if(stop.instant || stop.end == stop.len) {
  3135. var idToResizeMoveState = _getIdToResizeMoveState(eventInfo);
  3136. if(idToResizeMoveState[elementId]) idToResizeMoveState[elementId].resizeResult = undefined;
  3137. }
  3138. var css = {};
  3139. css.height = oldHeight + deltaHeight;
  3140. var obj = $obj(elementId);
  3141. //if it's 100% width, don't change its width
  3142. if($ax.dynamicPanelManager.isPercentWidthPanel(obj)) var is100Dp = true;
  3143. else css.width = oldWidth + deltaWidth;
  3144. var jobj = $jobj(elementId);
  3145. //if this is pinned dp, we will mantain the pin, no matter how you resize it; so no need changes left or top
  3146. //NOTE: currently only pinned DP has position == fixed
  3147. if(jobj.css('position') == 'fixed') {
  3148. if(obj.fixedHorizontal && obj.fixedHorizontal == 'center') css['margin-left'] = '+=' + delta.x;
  3149. if(obj.fixedVertical && obj.fixedVertical == 'middle') css['margin-top'] = '+=' + delta.y;
  3150. return css;
  3151. }
  3152. // If it is pinned, but temporarily not fixed because it is wrappen in a container, then just make sure to anchor it correctly
  3153. if(obj.fixedVertical) {
  3154. if(obj.fixedVertical == 'middle') anchor = obj.fixedHorizontal;
  3155. else anchor = obj.fixedVertical + (obj.fixedHorizontal == 'center' ? '' : ' ' + obj.fixedHorizontal);
  3156. }
  3157. //use position relative to parents
  3158. //var position = obj.generateCompound ? $ax.public.fn.getWidgetBoundingRect(elementId) : $ax.public.fn.getPositionRelativeToParent(elementId);
  3159. var locationShift;
  3160. switch(anchor) {
  3161. case "top left":
  3162. locationShift = { x: 0, y: 0 }; break;
  3163. case "top":
  3164. locationShift = { x: -deltaWidth / 2.0, y: 0.0 }; break;
  3165. case "top right":
  3166. locationShift = { x: -deltaWidth, y: 0.0 }; break;
  3167. case "left":
  3168. locationShift = { x: 0.0, y: -deltaHeight / 2.0 }; break;
  3169. case "center":
  3170. locationShift = { x: -deltaWidth / 2.0, y: -deltaHeight / 2.0 }; break;
  3171. case "right":
  3172. locationShift = { x: -deltaWidth, y: -deltaHeight / 2.0 }; break;
  3173. case "bottom left":
  3174. locationShift = { x: 0.0, y: -deltaHeight }; break;
  3175. case "bottom":
  3176. locationShift = { x: -deltaWidth/2.0, y: -deltaHeight }; break;
  3177. case "bottom right":
  3178. locationShift = { x: -deltaWidth, y: -deltaHeight }; break;
  3179. }
  3180. if(handleMove) {
  3181. if(jobj.css('position') === 'absolute') {
  3182. css.left = $ax.getNumFromPx(jobj.css('left')) + locationShift.x + delta.x;
  3183. css.top = $ax.getNumFromPx(jobj.css('top')) + locationShift.y + delta.y;
  3184. } else {
  3185. var axQuery = $ax('#' + elementId);
  3186. css.left = axQuery.left(true) + locationShift.x + delta.x;
  3187. css.top = axQuery.top(true) + locationShift.y + delta.y;
  3188. }
  3189. } else {
  3190. delta.x += locationShift.x;
  3191. delta.y += locationShift.y;
  3192. }
  3193. return css;
  3194. };
  3195. var _getCssForResizingLayerChild = function (elementId, anchor, layerBoundingRect, widthChangedPercent, heightChangedPercent, deltaLoc) {
  3196. var boundingRect = $ax.public.fn.getWidgetBoundingRect(elementId);
  3197. var childCenterPoint = boundingRect.centerPoint;
  3198. var currentSize = $ax('#' + elementId).size();
  3199. var newWidth = currentSize.width + currentSize.width * widthChangedPercent;
  3200. var newHeight = currentSize.height + currentSize.height * heightChangedPercent;
  3201. var css = {};
  3202. css.height = newHeight;
  3203. var obj = $obj(elementId);
  3204. //if it's 100% width, don't change its width and left
  3205. var changeLeft = true;
  3206. if($ax.dynamicPanelManager.isPercentWidthPanel(obj)) changeLeft = false;
  3207. else css.width = newWidth;
  3208. var jobj = $jobj(elementId);
  3209. //if this is pinned dp, we will mantain the pin, no matter how you resize it; so no need changes left or top
  3210. //NOTE: currently only pinned DP has position == fixed
  3211. if(jobj.css('position') == 'fixed') return css;
  3212. //use bounding rect position relative to parents to calculate delta
  3213. var axObj = $ax('#' + elementId);
  3214. // This will be absolute world coordinates, but we want body coordinates.
  3215. var currentLeft = axObj.locRelativeIgnoreLayer(false);
  3216. var currentTop = axObj.locRelativeIgnoreLayer(true);
  3217. var resizable = $ax.public.fn.IsResizable(obj.type);
  3218. if(anchor.indexOf("top") > -1) {
  3219. var topDelta = (currentTop - layerBoundingRect.top) * heightChangedPercent;
  3220. if(!resizable && Math.round(topDelta)) topDelta += currentSize.height * heightChangedPercent;
  3221. } else if(anchor.indexOf("bottom") > -1) {
  3222. if(resizable) topDelta = (currentTop - layerBoundingRect.bottom) * heightChangedPercent;
  3223. else {
  3224. var bottomDelta = Math.round(currentTop + currentSize.height - layerBoundingRect.bottom) * heightChangedPercent;
  3225. if(bottomDelta) topDelta = bottomDelta - currentSize.height * heightChangedPercent;
  3226. else topDelta = 0;
  3227. }
  3228. } else { //center vertical
  3229. if(resizable) topDelta = (childCenterPoint.y - layerBoundingRect.centerPoint.y)*heightChangedPercent - currentSize.height*heightChangedPercent/2;
  3230. else {
  3231. var centerTopChange = Math.round(childCenterPoint.y - layerBoundingRect.centerPoint.y)*heightChangedPercent;
  3232. if(centerTopChange > 0) topDelta = centerTopChange + Math.abs(currentSize.height * heightChangedPercent / 2);
  3233. else if(centerTopChange < 0) topDelta = centerTopChange - Math.abs(currentSize.height * heightChangedPercent / 2);
  3234. else topDelta = 0;
  3235. }
  3236. }
  3237. if(changeLeft) {
  3238. if(anchor.indexOf("left") > -1) {
  3239. var leftDelta = (currentLeft - layerBoundingRect.left) * widthChangedPercent;
  3240. if(!resizable && Math.round(leftDelta)) leftDelta += currentSize.width * widthChangedPercent;
  3241. } else if(anchor.indexOf("right") > -1) {
  3242. if(resizable) leftDelta = (currentLeft - layerBoundingRect.right) * widthChangedPercent;
  3243. else {
  3244. var rightDelta = Math.round(currentLeft + currentSize.width - layerBoundingRect.right) * widthChangedPercent;
  3245. if(rightDelta) leftDelta = rightDelta - currentSize.width * widthChangedPercent;
  3246. else leftDelta = 0;
  3247. }
  3248. } else { //center horizontal
  3249. if(resizable) leftDelta = (childCenterPoint.x - layerBoundingRect.centerPoint.x)*widthChangedPercent - currentSize.width*widthChangedPercent/2;
  3250. else {
  3251. var centerLeftChange = Math.round(childCenterPoint.x - layerBoundingRect.centerPoint.x) * widthChangedPercent;
  3252. if(centerLeftChange > 0) leftDelta = centerLeftChange + Math.abs(currentSize.width * widthChangedPercent / 2);
  3253. else if(centerLeftChange < 0) leftDelta = centerLeftChange - Math.abs(currentSize.width * widthChangedPercent / 2);
  3254. else leftDelta = 0;
  3255. }
  3256. }
  3257. }
  3258. if(topDelta) deltaLoc.y += topDelta;
  3259. if(leftDelta && changeLeft) deltaLoc.x += leftDelta;
  3260. return css;
  3261. };
  3262. _actionHandlers.setPanelOrder = function(eventInfo, actions, index) {
  3263. var action = actions[index];
  3264. for(var i = 0; i < action.panelPaths.length; i++) {
  3265. var func = action.panelPaths[i].setOrderInfo.bringToFront ? 'bringToFront' : 'sendToBack';
  3266. var elementIds = $ax.getElementIdsFromPath(action.panelPaths[i].panelPath, eventInfo);
  3267. for(var j = 0; j < elementIds.length; j++) $ax('#' + elementIds[j])[func]();
  3268. }
  3269. _dispatchAction(eventInfo, actions, index + 1);
  3270. };
  3271. _actionHandlers.modifyDataSetEditItems = function(eventInfo, actions, index) {
  3272. var action = actions[index];
  3273. var add = action.repeatersToAddTo;
  3274. var repeaters = add || action.repeatersToRemoveFrom;
  3275. var itemId;
  3276. for(var i = 0; i < repeaters.length; i++) {
  3277. var data = repeaters[i];
  3278. // Grab the first one because repeaters must have only element id, as they cannot be inside repeaters
  3279. // or none if unplaced
  3280. var id = $ax.getElementIdsFromPath(data.path, eventInfo)[0];
  3281. if(!id) continue;
  3282. if(data.addType == 'this') {
  3283. var scriptId = $ax.repeater.getScriptIdFromElementId(eventInfo.srcElement);
  3284. itemId = $ax.repeater.getItemIdFromElementId(eventInfo.srcElement);
  3285. var repeaterId = $ax.getParentRepeaterFromScriptId(scriptId);
  3286. if(add) $ax.repeater.addEditItems(repeaterId, [itemId]);
  3287. else $ax.repeater.removeEditItems(repeaterId, [itemId]);
  3288. } else if(data.addType == 'all') {
  3289. var allItems = $ax.repeater.getAllItemIds(id);
  3290. if(add) $ax.repeater.addEditItems(id, allItems);
  3291. else $ax.repeater.removeEditItems(id, allItems);
  3292. } else {
  3293. var oldTarget = eventInfo.targetElement;
  3294. var itemIds = $ax.repeater.getAllItemIds(id);
  3295. var itemIdsToAdd = [];
  3296. for(var j = 0; j < itemIds.length; j++) {
  3297. itemId = itemIds[j];
  3298. eventInfo.targetElement = $ax.repeater.createElementId(id, itemId);
  3299. if($ax.expr.evaluateExpr(data.query, eventInfo) == "true") {
  3300. itemIdsToAdd[itemIdsToAdd.length] = String(itemId);
  3301. }
  3302. eventInfo.targetElement = oldTarget;
  3303. }
  3304. if(add) $ax.repeater.addEditItems(id, itemIdsToAdd);
  3305. else $ax.repeater.removeEditItems(id, itemIdsToAdd);
  3306. }
  3307. }
  3308. _dispatchAction(eventInfo, actions, index + 1);
  3309. };
  3310. _action.repeaterInfoNames = { addItemsToDataSet: 'dataSetsToAddTo', deleteItemsFromDataSet: 'dataSetItemsToRemove', updateItemsInDataSet: 'dataSetsToUpdate',
  3311. addFilterToRepeater: 'repeatersToAddFilter', removeFilterFromRepeater: 'repeatersToRemoveFilter',
  3312. addSortToRepeater: 'repeaterToAddSort', removeSortFromRepeater: 'repeaterToRemoveSort',
  3313. setRepeaterToPage: 'repeatersToSetPage', setItemsPerRepeaterPage: 'repeatersToSetItemCount'
  3314. };
  3315. _actionHandlers.addItemsToDataSet = function(eventInfo, actions, index) {
  3316. var action = actions[index];
  3317. for(var i = 0; i < action.dataSetsToAddTo.length; i++) {
  3318. var datasetInfo = action.dataSetsToAddTo[i];
  3319. // Grab the first one because repeaters must have only element id, as they cannot be inside repeaters
  3320. // or none if unplaced
  3321. var id = $ax.getElementIdsFromPath(datasetInfo.path, eventInfo)[0];
  3322. if(!id || _ignoreAction(id)) continue;
  3323. var dataset = datasetInfo.data;
  3324. for(var j = 0; j < dataset.length; j++) $ax.repeater.addItem(id, $ax.deepCopy(dataset[j]), eventInfo);
  3325. if(dataset.length) _addRefresh(id);
  3326. }
  3327. _dispatchAction(eventInfo, actions, index + 1);
  3328. };
  3329. _actionHandlers.deleteItemsFromDataSet = function(eventInfo, actions, index) {
  3330. var action = actions[index];
  3331. for(var i = 0; i < action.dataSetItemsToRemove.length; i++) {
  3332. // Grab the first one because repeaters must have only element id, as they cannot be inside repeaters
  3333. // or none if unplaced
  3334. var deleteInfo = action.dataSetItemsToRemove[i];
  3335. var id = $ax.getElementIdsFromPath(deleteInfo.path, eventInfo)[0];
  3336. if(!id || _ignoreAction(id)) continue;
  3337. $ax.repeater.deleteItems(id, eventInfo, deleteInfo.type, deleteInfo.rule);
  3338. _addRefresh(id);
  3339. }
  3340. _dispatchAction(eventInfo, actions, index + 1);
  3341. };
  3342. _actionHandlers.updateItemsInDataSet = function(eventInfo, actions, index) {
  3343. var action = actions[index];
  3344. for(var i = 0; i < action.dataSetsToUpdate.length; i++) {
  3345. var dataSet = action.dataSetsToUpdate[i];
  3346. // Grab the first one because repeaters must have only element id, as they cannot be inside repeaters
  3347. // or none if unplaced
  3348. var id = $ax.getElementIdsFromPath(dataSet.path, eventInfo)[0];
  3349. if(!id || _ignoreAction(id)) continue;
  3350. $ax.repeater.updateEditItems(id, dataSet.props, eventInfo, dataSet.type, dataSet.rule);
  3351. _addRefresh(id);
  3352. }
  3353. _dispatchAction(eventInfo, actions, index + 1);
  3354. };
  3355. _actionHandlers.setRepeaterToDataSet = function(eventInfo, actions, index) {
  3356. var action = actions[index];
  3357. for(var i = 0; i < action.repeatersToSet.length; i++) {
  3358. var setRepeaterInfo = action.repeatersToSet[i];
  3359. // Grab the first one because repeaters must have only element id, as they cannot be inside repeaters
  3360. // or none if unplaced
  3361. var id = $ax.getElementIdsFromPath(setRepeaterInfo.path, eventInfo)[0];
  3362. if(!id) continue;
  3363. $ax.repeater.setDataSet(id, setRepeaterInfo.localDataSetId);
  3364. }
  3365. _dispatchAction(eventInfo, actions, index + 1);
  3366. };
  3367. _actionHandlers.addFilterToRepeater = function(eventInfo, actions, index) {
  3368. var action = actions[index];
  3369. for(var i = 0; i < action.repeatersToAddFilter.length; i++) {
  3370. var addFilterInfo = action.repeatersToAddFilter[i];
  3371. // Grab the first one because repeaters must have only element id, as they cannot be inside repeaters
  3372. // or none if unplaced
  3373. var id = $ax.getElementIdsFromPath(addFilterInfo.path, eventInfo)[0];
  3374. if(!id || _ignoreAction(id)) continue;
  3375. $ax.repeater.addFilter(id, addFilterInfo.removeOtherFilters, addFilterInfo.label, addFilterInfo.filter, eventInfo.srcElement);
  3376. _addRefresh(id);
  3377. }
  3378. _dispatchAction(eventInfo, actions, index + 1);
  3379. };
  3380. _actionHandlers.removeFilterFromRepeater = function(eventInfo, actions, index) {
  3381. var action = actions[index];
  3382. for(var i = 0; i < action.repeatersToRemoveFilter.length; i++) {
  3383. var removeFilterInfo = action.repeatersToRemoveFilter[i];
  3384. // Grab the first one because repeaters must have only element id, as they cannot be inside repeaters
  3385. // or none if unplaced
  3386. var id = $ax.getElementIdsFromPath(removeFilterInfo.path, eventInfo)[0];
  3387. if(!id || _ignoreAction(id)) continue;
  3388. if(removeFilterInfo.removeAll) $ax.repeater.removeFilter(id);
  3389. else if(removeFilterInfo.filterName != '') {
  3390. $ax.repeater.removeFilter(id, removeFilterInfo.filterName);
  3391. }
  3392. _addRefresh(id);
  3393. }
  3394. _dispatchAction(eventInfo, actions, index + 1);
  3395. };
  3396. _actionHandlers.addSortToRepeater = function(eventInfo, actions, index) {
  3397. var action = actions[index];
  3398. for(var i = 0; i < action.repeatersToAddSort.length; i++) {
  3399. var addSortInfo = action.repeatersToAddSort[i];
  3400. // Grab the first one because repeaters must have only element id, as they cannot be inside repeaters
  3401. // or none if unplaced
  3402. var id = $ax.getElementIdsFromPath(addSortInfo.path, eventInfo)[0];
  3403. if(!id || _ignoreAction(id)) continue;
  3404. $ax.repeater.addSort(id, addSortInfo.label, addSortInfo.columnName, addSortInfo.ascending, addSortInfo.toggle, addSortInfo.sortType);
  3405. _addRefresh(id);
  3406. }
  3407. _dispatchAction(eventInfo, actions, index + 1);
  3408. };
  3409. _actionHandlers.removeSortFromRepeater = function(eventInfo, actions, index) {
  3410. var action = actions[index];
  3411. for(var i = 0; i < action.repeatersToRemoveSort.length; i++) {
  3412. var removeSortInfo = action.repeatersToRemoveSort[i];
  3413. // Grab the first one because repeaters must have only element id, as they cannot be inside repeaters
  3414. // or none if unplaced
  3415. var id = $ax.getElementIdsFromPath(removeSortInfo.path, eventInfo)[0];
  3416. if(!id || _ignoreAction(id)) continue;
  3417. if(removeSortInfo.removeAll) $ax.repeater.removeSort(id);
  3418. else if(removeSortInfo.sortName != '') $ax.repeater.removeSort(id, removeSortInfo.sortName);
  3419. _addRefresh(id);
  3420. }
  3421. _dispatchAction(eventInfo, actions, index + 1);
  3422. };
  3423. _actionHandlers.setRepeaterToPage = function(eventInfo, actions, index) {
  3424. var action = actions[index];
  3425. for(var i = 0; i < action.repeatersToSetPage.length; i++) {
  3426. var setPageInfo = action.repeatersToSetPage[i];
  3427. // Grab the first one because repeaters must have only element id, as they cannot be inside repeaters
  3428. // or none if unplaced
  3429. var id = $ax.getElementIdsFromPath(setPageInfo.path, eventInfo)[0];
  3430. if(!id || _ignoreAction(id)) continue;
  3431. var oldTarget = eventInfo.targetElement;
  3432. eventInfo.targetElement = id;
  3433. $ax.repeater.setRepeaterToPage(id, setPageInfo.pageType, setPageInfo.pageValue, eventInfo);
  3434. eventInfo.targetElement = oldTarget;
  3435. _addRefresh(id);
  3436. }
  3437. _dispatchAction(eventInfo, actions, index + 1);
  3438. };
  3439. _actionHandlers.setItemsPerRepeaterPage = function(eventInfo, actions, index) {
  3440. var action = actions[index];
  3441. for(var i = 0; i < action.repeatersToSetItemCount.length; i++) {
  3442. var setItemCountInfo = action.repeatersToSetItemCount[i];
  3443. // Grab the first one because repeaters must have only element id, as they cannot be inside repeaters
  3444. // or none if unplaced
  3445. var id = $ax.getElementIdsFromPath(setItemCountInfo.path, eventInfo)[0];
  3446. if(!id || _ignoreAction(id)) continue;
  3447. if(setItemCountInfo.noLimit) $ax.repeater.setNoItemLimit(id);
  3448. else $ax.repeater.setItemLimit(id, setItemCountInfo.itemCountValue, eventInfo);
  3449. _addRefresh(id);
  3450. }
  3451. _dispatchAction(eventInfo, actions, index + 1);
  3452. };
  3453. _actionHandlers.refreshRepeater = function(eventInfo, actions, index) {
  3454. // We use this as a psudo action now.
  3455. var action = actions[index];
  3456. for (var i = 0; i < action.repeatersToRefresh.length; i++) {
  3457. // Grab the first one because repeaters must have only element id, as they cannot be inside repeaters
  3458. // or none if unplaced
  3459. var id = $ax.getElementIdsFromPath(action.repeatersToRefresh[i], eventInfo)[0];
  3460. if(id) _tryRefreshRepeater(id, eventInfo);
  3461. }
  3462. _dispatchAction(eventInfo, actions, index + 1);
  3463. };
  3464. var _tryRefreshRepeater = function(id, eventInfo) {
  3465. var idIndex = _repeatersToRefresh.indexOf(id);
  3466. if(idIndex == -1) return;
  3467. $ax.splice(_repeatersToRefresh, idIndex, 1);
  3468. $ax.repeater.refreshRepeater(id, eventInfo);
  3469. };
  3470. _action.tryRefreshRepeaters = function(ids, eventInfo) {
  3471. for(var i = 0; i < ids.length; i++) _tryRefreshRepeater(ids[i], eventInfo);
  3472. };
  3473. _actionHandlers.scrollToWidget = function(eventInfo, actions, index) {
  3474. var action = actions[index];
  3475. var elementIds = $ax.getElementIdsFromPath(action.objectPath, eventInfo);
  3476. if(elementIds.length > 0) $ax('#' + elementIds[0]).scroll(action.options);
  3477. _dispatchAction(eventInfo, actions, index + 1);
  3478. };
  3479. _actionHandlers.enableDisableWidgets = function(eventInfo, actions, index) {
  3480. var action = actions[index];
  3481. for(var i = 0; i < action.pathToInfo.length; i++) {
  3482. var elementIds = $ax.getElementIdsFromPath(action.pathToInfo[i].objectPath, eventInfo);
  3483. var enable = action.pathToInfo[i].enableDisableInfo.enable;
  3484. for(var j = 0; j < elementIds.length; j++) $ax('#' + elementIds[j]).enabled(enable);
  3485. }
  3486. _dispatchAction(eventInfo, actions, index + 1);
  3487. };
  3488. _actionHandlers.setImage = function(eventInfo, actions, index) {
  3489. var oldTarget = eventInfo.targetElement;
  3490. var action = actions[index];
  3491. var view = $ax.adaptive.currentViewId;
  3492. eventInfo.image = true;
  3493. for(var i = 0; i < action.imagesToSet.length; i++) {
  3494. var imgInfo = action.imagesToSet[i];
  3495. imgInfo = view ? imgInfo.adaptive[view] : imgInfo.base;
  3496. var elementIds = $ax.getElementIdsFromPath(action.imagesToSet[i].objectPath, eventInfo);
  3497. for(var j = 0; j < elementIds.length; j++) {
  3498. var elementId = elementIds[j];
  3499. eventInfo.targetElement = elementId;
  3500. var evaluatedImgs = _evaluateImages(imgInfo, eventInfo);
  3501. var img = evaluatedImgs.normal;
  3502. if($ax.style.IsWidgetDisabled(elementId)) {
  3503. if(imgInfo.disabled) img = evaluatedImgs.disabled;
  3504. } else if($ax.style.IsWidgetSelected(elementId)) {
  3505. if(imgInfo.selected) img = evaluatedImgs.selected;
  3506. } else if($ax.event.mouseDownObjectId == elementId && imgInfo.mouseDown) img = evaluatedImgs.mouseDown;
  3507. else if($ax.event.mouseOverIds.indexOf(elementId) != -1 && imgInfo.mouseOver) {
  3508. img = evaluatedImgs.mouseOver;
  3509. //Update mouseOverObjectId
  3510. var currIndex = $ax.event.mouseOverIds.indexOf($ax.event.mouseOverObjectId);
  3511. var imgIndex = $ax.event.mouseOverIds.indexOf(elementId);
  3512. if(currIndex < imgIndex) $ax.event.mouseOverObjectId = elementId;
  3513. } else if(imgInfo.mouseOver && elementId == eventInfo.srcElement) {
  3514. img = evaluatedImgs.mouseOver;
  3515. }
  3516. // $('#' + $ax.repeater.applySuffixToElementId(elementId, '_img')).attr('src', img);
  3517. $jobj($ax.GetImageIdFromShape(elementId)).attr('src', img);
  3518. //Set up overrides
  3519. $ax.style.mapElementIdToImageOverrides(elementId, evaluatedImgs);
  3520. $ax.style.updateElementIdImageStyle(elementId);
  3521. if(evaluatedImgs.mouseOver || evaluatedImgs.mouseDown) $ax.event.updateIxStyleEvents(elementId);
  3522. }
  3523. }
  3524. eventInfo.targetElement = oldTarget;
  3525. eventInfo.image = false;
  3526. _dispatchAction(eventInfo, actions, index + 1);
  3527. };
  3528. var _evaluateImages = function(imgInfo, eventInfo) {
  3529. var retVal = {};
  3530. for(var state in imgInfo) {
  3531. if(!imgInfo.hasOwnProperty(state)) continue;
  3532. var img = imgInfo[state][$ax.adaptive.getSketchKey()] || $ax.expr.evaluateExpr(imgInfo[state].literal, eventInfo);
  3533. if(!img) img = $axure.utils.getTransparentGifPath();
  3534. retVal[state] = img;
  3535. }
  3536. return retVal;
  3537. };
  3538. $ax.clearRepeaterImageOverrides = function(repeaterId) {
  3539. var childIds = $ax.getChildElementIdsForRepeater(repeaterId);
  3540. for(var i = childIds; i < childIds.length; i++) $ax.style.deleteElementIdToImageOverride(childIds[i]);
  3541. };
  3542. _actionHandlers.setFocusOnWidget = function(eventInfo, actions, index) {
  3543. var action = actions[index];
  3544. if(action.objectPaths.length > 0) {
  3545. var elementIds = $ax.getElementIdsFromPath(action.objectPaths[0], eventInfo);
  3546. if(elementIds.length > 0) {
  3547. $ax('#' + elementIds[0]).focus();
  3548. //if select text and not in placeholder mode, then select all text
  3549. if(action.selectText && !$ax.placeholderManager.isActive(elementIds[0])) {
  3550. var elementChildren = document.getElementById(elementIds[0]).children;
  3551. //find the input or textarea element
  3552. for(var i = 0; i < elementChildren.length; i++) {
  3553. if (elementChildren[i].id.indexOf('_input') == -1) continue;
  3554. var elementTagName = elementChildren[i].tagName;
  3555. if(elementTagName && (elementTagName.toLowerCase() == "input" || elementTagName.toLowerCase() == "textarea")) {
  3556. elementChildren[i].select();
  3557. }
  3558. }
  3559. }
  3560. }
  3561. }
  3562. _dispatchAction(eventInfo, actions, index + 1);
  3563. };
  3564. _actionHandlers.expandCollapseTree = function(eventInfo, actions, index) {
  3565. var action = actions[index];
  3566. for(var i = 0; i < action.pathToInfo.length; i++) {
  3567. var pair = action.pathToInfo[i];
  3568. var elementIds = $ax.getElementIdsFromPath(pair.treeNodePath, eventInfo);
  3569. for(var j = 0; j < elementIds.length; j++) $ax('#' + elementIds[j]).expanded(pair.expandCollapseInfo.expand);
  3570. }
  3571. _dispatchAction(eventInfo, actions, index + 1);
  3572. };
  3573. _actionHandlers.other = function(eventInfo, actions, index) {
  3574. var action = actions[index];
  3575. $ax.navigate({
  3576. url: $axure.utils.getOtherPath() + "#other=" + encodeURI(action.otherDescription),
  3577. target: "popup",
  3578. includeVariables: false,
  3579. popupOptions: action.popup
  3580. });
  3581. _dispatchAction(eventInfo, actions, index + 1);
  3582. };
  3583. _actionHandlers.fireEvents = function(eventInfo, actions, index) {
  3584. var action = actions[index];
  3585. //look for the nearest element id
  3586. var objId = eventInfo.srcElement;
  3587. var thisWidget = eventInfo.thiswidget;
  3588. var obj = $ax.getObjectFromElementId(objId);
  3589. var rdoId = obj ? $ax.getRdoParentFromElementId(objId) : "";
  3590. var rdo = $ax.getObjectFromElementId(rdoId);
  3591. var page = rdo ? $ax.pageData.masters[rdo.masterId] : $ax.pageData.page;
  3592. // Check if rdo should be this
  3593. var oldIsMasterEvent = eventInfo.isMasterEvent;
  3594. if (obj && $ax.public.fn.IsReferenceDiagramObject(obj.type) && eventInfo.isMasterEvent) {
  3595. rdoId = objId;
  3596. rdo = obj;
  3597. page = $ax.pageData.masters[rdo.masterId];
  3598. }
  3599. for(var i = 0; i < action.firedEvents.length; i++) {
  3600. var firedEvent = action.firedEvents[i];
  3601. var isPage = firedEvent.objectPath.length == 0;
  3602. var targetObjIds = isPage ? [rdoId] : $ax.getElementIdsFromPath(firedEvent.objectPath, eventInfo);
  3603. for (var j = 0; j < targetObjIds.length; j++) {
  3604. var targetObjId = targetObjIds[j];
  3605. var targetObj = isPage ? rdo : $ax.getObjectFromElementId(targetObjId);
  3606. eventInfo.srcElement = targetObjId || '';
  3607. eventInfo.thiswidget = $ax.getWidgetInfo(eventInfo.srcElement);
  3608. eventInfo.isMasterEvent = false;
  3609. var raisedEvents = firedEvent.raisedEventIds;
  3610. if(raisedEvents) {
  3611. for(var k = 0; k < raisedEvents.length; k++) {
  3612. var event = targetObj.interactionMap && targetObj.interactionMap.raised && targetObj.interactionMap.raised[raisedEvents[k]];
  3613. if(event) $ax.event.handleEvent(targetObjId, eventInfo, event, false, true);
  3614. }
  3615. }
  3616. if(isPage) {
  3617. eventInfo.isMasterEvent = true;
  3618. eventInfo.label = $ax.pageData.page.name;
  3619. eventInfo.friendlyType = 'Page';
  3620. }
  3621. var firedTarget = isPage ? page : targetObj;
  3622. var firedEventNames = firedEvent.firedEventNames;
  3623. if(firedEventNames) {
  3624. for(k = 0; k < firedEventNames.length; k++) {
  3625. event = firedTarget.interactionMap && firedTarget.interactionMap[firedEventNames[k]];
  3626. if(event) $ax.event.handleEvent(isPage ? '' : targetObjId, eventInfo, event, false, true);
  3627. }
  3628. }
  3629. if(isPage) eventInfo.isMasterEvent = oldIsMasterEvent;
  3630. }
  3631. eventInfo.srcElement = objId;
  3632. eventInfo.thiswidget = thisWidget;
  3633. eventInfo.isMasterEvent = oldIsMasterEvent;
  3634. }
  3635. _dispatchAction(eventInfo, actions, index + 1);
  3636. };
  3637. });
  3638. //***** expr.js *****//
  3639. // ******* Expr MANAGER ******** //
  3640. $axure.internal(function($ax) {
  3641. var _expr = $ax.expr = {};
  3642. var _binOpHandlers = {
  3643. '&&': function(left, right) { return _binOpOverride(left, right, function(left) { return $ax.getBool(left) && $ax.getBool(right()); }); },
  3644. '||': function(left, right) { return _binOpOverride(left, right, function(left) { return $ax.getBool(left) || $ax.getBool(right()); }); },
  3645. '==': function(left, right) { return isEqual(left, right, true); },
  3646. '!=': function(left, right) { return !isEqual(left, right, true); },
  3647. '>': function(left, right) { return _binOpNum(left, right, function(left, right) { return left > right; }); },
  3648. '<': function(left, right) { return _binOpNum(left, right, function(left, right) { return left < right; }); },
  3649. '>=': function(left, right) { return _binOpNum(left, right, function(left, right) { return left >= right; }); },
  3650. '<=': function(left, right) { return _binOpNum(left, right, function(left, right) { return left <= right; }); }
  3651. };
  3652. var checkOps = function(left, right) {
  3653. return left == undefined || right == undefined;
  3654. };
  3655. var isEqual = function (left, right, isFunction) {
  3656. if (isFunction) {
  3657. //if left and right is function, then get the value
  3658. //otherwise left and right should be already the value we want
  3659. left = left();
  3660. right = right();
  3661. }
  3662. if(checkOps(left, right)) return false;
  3663. if(left instanceof Date && right instanceof Date) {
  3664. if(left.getMilliseconds() != right.getMilliseconds()) return false;
  3665. if(left.getSeconds() != right.getSeconds()) return false;
  3666. if(left.getMinutes() != right.getMinutes()) return false;
  3667. if(left.getHours() != right.getHours()) return false;
  3668. if(left.getDate() != right.getDate()) return false;
  3669. if(left.getMonth() != right.getMonth()) return false;
  3670. if(left.getYear() != right.getYear()) return false;
  3671. return true;
  3672. }
  3673. if(left instanceof Object && right instanceof Object) {
  3674. var prop;
  3675. // Go through all of lefts properties and compare them to rights.
  3676. for(prop in left) {
  3677. if(!left.hasOwnProperty(prop)) continue;
  3678. // If left has a property that the right doesn't they are not equal.
  3679. if(!right.hasOwnProperty(prop)) return false;
  3680. // If any of their properties are not equal, they are not equal.
  3681. if(!isEqual(left[prop], right[prop], false)) return false;
  3682. }
  3683. for(prop in right) {
  3684. // final check to make sure right doesn't have some extra properties that make them not equal.
  3685. if(left.hasOwnProperty(prop) != right.hasOwnProperty(prop)) return false;
  3686. }
  3687. return true;
  3688. }
  3689. return $ax.getBool(left) == $ax.getBool(right);
  3690. };
  3691. var _binOpOverride = function(left, right, func) {
  3692. left = left();
  3693. if(left == undefined) return false;
  3694. var res = func(left, right);
  3695. return res == undefined ? false : res;
  3696. };
  3697. var _binOpNum = function(left, right, func) {
  3698. var left = left();
  3699. var right = right();
  3700. if(checkOps(left, right)) return false;
  3701. return func(left, Number(right));
  3702. };
  3703. var _exprHandlers = {};
  3704. _exprHandlers.array = function(expr, eventInfo) {
  3705. var returnVal = [];
  3706. for(var i = 0; i < expr.items.length; i++) {
  3707. returnVal[returnVal.length] = _evaluateExpr(expr.items[i], eventInfo);
  3708. }
  3709. return returnVal;
  3710. };
  3711. _exprHandlers.binaryOp = function(expr, eventInfo) {
  3712. var left = function() { return expr.leftExpr && _evaluateExpr(expr.leftExpr, eventInfo); };
  3713. var right = function() { return expr.rightExpr && _evaluateExpr(expr.rightExpr, eventInfo); };
  3714. if(left == undefined || right == undefined) return false;
  3715. return _binOpHandlers[expr.op](left, right);
  3716. };
  3717. _exprHandlers.block = function(expr, eventInfo) {
  3718. var subExprs = expr.subExprs;
  3719. for(var i = 0; i < subExprs.length; i++) {
  3720. _evaluateExpr(subExprs[i], eventInfo); //ignore the result
  3721. }
  3722. };
  3723. _exprHandlers.booleanLiteral = function(expr) {
  3724. return expr.value;
  3725. };
  3726. _exprHandlers.nullLiteral = function() { return null; };
  3727. _exprHandlers.pathLiteral = function(expr, eventInfo) {
  3728. if(expr.isThis) return [eventInfo.srcElement];
  3729. if(expr.isFocused && window.lastFocusedControl) {
  3730. $ax('#' + window.lastFocusedControl).focus();
  3731. return [window.lastFocusedControl];
  3732. }
  3733. if(expr.isTarget) return [eventInfo.targetElement];
  3734. return $ax.getElementIdsFromPath(expr.value, eventInfo);
  3735. };
  3736. _exprHandlers.panelDiagramLiteral = function(expr, eventInfo) {
  3737. var elementIds = $ax.getElementIdsFromPath(expr.panelPath, eventInfo);
  3738. var elementIdsWithSuffix = [];
  3739. var suffix = '_state' + expr.panelIndex;
  3740. for(var i = 0; i < elementIds.length; i++) {
  3741. elementIdsWithSuffix[i] = $ax.repeater.applySuffixToElementId(elementIds[i], suffix);
  3742. }
  3743. return String($jobj(elementIdsWithSuffix).data('label'));
  3744. };
  3745. _exprHandlers.fcall = function(expr, eventInfo) {
  3746. var oldTarget = eventInfo.targetElement;
  3747. var targets = [];
  3748. var fcallArgs = [];
  3749. var exprArgs = expr.arguments;
  3750. for(var i = 0; i < expr.arguments.length; i++) {
  3751. var exprArg = exprArgs[i];
  3752. var fcallArg = '';
  3753. if(targets.length) {
  3754. for(var j = 0; j < targets.length; j++) {
  3755. if(exprArg == null) {
  3756. fcallArgs[j][i] = null;
  3757. continue;
  3758. }
  3759. eventInfo.targetElement = targets[j];
  3760. fcallArg = _evaluateExpr(exprArg, eventInfo);
  3761. if(typeof (fcallArg) == 'undefined') return '';
  3762. fcallArgs[j][i] = fcallArg;
  3763. }
  3764. } else {
  3765. if(exprArg == null) {
  3766. fcallArgs[i] = null;
  3767. continue;
  3768. }
  3769. fcallArg = _evaluateExpr(exprArg, eventInfo);
  3770. if(typeof (fcallArg) == 'undefined') return '';
  3771. fcallArgs[i] = fcallArg;
  3772. }
  3773. // We do support null exprArgs...
  3774. // TODO: This makes 2 assumptions that may change in the future. 1. The pathLiteral is the always the first arg. 2. there is always only 1 pathLiteral
  3775. if(exprArg && exprArg.exprType == 'pathLiteral') {
  3776. targets = fcallArg;
  3777. // fcallArgs is now an array of an array of args
  3778. for(j = 0; j < targets.length; j++) fcallArgs[j] = [[fcallArg[j]]];
  3779. }
  3780. }
  3781. // we want to preserve the target element from outside this function.
  3782. eventInfo.targetElement = oldTarget;
  3783. var retval = '';
  3784. if(targets.length) {
  3785. // Go backwards so retval is the first item.
  3786. for(i = targets.length - 1; i >= 0; i--) {
  3787. var args = fcallArgs[i];
  3788. // Add event info to the end
  3789. args[args.length] = eventInfo;
  3790. retval = _exprFunctions[expr.functionName].apply(this, args);
  3791. }
  3792. } else fcallArgs[fcallArgs.length] = eventInfo;
  3793. return targets.length ? retval : _exprFunctions[expr.functionName].apply(this, fcallArgs);
  3794. };
  3795. _exprHandlers.globalVariableLiteral = function(expr) {
  3796. return expr.variableName;
  3797. };
  3798. _exprHandlers.keyPressLiteral = function(expr) {
  3799. var keyInfo = {};
  3800. keyInfo.keyCode = expr.keyCode;
  3801. keyInfo.ctrl = expr.ctrl;
  3802. keyInfo.alt = expr.alt;
  3803. keyInfo.shift = expr.shift;
  3804. return keyInfo;
  3805. };
  3806. _exprHandlers.adaptiveViewLiteral = function(expr) {
  3807. return expr.id;
  3808. };
  3809. _exprHandlers.optionLiteral = function(expr) {
  3810. return expr.value;
  3811. }
  3812. var _substituteSTOs = function(expr, eventInfo) {
  3813. //first evaluate the local variables
  3814. var scope = {};
  3815. for(var varName in expr.localVariables) {
  3816. scope[varName] = $ax.expr.evaluateExpr(expr.localVariables[varName], eventInfo);
  3817. }
  3818. // TODO: [ben] Date and data object (obj with info for url or image) both need to return non-strings.
  3819. var i = 0;
  3820. var retval;
  3821. var retvalString = expr.value.replace(/\[\[(?!\[)(.*?)\]\](?=\]*)/g, function(match) {
  3822. var sto = expr.stos[i++];
  3823. if(sto.sto == 'error') return match;
  3824. try {
  3825. var result = $ax.evaluateSTO(sto, scope, eventInfo);
  3826. } catch(e) {
  3827. return match;
  3828. }
  3829. if((result instanceof Object) && i == 1 && expr.value.substring(0, 2) == '[[' &&
  3830. expr.value.substring(expr.value.length - 2) == ']]') {
  3831. // If the result was an object, this was the first result, and the whole thing was this expresion.
  3832. retval = result;
  3833. }
  3834. return ((result instanceof Object) && (result.label || result.text)) || result;
  3835. });
  3836. // If more than one group returned, the object is not valid
  3837. if(i != 1) retval = false;
  3838. return retval || retvalString;
  3839. };
  3840. _exprHandlers.htmlLiteral = function (expr, eventInfo) {
  3841. eventInfo.htmlLiteral = true;
  3842. var html = _substituteSTOs(expr, eventInfo);
  3843. eventInfo.htmlLiteral = false
  3844. return html;
  3845. };
  3846. _exprHandlers.stringLiteral = function(expr, eventInfo) {
  3847. return _substituteSTOs(expr, eventInfo);
  3848. };
  3849. var _exprFunctions = {};
  3850. _exprFunctions.SetCheckState = function(elementIds, value) {
  3851. var toggle = value == 'toggle';
  3852. var boolValue = Boolean(value) && value != 'false';
  3853. for(var i = 0; i < elementIds.length; i++) {
  3854. var query = $ax('#' + elementIds[i]);
  3855. query.selected(toggle ? !query.selected() : boolValue);
  3856. }
  3857. };
  3858. _exprFunctions.SetSelectedOption = function(elementIds, value) {
  3859. for(var i = 0; i < elementIds.length; i++) {
  3860. var elementId = elementIds[i];
  3861. var obj = $jobj($ax.INPUT(elementId));
  3862. if(obj.val() == value) return;
  3863. obj.val(value);
  3864. if($ax.event.HasSelectionChanged($ax.getObjectFromElementId(elementId))) $ax.event.raiseSyntheticEvent(elementId, 'onSelectionChange');
  3865. }
  3866. };
  3867. _exprFunctions.SetGlobalVariableValue = function(varName, value) {
  3868. $ax.globalVariableProvider.setVariableValue(varName, value);
  3869. };
  3870. _exprFunctions.SetWidgetFormText = function(elementIds, value) {
  3871. for(var i = 0; i < elementIds.length; i++) {
  3872. var elementId = elementIds[i];
  3873. var inputId = $ax.repeater.applySuffixToElementId(elementId, '_input');
  3874. var obj = $jobj(inputId);
  3875. if(obj.val() == value || (value == '' && $ax.placeholderManager.isActive(elementId))) return;
  3876. obj.val(value);
  3877. $ax.placeholderManager.updatePlaceholder(elementId, !value);
  3878. if($ax.event.HasTextChanged($ax.getObjectFromElementId(elementId))) $ax.event.TryFireTextChanged(elementId);
  3879. }
  3880. };
  3881. _exprFunctions.SetFocusedWidgetText = function(elementId, value) {
  3882. if(window.lastFocusedControl) {
  3883. var elementId = window.lastFocusedControl;
  3884. var type = $obj(elementId).type;
  3885. if ($ax.public.fn.IsTextBox(type) || $ax.public.fn.IsTextArea(type)) _exprFunctions.SetWidgetFormText([elementId], value);
  3886. else _exprFunctions.SetWidgetRichText([elementId], value, true);
  3887. }
  3888. };
  3889. _exprFunctions.GetRtfElementHeight = function(rtfElement) {
  3890. if(rtfElement.innerHTML == '') rtfElement.innerHTML = '&nbsp;';
  3891. return rtfElement.offsetHeight;
  3892. };
  3893. _exprFunctions.SetWidgetRichText = function(ids, value, plain) {
  3894. // Converts dates, widgetinfo, and the like to strings.
  3895. value = _exprFunctions.ToString(value);
  3896. //Replace any newlines with line breaks
  3897. var finalValue = value.replace(/\r\n/g, '<br>').replace(/\n/g, '<br>');
  3898. for(var i = 0; i < ids.length; i++) {
  3899. var id = ids[i];
  3900. // If calling this on button shape, get the id of the rich text panel inside instead
  3901. if($obj(id).type !== $ax.constants.LINK_TYPE) id = $ax.GetTextPanelId(id, true);
  3902. var element = window.document.getElementById(id);
  3903. $ax.visibility.SetVisible(element, value != '');
  3904. $ax.style.transformTextWithVerticalAlignment(id, function() {
  3905. var spans = $jobj(id).find('span');
  3906. if(plain) {
  3907. // Can't set value as text because '<br/>' doesn't actually do a line break
  3908. // Can't set vaule as html because it doesn't like '<' and ignores all after it
  3909. // Create tags yourself
  3910. var lines = value.split(/\r\n|\n/);
  3911. //if we are dealing with only one line, just reuse the old one
  3912. if(spans.length === 1 && lines.length === 1) {
  3913. $(spans[0]).text(value);
  3914. return;
  3915. }
  3916. // Wrap in span and p, style them accordingly.
  3917. var span = $('<span></span>');
  3918. if(spans.length > 0) {
  3919. span.attr('style', $(spans[0]).attr('style'));
  3920. span.attr('id', $(spans[0]).attr('id'));
  3921. }
  3922. if(lines.length == 1) span.text(value);
  3923. else {
  3924. for(var i = 0; i < lines.length; i++) {
  3925. if(i != 0) span.append($('<br />'));
  3926. var line = lines[i];
  3927. if(line.length == 0) continue;
  3928. var subSpan = $('<span />');
  3929. subSpan.text(line);
  3930. span.append(subSpan);
  3931. }
  3932. }
  3933. var ps = $jobj(id).find('p');
  3934. if(ps && ps.length) {
  3935. ps[0].innerHTML = $('<div></div>').append(span).html();;
  3936. if(ps.length > 1) {
  3937. for(var i = 1; i < ps.length; i++) {
  3938. $(ps[i]).remove();
  3939. }
  3940. }
  3941. } else {
  3942. var p = $('<p></p>');
  3943. p.append(span);
  3944. element.innerHTML = $('<div></div>').append(p).html();
  3945. }
  3946. } else element.innerHTML = finalValue;
  3947. });
  3948. if(!plain) $ax.style.CacheOriginalText(id, true);
  3949. }
  3950. };
  3951. _exprFunctions.GetCheckState = function(ids) {
  3952. return $ax('#' + ids[0]).selected();
  3953. };
  3954. _exprFunctions.GetSelectedOption = function (ids) {
  3955. var inputs = $jobj($ax.INPUT(ids[0]));
  3956. return inputs.length ? inputs[0].value : '';
  3957. };
  3958. _exprFunctions.GetNum = function(str) {
  3959. //Setting a GlobalVariable to some blank text then setting a widget to the value of that variable would result in 0 not ""
  3960. //I have fixed this another way so commenting this should be fine now
  3961. //if (!str) return "";
  3962. return isNaN(str) ? str : Number(str);
  3963. };
  3964. _exprFunctions.GetGlobalVariableValue = function(id) {
  3965. return $ax.globalVariableProvider.getVariableValue(id);
  3966. };
  3967. _exprFunctions.GetGlobalVariableLength = function(id) {
  3968. return _exprFunctions.GetGlobalVariableValue(id).length;
  3969. };
  3970. _exprFunctions.GetWidgetText = function(ids) {
  3971. if($ax.placeholderManager.isActive(ids[0])) return '';
  3972. var input = $ax.INPUT(ids[0]);
  3973. return $ax('#' + ($jobj(input).length ? input : ids[0])).text();
  3974. };
  3975. _exprFunctions.GetFocusedWidgetText = function() {
  3976. if(window.lastFocusedControl) {
  3977. return $ax('#' + window.lastFocusedControl).text();
  3978. } else {
  3979. return "";
  3980. }
  3981. };
  3982. _exprFunctions.GetWidgetValueLength = function(ids) {
  3983. var id = ids[0];
  3984. if(!id) return undefined;
  3985. if($ax.placeholderManager.isActive(id)) return 0;
  3986. var obj = $jobj($ax.INPUT(id));
  3987. if(!obj.length) obj = $jobj(id);
  3988. var val = obj[0].value || _exprFunctions.GetWidgetText([id]);
  3989. return val.length;
  3990. };
  3991. _exprFunctions.GetPanelState = function(ids) {
  3992. var id = ids[0];
  3993. if(!id) return undefined;
  3994. var stateId = $ax.visibility.GetPanelState(id);
  3995. return stateId && String($jobj(stateId).data('label'));
  3996. };
  3997. _exprFunctions.GetWidgetVisibility = function(ids) {
  3998. var id = ids[0];
  3999. if(!id) return undefined;
  4000. return $ax.visibility.IsIdVisible(id);
  4001. };
  4002. // ***************** Validation Functions ***************** //
  4003. _exprFunctions.IsValueAlpha = function(val) {
  4004. var isAlphaRegex = new RegExp("^[a-z\\s]+$", "gi");
  4005. return isAlphaRegex.test(val);
  4006. };
  4007. _exprFunctions.IsValueNumeric = function(val) {
  4008. var isNumericRegex = new RegExp("^[0-9,\\.\\s]+$", "gi");
  4009. return isNumericRegex.test(val);
  4010. };
  4011. _exprFunctions.IsValueAlphaNumeric = function(val) {
  4012. var isAlphaNumericRegex = new RegExp("^[0-9a-z\\s]+$", "gi");
  4013. return isAlphaNumericRegex.test(val);
  4014. };
  4015. _exprFunctions.IsValueOneOf = function(val, values) {
  4016. for(var i = 0; i < values.length; i++) {
  4017. var option = values[i];
  4018. if(val == option) return true;
  4019. }
  4020. //by default, return false
  4021. return false;
  4022. };
  4023. _exprFunctions.IsValueNotAlpha = function(val) {
  4024. return !_exprFunctions.IsValueAlpha(val);
  4025. };
  4026. _exprFunctions.IsValueNotNumeric = function(val) {
  4027. return !_exprFunctions.IsValueNumeric(val);
  4028. };
  4029. _exprFunctions.IsValueNotAlphaNumeric = function(val) {
  4030. return !_exprFunctions.IsValueAlphaNumeric(val);
  4031. };
  4032. _exprFunctions.IsValueNotOneOf = function(val, values) {
  4033. return !_exprFunctions.IsValueOneOf(val, values);
  4034. };
  4035. _exprFunctions.GetKeyPressed = function(eventInfo) {
  4036. return eventInfo.keyInfo;
  4037. };
  4038. _exprFunctions.GetCursorRectangles = function() {
  4039. var rects = new Object();
  4040. rects.lastRect = new $ax.drag.Rectangle($ax.lastMouseLocation.x, $ax.lastMouseLocation.y, 1, 1);
  4041. rects.currentRect = new $ax.drag.Rectangle($ax.mouseLocation.x, $ax.mouseLocation.y, 1, 1);
  4042. return rects;
  4043. };
  4044. _exprFunctions.GetWidgetRectangles = function (elementIds, eventInfo) {
  4045. var elementId = elementIds[0];
  4046. var rects = new Object();
  4047. var jObj = $jobj(elementId);
  4048. var invalid = jObj.length == 0;
  4049. var parent = jObj;
  4050. // Or are in valid if no obj can be found, or if it is not visible.
  4051. while(parent.length != 0 && !parent.is('body')) {
  4052. if(parent.css('display') == 'none') {
  4053. invalid = true;
  4054. break;
  4055. }
  4056. parent = parent.parent();
  4057. }
  4058. if(invalid) {
  4059. rects.lastRect = rects.currentRect = new $ax.drag.Rectangle(-1, -1, -1, -1);
  4060. return rects;
  4061. }
  4062. var axObj = $ax('#' + elementId);
  4063. rects.lastRect = new $ax.drag.Rectangle(
  4064. axObj.left(),
  4065. axObj.top(),
  4066. axObj.width(),
  4067. axObj.height());
  4068. rects.currentRect = rects.lastRect;
  4069. return rects;
  4070. };
  4071. _exprFunctions.GetWidget = function(elementId) {
  4072. return $ax.getWidgetInfo(elementId[0]);
  4073. };
  4074. _exprFunctions.GetAdaptiveView = function() {
  4075. return $ax.adaptive.currentViewId || '';
  4076. };
  4077. _exprFunctions.IsEntering = function(movingRects, targetRects) {
  4078. return !movingRects.lastRect.IntersectsWith(targetRects.currentRect) && movingRects.currentRect.IntersectsWith(targetRects.currentRect);
  4079. };
  4080. _exprFunctions.IsLeaving = function(movingRects, targetRects) {
  4081. return movingRects.lastRect.IntersectsWith(targetRects.currentRect) && !movingRects.currentRect.IntersectsWith(targetRects.currentRect);
  4082. };
  4083. var _IsOver = _exprFunctions.IsOver = function(movingRects, targetRects) {
  4084. return movingRects.currentRect.IntersectsWith(targetRects.currentRect);
  4085. };
  4086. _exprFunctions.IsNotOver = function(movingRects, targetRects) {
  4087. return !_IsOver(movingRects, targetRects);
  4088. };
  4089. _exprFunctions.ValueContains = function(inputString, value) {
  4090. return inputString.indexOf(value) > -1;
  4091. };
  4092. _exprFunctions.ValueNotContains = function(inputString, value) {
  4093. return !_exprFunctions.ValueContains(inputString, value);
  4094. };
  4095. _exprFunctions.ToString = function(value) {
  4096. if(value.isWidget) {
  4097. return value.text;
  4098. }
  4099. return String(value);
  4100. };
  4101. var _evaluateExpr = $ax.expr.evaluateExpr = function(expr, eventInfo, toString) {
  4102. if(expr === undefined || expr === null) return undefined;
  4103. var result = _exprHandlers[expr.exprType](expr, eventInfo);
  4104. return toString ? _exprFunctions.ToString(result) : result;
  4105. };
  4106. });
  4107. //***** geometry.js *****//
  4108. // ******* Region MANAGER ******** //
  4109. $axure.internal(function($ax) {
  4110. var _geometry = $ax.geometry = {};
  4111. var regionMap = {};
  4112. var regionList = [];
  4113. var _unregister = function(label) {
  4114. var regionIndex = regionList.indexOf(label);
  4115. if(regionIndex != -1) {
  4116. var end = $ax.splice(regionList, regionIndex + 1);
  4117. $ax.splice(regionList, regionIndex, regionList.length - regionIndex);
  4118. regionList = regionList.concat(end);
  4119. }
  4120. delete regionMap[label];
  4121. };
  4122. _geometry.unregister = _unregister;
  4123. var clear = function() {
  4124. regionMap = {};
  4125. regionList = [];
  4126. };
  4127. var _polygonRegistered = function(label) {
  4128. return Boolean(regionMap[label]);
  4129. };
  4130. _geometry.polygonRegistered = _polygonRegistered;
  4131. // Must be counterclockwise, or enter/exit will be wrong
  4132. var _registerPolygon = function(label, points, callback, info) {
  4133. var regionIndex = regionList.indexOf(label);
  4134. if(regionIndex == -1) regionList.push(label);
  4135. regionMap[label] = { points: points, callback: callback, info: info };
  4136. };
  4137. _geometry.registerPolygon = _registerPolygon;
  4138. var _getPolygonInfo = function(label) {
  4139. if(!_polygonRegistered(label)) return undefined;
  4140. return regionMap[label].info;
  4141. };
  4142. _geometry.getPolygonInfo = _getPolygonInfo;
  4143. var _genRect = function(info, roundHalfPixel) {
  4144. var x = info.pagex();
  4145. var y = info.pagey();
  4146. var w = info.width();
  4147. var h = info.height();
  4148. if(roundHalfPixel) {
  4149. if(x % 1 != 0) {
  4150. x = Math.floor(x);
  4151. w++;
  4152. }
  4153. if(y % 1 != 0) {
  4154. y = Math.floor(y);
  4155. h++;
  4156. }
  4157. }
  4158. var r = x + w;
  4159. var b = y + h;
  4160. var rect = {
  4161. X: function() { return x; },
  4162. Y: function() { return y; },
  4163. Wigth: function() { return w; },
  4164. Height: function() { return h; },
  4165. Left: function() { return x; },
  4166. Right: function() { return r; },
  4167. Top: function() { return y; },
  4168. Bottom: function() { return b; }
  4169. };
  4170. return rect;
  4171. };
  4172. _geometry.genRect = _genRect;
  4173. var _genPoint = function(x, y) {
  4174. return { x: x, y: y };
  4175. };
  4176. _geometry.genPoint = _genPoint;
  4177. var oldPoint = _genPoint(0, 0);
  4178. _geometry.tick = function(x, y, end) {
  4179. var lastPoint = oldPoint;
  4180. var nextPoint = oldPoint = _genPoint(x, y);
  4181. var line = { p1: lastPoint, p2: nextPoint };
  4182. if(!regionList.length) return;
  4183. for(var i = 0; i < regionList.length; i++) {
  4184. var region = regionMap[regionList[i]];
  4185. var points = region.points;
  4186. if(!region.checked) {
  4187. if(!_checkInside(points, $ax.mouseLocation)) {
  4188. region.callback({ outside: true });
  4189. continue;
  4190. }
  4191. region.checked = true;
  4192. }
  4193. for(var j = 0; j < points.length; j++) {
  4194. var startSegment = points[j];
  4195. var endSegment = points[(j + 1) % points.length];
  4196. var intersectInfo = linesIntersect(line, { p1: startSegment, p2: endSegment });
  4197. if(intersectInfo) {
  4198. region.callback(intersectInfo);
  4199. break;
  4200. }
  4201. }
  4202. }
  4203. if(end) clear();
  4204. };
  4205. // Info if the one line touches the other (even barely), false otherwise
  4206. // Info includes point, if l1 is entering or exiting l2, and any ties that happened, or parallel info
  4207. var linesIntersect = function(l1, l2) {
  4208. var retval = {};
  4209. var ties = {};
  4210. var l1p1 = l1.p1.x < l1.p2.x || (l1.p1.x == l1.p2.x && l1.p1.y < l1.p2.y) ? l1.p1 : l1.p2;
  4211. var l1p2 = l1.p1.x < l1.p2.x || (l1.p1.x == l1.p2.x && l1.p1.y < l1.p2.y) ? l1.p2 : l1.p1;
  4212. var m1 = (l1p2.y - l1p1.y) / (l1p2.x - l1p1.x);
  4213. var l2p1 = l2.p1.x < l2.p2.x || (l2.p1.x == l2.p2.x && l2.p1.y < l2.p2.y) ? l2.p1 : l2.p2;
  4214. var l2p2 = l2.p1.x < l2.p2.x || (l2.p1.x == l2.p2.x && l2.p1.y < l2.p2.y) ? l2.p2 : l2.p1;
  4215. var m2 = (l2p2.y - l2p1.y) / (l2p2.x - l2p1.x);
  4216. var l1Vert = l1.p1.x == l1.p2.x;
  4217. var l2Vert = l2.p1.x == l2.p2.x;
  4218. if(l1Vert || l2Vert) {
  4219. if(l1Vert && l2Vert) {
  4220. // If the lines don't follow the same path, return
  4221. if(l1p1.x != l2p1.x) return false;
  4222. // if they never meet, return
  4223. if(l1p2.y < l2p1.y || l1p1.y > l2p2.y) return false;
  4224. var firstVert = l1p1.y >= l2p1.y ? l1p1 : l2p1;
  4225. var secondVert = l1p2.y <= l2p2.y ? l1p2 : l2p2;
  4226. // First is from the perspective of l1
  4227. retval.parallel = {
  4228. first: l1p1 == l1.p1 ? firstVert : secondVert,
  4229. second: l1p2 == l1.p2 ? secondVert : firstVert,
  4230. sameDirection: (l1p1 == l1.p1) == (l2p1 == l2.p1)
  4231. };
  4232. return retval;
  4233. }
  4234. var x1 = l2Vert ? l1p1.x : l2p1.x;
  4235. var x2 = l2Vert ? l1p2.x : l2p2.x;
  4236. var xVert = l2Vert ? l2p1.x : l1p1.x;
  4237. var y = l2Vert ? l1p1.y + (xVert - x1) * m1 : l2p1.y + (xVert - x1) * m2;
  4238. var y1 = l2Vert ? l2p1.y : l1p1.y;
  4239. var y2 = l2Vert ? l2p2.y : l1p2.y;
  4240. if(xVert >= x1 && xVert <= x2 && y >= y1 && y <= y2) {
  4241. retval.point = { x: xVert, y: y };
  4242. retval.exiting = l2Vert == (y1 == (l2Vert ? l2.p1.y : l1.p1.y)) == (x1 == (l2Vert ? l1.p1.x : l2.p1.x));
  4243. retval.entering = !retval.exiting;
  4244. // Calculate ties
  4245. if(x1 == xVert) {
  4246. ties[l2Vert ? 'l1' : 'l2'] = (x1 == (l2Vert ? l1.p1.x : l2.p1.x)) ? 'start' : 'end';
  4247. retval.ties = ties;
  4248. } else if(x2 == xVert) {
  4249. ties[l2Vert ? 'l1' : 'l2'] = (x2 == (l2Vert ? l1.p2.x : l2.p2.x)) ? 'end' : 'start';
  4250. retval.ties = ties;
  4251. }
  4252. if(y1 == y) {
  4253. ties[l2Vert ? 'l2' : 'l1'] = (y1 == (l2Vert ? l2.p1.y : l1.p1.y)) ? 'start' : 'end';
  4254. retval.ties = ties;
  4255. } else if(y2 == y) {
  4256. ties[l2Vert ? 'l2' : 'l1'] = (y2 == (l2Vert ? l2.p2.y : l1.p2.y)) ? 'end' : 'start';
  4257. retval.ties = ties;
  4258. }
  4259. return retval;
  4260. }
  4261. return false;
  4262. }
  4263. // If here, no vertical lines
  4264. if(m1 == m2) {
  4265. // If the lines don't follow the same path, return
  4266. if(l1p1.y != (l2p1.y + (l1p1.x - l2p1.x) * m1)) return false;
  4267. // if they never meet, return
  4268. if(l1p2.x < l2p1.x || l1p1.x > l2p2.x) return false;
  4269. var first = l1p1.x >= l2p1.x ? l1p1 : l2p1;
  4270. var second = l1p2.x <= l2p2.x ? l1p2 : l2p2;
  4271. // First is from the perspective of l1
  4272. retval.parallel = {
  4273. first: l1p1 == l1.p1 ? first : second,
  4274. second: l1p2 == l1.p2 ? second : first,
  4275. sameDirection: (l1p1 == l1.p1) == (l2p1 == l2.p1)
  4276. };
  4277. return retval;
  4278. }
  4279. var x = (l2p1.y - l2p1.x * m2 - l1p1.y + l1p1.x * m1) / (m1 - m2);
  4280. // Check if x is out of bounds
  4281. if(x >= l1p1.x && x <= l1p2.x && x >= l2p1.x && x <= l2p2.x) {
  4282. var y = l1p1.y + (x - l1p1.x) * m1;
  4283. retval.point = { x: x, y: y };
  4284. retval.entering = m1 > m2 == (l1p1 == l1.p1) == (l2p1 == l2.p1);
  4285. retval.exiting = !retval.entering;
  4286. // Calculate ties
  4287. if(l1.p1.x == x) {
  4288. ties.l1 = 'start';
  4289. retval.ties = ties;
  4290. } else if(l1.p2.x == x) {
  4291. ties.l1 = 'end';
  4292. retval.ties = ties;
  4293. }
  4294. if(l2.p1.x == x) {
  4295. ties.l2 = 'start';
  4296. retval.ties = ties;
  4297. } else if(l2.p2.x == x) {
  4298. ties.l2 = 'end';
  4299. retval.ties = ties;
  4300. }
  4301. return retval;
  4302. }
  4303. return false;
  4304. };
  4305. var _checkInsideRegion = function(label, point) {
  4306. if(!_polygonRegistered(label)) return false;
  4307. return _checkInside(regionMap[label].points, point || $ax.mouseLocation);
  4308. };
  4309. _geometry.checkInsideRegion = _checkInsideRegion;
  4310. // Returns true if point is inside the polygon, including ties
  4311. var _checkInside = function(polygon, point) {
  4312. // Make horizontal line wider than the polygon, with the y of point to test location
  4313. var firstX = polygon[0].x;
  4314. var secondX = firstX;
  4315. var i;
  4316. for(i = 1; i < polygon.length; i++) {
  4317. var polyX = polygon[i].x;
  4318. firstX = Math.min(firstX, polyX);
  4319. secondX = Math.max(secondX, polyX);
  4320. }
  4321. var line = {
  4322. p1: _genPoint(--firstX, point.y),
  4323. p2: _genPoint(++secondX, point.y)
  4324. };
  4325. // If entered true, with closest intersection says you are inside the polygon.
  4326. var entered = false;
  4327. // Closest is the closest intersection to the left of the point
  4328. var closest = line.p1.x;
  4329. // This is for if intersections hit the same point, to find out which is correct
  4330. var cos = -2;
  4331. var getCos = function(line) {
  4332. var x = line.p2.x - line.p1.x;
  4333. var y = line.p2.y - line.p1.y;
  4334. return x / Math.sqrt(x * x + y * y);
  4335. };
  4336. for(i = 0; i < polygon.length; i++) {
  4337. var polyLine = { p1: polygon[i], p2: polygon[(i + 1) % polygon.length] };
  4338. var intersectInfo = linesIntersect(line, polyLine);
  4339. if(!intersectInfo) continue;
  4340. if(intersectInfo.parallel) {
  4341. // Only really care about this if it actually touches the point
  4342. if(intersectInfo.parallel.first.x <= point.x && intersectInfo.parallel.second.x >= point.x) return true;
  4343. continue;
  4344. }
  4345. var intersectionX = intersectInfo.point.x;
  4346. if(intersectionX > point.x || intersectionX < closest) continue;
  4347. if(intersectionX == point.x) return true;
  4348. // If closer than last time, reset cosine.
  4349. if(intersectionX != closest) cos = -2;
  4350. // For getting cosine, need to possibly reverse the direction of polyLine.
  4351. if(intersectInfo.ties) {
  4352. // Tie must be on l2, if the ties is end, reverse so cosine indicates how close the angle is to that of 'point' from here.
  4353. if(intersectInfo.ties.l2 == 'end') polyLine = { p1: polyLine.p2, p2: polyLine.p1 };
  4354. } else {
  4355. // It is on both side, so you can take the larger one
  4356. if(polyLine.p1.x > polyLine.p2.x) polyLine = { p1: polyLine.p2, p2: polyLine.p1 };
  4357. }
  4358. var currCos = getCos(polyLine);
  4359. if(currCos > cos) {
  4360. cos = currCos;
  4361. closest = intersectionX;
  4362. entered = intersectInfo.entering;
  4363. }
  4364. }
  4365. return entered;
  4366. };
  4367. _geometry.checkInside = _checkInside;
  4368. });
  4369. //***** flyout.js *****//
  4370. // ******* Flyout MANAGER ******** //
  4371. $axure.internal(function($ax) {
  4372. var _flyoutManager = $ax.flyoutManager = {};
  4373. var getFlyoutLabel = function(panelId) {
  4374. return panelId + '_flyout';
  4375. };
  4376. var _unregisterPanel = function(panelId, keepShown) {
  4377. $ax.geometry.unregister(getFlyoutLabel(panelId));
  4378. if(panelToSrc[panelId]) {
  4379. $ax.style.RemoveRolloverOverride(panelToSrc[panelId]);
  4380. delete panelToSrc[panelId];
  4381. }
  4382. if(!keepShown) {
  4383. $ax.action.addAnimation(panelId, $ax.action.queueTypes.fade, function() {
  4384. $ax('#' + panelId).hide();
  4385. });
  4386. }
  4387. };
  4388. _flyoutManager.unregisterPanel = _unregisterPanel;
  4389. var genPoint = $ax.geometry.genPoint;
  4390. var _updateFlyout = function(panelId) {
  4391. var label = getFlyoutLabel(panelId);
  4392. if(!$ax.geometry.polygonRegistered(label)) return;
  4393. var info = $ax.geometry.getPolygonInfo(label);
  4394. var rects = info && info.rects;
  4395. var targetWidget = $ax.getWidgetInfo(panelId);
  4396. rects.target = $ax.geometry.genRect(targetWidget);
  4397. // Src will stay the same, just updating
  4398. $ax.flyoutManager.registerFlyout(rects, panelId, panelToSrc[panelId]);
  4399. if(!$ax.geometry.checkInsideRegion(label)) _unregisterPanel(panelId);
  4400. };
  4401. _flyoutManager.updateFlyout = _updateFlyout;
  4402. var panelToSrc = {};
  4403. var _registerFlyout = function(rects, panelId, srcId) {
  4404. var label = _getFlyoutLabel(panelId);
  4405. var callback = function(info) {
  4406. // If leaving object or already outside it, then unregister, otherwise just return
  4407. if(!info.exiting && !info.outside) return;
  4408. _unregisterPanel(panelId);
  4409. };
  4410. var points = [];
  4411. var lastSrcId = panelToSrc[panelId];
  4412. if(lastSrcId != srcId) {
  4413. if(lastSrcId) $ax.style.RemoveRolloverOverride(lastSrcId);
  4414. if(srcId) {
  4415. $ax.style.AddRolloverOverride(srcId);
  4416. panelToSrc[panelId] = srcId;
  4417. } else delete panelToSrc[panelId];
  4418. }
  4419. // rects should be one or two rectangles
  4420. if(!rects.src) {
  4421. var rect = rects.target;
  4422. points.push(genPoint(rect.Left(), rect.Top()));
  4423. points.push(genPoint(rect.Right(), rect.Top()));
  4424. points.push(genPoint(rect.Right(), rect.Bottom()));
  4425. points.push(genPoint(rect.Left(), rect.Bottom()));
  4426. } else {
  4427. var r0 = rects.src;
  4428. var r1 = rects.target;
  4429. // Right left of right, left right of left, top below top, bottom above bottom
  4430. var rlr = r0.Right() <= r1.Right();
  4431. var lrl = r0.Left() >= r1.Left();
  4432. var tbt = r0.Top() >= r1.Top();
  4433. var bab = r0.Bottom() <= r1.Bottom();
  4434. var info = { rlr: rlr, lrl: lrl, tbt: tbt, bab: bab };
  4435. if((rlr && lrl) || (tbt && bab)) {
  4436. points = getSmallPolygon(r0, r1, info);
  4437. } else {
  4438. points = getLargePolygon(r0, r1, info);
  4439. }
  4440. }
  4441. $ax.geometry.registerPolygon(label, points, callback, { rects: rects });
  4442. };
  4443. _flyoutManager.registerFlyout = _registerFlyout;
  4444. var _getFlyoutLabel = function(panelId) {
  4445. return panelId + '_flyout';
  4446. };
  4447. var _reregisterAllFlyouts = function() {
  4448. for(var panelId in panelToSrc) _reregisterFlyout(panelId);
  4449. };
  4450. _flyoutManager.reregisterAllFlyouts = _reregisterAllFlyouts;
  4451. var _reregisterFlyout = function(panelId) {
  4452. var rects = $ax.geometry.getPolygonInfo(getFlyoutLabel(panelId)).rects;
  4453. _registerFlyout(rects, panelId, panelToSrc[panelId]);
  4454. };
  4455. // This is the reduced size polygon connecting r0 to r1 by means of horizontal or vertical lines.
  4456. var getSmallPolygon = function(r0, r1, info) {
  4457. var points = [];
  4458. // NOTE: currently I make the assumption that if horizontal/vertical connecting lines from the src hit the target
  4459. // Meaning if horizontal, rlr and lrl are true, and if vertical, tbt and bab are true.
  4460. var r0Left = r0.Left();
  4461. var r0Right = r0.Right();
  4462. var r0Top = r0.Top();
  4463. var r0Bottom = r0.Bottom();
  4464. var r1Left = r1.Left();
  4465. var r1Right = r1.Right();
  4466. var r1Top = r1.Top();
  4467. var r1Bottom = r1.Bottom();
  4468. points.push(genPoint(r1Left, r1Top));
  4469. if(!info.tbt) {
  4470. points.push(genPoint(r0Left, r1Top));
  4471. points.push(genPoint(r0Left, r0Top));
  4472. points.push(genPoint(r0Right, r0Top));
  4473. points.push(genPoint(r0Right, r1Top));
  4474. }
  4475. points.push(genPoint(r1Right, r1Top));
  4476. if(!info.rlr) {
  4477. points.push(genPoint(r1Right, r0Top));
  4478. points.push(genPoint(r0Right, r0Top));
  4479. points.push(genPoint(r0Right, r0Bottom));
  4480. points.push(genPoint(r1Right, r0Bottom));
  4481. }
  4482. points.push(genPoint(r1Right, r1Bottom));
  4483. if(!info.bab) {
  4484. points.push(genPoint(r0Right, r1Bottom));
  4485. points.push(genPoint(r0Right, r0Bottom));
  4486. points.push(genPoint(r0Left, r0Bottom));
  4487. points.push(genPoint(r0Left, r1Bottom));
  4488. }
  4489. points.push(genPoint(r1Left, r1Bottom));
  4490. if(!info.lrl) {
  4491. points.push(genPoint(r1Left, r0Bottom));
  4492. points.push(genPoint(r0Left, r0Bottom));
  4493. points.push(genPoint(r0Left, r0Top));
  4494. points.push(genPoint(r1Left, r0Top));
  4495. }
  4496. return points;
  4497. };
  4498. // This is the original algorithm that connects the most extream corners to make polygon
  4499. var getLargePolygon = function(r0, r1, info) {
  4500. var points = [];
  4501. var r0Left = r0.Left();
  4502. var r0Right = r0.Right();
  4503. var r0Top = r0.Top();
  4504. var r0Bottom = r0.Bottom();
  4505. var r1Left = r1.Left();
  4506. var r1Right = r1.Right();
  4507. var r1Top = r1.Top();
  4508. var r1Bottom = r1.Bottom();
  4509. // Top lefts
  4510. if(info.tbt) {
  4511. if(!info.lrl) points.push(genPoint(r0Left, r0Top));
  4512. points.push(genPoint(r1Left, r1Top));
  4513. } else {
  4514. if(info.lrl) points.push(genPoint(r1Left, r1Top));
  4515. points.push(genPoint(r0Left, r0Top));
  4516. }
  4517. // Top rights
  4518. if(info.tbt) {
  4519. points.push(genPoint(r1Right, r1Top));
  4520. if(!info.rlr) points.push(genPoint(r0Right, r0Top));
  4521. } else {
  4522. points.push(genPoint(r0Right, r0Top));
  4523. if(info.rlr) points.push(genPoint(r1Right, r1Top));
  4524. }
  4525. // Bottom rights
  4526. if(info.bab) {
  4527. if(!info.rlr) points.push(genPoint(r0Right, r0Bottom));
  4528. points.push(genPoint(r1Right, r1Bottom));
  4529. } else {
  4530. if(info.rlr) points.push(genPoint(r1Right, r1Bottom));
  4531. points.push(genPoint(r0Right, r0Bottom));
  4532. }
  4533. // Bottom Lefts
  4534. if(info.bab) {
  4535. points.push(genPoint(r1Left, r1Bottom));
  4536. if(!info.lrl) points.push(genPoint(r0Left, r0Bottom));
  4537. } else {
  4538. points.push(genPoint(r0Left, r0Bottom));
  4539. if(info.lrl) points.push(genPoint(r1Left, r1Bottom));
  4540. }
  4541. return points;
  4542. };
  4543. });
  4544. // ******* Placeholder Manager ********* //
  4545. $axure.internal(function($ax) {
  4546. var _placeholderManager = $ax.placeholderManager = {};
  4547. var idToPlaceholderInfo = {};
  4548. var _registerPlaceholder = function(elementId, text, password) {
  4549. idToPlaceholderInfo[elementId] = { text: text, password: password, active: false };
  4550. };
  4551. _placeholderManager.registerPlaceholder = _registerPlaceholder;
  4552. _placeholderManager.refreshPlaceholder = function (elementId) {
  4553. var info = idToPlaceholderInfo[elementId];
  4554. if (!info || !info.active) return;
  4555. $ax.style.SetWidgetPlaceholder(elementId, true, info.text, info.password);
  4556. }
  4557. var _updatePlaceholder = function(elementId, active, clearText) {
  4558. var inputId = $ax.repeater.applySuffixToElementId(elementId, '_input');
  4559. var info = idToPlaceholderInfo[elementId];
  4560. if(!info || info.active == active) return;
  4561. info.active = active;
  4562. if(active) var text = info.text;
  4563. else if(!ANDROID) text = clearText ? '' : document.getElementById(inputId).value;
  4564. else {
  4565. var currentText = document.getElementById(inputId).value;
  4566. if(!clearText) text = currentText;
  4567. else if(currentText == info.text) text = "";
  4568. else {
  4569. var lastIndex = currentText.lastIndexOf(info.text);
  4570. //here i am assuming the text is always inserted in front
  4571. text = currentText.substring(0, lastIndex);
  4572. }
  4573. }
  4574. $ax.style.SetWidgetPlaceholder(elementId, active, text, info.password);
  4575. };
  4576. _placeholderManager.updatePlaceholder = _updatePlaceholder;
  4577. var _isActive = function(elementId) {
  4578. var info = idToPlaceholderInfo[elementId];
  4579. return Boolean(info && info.active);
  4580. };
  4581. _placeholderManager.isActive = _isActive;
  4582. var _selectRange = function(elementId, start, end) {
  4583. $jobj(elementId).each(function() {
  4584. if(this.setSelectionRange) {
  4585. var validTypes = ["text", "search", "url", "tel", "password"];
  4586. if(this.tagName.toLowerCase() != "input" || validTypes.indexOf(this.type) > -1) {
  4587. this.focus();
  4588. this.setSelectionRange(start, end);
  4589. }
  4590. } else if(this.createTextRange) {
  4591. var range = this.createTextRange();
  4592. range.collapse(true);
  4593. range.moveEnd('character', end);
  4594. range.moveStart('character', start);
  4595. range.select();
  4596. }
  4597. });
  4598. };
  4599. _placeholderManager.selectRange = _selectRange;
  4600. var _moveCaret = function(id, index) {
  4601. var inputIndex = id.indexOf('_input');
  4602. if(inputIndex == -1) return;
  4603. var inputId = id.substring(0, inputIndex);
  4604. if(!_isActive(inputId)) return;
  4605. _selectRange(id, index, index);
  4606. };
  4607. _placeholderManager.moveCaret = _moveCaret;
  4608. });
  4609. //***** ie.js *****//
  4610. // ******* Internet Explorer MANAGER ******** //
  4611. //this is to handle all the stupid IE Stuff
  4612. $axure.internal(function($ax) {
  4613. if(!IE_10_AND_BELOW) return;
  4614. var _ieColorManager = {};
  4615. if(Number(BROWSER_VERSION) < 9) $ax.ieColorManager = _ieColorManager;
  4616. var _applyIEFixedPosition = function() {
  4617. if(Number(BROWSER_VERSION) >= 7) return;
  4618. $axure(function(diagramObject) { return diagramObject.fixedVertical; }).$()
  4619. .appendTo($('body'))
  4620. .css('position', 'absolute').css('margin-left', 0 + 'px').css('margin-top', 0 + 'px');
  4621. var handleScroll = function() {
  4622. $axure(function(diagramObject) { return diagramObject.fixedVertical; })
  4623. .each(function(diagramObject, elementId) {
  4624. var win = $(window);
  4625. var windowWidth = win.width();
  4626. var windowHeight = win.height();
  4627. var windowScrollLeft = win.scrollLeft();
  4628. var windowScrollTop = win.scrollTop();
  4629. var newLeft = 0;
  4630. var newTop = 0;
  4631. var elementQuery = $('#' + elementId);
  4632. var elementAxQuery = $ax('#' + elementId);
  4633. var width = elementAxQuery.width();
  4634. var height = elementAxQuery.height();
  4635. var horz = diagramObject.fixedHorizontal;
  4636. if(horz == 'left') {
  4637. newLeft = windowScrollLeft + diagramObject.fixedMarginHorizontal;
  4638. } else if(horz == 'center') {
  4639. newLeft = windowScrollLeft + ((windowWidth - width) / 2) + diagramObject.fixedMarginHorizontal;
  4640. } else if(horz == 'right') {
  4641. newLeft = windowScrollLeft + windowWidth - width - diagramObject.fixedMarginHorizontal;
  4642. }
  4643. var vert = diagramObject.fixedVertical;
  4644. if(vert == 'top') {
  4645. newTop = windowScrollTop + diagramObject.fixedMarginVertical;
  4646. } else if(vert == 'middle') {
  4647. newTop = windowScrollTop + ((windowHeight - height) / 2) + diagramObject.fixedMarginVertical;
  4648. } else if(vert == 'bottom') {
  4649. newTop = windowScrollTop + windowHeight - height - diagramObject.fixedMarginVertical;
  4650. }
  4651. elementQuery.css('top', newTop + 'px').css('left', newLeft + 'px');
  4652. });
  4653. };
  4654. $(window).scroll(handleScroll);
  4655. $axure.resize(handleScroll);
  4656. handleScroll();
  4657. };
  4658. var _applyBackground = function() {
  4659. if(Number(BROWSER_VERSION) >= 9) return;
  4660. var styleChain = $ax.adaptive.getAdaptiveIdChain($ax.adaptive.currentViewId);
  4661. var argb = _getArgb($ax.pageData.page, styleChain);
  4662. var hexColor = _getHexColor(argb, false);
  4663. if(hexColor) $('body').css('background-color', hexColor);
  4664. _applyBackgroundToQuery($ax('*'));
  4665. };
  4666. var _applyBackgroundToQuery = function(query) {
  4667. if(Number(BROWSER_VERSION) >= 9) return;
  4668. var styleChain = $ax.adaptive.getAdaptiveIdChain($ax.adaptive.currentViewId);
  4669. query.each(function(obj, elementId) {
  4670. if ($ax.public.fn.IsDynamicPanel(obj.type)) {
  4671. var stateCount = obj.diagrams.length;
  4672. for(var j = 0; j < stateCount; j++) {
  4673. var stateId = $ax.repeater.applySuffixToElementId(elementId, '_state' + j);
  4674. var argb = _getArgb(obj.diagrams[j], styleChain);
  4675. var hexColor = _getHexColor(argb, true);
  4676. if(hexColor) $jobj(stateId).css('background-color', hexColor);
  4677. }
  4678. } else if ($ax.public.fn.IsRepeater(obj.type)) {
  4679. }
  4680. });
  4681. };
  4682. _ieColorManager.applyBackground = _applyBackgroundToQuery;
  4683. var _getArgb = function(diagram, styleChain) {
  4684. var argb = undefined;
  4685. for(var i = 0; i < styleChain.length && !argb; i++) {
  4686. var style = diagram.adaptiveStyles[styleChain[i]];
  4687. argb = style.fill && style.fill.color;
  4688. }
  4689. if(!argb) argb = diagram.style.fill.color;
  4690. return argb;
  4691. };
  4692. var gMult = 256;
  4693. var rMult = gMult * 256;
  4694. var aMult = rMult * 256;
  4695. var _getHexColor = function(argb, allowWhite) {
  4696. var a = Math.floor(argb / aMult);
  4697. argb -= a * aMult;
  4698. var r = Math.floor(argb / rMult);
  4699. argb -= r * rMult;
  4700. var g = Math.floor(argb / gMult);
  4701. var b = argb - g * gMult;
  4702. return _getColorFromArgb(a, r, g, b, allowWhite);
  4703. };
  4704. var _getColorFromArgb = function(a, r, g, b, allowWhite) {
  4705. if(Number(BROWSER_VERSION) >= 9) return undefined;
  4706. //convert the color with alpha to a color with no alpha (assuming white background)
  4707. r = Math.min((r * a) / 255 + 255 - a, 255);
  4708. g = Math.min((g * a) / 255 + 255 - a, 255);
  4709. b = Math.min((b * a) / 255 + 255 - a, 255);
  4710. if(a == 0) return undefined;
  4711. if(!allowWhite && (r == 255 && g == 255 && b == 255)) return undefined;
  4712. var color = '#';
  4713. color += Math.floor(r / 16).toString(16);
  4714. color += Math.floor(r % 16).toString(16);
  4715. color += Math.floor(g / 16).toString(16);
  4716. color += Math.floor(g % 16).toString(16);
  4717. color += Math.floor(b / 16).toString(16);
  4718. color += Math.floor(b % 16).toString(16);
  4719. return color;
  4720. };
  4721. _ieColorManager.getColorFromArgb = _getColorFromArgb;
  4722. var getIEOffset = function(transform, rect) {
  4723. var translatedVertexes = [
  4724. $axure.utils.Vector2D(0, 0), //we dont translate, so the orgin is fixed
  4725. transform.mul($axure.utils.Vector2D(0, rect.height)),
  4726. transform.mul($axure.utils.Vector2D(rect.width, 0)),
  4727. transform.mul($axure.utils.Vector2D(rect.width, rect.height))];
  4728. var minX = 0, minY = 0, maxX = 0, maxY = 0;
  4729. $.each(translatedVertexes, function(index, p) {
  4730. minX = Math.min(minX, p.x);
  4731. minY = Math.min(minY, p.y);
  4732. maxX = Math.max(maxX, p.x);
  4733. maxY = Math.max(maxY, p.y);
  4734. });
  4735. return $axure.utils.Vector2D(
  4736. (maxX - minX - rect.width) / 2,
  4737. (maxY - minY - rect.height) / 2);
  4738. };
  4739. var _filterFromTransform = function(transform) {
  4740. return "progid:DXImageTransform.Microsoft.Matrix(M11=" + transform.m11 +
  4741. ", M12=" + transform.m12 + ", M21=" + transform.m21 +
  4742. ", M22=" + transform.m22 + ", SizingMethod='auto expand')";
  4743. };
  4744. var _applyIERotation = function() {
  4745. if(Number(BROWSER_VERSION) >= 9) return;
  4746. $axure(function(diagramObject) {
  4747. return ((diagramObject.style.rotation && Math.abs(diagramObject.style.rotation) > 0.1)
  4748. || (diagramObject.style.textRotation && Math.abs(diagramObject.style.textRotation) > 0.1))
  4749. && !diagramObject.isContained;
  4750. }).each(function(diagramObject, elementId) {
  4751. var rotation = diagramObject.style.rotation || 0;
  4752. var $element = $('#' + elementId);
  4753. var axElement = $ax('#' + elementId);
  4754. var width = axElement.width();
  4755. var height = axElement.height();
  4756. var originX = width / 2;
  4757. var originY = height / 2;
  4758. var shapeIeOffset;
  4759. $element.children().each(function() {
  4760. var $child = $(this);
  4761. var axChild = $ax('#' + $child.attr('id'));
  4762. var childWidth = axChild.width();
  4763. var childHeight = axChild.height() + $child.position().top;
  4764. var centerX = $child.position().left + (childWidth / 2);
  4765. var centerY = $child.position().top + (childHeight / 2);
  4766. var deltaX = centerX - originX;
  4767. var deltaY = centerY - originY;
  4768. var effectiveRotation = rotation;
  4769. var textObject = $ax.getObjectFromElementId($child.attr('id'));
  4770. if(textObject) {
  4771. if(textObject.style.textRotation) effectiveRotation = textObject.style.textRotation;
  4772. else return;
  4773. }
  4774. var transform = $ax.utils.Matrix2D.identity().rotate(effectiveRotation);
  4775. var filter = _filterFromTransform(transform);
  4776. $child.css('filter', filter)
  4777. .width(childWidth + 1)
  4778. .height(childHeight + 1);
  4779. var p = transform.mul($ax.utils.Vector2D(deltaX, deltaY));
  4780. var ieOffset = getIEOffset(transform, { width: childWidth, height: childHeight });
  4781. if(!textObject) {
  4782. shapeIeOffset = ieOffset;
  4783. } else {
  4784. // This is a close approximation, but not exact
  4785. if(diagramObject.style.verticalAlignment != 'top') ieOffset.y -= shapeIeOffset.y + Math.abs(shapeIeOffset.x);
  4786. }
  4787. $child.css("margin-left", -ieOffset.x - deltaX + p.x).css("margin-top", -ieOffset.y - deltaY + p.y);
  4788. });
  4789. });
  4790. };
  4791. var _fixIEStretchBackground = function() {
  4792. if(Number(BROWSER_VERSION) >= 9) return;
  4793. var pageStyle = $ax.adaptive.getPageStyle();
  4794. if(!pageStyle.imageRepeat || pageStyle.imageRepeat == 'auto') return;
  4795. $('body').css('background-image', 'none');
  4796. var viewId = $ax.adaptive.currentViewId;
  4797. var imageInfo = viewId ? $ax.pageData.viewIdToBackgroundImageInfo && $ax.pageData.viewIdToBackgroundImageInfo[viewId] : $ax.pageData.defaultBackgroundImageInfo;
  4798. if(imageInfo && imageInfo.path) {
  4799. if($('#bg_img').length == 0) $('body').append('<img id="bg_img"/>');
  4800. $('#bg_img').attr('src', imageInfo.path).css('position', 'fixed').css('z-index', '-10000');
  4801. _resizeIEBackground();
  4802. } else $('#bg_img').remove();
  4803. };
  4804. var _resizeIEBackground = function() {
  4805. if(Number(BROWSER_VERSION) >= 9) return;
  4806. //var page = $ax.pageData.page;
  4807. var viewId = $ax.adaptive.currentViewId;
  4808. var pageStyle = $ax.adaptive.getPageStyle();
  4809. if(!$ax.pageData.defaultBackgroundImageInfo && !$ax.pageData.viewIdToBackgroundImageInfo) return;
  4810. var imageInfo = viewId ? $ax.pageData.viewIdToBackgroundImageInfo[viewId] : $ax.pageData.defaultBackgroundImageInfo;
  4811. if(!imageInfo) return;
  4812. var imageWidth = imageInfo.width;
  4813. var imageHeight = imageInfo.height;
  4814. var windowWidth = $(window).width();
  4815. var windowHeight = $(window).height();
  4816. var isCover = pageStyle.imageRepeat == 'cover';
  4817. var wRatio = windowWidth / imageWidth;
  4818. var hRatio = windowHeight / imageHeight;
  4819. var ratio = wRatio;
  4820. if(isCover) {
  4821. if(hRatio > wRatio) ratio = hRatio;
  4822. } else {
  4823. if(hRatio < wRatio) ratio = hRatio;
  4824. }
  4825. var width = imageWidth * ratio;
  4826. var height = imageHeight * ratio;
  4827. var left = '0px';
  4828. if((isCover && width > windowWidth) || (!isCover && width < windowWidth)) {
  4829. if(pageStyle.imageHorizontalAlignment == 'center') {
  4830. left = ((windowWidth - width) / 2) + 'px';
  4831. } else if(pageStyle.imageHorizontalAlignment == 'far') {
  4832. left = (windowWidth - width) + 'px';
  4833. }
  4834. }
  4835. var top = '0px';
  4836. if((isCover && height > windowHeight) || (!isCover && height < windowHeight)) {
  4837. if(pageStyle.imageVerticalAlignment == 'center') {
  4838. top = ((windowHeight - height) / 2) + 'px';
  4839. } else if(pageStyle.imageVerticalAlignment == 'far') {
  4840. top = (windowHeight - height) + 'px';
  4841. }
  4842. }
  4843. $('#bg_img').css('top', top).css('left', left).css('width', width).css('height', height);
  4844. };
  4845. var _fixAllPngs = function() {
  4846. if(!(/MSIE ((5\.5)|6)/.test(window.navigator.userAgent) && window.navigator.platform == "Win32")) return;
  4847. $('img[src$=".png"]').each(function() {
  4848. if(!this.complete) {
  4849. this.onload = function() { $axure.utils.fixPng(this); };
  4850. } else {
  4851. $axure.utils.fixPng(this);
  4852. }
  4853. });
  4854. };
  4855. var _fixInputSize = function() {
  4856. if(Number(BROWSER_VERSION) >= 8 || window.navigator.userAgent.indexOf("Trident/4.0") > -1) return;
  4857. var inputs = $('input').not(':input[type=button], :input[type=submit], :input[type=radio], :input[type=checkbox]');
  4858. inputs.each(function() {
  4859. var $input = $(this);
  4860. var axInput = $ax('#' + $input.attr('id'));
  4861. $input.css('height', (axInput.height() - 4 + 'px')).css('width', (axInput.width() - 2 + 'px'));
  4862. });
  4863. var textAreas = $($ax.constants.TEXT_AREA_TYPE);
  4864. textAreas.each(function() {
  4865. var $textArea = $(this);
  4866. var axText = $ax('#' + $textArea.attr('id'));
  4867. $textArea.css('height', (axText.height() - 6 + 'px')).css('width', (axText.width() - 6 + 'px'));
  4868. });
  4869. };
  4870. var _fixInputBackground = function() {
  4871. var inputs = $('input').not(':input[type=button], :input[type=submit], :input[type=radio], :input[type=checkbox]');
  4872. inputs = inputs.add($($ax.constants.TEXT_AREA_TYPE));
  4873. inputs.each(function() {
  4874. var $input = $(this);
  4875. if($input.css('background-color') == 'transparent') {
  4876. $input.css('background-image', 'url(../../transparent.gif)');
  4877. } else {
  4878. $input.css('background-image', '');
  4879. }
  4880. });
  4881. };
  4882. $(document).ready(function() {
  4883. _fixIEStretchBackground();
  4884. _applyIEFixedPosition();
  4885. $axure.resize(function() {
  4886. _resizeIEBackground();
  4887. });
  4888. $ax.adaptive.bind('viewChanged', function() {
  4889. _fixIEStretchBackground();
  4890. _applyBackground();
  4891. _fixInputBackground();
  4892. });
  4893. _fixAllPngs();
  4894. _applyIERotation();
  4895. _applyBackground();
  4896. _fixInputSize();
  4897. _fixInputBackground();
  4898. });
  4899. });
  4900. //***** model.js *****//
  4901. // ******* Object Model ******** //
  4902. $axure.internal(function($ax) {
  4903. var _implementations = {};
  4904. var _initializeObject = function(type, obj) {
  4905. $.extend(obj, _implementations[type]);
  4906. };
  4907. $ax.initializeObject = _initializeObject;
  4908. var _model = $ax.model = {};
  4909. _model.idsInRdoToHideOrLimbo = function(rdoId, scriptIds) {
  4910. var rdoScriptId = $ax.repeater.getScriptIdFromElementId(rdoId);
  4911. var path = $ax.getPathFromScriptId(rdoScriptId);
  4912. if(!scriptIds) scriptIds = [];
  4913. var rdo = $ax.getObjectFromElementId(rdoId);
  4914. var master = $ax.pageData.masters[rdo.masterId];
  4915. var masterChildren = master.diagram.objects;
  4916. for(var i = 0; i < masterChildren.length; i++) {
  4917. var obj = masterChildren[i];
  4918. var objScriptIds = obj.scriptIds;
  4919. for(var j = 0; j < objScriptIds.length; j++) {
  4920. var scriptId = objScriptIds[j];
  4921. // Anything in a layer is already handled by the layer
  4922. if($ax.getLayerParentFromElementId(scriptId)) continue;
  4923. // Make sure in same rdo
  4924. var elementPath = $ax.getPathFromScriptId(scriptId);
  4925. // This is because last part of path is for the obj itself.
  4926. elementPath.pop();
  4927. if(elementPath.length != path.length) continue;
  4928. var samePath = true;
  4929. for(var k = 0; k < path.length; k++) {
  4930. if(elementPath[k] != path[k]) {
  4931. samePath = false;
  4932. break;
  4933. }
  4934. }
  4935. if(!samePath) continue;
  4936. if($ax.public.fn.IsReferenceDiagramObject(obj.type)) _model.idsInRdoToHideOrLimbo(scriptId, scriptIds);
  4937. else if(scriptIds.indexOf(scriptId) == -1) scriptIds.push(scriptId);
  4938. break;
  4939. }
  4940. }
  4941. return scriptIds;
  4942. };
  4943. });
  4944. //***** repeater.js *****//
  4945. // ******* Repeater MANAGER ******** //
  4946. $axure.internal(function($ax) {
  4947. var _repeaterManager = {};
  4948. $ax.repeater = _repeaterManager;
  4949. var _refreshType = _repeaterManager.refreshType = {
  4950. reset: 1,
  4951. persist: 2,
  4952. preEval: 3
  4953. };
  4954. //This is a mapping of current editItems
  4955. var repeaterToEditItems = {};
  4956. //This is a mapping of current filters
  4957. var repeaterToFilters = {};
  4958. // This is a mapping of current sorts
  4959. var repeaterToSorts = {};
  4960. // This is a mapping of repeater page info
  4961. var repeaterToPageInfo = {};
  4962. //Hopefully this can be simplified, but for now I think 3 are needed.
  4963. //This is the data set that is owned by this repeater. The repeater may or may not reference this data set, and others can reference it.
  4964. var repeaterToLocalDataSet = {};
  4965. //This is the data set referenced by the repeater. It is not a copy of the local data set, but a reference to a local data set (or eventually a global data set could be referenced).
  4966. var repeaterToCurrentDataSet = {};
  4967. //This is a copy of the current data set, that is replaced whenever a set or refresh is done.
  4968. var repeaterToActiveDataSet = {};
  4969. var _loadRepeaters = function() {
  4970. $ax(function(obj) {
  4971. return $ax.public.fn.IsRepeater(obj.type);
  4972. }).each(function(obj, repeaterId) {
  4973. repeaterToLocalDataSet[repeaterId] = $ax.deepCopy(obj.data);
  4974. repeaterToLocalDataSet[repeaterId].props = obj.dataProps;
  4975. repeaterToEditItems[repeaterId] = [];
  4976. _initPageInfo(obj, repeaterId);
  4977. _setRepeaterDataSet(repeaterId, repeaterId);
  4978. var initialItemIds = obj.repeaterPropMap.itemIds;
  4979. for (var i = 0; i < initialItemIds.length; i++) $ax.addItemIdToRepeater(initialItemIds[i], repeaterId);
  4980. $ax.visibility.initRepeater(repeaterId);
  4981. });
  4982. };
  4983. _repeaterManager.load = _loadRepeaters;
  4984. var fullRefresh = {};
  4985. var repeatersReady = false;
  4986. var _initRepeaters = function () {
  4987. repeatersReady = true;
  4988. $ax(function(obj, repeaterId) {
  4989. return $ax.public.fn.IsRepeater(obj.type);
  4990. }).each(function(obj, repeaterId) {
  4991. _refreshRepeater(repeaterId, undefined, _refreshType.reset, !fullRefresh[repeaterId]);
  4992. //// Fix selected and default if necessary
  4993. //var states = obj.evaluatedStates[repeaterId];
  4994. //if(!states) return; // If there are no evaluated states the repeater id key could not be mapped to an array of states.
  4995. //for(var i = 0; i < states.length; i++) {
  4996. // var state = states[i];
  4997. // $ax.style.SetWidgetEnabled(state.id, true); // So selected will take place. If disabled, selected wouldn't happen.
  4998. // $ax.style.SetWidgetSelected(state.id, state.selected);
  4999. // $ax.style.SetWidgetEnabled(state.id, !state.disabled);
  5000. //}
  5001. });
  5002. };
  5003. _repeaterManager.initRefresh = _initRepeaters;
  5004. var repeatersHaveNewDataSet = [];
  5005. var _setRepeaterDataSet = function(repeaterId, dataSetId) {
  5006. //TODO: No idea about how global data sets will be handled...
  5007. repeaterToCurrentDataSet[repeaterId] = repeaterToLocalDataSet[dataSetId];
  5008. repeaterToActiveDataSet[repeaterId] = getActiveDataSet(repeaterId);
  5009. repeaterToFilters[repeaterId] = [];
  5010. repeaterToSorts[repeaterId] = [];
  5011. // Not using this currently
  5012. // if(repeatersHaveNewDataSet.indexOf(repeaterId) == -1) repeatersHaveNewDataSet[repeatersHaveNewDataSet.length] = repeaterId;
  5013. };
  5014. _repeaterManager.setDataSet = _setRepeaterDataSet;
  5015. var _refreshRepeater = function(repeaterId, eventInfo, refreshType, itemsPregen) {
  5016. if(!refreshType) refreshType = _refreshType.reset; // Set default
  5017. if(!repeatersReady) {
  5018. fullRefresh[repeaterId] = true;
  5019. return;
  5020. }
  5021. // Reset selected/disabled dictionaries upon reset, if necessary (reset must, persist can't, and preeval doesn't care because it hasn't been set up yet.
  5022. if(refreshType == _refreshType.reset) $ax.style.clearStateForRepeater(repeaterId);
  5023. // Don't show if you have a parent rdos thats limboed.
  5024. var rdoPath = $ax.getPathFromScriptId(repeaterId);
  5025. // Check each parent rdo through appropriate views to see if you are limboed
  5026. while (rdoPath.length > 0) {
  5027. if(!$ax.getScriptIdFromPath(rdoPath)) {
  5028. removeItems(repeaterId);
  5029. return;
  5030. }
  5031. $ax.splice(rdoPath, rdoPath.length - 1, 1);
  5032. }
  5033. $ax.action.refreshStart(repeaterId);
  5034. $ax.style.ClearCacheForRepeater(repeaterId);
  5035. if($ax.visibility.limboIds[repeaterId]) {
  5036. removeItems(repeaterId);
  5037. $ax.dynamicPanelManager.fitParentPanel(repeaterId);
  5038. return;
  5039. }
  5040. // Remove delete map if there is one at this point
  5041. if(eventInfo && eventInfo.repeaterDeleteMap) delete eventInfo.repeaterDeleteMap[repeaterId];
  5042. var path = $ax.getPathFromScriptId(repeaterId);
  5043. path.pop();
  5044. if(eventInfo) {
  5045. eventInfo = $ax.eventCopy(eventInfo);
  5046. }
  5047. var obj = $ax.getObjectFromScriptId(repeaterId);
  5048. var propMap = obj.repeaterPropMap;
  5049. //If there is no wrap, then set it to be above the number of rows
  5050. var viewId = $ax.adaptive.currentViewId || '';
  5051. var wrap = _getAdaptiveProp(propMap, 'wrap', viewId);
  5052. var vertical = _getAdaptiveProp(propMap, 'vertical', viewId);
  5053. var offset = propMap[viewId];
  5054. // Right now pregen only works for default adaptive view
  5055. if(viewId) itemsPregen = false;
  5056. var orderedIds = [];
  5057. if(itemsPregen) {
  5058. var repeaterChildren = $jobj(repeaterId).children();
  5059. // Start at 1 to skip script div child
  5060. for(var i = 1; i < repeaterChildren.length; i++) {
  5061. orderedIds.push(_getItemIdFromElementId($(repeaterChildren[i]).attr('id')));
  5062. }
  5063. } else orderedIds = getOrderedIds(repeaterId, eventInfo);
  5064. var ids = [];
  5065. var background = _getAdaptiveProp(propMap, 'backColor', viewId);
  5066. var hasAltColor = _getAdaptiveProp(propMap, 'hasAltColor', viewId);
  5067. var altColor = hasAltColor ? _getAdaptiveProp(propMap, 'altColor', viewId) : undefined;
  5068. var useAlt = false;
  5069. if(itemsPregen) {
  5070. var start = 0;
  5071. var end = orderedIds.length;
  5072. } else {
  5073. var bounds = _getVisibleDataBounds(repeaterToPageInfo[repeaterId], itemsPregen ? obj.data.length : orderedIds.length);
  5074. start = bounds[0];
  5075. end = bounds[1];
  5076. }
  5077. var repeaterObj = $jobj(repeaterId);
  5078. var preevalMap = {};
  5079. if(itemsPregen) {
  5080. var templateIds = [repeaterId];
  5081. var processScriptIds = function (full, prop, id) {
  5082. if(id.indexOf('_') <= 0 && id.indexOf('p') == -1) templateIds.push('u' + id);
  5083. };
  5084. $('#' + repeaterId + '_script').html().replace(/(id|for)="?u([0-9]+(p([0-9]){3})?(_[_a-z0-9]*)?)"?/g, processScriptIds);
  5085. for(var i = 0; i < templateIds.length; i++) {
  5086. for(var j = 0; j < orderedIds.length; j++) {
  5087. ids.push(_createElementId(templateIds[i], orderedIds[j]));
  5088. }
  5089. }
  5090. for(var pos = start; pos < end; pos++) {
  5091. var itemId = orderedIds[pos];
  5092. itemElementId = _createElementId(repeaterId, itemId);
  5093. var jobj = $jobj(itemElementId);
  5094. if(jobj.hasClass('preeval')) refreshType = _refreshType.preEval;
  5095. for(var i = 0; i < templateIds.length; i++) $ax.initializeObjectEvents($ax('#' + _createElementId(templateIds[i], itemId)), refreshType);
  5096. if(refreshType == _refreshType.preEval) {
  5097. preevalMap[itemId] = true;
  5098. jobj.removeClass('preeval');
  5099. }
  5100. }
  5101. } else {
  5102. var html = $('#' + repeaterId + '_script').html();
  5103. // var container = $('<div></div>');
  5104. // container.html(html);
  5105. // container.attr('id', '' + repeaterId + '_container');
  5106. // container.css({ position: 'absolute' });
  5107. // container.offset({ left: -obj.x, top: -obj.y });
  5108. var div = $('<div></div>');
  5109. div.html(html);
  5110. div.find('.' + $ax.visibility.HIDDEN_CLASS).removeClass($ax.visibility.HIDDEN_CLASS);
  5111. div.find('.' + $ax.visibility.UNPLACED_CLASS).removeClass($ax.visibility.UNPLACED_CLASS);
  5112. var paddingTop = _getAdaptiveProp(propMap, 'paddingTop', viewId);
  5113. var paddingLeft = _getAdaptiveProp(propMap, 'paddingLeft', viewId);
  5114. var paddingY = paddingTop + _getAdaptiveProp(propMap, 'paddingBottom', viewId);
  5115. var paddingX = paddingLeft + _getAdaptiveProp(propMap, 'paddingRight', viewId);
  5116. var spacingX = _getAdaptiveProp(propMap, 'horizontalSpacing', viewId);
  5117. var xOffset = offset.width + spacingX;
  5118. var spacingY = _getAdaptiveProp(propMap, 'verticalSpacing', viewId);
  5119. var yOffset = offset.height + spacingY;
  5120. div.css({
  5121. width: offset.width,
  5122. height: offset.height
  5123. });
  5124. _applyColorCss(background, div);
  5125. var altDiv = div;
  5126. if(hasAltColor) altDiv = _applyColorCss(altColor, div.clone());
  5127. // Hide repeater, if shown, while updating.
  5128. var shown = $ax.visibility.IsIdVisible(repeaterId);
  5129. if(shown) document.getElementById(repeaterId).style.visibility = 'hidden';
  5130. //clean up old items as late as possible
  5131. removeItems(repeaterId);
  5132. resetItemSizes(repeaterId, offset, bounds, orderedIds, vertical, wrap);
  5133. var i = 0;
  5134. var startTop = paddingTop;
  5135. var startLeft = paddingLeft;
  5136. if(repeaterObj.css('box-sizing') == 'border-box') {
  5137. startTop -= $ax.getNumFromPx(repeaterObj.css('border-top-width')) || 0;
  5138. startLeft -= $ax.getNumFromPx(repeaterObj.css('border-left-width')) || 0;
  5139. }
  5140. var top = startTop;
  5141. var left = startLeft;
  5142. for(pos = start; pos < end; pos++) {
  5143. itemId = orderedIds[pos];
  5144. var itemElementId = _createElementId(repeaterId, itemId);
  5145. $ax.addItemIdToRepeater(itemId, repeaterId);
  5146. ids.push(itemElementId);
  5147. var processId = function(full, prop, id) {
  5148. var elementId = _createElementId('u' + id, itemId);
  5149. //If there is a suffix (ex. _img), then don't push the id.
  5150. if (id.indexOf('_') <= 0 && id.indexOf('p') == -1) ids.push(elementId);
  5151. return prop + '="' + elementId + '"';
  5152. };
  5153. var copy = (useAlt ? altDiv : div).clone();
  5154. useAlt = !useAlt;
  5155. copy.attr('id', itemElementId);
  5156. copy.html(div.html().replace(/(id|for)="?u([0-9]+(p([0-9]){3})?(_[_a-z0-9]*)?)"?/g, processId));
  5157. if(obj.repeaterPropMap.isolateRadio) {
  5158. var radioButtons = copy.find(':radio');
  5159. for(var radioIndex = 0; radioIndex < radioButtons.length; radioIndex++) {
  5160. var radio = $(radioButtons[radioIndex]);
  5161. var oldName = radio.attr('name') || '';
  5162. // Can't use create element id because there could be an underscore in name
  5163. if(oldName) radio.attr('name', oldName + '-' + itemId);
  5164. }
  5165. }
  5166. copy.css({
  5167. 'position': 'absolute',
  5168. 'top': top + 'px',
  5169. 'left': left + 'px',
  5170. 'width': obj.width + 'px',
  5171. 'height': obj.height + 'px'
  5172. });
  5173. $('#' + repeaterId).append(copy);
  5174. i++;
  5175. if(wrap != -1 && i % wrap == 0) {
  5176. if(vertical) {
  5177. top = startTop;
  5178. left += xOffset;
  5179. } else {
  5180. left = startLeft;
  5181. top += yOffset;
  5182. }
  5183. } else if (vertical) top += yOffset;
  5184. else left += xOffset;
  5185. }
  5186. var shownCount = end - start;
  5187. var repeaterSize = { width: paddingX, height: paddingY};
  5188. if(shownCount > 0) {
  5189. var primaryCount = wrap == -1 ? shownCount : Math.min(shownCount, wrap);
  5190. var secondaryCount = wrap == -1 ? 1 : Math.ceil(shownCount / wrap);
  5191. var widthCount = vertical ? secondaryCount : primaryCount;
  5192. var heightCount = vertical ? primaryCount : secondaryCount;
  5193. repeaterSize.width += offset.width + (widthCount - 1) * xOffset;
  5194. repeaterSize.height += offset.height + (heightCount - 1) * yOffset;
  5195. }
  5196. repeaterObj.css(repeaterSize);
  5197. // Had to move this here because it sets up cursor: pointer on inline links,
  5198. // but must be done before style cached when adaptive view is set.
  5199. // TODO: Should be able to combine this with initialization done in pregen items. Just need to have ids and template ids be the same.
  5200. for (var i = 0; i < ids.length; i++) {
  5201. var id = ids[i];
  5202. var childJobj = $jobj(id);
  5203. if (obj.repeaterPropMap.isolateSelection && childJobj.attr('selectiongroup')) {
  5204. childJobj.attr('selectiongroup', _createElementId(childJobj.attr('selectiongroup'), _getItemIdFromElementId(id)));
  5205. }
  5206. $ax.initializeObjectEvents($ax('#' + id), refreshType);
  5207. }
  5208. }
  5209. var query = _getItemQuery(repeaterId);
  5210. if(viewId) $ax.adaptive.applyView(viewId, query);
  5211. else $ax.visibility.resetLimboAndHiddenToDefaults(_getItemQuery(repeaterId, preevalMap));
  5212. $ax.annotation.InitializeAnnotations(query);
  5213. for(var index = 0; index < ids.length; index++) {
  5214. id = ids[index];
  5215. if ($ax.ieColorManager) $ax.ieColorManager.applyBackground($ax('#' + id));
  5216. $ax.style.initializeObjectTextAlignment($ax('#' + id));
  5217. $ax.applyHighlight($ax('#' + id), true);
  5218. }
  5219. $ax.messageCenter.startCombineEventMessages();
  5220. $ax.cacheRepeaterInfo(repeaterId, $ax.getWidgetInfo(repeaterId));
  5221. // Now load
  5222. for(pos = start; pos < end; pos++) {
  5223. itemId = orderedIds[pos];
  5224. itemElementId = _createElementId(repeaterId, itemId);
  5225. if(!preevalMap[orderedIds[pos]]) $ax.event.raiseSyntheticEvent(itemElementId, 'onItemLoad', true);
  5226. $ax.loadDynamicPanelsAndMasters(obj.objects, path, itemId);
  5227. }
  5228. $ax.removeCachedRepeaterInfo(repeaterId);
  5229. $ax.messageCenter.endCombineEventMessages();
  5230. // Reshow repeater if it was originally shown (load is complete by now)
  5231. if(shown && !itemsPregen) document.getElementById(repeaterId).style.visibility = 'inherit';
  5232. $ax.dynamicPanelManager.fitParentPanel(repeaterId);
  5233. // Need to reapply the state style after refresh for text styles, and for applying a non-default style that wasn't reset for certain refreshes (adaptive changed for example). This could be way more selective but doing a safe change for the moment
  5234. if(refreshType != _refreshType.preEval) $ax.style.updateStateClass(repeaterId);
  5235. // Right now we assume only one refresh at a time. If we can manually trigger refreshes, that may possibly change.
  5236. $ax.action.refreshEnd();
  5237. };
  5238. _repeaterManager.refreshRepeater = _refreshRepeater;
  5239. var _getItemQuery = function(repeaterId, preevalMap) {
  5240. var query = $ax(function (diagramObject, elementId) {
  5241. // Also need to check that this in not preeval
  5242. if(preevalMap) {
  5243. var itemId = _getItemIdFromElementId(elementId);
  5244. if(preevalMap[itemId]) return false;
  5245. }
  5246. // All objects with the repeater as their parent, except the repeater itself.
  5247. var scriptId = _getScriptIdFromElementId(elementId);
  5248. return $ax.getParentRepeaterFromScriptId(scriptId) == repeaterId && scriptId != repeaterId;
  5249. });
  5250. return query;
  5251. }
  5252. _repeaterManager.refreshAllRepeaters = function() {
  5253. $ax('*').each(function(diagramObject, elementId) {
  5254. if(!$ax.public.fn.IsRepeater(diagramObject.type)) return;
  5255. if($ax.visibility.isElementIdLimboOrInLimboContainer(elementId)) return;
  5256. _initPageInfo(diagramObject, elementId);
  5257. _refreshRepeater(elementId, $ax.getEventInfoFromEvent($ax.getjBrowserEvent()), _refreshType.persist);
  5258. });
  5259. };
  5260. _repeaterManager.refreshRepeaters = function(ids, eventInfo) {
  5261. for(var i = 0; i < ids.length; i++) _refreshRepeater(ids[i], eventInfo);
  5262. };
  5263. var _initPageInfo = function(obj, elementId) {
  5264. var pageInfo = {};
  5265. var map = obj.repeaterPropMap;
  5266. var currentViewId = $ax.adaptive.currentViewId || '';
  5267. var itemsPerPage = _getAdaptiveProp(map, 'itemsPerPage', currentViewId);
  5268. if(itemsPerPage == -1) pageInfo.noLimit = true;
  5269. else {
  5270. pageInfo.itemsPerPage = itemsPerPage;
  5271. pageInfo.currPage = _getAdaptiveProp(map, 'currPage', currentViewId);
  5272. }
  5273. repeaterToPageInfo[elementId] = pageInfo;
  5274. };
  5275. _repeaterManager.initialize = function() {
  5276. $ax(function (obj) {
  5277. return $ax.public.fn.IsRepeater(obj.type);
  5278. }).each(function (obj, repeaterId) {
  5279. _initPregen(repeaterId);
  5280. });
  5281. }
  5282. var _initPregen = function(repeaterId) {
  5283. var obj = $ax.getObjectFromScriptId(repeaterId);
  5284. var propMap = obj.repeaterPropMap;
  5285. //If there is no wrap, then set it to be above the number of rows
  5286. var viewId = $ax.adaptive.currentViewId || '';
  5287. var wrap = _getAdaptiveProp(propMap, 'wrap', viewId);
  5288. var vertical = _getAdaptiveProp(propMap, 'vertical', viewId);
  5289. var orderedIds = [];
  5290. var ids = [];
  5291. var background = _getAdaptiveProp(propMap, 'backColor', viewId);
  5292. var hasAltColor = _getAdaptiveProp(propMap, 'hasAltColor', viewId);
  5293. var altColor = hasAltColor ? _getAdaptiveProp(propMap, 'altColor', viewId) : undefined;
  5294. var useAlt = false;
  5295. var bounds = _getVisibleDataBounds(repeaterToPageInfo[repeaterId], obj.data.length);
  5296. var start = bounds[0];
  5297. var end = bounds[1];
  5298. // Starts empty
  5299. if(start == end) {
  5300. $ax.action.refreshEnd(repeaterId);
  5301. return;
  5302. }
  5303. var unprocessedBaseIds = $jobj($ax.repeater.createElementId(repeaterId, start + 1)).html().match(/(id|for)="?u([0-9]+)/g);
  5304. var baseIds = [];
  5305. if(unprocessedBaseIds) {
  5306. for(var i = 0; i < unprocessedBaseIds.length; i++) {
  5307. var val = unprocessedBaseIds[i].split('=')[1].substr(1);
  5308. if(baseIds.indexOf(val) == -1) baseIds.push(val);
  5309. }
  5310. }
  5311. for(var itemNum = start; itemNum < end; itemNum++) {
  5312. ids.push($ax.repeater.createElementId(repeaterId, itemNum + 1));
  5313. for(i = 0; i < baseIds.length; i++) ids.push($ax.repeater.createElementId(baseIds[i], itemNum + 1));
  5314. var itemId = itemNum + 1;
  5315. orderedIds[itemNum] = itemId;
  5316. var itemDiv = $jobj($ax.repeater.createElementId(repeaterId, itemNum + 1));
  5317. _applyColorCss(useAlt ? altColor : background, itemDiv);
  5318. if(hasAltColor) useAlt = !useAlt;
  5319. }
  5320. resetItemSizes(repeaterId, undefined, bounds, orderedIds, vertical, wrap);
  5321. };
  5322. var _applyColorCss = function(json, div) {
  5323. var args = json.r + ', ' + json.g + ', ' + json.b;
  5324. var background = json.a == 0 ? '' : json.a == 1 ? 'rgb(' + args + ')' : 'rgba(' + args + ', ' + json.a + ')';
  5325. if($ax.ieColorManager && json.a != 0 && json.a != 1) {
  5326. var ieColor = $ax.ieColorManager.getColorFromArgb(json.a * 255, json.r, json.g, json.b, true);
  5327. if(ieColor) background = ieColor;
  5328. }
  5329. div.css('background-color', background);
  5330. return div;
  5331. };
  5332. var _getAdaptiveProp = _repeaterManager.getAdaptiveProp = function(map, prop, viewId) {
  5333. var viewChain = $ax.adaptive.getAdaptiveIdChain(viewId);
  5334. for(var i = viewChain.length - 1; i >= 0; i--) {
  5335. viewId = viewChain[i];
  5336. var viewProps = map[viewId];
  5337. if(viewProps.hasOwnProperty(prop)) return viewProps[prop];
  5338. }
  5339. var base = map[''];
  5340. if(base.hasOwnProperty(prop)) return base[prop];
  5341. return map['default'][prop];
  5342. };
  5343. _repeaterManager.getItemCount = function(repeaterId) {
  5344. var data = repeaterToActiveDataSet[repeaterId].length;
  5345. var info = repeaterToPageInfo[repeaterId];
  5346. if(!info.noLimit) {
  5347. var start = Math.min(data, info.itemsPerPage * info.currPage);
  5348. var end = Math.min(data, start + info.itemsPerPage);
  5349. data = end - start;
  5350. }
  5351. return data;
  5352. };
  5353. _repeaterManager.setDisplayProps = function(obj, repeaterId, itemIndex) {
  5354. var data = repeaterToActiveDataSet[repeaterId];
  5355. var info = repeaterToPageInfo[repeaterId];
  5356. var start = 0;
  5357. var end = data.length;
  5358. if(!info.noLimit) {
  5359. start = Math.min(end, info.itemsPerPage * (info.currPage - 1));
  5360. end = Math.min(end, start + info.itemsPerPage);
  5361. }
  5362. var count = end - start;
  5363. var index = -1;
  5364. for(var i = 0; i < count; i++) {
  5365. if(data[start + i].index == itemIndex) index = i + 1;
  5366. }
  5367. if(index == -1) return;
  5368. obj.index = index;
  5369. obj.isfirst = index == 1;
  5370. obj.islast = index == end - start;
  5371. obj.iseven = index % 2 == 0;
  5372. obj.isodd = index % 2 == 1;
  5373. };
  5374. var _getVisibleDataBounds = function(pageInfo, count) {
  5375. var retval = [0, count];
  5376. if(!pageInfo.noLimit) {
  5377. var end = pageInfo.itemsPerPage * pageInfo.currPage;
  5378. var start = end - pageInfo.itemsPerPage;
  5379. // If past the end, move to last page
  5380. if(start >= count) {
  5381. pageInfo.currPage = Math.floor((count - 1) / pageInfo.itemsPerPage) + 1;
  5382. if(pageInfo.currPage <= 0) pageInfo.currPage = 1;
  5383. end = pageInfo.itemsPerPage * pageInfo.currPage;
  5384. start = end - pageInfo.itemsPerPage;
  5385. }
  5386. end = Math.min(end, count);
  5387. retval[0] = start;
  5388. retval[1] = end;
  5389. }
  5390. return retval;
  5391. };
  5392. _repeaterManager.getVisibleDataCount = function(repeaterId) {
  5393. var bounds = _getVisibleDataBounds(repeaterToPageInfo[repeaterId], repeaterToActiveDataSet[repeaterId].length);
  5394. return bounds[1] - bounds[0];
  5395. };
  5396. _repeaterManager.getDataCount = function(repeaterId) {
  5397. return repeaterToCurrentDataSet[repeaterId].length;
  5398. };
  5399. var _getFilteredDataCount = _repeaterManager.getFilteredDataCount = function(repeaterId) {
  5400. return repeaterToActiveDataSet[repeaterId].length;
  5401. };
  5402. _repeaterManager.getPageCount = function(repeaterId) {
  5403. var info = repeaterToPageInfo[repeaterId];
  5404. return info.noLimit ? 1 : Math.ceil(_getFilteredDataCount(repeaterId) / info.itemsPerPage);
  5405. };
  5406. _repeaterManager.getPageIndex = function(repeaterId) {
  5407. var info = repeaterToPageInfo[repeaterId];
  5408. return info.noLimit ? 1 : info.currPage;
  5409. };
  5410. var getActiveDataSet = function(repeaterId) {
  5411. var active = $ax.deepCopy(repeaterToCurrentDataSet[repeaterId]);
  5412. // Set up 1 indexing each item.
  5413. for(var i = 0; i < active.length; i++) active[i].index = i + 1;
  5414. return active;
  5415. };
  5416. var getOrderedIds = function(repeaterId, eventInfo) {
  5417. var data = repeaterToActiveDataSet[repeaterId] = getActiveDataSet(repeaterId);
  5418. // Filter first so less to sort
  5419. applyFilter(repeaterId, data, eventInfo);
  5420. // Sort next
  5421. var sorts = repeaterToSorts[repeaterId] || [];
  5422. if(sorts.length != 0 && data.length > 1) {
  5423. // TODO: Make this generic and factor out if we want to use it elsewhere...
  5424. // Compare is a function that takes 2 arguments, and returns a number. A high number means the second should go first
  5425. // Otherwise the first stays first.
  5426. var mergesort = function(list, start, end, compare) {
  5427. var middle = Math.floor((start + end) / 2);
  5428. if(middle - start > 1) mergesort(list, start, middle, compare);
  5429. if(end - middle > 1) mergesort(list, middle, end, compare);
  5430. var index1 = start;
  5431. var index2 = middle;
  5432. var tempList = [];
  5433. while(index1 < middle && index2 < end) {
  5434. tempList[tempList.length] = list[compare(list[index1], list[index2]) > 0 ? index2++ : index1++];
  5435. }
  5436. while(index1 < middle) tempList[tempList.length] = list[index1++];
  5437. while(index2 < end) tempList[tempList.length] = list[index2++];
  5438. // transfer from temp list to the real list.
  5439. for(var i = 0; i < tempList.length; i++) list[start + i] = tempList[i];
  5440. };
  5441. // Compare is the tie breaking function to us if necessary.
  5442. var getComparator = function(columnName, ascending, type, compare) {
  5443. // If this needs to be sped up, break up into several smaller functions conditioned off of type
  5444. return function(row1, row2) {
  5445. // If column undefined have it be empty string, NaN, or invalid date
  5446. //// If column undefined, no way to measure this, so call it a tie.
  5447. //if(row1[columnName] === undefined || row2[columnName] === undefined) return 0;
  5448. var text1 = (row1[columnName] && row1[columnName].text) || '';
  5449. var text2 = (row2[columnName] && row2[columnName].text) || '';
  5450. // This means we are case insensitive, so lowercase everything to kill casing
  5451. if(type == 'Text') {
  5452. text1 = text1.toLowerCase();
  5453. text2 = text2.toLowerCase();
  5454. }
  5455. //If tied, go to tie breaker
  5456. if(text1 == text2) {
  5457. if(compare) return compare(row1, row2);
  5458. // Actually a tie.
  5459. return 0;
  5460. }
  5461. if(type == 'Text' || type == 'Text (Case Sensitive)') {
  5462. if(text1 < text2 ^ ascending) return 1;
  5463. else return -1;
  5464. } else if(type == 'Number') {
  5465. var num1 = text1 == '' ? NaN : Number(text1);
  5466. var num2 = text2 == '' ? NaN : Number(text2);
  5467. if(isNaN(num1) && isNaN(num2)) return 0;
  5468. if(isNaN(num1) || isNaN(num2)) return isNaN(num1) ? 1 : -1;
  5469. if(num1 < num2 ^ ascending) return 1;
  5470. else return -1;
  5471. } else if(type == 'Date - YYYY-MM-DD' || type == 'Date - MM/DD/YYYY') {
  5472. var func = type == 'Date - YYYY-MM-DD' ? getDate1 : getDate2;
  5473. var date1 = func(text1);
  5474. var date2 = func(text2);
  5475. if(!date1.valid && !date2.valid) return 0;
  5476. if(!date1.valid || !date2.valid) return date1.valid ? -1 : 1;
  5477. var diff = date2.year - date1.year;
  5478. if(diff == 0) diff = date2.month - date1.month;
  5479. if(diff == 0) diff = date2.day - date1.day;
  5480. if(diff == 0) return 0;
  5481. return diff > 0 ^ ascending ? 1 : -1;
  5482. }
  5483. console.log('unhandled sort type');
  5484. return 0;
  5485. };
  5486. };
  5487. var compareFunc = null;
  5488. for(var i = 0; i < sorts.length; i++) compareFunc = getComparator(sorts[i].columnName, sorts[i].ascending, sorts[i].sortType, compareFunc);
  5489. mergesort(data, 0, data.length, compareFunc);
  5490. }
  5491. var ids = [];
  5492. for(i = 0; i < data.length; i++) ids[i] = data[i].index;
  5493. return ids;
  5494. };
  5495. var getDate1 = function(text) {
  5496. var date = { valid: false };
  5497. var sections = text.split('-');
  5498. if(sections.length == 1) sections = text.split('/');
  5499. if(sections.length != 3) return date;
  5500. date.year = Number(sections[0]);
  5501. date.month = Number(sections[1]);
  5502. date.day = Number(sections[2]);
  5503. date.valid = !isNaN(date.year);
  5504. date.valid &= !isNaN(date.month) && date.month > 0 && date.month <= 12;
  5505. date.valid &= !isNaN(date.day) && date.day > 0 && date.day <= daysPerMonth(date.month, date.year);
  5506. return date;
  5507. };
  5508. var getDate2 = function(text) {
  5509. var date = { valid: false };
  5510. var sections = text.split('-');
  5511. if(sections.length == 1) sections = text.split('/');
  5512. if(sections.length != 3) return date;
  5513. date.month = Number(sections[0]);
  5514. date.day = Number(sections[1]);
  5515. date.year = Number(sections[2]);
  5516. date.valid = !isNaN(date.year);
  5517. date.valid &= !isNaN(date.month) && date.month > 0 && date.month <= 12;
  5518. date.valid &= !isNaN(date.day) && date.day > 0 && date.day <= daysPerMonth(date.month, date.year);
  5519. return date;
  5520. };
  5521. var daysPerMonth = function(month, year) {
  5522. if(month == 9 || month == 4 || month == 6 || month == 11) return 30;
  5523. if(month != 2) return 31;
  5524. if(year % 4 != 0) return 28;
  5525. if(year % 100 != 0) return 29;
  5526. return year % 400 == 0 ? 29 : 28;
  5527. };
  5528. var applyFilter = function(repeaterId, data, eventInfo) {
  5529. var dataFiltered = [];
  5530. var filters = repeaterToFilters[repeaterId] || [];
  5531. if (filters.length != 0) {
  5532. if(!eventInfo) eventInfo = $ax.getBasicEventInfo();
  5533. var oldTarget = eventInfo.targetElement;
  5534. var oldSrc = eventInfo.srcElement;
  5535. var oldThis = eventInfo.thiswidget;
  5536. var oldItem = eventInfo.item;
  5537. var idToWidgetInfo = {};
  5538. outer:
  5539. for(var i = 1; i <= data.length; i++) {
  5540. for(var j = 0; j < filters.length; j++) {
  5541. eventInfo.targetElement = _createElementId(repeaterId, i);
  5542. eventInfo.srcElement = filters[j].thisId;
  5543. if(!idToWidgetInfo[eventInfo.srcElement]) idToWidgetInfo[eventInfo.srcElement] = $ax.getWidgetInfo(eventInfo.srcElement);
  5544. eventInfo.thiswidget = idToWidgetInfo[eventInfo.srcElement];
  5545. eventInfo.item = $ax.getItemInfo(eventInfo.srcElement);
  5546. if($ax.expr.evaluateExpr(filters[j].filter, eventInfo) != 'true') continue outer;
  5547. }
  5548. dataFiltered[dataFiltered.length] = data[i - 1];
  5549. }
  5550. for(i = 0; i < dataFiltered.length; i++) data[i] = dataFiltered[i];
  5551. while(data.length > dataFiltered.length) data.pop();
  5552. eventInfo.targetElement = oldTarget;
  5553. eventInfo.srcElement = oldSrc;
  5554. eventInfo.thiswidget = oldThis;
  5555. eventInfo.item = oldItem;
  5556. }
  5557. };
  5558. var _addFilter = function(repeaterId, removeOtherFilters, label, filter, thisId) {
  5559. if(removeOtherFilters) _removeFilter(repeaterId);
  5560. var filterList = repeaterToFilters[repeaterId];
  5561. if(!filterList) repeaterToFilters[repeaterId] = filterList = [];
  5562. var filterObj = { filter: filter, thisId: thisId };
  5563. if(label) filterObj.label = label;
  5564. filterList[filterList.length] = filterObj;
  5565. };
  5566. _repeaterManager.addFilter = _addFilter;
  5567. var _removeFilter = function(repeaterId, label) {
  5568. var filterList = repeaterToFilters[repeaterId];
  5569. // If no list, nothing to remove
  5570. if(!filterList) return;
  5571. // If no label, remove everything
  5572. if(!label) {
  5573. repeaterToFilters[repeaterId] = [];
  5574. return;
  5575. }
  5576. for(var i = filterList.length - 1; i >= 0; i--) {
  5577. var filterObj = filterList[i];
  5578. if(filterObj.label && filterObj.label == label) $ax.splice(filterList, i, 1);
  5579. }
  5580. };
  5581. _repeaterManager.removeFilter = _removeFilter;
  5582. var _addSort = function(repeaterId, label, columnName, ascending, toggle, sortType) {
  5583. var sortList = repeaterToSorts[repeaterId];
  5584. if(!sortList) repeaterToSorts[repeaterId] = sortList = [];
  5585. for(var i = 0; i < sortList.length; i++) {
  5586. if(columnName == sortList[i].columnName) {
  5587. var lastSortObj = $ax.splice(sortList, i, 1)[0];
  5588. if(toggle) ascending = !lastSortObj.ascending;
  5589. break;
  5590. }
  5591. }
  5592. var sortObj = { columnName: columnName, ascending: ascending, sortType: sortType };
  5593. if(label) sortObj.label = label;
  5594. sortList[sortList.length] = sortObj;
  5595. };
  5596. _repeaterManager.addSort = _addSort;
  5597. var _removeSort = function(repeaterId, label) {
  5598. var sortList = repeaterToSorts[repeaterId];
  5599. // If no list, nothing to remove
  5600. if(!sortList) return;
  5601. // If no label, remove everything
  5602. if(!label) {
  5603. repeaterToSorts[repeaterId] = [];
  5604. return;
  5605. }
  5606. for(var i = sortList.length - 1; i >= 0; i--) {
  5607. var sortObj = sortList[i];
  5608. if(sortObj.label && sortObj.label == label) $ax.splice(sortList, i, 1);
  5609. }
  5610. };
  5611. _repeaterManager.removeSort = _removeSort;
  5612. var _setRepeaterToPage = function(repeaterId, type, value, eventInfo) {
  5613. var pageInfo = repeaterToPageInfo[repeaterId];
  5614. // page doesn't matter if there is no limit.
  5615. if(pageInfo.noLimit) return;
  5616. var dataSet = repeaterToActiveDataSet[repeaterId];
  5617. if(!dataSet) dataSet = repeaterToCurrentDataSet[repeaterId];
  5618. var lastPage = Math.max(1, Math.ceil(dataSet.length / pageInfo.itemsPerPage));
  5619. if(type == 'Value') {
  5620. var val = Number($ax.expr.evaluateExpr(value, eventInfo));
  5621. // if invalid, default to 1, otherwise, clamp the value
  5622. if(isNaN(val)) val = 1;
  5623. else if(val < 1) val = 1;
  5624. else if(val > lastPage) val = lastPage;
  5625. pageInfo.currPage = val;
  5626. } else if(type == 'Previous') {
  5627. if(pageInfo.currPage > 1) pageInfo.currPage--;
  5628. } else if(type == 'Next') {
  5629. if(pageInfo.currPage < lastPage) pageInfo.currPage++;
  5630. } else if(type == 'Last') {
  5631. pageInfo.currPage = lastPage;
  5632. } else {
  5633. console.log('Unknown type');
  5634. }
  5635. };
  5636. _repeaterManager.setRepeaterToPage = _setRepeaterToPage;
  5637. var _setNoItemLimit = function(repeaterId) {
  5638. var pageInfo = repeaterToPageInfo[repeaterId];
  5639. delete pageInfo.currPage;
  5640. delete pageInfo.itemsPerPage;
  5641. pageInfo.noLimit = true;
  5642. };
  5643. _repeaterManager.setNoItemLimit = _setNoItemLimit;
  5644. var _setItemLimit = function(repeaterId, value, eventInfo) {
  5645. var pageInfo = repeaterToPageInfo[repeaterId];
  5646. if(pageInfo.noLimit) {
  5647. pageInfo.noLimit = false;
  5648. pageInfo.currPage = 1;
  5649. }
  5650. var oldTarget = eventInfo.targetElement;
  5651. eventInfo.targetElement = repeaterId;
  5652. var itemLimit = Number($ax.expr.evaluateExpr(value, eventInfo));
  5653. eventInfo.targetElement = oldTarget;
  5654. if(isNaN(itemLimit)) itemLimit = 20;
  5655. else if(itemLimit < 1) itemLimit = 1;
  5656. pageInfo.itemsPerPage = itemLimit;
  5657. };
  5658. _repeaterManager.setItemLimit = _setItemLimit;
  5659. var removeItems = function(repeaterId) {
  5660. var elementIds = $ax.getChildElementIdsForRepeater(repeaterId);
  5661. var itemId = $ax.getItemIdsForRepeater(repeaterId);
  5662. for(var i = 0; i < itemId.length; i++) $jobj(_createElementId(repeaterId, itemId[i])).remove();
  5663. $ax.visibility.clearLimboAndHiddenIds(elementIds);
  5664. $ax.clearItemsForRepeater(repeaterId);
  5665. };
  5666. var repeaterSizes = {};
  5667. var resetItemSizes = function (repeaterId, itemSize, bounds, ids, vertical, wrap) {
  5668. var calcItem = !itemSize;
  5669. if(calcItem) itemSize = {};
  5670. var repeaterMap = {};
  5671. repeaterMap.vert = vertical;
  5672. var sizesMap = {};
  5673. var sizes = [];
  5674. var currSizes = wrap == -1 ? sizes : [];
  5675. for(var i = 0; i + bounds[0] < bounds[1]; i++) {
  5676. var itemId = ids[i + bounds[0]];
  5677. if(calcItem) {
  5678. var itemJobj = $jobj(_createElementId(repeaterId, itemId));
  5679. itemSize.width = $ax.getNumFromPx(itemJobj.css('width'));
  5680. itemSize.height = $ax.getNumFromPx(itemJobj.css('height'));
  5681. }
  5682. var size = { itemId: itemId, width: itemSize.width, height: itemSize.height };
  5683. currSizes.push(size);
  5684. sizesMap[size.itemId] = size;
  5685. if(currSizes.length == wrap) {
  5686. sizes.push(currSizes);
  5687. currSizes = [];
  5688. }
  5689. }
  5690. if (wrap != -1 && currSizes.length > 0) sizes.push(currSizes);
  5691. repeaterMap.sizes = sizes;
  5692. repeaterMap.sizesMap = sizesMap;
  5693. repeaterSizes[repeaterId] = repeaterMap;
  5694. };
  5695. _repeaterManager.getItemSize = function(repeaterId, itemId) {
  5696. var repeaterSize = repeaterSizes[repeaterId];
  5697. if (!repeaterSize) return false;
  5698. return repeaterSize.sizesMap[itemId];
  5699. }
  5700. _repeaterManager.setItemSize = function (repeaterId, itemId, width, height) {
  5701. var repeaterSize = repeaterSizes[repeaterId];
  5702. if(!repeaterSize) return false;
  5703. var size = repeaterSize.sizesMap[itemId];
  5704. var deltaX = width - size.width;
  5705. var deltaY = height - size.height;
  5706. if(!deltaX && !deltaY) return false;
  5707. repeaterSize.resized = true;
  5708. if(deltaX) _pushItems(repeaterId, itemId, deltaX, false, true);
  5709. if(deltaY) _pushItems(repeaterId, itemId, deltaY, true, true);
  5710. if(deltaX || deltaY) $ax.event.raiseSyntheticEvent(_createElementId(repeaterId, itemId), 'onItemResize');
  5711. return true;
  5712. }
  5713. var _pushItems = _repeaterManager.pushItems = function (repeaterId, itemId, delta, vertical, suppressFire) {
  5714. if(delta == 0) return;
  5715. // Update repeater item size
  5716. var prop = vertical ? 'height' : 'width';
  5717. var itemObj = $jobj(_createElementId(repeaterId, itemId));
  5718. itemObj.css(prop, $ax.getNumFromPx(itemObj.css(prop)) + delta);
  5719. var repeaterObj = $jobj(repeaterId);
  5720. var repeaterMap = repeaterSizes[repeaterId];
  5721. var sizes = repeaterMap.sizes;
  5722. var wrap = sizes[0].length != undefined;
  5723. var vert = repeaterMap.vert;
  5724. // Not wrapping, has to push in primary direction
  5725. if (!wrap && vert != vertical) {
  5726. var before = 0;
  5727. var after = 0;
  5728. var limit = 0;
  5729. for(var i = 0; i < sizes.length; i++) {
  5730. var size = sizes[i];
  5731. if(size.itemId == itemId) {
  5732. before = size[prop];
  5733. size[prop] += delta;
  5734. after = size[prop];
  5735. } else {
  5736. limit = limit ? Math.max(limit, size[prop]) : size[prop];
  5737. }
  5738. }
  5739. // Repeater delta is because an item can increase secondary direction, but if another item is already larger, then repeater size isn't effected.
  5740. var repeaterDelta = delta;
  5741. if(sizes.length != 1) {
  5742. if(after >= limit) repeaterDelta = after - Math.max(limit, before);
  5743. else if(before > limit) repeaterDelta = limit - before;
  5744. else repeaterDelta = 0;
  5745. }
  5746. _updateRepeaterSize(prop, repeaterObj, repeaterDelta, vert);
  5747. if(!suppressFire) $ax.event.raiseSyntheticEvent(_createElementId(repeaterId, itemId), 'onItemResize');
  5748. return;
  5749. }
  5750. var index = 0;
  5751. var index2 = 0;
  5752. // Get the indices first
  5753. if(wrap) {
  5754. outer:
  5755. for(; index < sizes.length; index++) {
  5756. var innerSizes = sizes[index];
  5757. for(index2 = 0; index2 < innerSizes.length; index2++) if(innerSizes[index2].itemId == itemId) break outer;
  5758. }
  5759. } else {
  5760. for(; index < sizes.length; index++) if(sizes[index].itemId == itemId) break;
  5761. }
  5762. // Find out who is being pushed
  5763. var itemIdsEffected = [];
  5764. if (vert == vertical) {
  5765. // To check for repeater resize, non-wrap is easy, for wrap you have to see if your new size is enough to effect the size given other col/row sizes.
  5766. repeaterDelta = delta;
  5767. if(wrap && sizes.length > 1) {
  5768. var viewId = $ax.adaptive.currentViewId || '';
  5769. var spacing = _getAdaptiveProp($obj(repeaterId).repeaterPropMap, (vert ? 'vertical' : 'horizontal') + 'Spacing', viewId);
  5770. for(i = 0; i < sizes.length; i++) {
  5771. var rowColSize = 0;
  5772. var rowCol = sizes[i];
  5773. for(var j = 0; j < rowCol.length; j++) {
  5774. if(j != 0) rowColSize += spacing;
  5775. rowColSize += rowCol[j][prop];
  5776. }
  5777. if(i == index) {
  5778. before = rowColSize;
  5779. after = before + delta;
  5780. } else {
  5781. limit = limit ? Math.max(limit, rowColSize) : rowColSize;
  5782. }
  5783. }
  5784. if(after >= limit) repeaterDelta = after - Math.max(limit, before);
  5785. else if (before > limit) repeaterDelta = limit - before;
  5786. else repeaterDelta = 0;
  5787. }
  5788. if (repeaterDelta) {
  5789. _updateRepeaterSize(prop, repeaterObj, repeaterDelta, vert);
  5790. }
  5791. // Done the hard part, calculating/updating new repeater size. Now just resize items and find what to push.
  5792. var array = wrap ? sizes[index] : sizes;
  5793. i = wrap ? index2 : index;
  5794. array[i][prop] += delta;
  5795. for(i++; i < array.length; i++) itemIdsEffected.push(array[i].itemId);
  5796. } else {
  5797. // Secondary push is more interesting. See how much your primary row/column is already pushing, if that changes
  5798. // then effect all rows/columns after it
  5799. // Get the biggest one in the current row/column, ignoring the one we're changing
  5800. var biggest = 0;
  5801. var currSizes = sizes[index];
  5802. for(i = 0; i < currSizes.length; i++) {
  5803. if (i == index2) continue;
  5804. biggest = Math.max(biggest, currSizes[i][prop]);
  5805. }
  5806. var beforeSize = Math.max(biggest, currSizes[index2][prop]);
  5807. currSizes[index2][prop] += delta;
  5808. var afterSize = Math.max(biggest, currSizes[index2][prop]);
  5809. // Nothing pushed/pulled
  5810. if (afterSize == beforeSize) return;
  5811. for(i = index + 1; i < sizes.length; i++) {
  5812. currSizes = sizes[i];
  5813. for(j = 0; j < currSizes.length; j++) itemIdsEffected.push(currSizes[j].itemId);
  5814. }
  5815. // Delta is only how much the whole row/column changed
  5816. delta = afterSize - beforeSize;
  5817. // Repeater resize secondary is determined by the effective delta.
  5818. _updateRepeaterSize(prop, repeaterObj, delta, vert);
  5819. }
  5820. for(i = 0; i < itemIdsEffected.length; i++) {
  5821. var currItemId = itemIdsEffected[i];
  5822. var elementId = _createElementId(repeaterId, currItemId);
  5823. var loc = vertical ? 'top' : 'left';
  5824. var jobj = $jobj(elementId);
  5825. var currVal = Number(jobj.css(loc).replace('px', ''));
  5826. jobj.css(loc, currVal + delta);
  5827. }
  5828. if(!suppressFire) $ax.event.raiseSyntheticEvent(_createElementId(repeaterId, itemId), 'onItemResize');
  5829. }
  5830. var _updateRepeaterSize = function(prop, jobj, delta, vert) {
  5831. if (delta == 0) return;
  5832. var val = $ax.getNumFromPx(jobj.css(prop)) + delta;
  5833. var border = 0;
  5834. if(vert) border += $ax.getNumFromPx(jobj.css('border-top-width')) + $ax.getNumFromPx(jobj.css('border-bottom-width'));
  5835. else border += $ax.getNumFromPx(jobj.css('border-left-width')) + $ax.getNumFromPx(jobj.css('border-right-width'));
  5836. val += border;
  5837. jobj.css(prop, val);
  5838. $ax.dynamicPanelManager.fitParentPanel(jobj.attr('id'));
  5839. }
  5840. var _getDataFromDataSet = function (eventInfo, repeaterId, itemId, propName, type) {
  5841. var row = undefined;
  5842. var deleteMap = eventInfo && eventInfo.repeaterDeleteMap && eventInfo.repeaterDeleteMap[repeaterId];
  5843. if(deleteMap) row = deleteMap.idToRow[itemId];
  5844. if(!row) {
  5845. var itemNum = _getRealItemId(eventInfo, repeaterId, Number(itemId));
  5846. row = repeaterToCurrentDataSet[repeaterId][itemNum];
  5847. }
  5848. // Default to obj with text as empty string, as we don't generate the data for empty props
  5849. var data = row[propName] || { text: '' };
  5850. //For now text is always the default. May change this to depend on context.
  5851. switch(type) {
  5852. case 'data': return data.type == 'text' ? data.text : data
  5853. case 'img': return (data.img && data.img[$ax.adaptive.getSketchKey()]) || data.text;
  5854. default: return (type && data[type]) || data.text;
  5855. }
  5856. //return type == 'data' && data.type != 'text' ? data : (type && data[type]) || data['text'];
  5857. };
  5858. _repeaterManager.getData = _getDataFromDataSet;
  5859. _repeaterManager.hasData = function(id, propName) {
  5860. if(!_getItemIdFromElementId(id)) return false;
  5861. var repeaterId = $ax.getParentRepeaterFromScriptId(_getScriptIdFromElementId(id));
  5862. return Boolean(repeaterToCurrentDataSet[repeaterId] && repeaterToCurrentDataSet[repeaterId].props.indexOf(propName) != -1);
  5863. };
  5864. var _getEventDeleteData = function(eventInfo, repeaterId) {
  5865. var repeaterDeleteMap = eventInfo.repeaterDeleteMap;
  5866. if(!repeaterDeleteMap) repeaterDeleteMap = eventInfo.repeaterDeleteMap = {};
  5867. var myDeleteMap = repeaterDeleteMap[repeaterId];
  5868. if(!myDeleteMap) {
  5869. myDeleteMap = repeaterDeleteMap[repeaterId] = {};
  5870. myDeleteMap.deletedIds = [];
  5871. myDeleteMap.idToRow = {};
  5872. }
  5873. return myDeleteMap;
  5874. };
  5875. var _getRealItemId = function(eventInfo, repeaterId, itemId) {
  5876. var deletedBefore = 0;
  5877. var map = eventInfo.repeaterDeleteMap && eventInfo.repeaterDeleteMap[repeaterId];
  5878. var deletedIds = map && map.deletedIds;
  5879. if(!deletedIds) return itemId - 1;
  5880. for(var i = 0; i < deletedIds.length; i++) if (deletedIds[i] < itemId) deletedBefore++;
  5881. return itemId - deletedBefore - 1;
  5882. }
  5883. var _addItemToDataSet = function(repeaterId, row, itemEventInfo) {
  5884. itemEventInfo.data = true;
  5885. var oldTarget = itemEventInfo.targetElement;
  5886. itemEventInfo.targetElement = repeaterId;
  5887. var dataSet = repeaterToLocalDataSet[repeaterId];
  5888. for(var propName in row) {
  5889. if(!row.hasOwnProperty(propName)) continue;
  5890. var prop = row[propName];
  5891. if(prop.type == 'literal') {
  5892. var retval = $ax.expr.evaluateExpr(prop.literal, itemEventInfo);
  5893. if(typeof (retval) == 'string' || retval instanceof Date) retval = { type: 'text', text: retval };
  5894. row[propName] = retval;
  5895. }
  5896. }
  5897. itemEventInfo.targetElement = oldTarget;
  5898. dataSet[dataSet.length] = row;
  5899. itemEventInfo.data = false;
  5900. };
  5901. _repeaterManager.addItem = _addItemToDataSet;
  5902. var _deleteItemsFromDataSet = function(repeaterId, eventInfo, type, rule) {
  5903. var dataSet = repeaterToCurrentDataSet[repeaterId];
  5904. var deleteDataMap = _getEventDeleteData(eventInfo, repeaterId);
  5905. var items;
  5906. // Should always be this, marked, or rule.
  5907. if(type == 'this') items = [_getItemIdFromElementId(eventInfo.srcElement)];
  5908. else if(type == 'marked') items = $ax.deepCopy(repeaterToEditItems[repeaterId]);
  5909. else {
  5910. // This should be rule
  5911. var visibleData = repeaterToCurrentDataSet[repeaterId];
  5912. items = [];
  5913. var oldTarget = eventInfo.targetElement;
  5914. for(var i = 0; i < visibleData.length + deleteDataMap.deletedIds.length; i++) {
  5915. var index = i + 1;
  5916. if(deleteDataMap.deletedIds.indexOf(index) != -1) continue;
  5917. eventInfo.targetElement = _createElementId(repeaterId, index);
  5918. if($ax.expr.evaluateExpr(rule, eventInfo).toLowerCase() != 'true') continue;
  5919. items.push(index);
  5920. }
  5921. eventInfo.targetElement = oldTarget;
  5922. }
  5923. // Want them decending
  5924. items.sort(function(a, b) { return b - a; });
  5925. var editItems = repeaterToEditItems[repeaterId];
  5926. for(i = 0; i < items.length; i++) {
  5927. var itemId = items[i];
  5928. // Don't delete already deletedItem
  5929. if(deleteDataMap.deletedIds.indexOf(itemId) != -1) continue;
  5930. var deletedRow = $ax.splice(dataSet, _getRealItemId(eventInfo, repeaterId, itemId), 1)[0];
  5931. deleteDataMap.deletedIds.push(itemId);
  5932. deleteDataMap.idToRow[itemId] = deletedRow;
  5933. for(var j = editItems.length - 1; j >= 0; j--) {
  5934. var editItem = editItems[j];
  5935. if(editItem == itemId) $ax.splice(editItems, j, 1);
  5936. else if(editItem > itemId) editItems[j] = editItem - 1;
  5937. }
  5938. }
  5939. };
  5940. _repeaterManager.deleteItems = _deleteItemsFromDataSet;
  5941. var _updateEditItemsInDataSet = function(repeaterId, propMap, eventInfo, type, rule) {
  5942. var oldTarget = eventInfo.targetElement;
  5943. var dataSet = repeaterToCurrentDataSet[repeaterId];
  5944. var items;
  5945. // Should always be this, marked, or rule.
  5946. if(type == 'this') items = [_getItemIdFromElementId(eventInfo.srcElement)];
  5947. else if(type == 'marked') items = repeaterToEditItems[repeaterId];
  5948. else {
  5949. // This should be rule
  5950. var currData = repeaterToCurrentDataSet[repeaterId];
  5951. items = [];
  5952. oldTarget = eventInfo.targetElement;
  5953. for(var i = 0; i < currData.length; i++) {
  5954. var index = i + 1;
  5955. eventInfo.targetElement = _createElementId(repeaterId, index);
  5956. if($ax.expr.evaluateExpr(rule, eventInfo).toLowerCase() != 'true') continue;
  5957. items.push(index);
  5958. }
  5959. eventInfo.targetElement = oldTarget;
  5960. }
  5961. eventInfo.data = true;
  5962. for(var prop in propMap) {
  5963. if(!propMap.hasOwnProperty(prop)) continue;
  5964. for(i = 0; i < items.length; i++) {
  5965. var data = propMap[prop];
  5966. var item = items[i];
  5967. if(data.type == 'literal') {
  5968. eventInfo.targetElement = _createElementId(repeaterId, item);
  5969. data = $ax.expr.evaluateExpr(data.literal, eventInfo);
  5970. if(typeof (data) == 'object' && data.isWidget) data = data.text;
  5971. if(typeof (data) == 'string') data = { type: 'text', text: data };
  5972. }
  5973. dataSet[_getRealItemId(eventInfo, repeaterId, item)][prop] = data;
  5974. }
  5975. }
  5976. eventInfo.targetElement = oldTarget;
  5977. eventInfo.data = false;
  5978. };
  5979. _repeaterManager.updateEditItems = _updateEditItemsInDataSet;
  5980. var _getAllItemIds = function(repeaterId) {
  5981. var retval = [];
  5982. var currDataSet = repeaterToCurrentDataSet[repeaterId];
  5983. for(var i = 0; i < currDataSet.length; i++) retval.push(i + 1);
  5984. return retval;
  5985. };
  5986. _repeaterManager.getAllItemIds = _getAllItemIds;
  5987. var _addEditItemToRepeater = function(repeaterId, itemIds) {
  5988. for(var i = 0; i < itemIds.length; i++) {
  5989. var itemId = Number(itemIds[i]);
  5990. var items = repeaterToEditItems[repeaterId];
  5991. if(items.indexOf(itemId) == -1) items[items.length] = itemId;
  5992. }
  5993. };
  5994. _repeaterManager.addEditItems = _addEditItemToRepeater;
  5995. var _removeEditItemFromRepeater = function(repeaterId, itemIds) {
  5996. for(var i = 0; i < itemIds.length; i++) {
  5997. var itemId = itemIds[i];
  5998. var items = repeaterToEditItems[repeaterId];
  5999. var index = items.indexOf(Number(itemId));
  6000. if(index != -1) $ax.splice(items, index, 1);
  6001. }
  6002. };
  6003. _repeaterManager.removeEditItems = _removeEditItemFromRepeater;
  6004. _repeaterManager.isEditItem = function(repeaterId, itemId) {
  6005. var items = repeaterToEditItems[repeaterId];
  6006. return items.indexOf(Number(itemId)) != -1;
  6007. };
  6008. var _createElementId = function(scriptId, itemId) {
  6009. if(!itemId) return scriptId;
  6010. var i = scriptId.indexOf('_');
  6011. var sections = i > -1 ? [scriptId.substring(0, i), scriptId.substring(i + 1)] : [scriptId];
  6012. var retval = sections[0] + '-' + itemId;
  6013. return sections.length > 1 ? retval + '_' + sections[1] : retval;
  6014. };
  6015. _repeaterManager.createElementId = _createElementId;
  6016. var _getElementId = function(scriptId, childId) {
  6017. var elementId = scriptId;
  6018. if($ax.getParentRepeaterFromScriptId(scriptId)) {
  6019. // Must be in the same item as the child
  6020. var itemId = $ax.repeater.getItemIdFromElementId(childId);
  6021. elementId = $ax.repeater.createElementId(scriptId, itemId);
  6022. }
  6023. return elementId;
  6024. };
  6025. _repeaterManager.getElementId = _getElementId;
  6026. var _getScriptIdFromElementId = function(elementId) {
  6027. if(!elementId) return elementId;
  6028. var sections = elementId.split('-');
  6029. var retval = sections[0];
  6030. if(sections.length <= 1) return retval;
  6031. sections = sections[1].split('_');
  6032. return sections.length > 1 ? retval + '_' + sections[1] : retval;
  6033. };
  6034. _repeaterManager.getScriptIdFromElementId = _getScriptIdFromElementId;
  6035. var _getItemIdFromElementId = function(elementId) {
  6036. var sections = elementId.split('-');
  6037. if(sections.length < 2) return '';
  6038. sections = sections[1].split('_');
  6039. return sections[0];
  6040. };
  6041. _repeaterManager.getItemIdFromElementId = _getItemIdFromElementId;
  6042. // TODO: Just inline this if we keep it this way.
  6043. var _applySuffixToElementId = function(id, suffix) {
  6044. return id + suffix;
  6045. // return _createElementId(_getScriptIdFromElementId(id) + suffix, _getItemIdFromElementId(id));
  6046. };
  6047. _repeaterManager.applySuffixToElementId = _applySuffixToElementId;
  6048. var _removeSuffixFromElementId = function (id) {
  6049. var suffixId = id.indexOf('_');
  6050. if(suffixId != -1) return id.substr(0, suffixId);
  6051. var partId = id.indexOf('p');
  6052. if(partId != -1) return _createElementId(id.substr(0, partId), _getItemIdFromElementId(id)); // item id is after part, but before suffix
  6053. return id;
  6054. }
  6055. _repeaterManager.removeSuffixFromElementId = _removeSuffixFromElementId;
  6056. // var _getRepeaterSize = function(repeaterId) {
  6057. // var itemCount = ($ax.getItemIdsForRepeater(repeaterId) || []).length;
  6058. // if(itemCount == 0) return { width: 0, height: 0 };
  6059. // var repeater = $obj(repeaterId);
  6060. // // Width and height per item;
  6061. // var width = repeater.width;
  6062. // var height = repeater.height;
  6063. // var viewId = $ax.adaptive.currentViewId || '';
  6064. // var widthIncrement = width + _getAdaptiveProp(repeater.repeaterPropMap, 'horizontalSpacing', viewId);
  6065. // var heightIncrement = height + _getAdaptiveProp(repeater.repeaterPropMap, 'verticalSpacing', viewId);
  6066. // var wrap = _getAdaptiveProp(repeater.repeaterPropMap, 'wrap', viewId);
  6067. // var vertical = _getAdaptiveProp(repeater.repeaterPropMap, 'vertical', viewId);
  6068. // if(wrap == -1 || itemCount <= wrap) {
  6069. // if(vertical) height += heightIncrement * (itemCount - 1);
  6070. // else width += widthIncrement * (itemCount - 1);
  6071. // } else {
  6072. // var primaryDim = wrap;
  6073. // var secondaryDim = Math.ceil(itemCount / primaryDim);
  6074. // if(vertical) {
  6075. // height += heightIncrement * (primaryDim - 1);
  6076. // width += widthIncrement * (secondaryDim - 1);
  6077. // } else {
  6078. // width += widthIncrement * (primaryDim - 1);
  6079. // height += heightIncrement * (secondaryDim - 1);
  6080. // }
  6081. // }
  6082. // return { width: width, height: height };
  6083. // };
  6084. // _repeaterManager.getRepeaterSize = _getRepeaterSize;
  6085. });
  6086. // ******* Dynamic Panel Manager ******** //
  6087. $axure.internal(function($ax) {
  6088. // TODO: Probably a lot of the dynamic panel functions from pagescript should be moved here at some point...
  6089. var _dynamicPanelManager = $ax.dynamicPanelManager = {};
  6090. var _isIdFitToContent = _dynamicPanelManager.isIdFitToContent = function(id) {
  6091. var obj = $obj(id);
  6092. if (!obj || !$ax.public.fn.IsDynamicPanel(obj.type) || !obj.fitToContent) return false;
  6093. var jpanel = $jobj(id);
  6094. return !jpanel.attr('data-notfit');
  6095. };
  6096. //this function fit parent panel, also check for parent layer or repeaters
  6097. var _fitParentPanel = function (widgetId) {
  6098. var parentLayer = getParentLayer(widgetId);
  6099. if(parentLayer) {
  6100. if(_updateLayerRectCache(parentLayer)) _fitParentPanel(parentLayer);
  6101. return;
  6102. }
  6103. // Find parent panel if there is one.
  6104. var parentPanelInfo = getParentPanel(widgetId);
  6105. if(parentPanelInfo) {
  6106. var parentId = parentPanelInfo.parent;
  6107. if(_updateFitPanel(parentId, parentPanelInfo.state)) _fitParentPanel(parentId);
  6108. return;
  6109. }
  6110. // Otherwise, try to get parent repeater
  6111. var parentRepeaterId = $ax.getParentRepeaterFromElementId(widgetId);
  6112. var repeaterObj = $obj(parentRepeaterId);
  6113. if(!repeaterObj || widgetId == parentRepeaterId || !repeaterObj.repeaterPropMap.fitToContent) return;
  6114. var itemId = $ax.repeater.getItemIdFromElementId(widgetId);
  6115. var size = getContainerSize($ax.repeater.createElementId(parentRepeaterId, itemId));
  6116. $ax.repeater.setItemSize(parentRepeaterId, itemId, size.width, size.height);
  6117. };
  6118. _dynamicPanelManager.fitParentPanel = _fitParentPanel;
  6119. _dynamicPanelManager.initialize = function() {
  6120. $axure.resize(_handleResize);
  6121. };
  6122. var percentPanelToLeftCache = [];
  6123. var percentPanelsInitialized = false;
  6124. var _handleResize = function() {
  6125. if(percentPanelsInitialized) {
  6126. for(var key in percentPanelToLeftCache) {
  6127. //could optimize to only update non-contained panels
  6128. _updatePanelPercentWidth(key);
  6129. }
  6130. } else {
  6131. $ax('*').each(function(obj, elementId) {
  6132. if(_isPercentWidthPanel(obj)) _updatePanelPercentWidth(elementId);
  6133. });
  6134. percentPanelsInitialized = true;
  6135. }
  6136. };
  6137. var _isPercentWidthPanel = _dynamicPanelManager.isPercentWidthPanel = function(obj) {
  6138. return obj && $ax.public.fn.IsDynamicPanel(obj.type) && obj.percentWidth;
  6139. };
  6140. _dynamicPanelManager.updatePanelContentPercentWidth = function(elementId) {
  6141. // if(_isPercentWidthPanel($obj(elementId))) return;
  6142. var stateChildrenQuery = $jobj(elementId).children('.panel_state');
  6143. stateChildrenQuery.children('.panel_state_content').each(
  6144. function() {
  6145. $(this).children('.ax_dynamic_panel').each(
  6146. function() { _updatePanelPercentWidth(this.id); }
  6147. );
  6148. }
  6149. );
  6150. };
  6151. _dynamicPanelManager.updatePercentPanelCache = function(query) {
  6152. query.each(function(obj, elementId) {
  6153. if(_isPercentWidthPanel(obj)) {
  6154. if(_updatePercentPanelToLeftCache(obj, elementId, true)) {
  6155. _updatePanelPercentWidth(elementId);
  6156. }
  6157. }
  6158. });
  6159. };
  6160. _dynamicPanelManager.resetFixedPanel = function(obj, domElement) {
  6161. if(obj.fixedHorizontal == 'center') domElement.style.marginLeft = "";
  6162. if(obj.fixedVertical == 'middle') domElement.style.marginTop = "";
  6163. };
  6164. _dynamicPanelManager.resetAdaptivePercentPanel = function(obj, domElement) {
  6165. if(!_isPercentWidthPanel(obj)) return;
  6166. if(obj.fixedHorizontal == 'center') domElement.style.marginLeft = "";
  6167. else if(obj.fixedHorizontal == 'right') domElement.style.width = "";
  6168. };
  6169. var _updatePercentPanelToLeftCache = function(obj, elementId, overwrite) {
  6170. var wasUpdated = false;
  6171. var jObj = $jobj(elementId);
  6172. var axObj = $ax('#' + elementId);
  6173. if(percentPanelToLeftCache[elementId] == undefined || overwrite) {
  6174. if(obj.fixedHorizontal == 'center') percentPanelToLeftCache[elementId] = Number(jObj.css('margin-left').replace("px", ""));
  6175. else if(obj.fixedHorizontal == 'right') percentPanelToLeftCache[elementId] = axObj.width() + Number(jObj.css('right').replace("px", ""));
  6176. else percentPanelToLeftCache[elementId] = Number(jObj.css('left').replace("px", ""));
  6177. wasUpdated = true;
  6178. }
  6179. if(obj.fixedHorizontal == 'right' && _isIdFitToContent(elementId)) {
  6180. var fitWidth = getContainerSize($ax.visibility.GetPanelState(elementId) + '_content').width;
  6181. percentPanelToLeftCache[elementId] = fitWidth + Number(jObj.css('right').replace("px", ""));
  6182. wasUpdated = true;
  6183. }
  6184. return wasUpdated;
  6185. };
  6186. var _updatePanelPercentWidth = _dynamicPanelManager.updatePanelPercentWidth = function(elementId) {
  6187. var obj = $obj(elementId);
  6188. if(!_isPercentWidthPanel(obj)) return;
  6189. _updatePercentPanelToLeftCache(obj, elementId, false);
  6190. var width;
  6191. var x;
  6192. if(obj.fixedHorizontal) {
  6193. x = 0;
  6194. width = $(window).width();
  6195. } else {
  6196. var parentPanelInfo = getParentPanel(elementId);
  6197. if(parentPanelInfo) {
  6198. var parentId = parentPanelInfo.parent;
  6199. width = $ax('#' + parentId).width();
  6200. var parentObj = $obj(parentId);
  6201. if(parentObj.percentWidth) {
  6202. var stateId = $ax.repeater.applySuffixToElementId(parentId, '_state' + parentPanelInfo.state);
  6203. var stateContentId = stateId + '_content';
  6204. x = -Number($jobj(stateContentId).css('margin-left').replace("px", ""));
  6205. } else x = 0;
  6206. } else {
  6207. var parentRepeater = $ax.getParentRepeaterFromScriptId($ax.repeater.getScriptIdFromElementId(elementId));
  6208. if(parentRepeater) {
  6209. var itemId = $ax.repeater.getItemIdFromElementId(elementId);
  6210. var itemContainerId = $ax.repeater.createElementId(parentRepeater, itemId);
  6211. x = 0;
  6212. width = $ax('#' + itemContainerId).width();
  6213. } else {
  6214. var $window = $(window);
  6215. width = $window.width();
  6216. var bodyLeft = Number($('body').css('left').replace("px", ""));
  6217. var bodyWidth = Number($('body').css('width').replace("px", ""));
  6218. var isCenter = $ax.adaptive.getPageStyle().pageAlignment == 'center';
  6219. width = Math.max(width, bodyWidth);
  6220. x = isCenter ? -(width - bodyWidth) / 2 - bodyLeft : 0;
  6221. }
  6222. }
  6223. }
  6224. var jObj = $jobj(elementId);
  6225. if(obj.fixedHorizontal == 'left') jObj.css('left', x + 'px');
  6226. else if(obj.fixedHorizontal == 'center') {
  6227. jObj.css('left', x + 'px');
  6228. jObj.css('margin-left', 0 + 'px');
  6229. } else jObj.css('left', x + 'px');
  6230. jObj.css('width', width + 'px');
  6231. var panelLeft = percentPanelToLeftCache[elementId];
  6232. var stateParent = jObj;
  6233. while(stateParent.children()[0].id.indexOf($ax.visibility.CONTAINER_SUFFIX) != -1) stateParent = stateParent.children();
  6234. var stateChildrenQuery = stateParent.children('.panel_state');
  6235. stateChildrenQuery.css('width', width + 'px');
  6236. if(obj.fixedHorizontal == 'center')
  6237. stateChildrenQuery.children('.panel_state_content').css('left', '50%').css('margin-left', panelLeft + 'px');
  6238. else if(obj.fixedHorizontal == 'right')
  6239. stateChildrenQuery.children('.panel_state_content').css('left', width - panelLeft + 'px');
  6240. else stateChildrenQuery.children('.panel_state_content').css('margin-left', panelLeft - x + 'px');
  6241. };
  6242. _dynamicPanelManager.updateParentsOfNonDefaultFitPanels = function () {
  6243. $ax('*').each(function (diagramObject, elementId) {
  6244. if(!$ax.public.fn.IsDynamicPanel(diagramObject.type) || !diagramObject.fitToContent) return;
  6245. if($ax.visibility.isElementIdLimboOrInLimboContainer(elementId)) return;
  6246. var stateId = $ax.visibility.GetPanelState(elementId);
  6247. if(stateId != $ax.repeater.applySuffixToElementId(elementId, '_state0')) _fitParentPanel(elementId);
  6248. });
  6249. };
  6250. //_dynamicPanelManager.updateAllFitPanelsAndLayerSizeCaches = function() {
  6251. // var fitToContent = [];
  6252. // var layers = [];
  6253. // $ax('*').each(function (obj, elementId) {
  6254. // var isFitPanel = $ax.public.fn.IsDynamicPanel(obj.type) && obj.fitToContent;
  6255. // var isLayer = $ax.public.fn.IsLayer(obj.type);
  6256. // if(!isFitPanel && !isLayer) return;
  6257. // if($ax.visibility.isElementIdLimboOrInLimboContainer(elementId)) return;
  6258. // if(isFitPanel) {
  6259. // fitToContent[fitToContent.length] = elementId;
  6260. // } else if(isLayer) {
  6261. // layers[layers.length] = elementId;
  6262. // }
  6263. // });
  6264. // for(var i = fitToContent.length - 1; i >= 0; i--) {
  6265. // var panelId = fitToContent[i];
  6266. // var stateCount = $obj(panelId).diagrams.length;
  6267. // for(var j = 0; j < stateCount; j++) {
  6268. // $ax.dynamicPanelManager.setFitToContentCss(panelId, true);
  6269. // _updateFitPanel(panelId, j, true);
  6270. // }
  6271. // }
  6272. // for(var i = layers.length - 1; i >= 0; i--) {
  6273. // var layerId = layers[i];
  6274. // _updateLayerSizeCache(layerId);
  6275. // }
  6276. //};
  6277. var _getCachedLayerRect = function (elementId) {
  6278. var element = document.getElementById(elementId);
  6279. var rect = {};
  6280. rect.width = Number(element.getAttribute('data-width'));
  6281. rect.height = Number(element.getAttribute('data-height'));
  6282. rect.x = Number(element.getAttribute('data-left'));
  6283. rect.y = Number(element.getAttribute('data-top'));
  6284. return rect;
  6285. }
  6286. var _updateLayerRectCache = function (elementId) {
  6287. var oldRect = _getCachedLayerRect(elementId);
  6288. var axObj = $ax('#' + elementId);
  6289. var size = axObj.size();
  6290. var loc = {};
  6291. loc.x = axObj.locRelativeIgnoreLayer(false);
  6292. loc.y = axObj.locRelativeIgnoreLayer(true);
  6293. var sizeChange = oldRect.width != size.width || oldRect.height != size.height;
  6294. var locChange = oldRect.x != loc.x || oldRect.y != loc.y;
  6295. if(sizeChange || locChange) {
  6296. var element = document.getElementById(elementId);
  6297. if(sizeChange) {
  6298. element.setAttribute('data-width', size.width);
  6299. element.setAttribute('data-height', size.height);
  6300. $ax.event.raiseSyntheticEvent(elementId, 'onResize');
  6301. }
  6302. if(locChange) {
  6303. element.setAttribute('data-left', loc.x);
  6304. element.setAttribute('data-top', loc.y);
  6305. $ax.event.raiseSyntheticEvent(elementId, 'onMove');
  6306. }
  6307. return true;
  6308. }
  6309. return false;
  6310. }
  6311. _dynamicPanelManager.setFitToContentCss = function(elementId, fitToContent, oldWidth, oldHeight) {
  6312. if($ax.dynamicPanelManager.isIdFitToContent(elementId) == fitToContent) return;
  6313. var panel = $jobj(elementId);
  6314. var stateCss;
  6315. var scrollbars = $obj(elementId).scrollbars;
  6316. if(fitToContent) {
  6317. panel.attr('style', '');
  6318. panel.removeAttr('data-notfit');
  6319. stateCss = {};
  6320. stateCss.position = 'relative';
  6321. if(scrollbars != 'none') {
  6322. stateCss.overflow = 'visible';
  6323. stateCss['-webkit-overflow-scrolling'] = 'visible';
  6324. }
  6325. if(scrollbars == 'verticalAsNeeded') {
  6326. stateCss['overflow-x'] = 'visible';
  6327. stateCss['-ms-overflow-x'] = 'visible';
  6328. } else if(scrollbars == 'horizontalAsNeeded') {
  6329. stateCss['overflow-y'] = 'visible';
  6330. stateCss['-ms-overflow-y'] = 'visible';
  6331. }
  6332. panel.children().css(stateCss);
  6333. } else {
  6334. panel.attr('data-notfit', 'true');
  6335. var panelCss = { width: oldWidth, height: oldHeight };
  6336. stateCss = { width: oldWidth, height: oldHeight };
  6337. panelCss.overflow = 'hidden';
  6338. stateCss.position = 'absolute';
  6339. if(scrollbars != 'none') {
  6340. stateCss.overflow = 'auto';
  6341. stateCss['-webkit-overflow-scrolling'] = 'touch';
  6342. }
  6343. if(scrollbars == 'verticalAsNeeded') {
  6344. stateCss['overflow-x'] = 'hidden';
  6345. stateCss['-ms-overflow-x'] = 'hidden';
  6346. } else if(scrollbars == 'horizontalAsNeeded') {
  6347. stateCss['overflow-y'] = 'hidden';
  6348. stateCss['-ms-overflow-y'] = 'hidden';
  6349. }
  6350. panel.css(panelCss);
  6351. panel.children().css(stateCss);
  6352. }
  6353. };
  6354. var _getShownStateId = function (id) {
  6355. var obj = $obj(id);
  6356. if (!obj || !$ax.public.fn.IsDynamicPanel(obj.type)) return id;
  6357. var children = $ax.visibility.applyWidgetContainer(id, true, false, true).children();
  6358. for (var i = 0; i < children.length; i++) {
  6359. var child = children[i];
  6360. while ($ax.visibility.isContainer(child.id)) child = $(child).children()[0];
  6361. if (child && child.style && child.style.display != 'none') return child.id;
  6362. }
  6363. return id;
  6364. };
  6365. var _getShownStateObj = function(id) { return $ax('#' + _getShownStateId(id));}
  6366. _dynamicPanelManager.getShownState = function (id) { return $jobj(_getShownStateId(id)); };
  6367. var _getClamp = function(id) {
  6368. var obj = $obj(id);
  6369. if(!obj) return $ax('#' + id);
  6370. if ($ax.public.fn.IsDynamicPanel(obj.type)) return _getShownStateObj(id);
  6371. return $ax('#' + id);
  6372. };
  6373. var _updateFitPanel = function(panelId, stateIndex, initializingView) {
  6374. if(!panelId) return false;
  6375. // Only fit if fitToContent is true
  6376. if(!$ax.dynamicPanelManager.isIdFitToContent(panelId)) return false;
  6377. // Traverse through children to find what size it should be.
  6378. var stateId = $ax.repeater.applySuffixToElementId(panelId, '_state' + stateIndex);
  6379. var stateContentId = stateId + '_content';
  6380. var stateQuery = $jobj(stateId);
  6381. var size = getContainerSize(stateContentId);
  6382. // Skip if size hasn't changed
  6383. var oldWidth = stateQuery.width();
  6384. var oldHeight = stateQuery.height();
  6385. if(oldWidth == size.width && oldHeight == size.height) return false;
  6386. if(!$obj(panelId).percentWidth) stateQuery.width(size.width);
  6387. stateQuery.height(size.height);
  6388. //updatePercentWidth on all child panels
  6389. $jobj(stateContentId).children('.ax_dynamic_panel').each(
  6390. function() { _updatePanelPercentWidth(this.id); }
  6391. );
  6392. //do the following only if it is the current state
  6393. if(stateId != $ax.visibility.GetPanelState(panelId)) return false;
  6394. if(!initializingView) _adjustFixed(panelId, oldWidth, oldHeight, size.width, size.height);
  6395. else if(stateIndex != 0) {
  6396. var state0 = $jobj($ax.repeater.applySuffixToElementId(panelId, '_state0'));
  6397. _adjustFixed(panelId, state0.width(), state0.height(), size.width, size.height);
  6398. }
  6399. $ax.event.raiseSyntheticEvent(panelId, 'onResize');
  6400. $ax.flyoutManager.updateFlyout(panelId);
  6401. return true;
  6402. };
  6403. // widgetId is the one that crawls up masters until it finds a parent panel, targetId is the original widgetId (not the crawling master)
  6404. // finds the immediate parent panel and crawls up through masters but not repeaters
  6405. var getParentPanel = function(widgetId, path, targetId) {
  6406. path = path || $ax.getPathFromScriptId($ax.repeater.getScriptIdFromElementId(widgetId));
  6407. var obj = $obj(widgetId);
  6408. if(obj.parentDynamicPanel) {
  6409. path[path.length - 1] = obj.parentDynamicPanel;
  6410. var parentId = $ax.getScriptIdFromPath(path);
  6411. if(!parentId) return undefined;
  6412. parentId = $ax.repeater.getElementId(parentId, widgetId);
  6413. var parentObj = $obj(parentId);
  6414. var retVal = { parent: parentId };
  6415. for(var i = 0; i < parentObj.diagrams.length; i++) {
  6416. var stateId = $ax.repeater.applySuffixToElementId(parentId, '_state' + i);
  6417. var stateQuery = $jobj(stateId);
  6418. if(stateQuery.find('#' + (targetId || widgetId)).length != 0) {
  6419. retVal.state = i;
  6420. break;
  6421. }
  6422. }
  6423. return retVal;
  6424. }
  6425. if(path.length == 1) return undefined;
  6426. path.pop();
  6427. var parentMaster = $ax.getScriptIdFromPath(path);
  6428. if(!parentMaster) return undefined;
  6429. parentMaster = $ax.repeater.getElementId(parentMaster, widgetId);
  6430. //check if the master is in the same repeater as the widgetId widget
  6431. var parentMasterItemId = $ax.repeater.getItemIdFromElementId(parentMaster);
  6432. var widgetItemId = $ax.repeater.getItemIdFromElementId(widgetId);
  6433. if(parentMasterItemId != widgetItemId) return undefined;
  6434. return getParentPanel(parentMaster, path, targetId || widgetId);
  6435. };
  6436. // finds the immediate parent layer and crawls up through masters but not repeaters or panels
  6437. var getParentLayer = function (widgetId, path) {
  6438. path = path || $ax.getPathFromScriptId($ax.repeater.getScriptIdFromElementId(widgetId));
  6439. //gets immediate parent layer only
  6440. var layerId = $ax.getLayerParentFromElementId(widgetId);
  6441. if(layerId) return layerId;
  6442. if(path.length == 1) return undefined;
  6443. path.pop();
  6444. var parentMaster = $ax.getScriptIdFromPath(path);
  6445. if(!parentMaster) return undefined;
  6446. parentMaster = $ax.repeater.getElementId(parentMaster, widgetId);
  6447. //check if the master is in the same panel as the widgetId widget
  6448. var widgetParentPanel = getParentPanel(widgetId);
  6449. if(widgetParentPanel) {
  6450. var parentMasterParentPanel = getParentPanel(parentMaster);
  6451. if(!parentMasterParentPanel || widgetParentPanel.parent != parentMasterParentPanel.parent) return undefined;
  6452. }
  6453. //check if the master is in the same repeater as the widgetId widget
  6454. var parentMasterItemId = $ax.repeater.getItemIdFromElementId(parentMaster);
  6455. var widgetItemId = $ax.repeater.getItemIdFromElementId(widgetId);
  6456. if(parentMasterItemId != widgetItemId) return undefined;
  6457. return getParentLayer(parentMaster, path);
  6458. };
  6459. // TODO: May be a better location for this. Used currently for rdo and panel state containers
  6460. var getContainerSize = function(containerId) {
  6461. var containerQuery = containerId ? $jobj(containerId) : $('#base');
  6462. var children = containerQuery.children();
  6463. // Default size
  6464. var size = { width: 0, height: 0 };
  6465. for(var i = 0; i < children.length; i++) {
  6466. var child = $(children[i]);
  6467. var childId = child.attr('id');
  6468. //var axChild = $ax('#' + childId).width();
  6469. var childObj = $obj(childId);
  6470. if(!childObj) {
  6471. // On the body there are some children that should be ignored, as they are not objects.
  6472. if(!child.hasClass('basiclink') || child.get(0).tagName.toLowerCase() != 'a') continue;
  6473. // Otherwise it should be a basic link
  6474. var linkChildren = child.children();
  6475. if(!linkChildren.length) continue;
  6476. child = $(linkChildren[0]);
  6477. childId = child.attr('id');
  6478. childObj = $obj(childId);
  6479. }
  6480. // Ignore fixed
  6481. if(!childId || $ax.visibility.limboIds[childId] || !$ax.visibility.IsIdVisible(childId)
  6482. || $ax.public.fn.IsDynamicPanel(childObj.type) && childObj.fixedHorizontal) continue;
  6483. var boundingRect = $ax.public.fn.getWidgetBoundingRect(childId);
  6484. var position = { left: boundingRect.left, top: boundingRect.top };
  6485. var width = boundingRect.width;
  6486. var height = boundingRect.height;
  6487. if($ax.public.fn.IsMaster(childObj.type)) {
  6488. var masterSize = getContainerSize(childId);
  6489. width = masterSize.width;
  6490. height = masterSize.height;
  6491. // } else if($ax.public.fn.IsRepeater(childObj.type)) {
  6492. // var repeaterSize = $ax.repeater.getRepeaterSize(childId);
  6493. // width = repeaterSize.width;
  6494. // height = repeaterSize.height;
  6495. // if(width == 0 && height == 0) continue;
  6496. // position.left += childObj.x;
  6497. // position.top += childObj.y;
  6498. } else if ($ax.public.fn.IsDynamicPanel(childObj.type)) {
  6499. if($ax.dynamicPanelManager.isIdFitToContent(childId)) {
  6500. var stateQuery = $jobj($ax.visibility.GetPanelState(childId));
  6501. width = stateQuery.width();
  6502. height = stateQuery.height();
  6503. }
  6504. }
  6505. size.width = Math.max(size.width, position.left + width);
  6506. size.height = Math.max(size.height, position.top + height);
  6507. }
  6508. return size;
  6509. };
  6510. var _adjustFixed = _dynamicPanelManager.adjustFixed = function(panelId, oldWidth, oldHeight, width, height) {
  6511. var loc = _getFixedPosition(panelId, oldWidth, oldHeight, width, height);
  6512. if(loc) {
  6513. $ax.action.addAnimation(panelId, $ax.action.queueTypes.move, function() {
  6514. $ax.move.MoveWidget(panelId, loc[0], loc[1], { easing: 'none', duration: 0 }, false, null, true);
  6515. });
  6516. }
  6517. };
  6518. var _getFixedPosition = _dynamicPanelManager.getFixedPosition = function(panelId, oldWidth, oldHeight, width, height) {
  6519. var panelObj = $obj(panelId);
  6520. var x = 0;
  6521. var y = 0;
  6522. if(panelObj.fixedHorizontal == 'center') {
  6523. x = (oldWidth - width) / 2;
  6524. }
  6525. if(panelObj.fixedVertical == 'middle') {
  6526. y = (oldHeight - height) / 2;
  6527. }
  6528. return x == 0 && y == 0 ? undefined : [x, y];
  6529. };
  6530. _dynamicPanelManager.getFixedInfo = function(panelId) {
  6531. var panelObj = $obj(panelId);
  6532. if (!panelObj || !$ax.public.fn.IsDynamicPanel(panelObj.type)) return {};
  6533. var jobj = $jobj(panelId);
  6534. if(jobj.css('position') == 'absolute') return {};
  6535. var info = {};
  6536. var horizontal = panelObj.fixedHorizontal;
  6537. if(!horizontal) return info;
  6538. info.fixed = true;
  6539. info.horizontal = horizontal;
  6540. info.vertical = panelObj.fixedVertical;
  6541. if(info.horizontal == 'left') info.x = Number(jobj.css('left').replace('px', ''));
  6542. else if(info.horizontal == 'center') info.x = Number(jobj.css('margin-left').replace('px', ''));
  6543. else if(info.horizontal == 'right') info.x = Number(jobj.css('right').replace('px', ''));
  6544. if(info.vertical == 'top') info.y = Number(jobj.css('top').replace('px', ''));
  6545. else if(info.vertical == 'middle') info.y = Number(jobj.css('margin-top').replace('px', ''));
  6546. else if(info.vertical == 'bottom') info.y = Number(jobj.css('bottom').replace('px', ''));
  6547. return info;
  6548. };
  6549. // Show isn't necessary if this is always done before toggling (which is currently true), but I don't want that
  6550. // change (if it happened) to break this.
  6551. var _compressToggle = function (id, vert, show, easing, duration) {
  6552. var layer = $ax.getTypeFromElementId(id) == $ax.constants.LAYER_TYPE;
  6553. var locProp = vert ? 'top' : 'left';
  6554. var dimProp = vert ? 'height' : 'width';
  6555. var threshold;
  6556. var delta;
  6557. threshold = $ax('#' + id)[locProp](true);
  6558. delta = layer ? $ax('#' + id)[dimProp]() : _getShownStateObj(id)[dimProp]();
  6559. if(!show) {
  6560. // Need to make threshold bottom/right
  6561. threshold += delta;
  6562. // Delta is in the opposite direction
  6563. delta *= -1;
  6564. }
  6565. _compress(id, vert, threshold, delta, easing, duration);
  6566. };
  6567. _dynamicPanelManager.compressToggle = _compressToggle;
  6568. // Used when setting state of dynamic panel
  6569. var _compressDelta = function(id, oldState, newState, vert, easing, duration) {
  6570. var oldQuery = $jobj(oldState);
  6571. var newQuery = $jobj(newState);
  6572. var thresholdProp = vert ? 'top' : 'left';
  6573. var thresholdOffset = vert ? 'height' : 'width';
  6574. var threshold = $ax('#' + id)[thresholdProp](true);
  6575. threshold += oldQuery[thresholdOffset]();
  6576. var delta = newQuery[thresholdOffset]() - oldQuery[thresholdOffset]();
  6577. var clampOffset = vert ? 'width' : 'height';
  6578. var clampWidth = Math.max(oldQuery[clampOffset](), newQuery[clampOffset]());
  6579. _compress(id, vert, threshold, delta, easing, duration, clampWidth);
  6580. };
  6581. _dynamicPanelManager.compressDelta = _compressDelta;
  6582. var _compress = function (id, vert, threshold, delta, easing, duration, clampWidth) {
  6583. // If below, a horizantal clamp, otherwise a vertical clamp
  6584. var clamp = {
  6585. prop: vert ? 'left' : 'top',
  6586. offset: vert ? 'width' : 'height'
  6587. };
  6588. // Get clamp in coords relative to parent. Account for layers farther down
  6589. if($ax.getTypeFromElementId(id) == $ax.constants.LAYER_TYPE) {
  6590. clamp.start = $ax('#' + id)[clamp.prop](true);
  6591. clamp.end = clamp.start + $ax('#' + id)[clamp.offset]();
  6592. } else {
  6593. var clampLoc = $jobj(id);
  6594. if(typeof clampWidth == 'undefined') clampWidth = _getClamp(id)[clamp.offset]();
  6595. clamp.start = Number(clampLoc.css(clamp.prop).replace('px', ''));
  6596. clamp.end = clamp.start + clampWidth;
  6597. }
  6598. // If clamps, threshold, or delta is not a number, can't compress.
  6599. if (isNaN(clamp.start) || isNaN(clamp.end) || isNaN(threshold) || isNaN(delta)) return;
  6600. // Update clamp if fixed, to account for body position (only necessary when page centered)
  6601. if($jobj(id).css('position') == 'fixed') {
  6602. var clampDelta = $('#base').position().left;
  6603. clamp.start -= clampDelta;
  6604. clamp.end -= clampDelta;
  6605. }
  6606. if(!easing) {
  6607. easing = 'none';
  6608. duration = 0;
  6609. }
  6610. var parent = $ax('#' + id).getParents(false, ['item', 'state', 'layer'])[0];
  6611. var obj = parent && $ax.getObjectFromElementId($ax.repeater.removeSuffixFromElementId(parent));
  6612. // Go until you hit a parent item or state, or a layer that is hidden to use as parent.
  6613. // Account for layer container positions as you go.
  6614. while(obj && $ax.public.fn.IsLayer(obj.type) && $ax.visibility.IsIdVisible(parent)) {
  6615. var container = $ax.visibility.applyWidgetContainer(parent, true, true);
  6616. // If layer is using container, offset is going to be necessary
  6617. if(container.length) {
  6618. var offsetX = $ax.getNumFromPx(container.css('left'));
  6619. var offsetY = $ax.getNumFromPx(container.css('top'));
  6620. var clampProp = clamp.prop == 'left' ? offsetX : offsetY;
  6621. var threshProp = clamp.prop == 'left' ? offsetY : offsetX;
  6622. threshold += threshProp;
  6623. clamp.start += clampProp;
  6624. clamp.end += clampProp;
  6625. }
  6626. parent = $ax('#' + parent).getParents(false, ['item', 'state', 'layer'])[0];
  6627. obj = parent && $ax.getObjectFromElementId($ax.repeater.removeSuffixFromElementId(parent));
  6628. }
  6629. // Add container mid push causes strange behavior because we take container into account as we go down, but if after we accounted for it,
  6630. // a container is added, that container is not accounted for with threshold and clamp values.
  6631. var layer = obj && $ax.public.fn.IsLayer(obj.type) && parent;
  6632. if(layer) {
  6633. // If your parent layer is invisible, you want to be relative to it's container. That is true already if it has a container,
  6634. // but if you are just adding one now, then you need to offset your values
  6635. var needsOffset = !$jobj(layer + '_container').length && !$ax.visibility.IsIdVisible(layer);
  6636. $ax.visibility.pushContainer(layer, false);
  6637. if(needsOffset) {
  6638. container = $jobj(layer + '_container');
  6639. offsetX = $ax.getNumFromPx(container.css('left'));
  6640. offsetY = $ax.getNumFromPx(container.css('top'));
  6641. clampProp = clamp.prop == 'left' ? offsetX : offsetY;
  6642. threshProp = clamp.prop == 'left' ? offsetY : offsetX;
  6643. threshold -= threshProp;
  6644. clamp.start -= clampProp;
  6645. clamp.end -= clampProp;
  6646. }
  6647. }
  6648. // Note: If parent is body, some of these aren't widgets
  6649. if(parent && $jobj(parent + '_content').length > 0) parent = parent + '_content';
  6650. if(parent && $jobj(parent + '_container').length > 0) parent = parent + '_container';
  6651. _compressChildrenHelper(id, $(parent ? '#' + parent : '#base').children(), vert, threshold, delta, clamp, easing, duration);
  6652. if(layer) $ax.visibility.popContainer(layer, false);
  6653. // Do item push
  6654. var itemId = $ax.repeater.getItemIdFromElementId(id);
  6655. if(!itemId) return;
  6656. var repeaterId = $ax.getParentRepeaterFromElementId(id);
  6657. // Only need to push when parent is an item directly.
  6658. if(parent != $ax.repeater.createElementId(repeaterId, itemId)) return;
  6659. // If repeater is fit to content, then don't worry about it, it'll be handled elsewhere
  6660. if(!obj.repeaterPropMap.fitToContent) $ax.repeater.pushItems(repeaterId, itemId, delta, vert);
  6661. };
  6662. var _compressChildrenHelper = function (id, children, vert, threshold, delta, clamp, easing, duration, parentLayer) {
  6663. var toMove = [];
  6664. var allMove = true;
  6665. for (var i = 0; i < children.length; i++) {
  6666. var child = $(children[i]);
  6667. // Check for basic links
  6668. if(child[0] && child[0].tagName == 'A' && child.hasClass('basiclink')) child = child.children();
  6669. var childId = child.attr('id');
  6670. // TODO: Played with this a lot, went with a safer fix, but I don't like the catch all with !$obj(childId), should handle these cases explicitally.
  6671. // ann/ref suffixes should skip without turning off allMove, lightbox should be skipped, and is unclear if allMove should be turned off, I think others including container, inner_container, div, img, and text should not be hit ever.
  6672. // Don't move self, and check id to make sure it a widget and not a fixed panel
  6673. if(childId == id || !childId || childId[0] != 'u' || !$obj(childId) || $obj(childId).fixedVertical) {
  6674. // ann/ref widgets should not stop allMove, they move if their widget does, and that widget will be checked and turn this off if it doesn't move
  6675. var suffix = childId && childId.split('_')[1];
  6676. allMove = allMove && (suffix == 'ann' || suffix == 'ref');
  6677. continue;
  6678. }
  6679. if ($ax.getTypeFromElementId(childId) == $ax.constants.LAYER_TYPE) {
  6680. $ax.visibility.pushContainer(childId, false);
  6681. var addSelf;
  6682. var container = $ax.visibility.applyWidgetContainer(childId, true, true);
  6683. var layerChildren = (container.length ? container : child).children();
  6684. //if(container.length) {
  6685. var offsetX = -$ax.getNumFromPx(container.css('left'));
  6686. var offsetY = -$ax.getNumFromPx(container.css('top'));
  6687. var clampProp = clamp.prop == 'left' ? offsetX : offsetY;
  6688. var threshProp = clamp.prop == 'left' ? offsetY : offsetX;
  6689. var layerClamp = { prop: clamp.prop, offset: clamp.offset, start: clamp.start + clampProp, end: clamp.end + clampProp };
  6690. addSelf = _compressChildrenHelper(id, layerChildren, vert, threshold + threshProp, delta, layerClamp, easing, duration, childId);
  6691. //} else addSelf = _compressChildrenHelper(id, layerChildren, vert, threshold, delta, clamp, easing, duration, childId);
  6692. if(addSelf) toMove.push(childId);
  6693. else allMove = false;
  6694. $ax.visibility.popContainer(childId, false);
  6695. continue;
  6696. }
  6697. var numbers = childId.substring(1).split('-');
  6698. if(numbers.length < 1 || isNaN(Number(numbers[0])) || (numbers.length == 2 && isNaN(Number(numbers[1]))) || numbers.length > 2) continue;
  6699. var marker, childClamp;
  6700. var axChild = $ax('#' + childId);
  6701. var markerProp = vert ? 'top' : 'left';
  6702. marker = Number(axChild[markerProp](true));
  6703. childClamp = [Number(axChild[clamp.prop](true))];
  6704. // Dynamic panels are not reporting correct size sometimes, so pull it from the state. Get shown state just returns the widget if it is not a dynamic panel.
  6705. var sizeChild = _getShownStateObj(childId);
  6706. childClamp[1] = childClamp[0] + sizeChild[clamp.offset]();
  6707. if(isNaN(marker) || isNaN(childClamp[0]) || isNaN(childClamp[1]) ||
  6708. marker < threshold || childClamp[1] <= clamp.start || childClamp[0] >= clamp.end) {
  6709. allMove = false;
  6710. continue;
  6711. }
  6712. toMove.push(childId);
  6713. }
  6714. if (allMove && parentLayer) {
  6715. return true;
  6716. } else {
  6717. for(var i = 0; i < toMove.length; i++) {
  6718. $ax('#' + toMove[i]).moveBy(vert ? 0 : delta, vert ? delta : 0, easing == 'none' ? {} : { duration: duration, easing: easing });
  6719. }
  6720. }
  6721. return false;
  6722. };
  6723. var _parentHandlesStyles = function(id) {
  6724. var parents = $ax('#' + id).getParents(true, ['dynamicPanel', 'layer'])[0];
  6725. if(!parents) return false;
  6726. var directParent = true;
  6727. for(var i = 0; i < parents.length; i++) {
  6728. var parentId = parents[i];
  6729. var parentObj = $obj(parentId);
  6730. if(!parentObj.propagate) {
  6731. directParent = false;
  6732. continue;
  6733. }
  6734. return { id: parentId, direct: directParent };
  6735. }
  6736. return false;
  6737. };
  6738. _dynamicPanelManager.parentHandlesStyles = _parentHandlesStyles;
  6739. var _propagateMouseOver = function(id, value) {
  6740. propagate(id, true, value);
  6741. };
  6742. _dynamicPanelManager.propagateMouseOver = _propagateMouseOver;
  6743. var _propagateMouseDown = function(id, value) {
  6744. propagate(id, false, value);
  6745. };
  6746. _dynamicPanelManager.propagateMouseDown = _propagateMouseDown;
  6747. var propagate = function(id, hover, value) {
  6748. var hoverChildren = function(children) {
  6749. if(!children) return;
  6750. for(var i = 0; i < children.length; i++) {
  6751. var elementId = children[i].id;
  6752. var obj = $obj(elementId);
  6753. if(obj == null) {
  6754. elementId = elementId.split('_')[0];
  6755. obj = $obj(elementId);
  6756. }
  6757. if(obj == null) continue;
  6758. if (($ax.public.fn.IsDynamicPanel(obj.type) || $ax.public.fn.IsLayer(obj.type)) && !obj.propagate) continue;
  6759. if(hover) $ax.style.SetWidgetHover(elementId, value);
  6760. else $ax.style.SetWidgetMouseDown(elementId, value);
  6761. $ax.annotation.updateLinkLocations(elementId);
  6762. hoverChildren(children[i].children);
  6763. }
  6764. };
  6765. hoverChildren($ax('#' + id).getChildren(true)[0].children);
  6766. };
  6767. });
  6768. //***** sto.js *****//
  6769. $axure.internal(function($ax) {
  6770. var funcs = {};
  6771. var weekday = new Array(7);
  6772. weekday[0] = "Sunday";
  6773. weekday[1] = "Monday";
  6774. weekday[2] = "Tuesday";
  6775. weekday[3] = "Wednesday";
  6776. weekday[4] = "Thursday";
  6777. weekday[5] = "Friday";
  6778. weekday[6] = "Saturday";
  6779. funcs.getDayOfWeek = function() {
  6780. return _getDayOfWeek(this.getDay());
  6781. };
  6782. var _getDayOfWeek = $ax.getDayOfWeek = function(day) {
  6783. return weekday[day];
  6784. };
  6785. var month = new Array(12);
  6786. month[0] = "January";
  6787. month[1] = "February";
  6788. month[2] = "March";
  6789. month[3] = "April";
  6790. month[4] = "May";
  6791. month[5] = "June";
  6792. month[6] = "July";
  6793. month[7] = "August";
  6794. month[8] = "September";
  6795. month[9] = "October";
  6796. month[10] = "November";
  6797. month[11] = "December";
  6798. funcs.getMonthName = function() {
  6799. return _getMonthName(this.getMonth());
  6800. };
  6801. var _getMonthName = $ax.getMonthName = function(monthNum) {
  6802. return month[monthNum];
  6803. };
  6804. funcs.getMonth = function() {
  6805. return this.getMonth() + 1;
  6806. };
  6807. funcs.addYears = function(years) {
  6808. var retVal = new Date(this.valueOf());
  6809. retVal.setFullYear(this.getFullYear() + Number(years));
  6810. return retVal;
  6811. };
  6812. funcs.addMonths = function(months) {
  6813. var retVal = new Date(this.valueOf());
  6814. retVal.setMonth(this.getMonth() + Number(months));
  6815. return retVal;
  6816. };
  6817. funcs.addDays = function(days) {
  6818. var retVal = new Date(this.valueOf());
  6819. retVal.setDate(this.getDate() + Number(days));
  6820. return retVal;
  6821. };
  6822. funcs.addHours = function(hours) {
  6823. var retVal = new Date(this.valueOf());
  6824. retVal.setHours(this.getHours() + Number(hours));
  6825. return retVal;
  6826. };
  6827. funcs.addMinutes = function(minutes) {
  6828. var retVal = new Date(this.valueOf());
  6829. retVal.setMinutes(this.getMinutes() + Number(minutes));
  6830. return retVal;
  6831. };
  6832. funcs.addSeconds = function(seconds) {
  6833. var retVal = new Date(this.valueOf());
  6834. retVal.setSeconds(this.getSeconds() + Number(seconds));
  6835. return retVal;
  6836. };
  6837. funcs.addMilliseconds = function(milliseconds) {
  6838. var retVal = new Date(this.valueOf());
  6839. retVal.setMilliseconds(this.getMilliseconds() + Number(milliseconds));
  6840. return retVal;
  6841. };
  6842. var _stoHandlers = {};
  6843. _stoHandlers.literal = function(sto, scope, eventInfo) {
  6844. return sto.value;
  6845. };
  6846. //need angle bracket syntax because var is a reserved word
  6847. _stoHandlers['var'] = function(sto, scope, eventInfo) {
  6848. // Can't us 'A || B' here, because the first value can be false, true, or empty string and still be valid.
  6849. var retVal = scope.hasOwnProperty(sto.name) ? scope[sto.name] : $ax.globalVariableProvider.getVariableValue(sto.name, eventInfo);
  6850. // Handle desired type here?
  6851. if(retVal && retVal.exprType) {
  6852. retVal = $ax.expr.evaluateExpr(retVal, eventInfo);
  6853. }
  6854. if((sto.desiredType == 'int' || sto.desiredType == 'float')) {
  6855. var num = new Number(retVal);
  6856. retVal = isNaN(num.valueOf()) ? retVal : num;
  6857. }
  6858. return retVal;
  6859. };
  6860. //TODO: Perhaps repeaterId can be detirmined at generation, and stored in the sto info.
  6861. _stoHandlers.item = function(sto, scope, eventInfo, prop) {
  6862. prop = prop || (eventInfo.data ? 'data' : eventInfo.link ? 'url' : eventInfo.image ? 'img' : 'text');
  6863. var id = sto.isTarget || !$ax.repeater.hasData(eventInfo.srcElement, sto.name) ? eventInfo.targetElement : eventInfo.srcElement;
  6864. return getData(eventInfo, id, sto.name, prop);
  6865. };
  6866. var getData = function(eventInfo, id, name, prop) {
  6867. var repeaterId = $ax.getParentRepeaterFromScriptId($ax.repeater.getScriptIdFromElementId(id));
  6868. var itemId = $ax.repeater.getItemIdFromElementId(id);
  6869. return $ax.repeater.getData(eventInfo, repeaterId, itemId, name, prop);
  6870. };
  6871. _stoHandlers.paren = function(sto, scope, eventInfo) {
  6872. return _evaluateSTO(sto.innerSTO, scope, eventInfo);
  6873. };
  6874. _stoHandlers.fCall = function(sto, scope, eventInfo) {
  6875. //TODO: [mas] handle required type
  6876. var thisObj = _evaluateSTO(sto.thisSTO, scope, eventInfo);
  6877. if(sto.thisSTO.desiredType == 'string' && sto.thisSTO.computedType != 'string') thisObj = thisObj.toString();
  6878. var args = [];
  6879. for(var i = 0; i < sto.arguments.length; i++) {
  6880. args[i] = _evaluateSTO(sto.arguments[i], scope, eventInfo);
  6881. }
  6882. var fn = (funcs.hasOwnProperty(sto.func) && funcs[sto.func]) || thisObj[sto.func];
  6883. return fn.apply(thisObj, args);
  6884. };
  6885. _stoHandlers.propCall = function(sto, scope, eventInfo) {
  6886. //TODO: [mas] handle required type
  6887. if((sto.prop == 'url' || sto.prop == 'img') && sto.thisSTO.sto == 'item') return _stoHandlers.item(sto.thisSTO, scope, eventInfo, sto.prop);
  6888. var thisObj = _evaluateSTO(sto.thisSTO, scope, eventInfo);
  6889. var prop = thisObj[sto.prop] instanceof Function ? thisObj[sto.prop]() : thisObj[sto.prop];
  6890. return prop;
  6891. };
  6892. var _binOps = {};
  6893. _binOps['+'] = function(left, right) {
  6894. if(left instanceof Date) return addDayToDate(left, right);
  6895. if(right instanceof Date) return addDayToDate(right, left);
  6896. var num = Number(left) + Number(right);
  6897. return isNaN(num) ? (String(left) + String(right)) : num;
  6898. };
  6899. _binOps['-'] = function(left, right) {
  6900. if(left instanceof Date) return addDayToDate(left, -right);
  6901. return left - right;
  6902. };
  6903. _binOps['*'] = function(left, right) { return Number(left) * Number(right); };
  6904. _binOps['/'] = function(left, right) { return Number(left) / Number(right); };
  6905. _binOps['%'] = function(left, right) { return Number(left) % Number(right); };
  6906. _binOps['=='] = function(left, right) { return _getBool(left) == _getBool(right); };
  6907. _binOps['!='] = function(left, right) { return _getBool(left) != _getBool(right); };
  6908. _binOps['<'] = function(left, right) { return Number(left) < Number(right); };
  6909. _binOps['<='] = function(left, right) { return Number(left) <= Number(right); };
  6910. _binOps['>'] = function(left, right) { return Number(left) > Number(right); };
  6911. _binOps['>='] = function(left, right) { return Number(left) >= Number(right); };
  6912. _binOps['&&'] = function(left, right) { return _getBool(left) && _getBool(right); };
  6913. _binOps['||'] = function(left, right) { return _getBool(left) || _getBool(right); };
  6914. // TODO: Move this to generic place to be used.
  6915. var addDayToDate = function(date, days) {
  6916. var retVal = new Date(date.valueOf());
  6917. retVal.setDate(date.getDate() + days);
  6918. return retVal;
  6919. };
  6920. var _unOps = {};
  6921. _unOps['+'] = function(arg) { return +arg; };
  6922. _unOps['-'] = function(arg) { return -arg; };
  6923. _unOps['!'] = function(arg) { return !_getBool(arg); };
  6924. _stoHandlers.binOp = function(sto, scope, eventInfo) {
  6925. var left = _evaluateSTO(sto.leftSTO, scope, eventInfo);
  6926. var right = _evaluateSTO(sto.rightSTO, scope, eventInfo);
  6927. return _binOps[sto.op](left, right);
  6928. };
  6929. _stoHandlers.unOp = function(sto, scope, eventInfo) {
  6930. var input = _evaluateSTO(sto.inputSTO, scope, eventInfo);
  6931. return _unOps[sto.op](input);
  6932. };
  6933. var _getBool = function(val) {
  6934. var lowerVal = val.toLowerCase ? val.toLowerCase() : val;
  6935. return lowerVal == "false" ? false : lowerVal == "true" ? true : val;
  6936. };
  6937. $ax.getBool = _getBool;
  6938. var _evaluateSTO = function(sto, scope, eventInfo) {
  6939. if(sto.sto == 'error') return undefined;
  6940. return _tryEscapeRichText(castSto(_stoHandlers[sto.sto](sto, scope, eventInfo), sto), eventInfo);
  6941. };
  6942. $ax.evaluateSTO = _evaluateSTO;
  6943. var castSto = function(val, sto) {
  6944. var type = sto.computedType || sto.desiredType;
  6945. if(type == 'string') val = String(val);
  6946. else if(type == 'date' && !(val instanceof Date)) val = new Date(val);
  6947. else if(type == 'int' || type == 'float') val = Number(val);
  6948. else if(type == 'bool') val = Boolean(val);
  6949. return val;
  6950. };
  6951. var _tryEscapeRichText = function(text, eventInfo) {
  6952. return eventInfo.htmlLiteral ? _escapeRichText(text) : text;
  6953. };
  6954. var _escapeRichText = function(text) {
  6955. if(typeof (text) != 'string') return text;
  6956. return text.replace('<', '&lt;');
  6957. };
  6958. });
  6959. //***** utils.temp.js *****//
  6960. // ******* Deep Copy ******** //
  6961. $axure.internal(function($ax) {
  6962. // TODO: [ben] Ah, infinite loops cause major issues here. Tried saving objects we've already hit, but that didn't seem to work (at least at my first shot).
  6963. // TODO: [ben] To continue from above, added a filter to filter out problem keys. Will need a better way of sorting this out eventually.
  6964. var _deepCopy = function (original, trackCopies, filter) {
  6965. if(trackCopies) {
  6966. var index = _getCopyIndex(original);
  6967. if(index != -1) return _originalToCopy[index][1];
  6968. }
  6969. var isArray = original instanceof Array;
  6970. var isObject = !(original instanceof Function) && !(original instanceof Date) && (original instanceof Object);
  6971. if(!isArray && !isObject) return original;
  6972. var copy = isArray ? [] : { };
  6973. if(trackCopies) _originalToCopy.push([original, copy]);
  6974. isArray ? deepCopyArray(original, trackCopies, copy, filter) : deepCopyObject(original, trackCopies, copy, filter);
  6975. return copy;
  6976. };
  6977. $ax.deepCopy = _deepCopy;
  6978. // Hacky way to copy event info. Copying dragInfo causes major issues due to infinite loops
  6979. // Hashmap doesn't map objects well. It just toStrings them, making them all the same key. This has to be slow...
  6980. var _originalToCopy = [];
  6981. var _getCopyIndex = function(original) {
  6982. for(var i = 0; i < _originalToCopy.length; i++) if(original === _originalToCopy[i][0]) return i;
  6983. return -1;
  6984. };
  6985. $ax.eventCopy = function(eventInfo) {
  6986. var copy = _deepCopy(eventInfo, true, ['dragInfo', 'elementQuery', 'obj']);
  6987. // reset the map. TODO: May need to reset elsewhere too, but this is the only way it's used currently
  6988. _originalToCopy = [];
  6989. return copy;
  6990. };
  6991. var deepCopyArray = function(original, trackCopies, copy, filter) {
  6992. for(var i = 0; i < original.length; i++) {
  6993. copy[i] = _deepCopy(original[i], trackCopies, filter);
  6994. }
  6995. };
  6996. var deepCopyObject = function(original, trackCopies, copy, filter) {
  6997. for(var key in original) {
  6998. if(!original.hasOwnProperty(key)) continue; // Continue if the prop was not put there like a dictionary, but just a native part of the object
  6999. if(filter && filter.indexOf[key] != -1) copy[key] = original[key]; // If that key is filtered out, skip recursion on it.
  7000. else copy[key] = _deepCopy(original[key], trackCopies, filter);
  7001. }
  7002. };
  7003. // Our implementation of splice because it is broken in IE8...
  7004. $ax.splice = function(array, startIndex, count) {
  7005. var retval = [];
  7006. if(startIndex >= array.length || startIndex < 0 || count == 0) return retval;
  7007. if(!count || startIndex + count > array.length) count = array.length - startIndex;
  7008. for(var i = 0; i < count; i++) retval[i] = array[startIndex + i];
  7009. for(i = startIndex + count; i < array.length; i++) array[i - count] = array[i];
  7010. for(i = 0; i < count; i++) array.pop();
  7011. return retval;
  7012. };
  7013. });
  7014. // ******* Flow Shape Links ******** //
  7015. $axure.internal(function($ax) {
  7016. if(!$ax.document.configuration.linkFlowsToPages && !$ax.document.configuration.linkFlowsToPagesNewWindow) return;
  7017. $(window.document).ready(function() {
  7018. $ax(function (dObj) { return ($ax.public.fn.IsVector(dObj.type) || $ax.public.fn.IsSnapshot(dObj.type)) && dObj.referencePageUrl; }).each(function (dObj, elementId) {
  7019. var elementIdQuery = $('#' + elementId);
  7020. if($ax.document.configuration.linkFlowsToPages && !$ax.event.HasClick(dObj)) {
  7021. elementIdQuery.css("cursor", "pointer");
  7022. elementIdQuery.click(function() {
  7023. $ax.navigate({
  7024. url: dObj.referencePageUrl,
  7025. target: "current",
  7026. includeVariables: true
  7027. });
  7028. });
  7029. }
  7030. if($ax.document.configuration.linkFlowsToPagesNewWindow) {
  7031. $('#' + elementId + "_ref").append("<div id='" + elementId + "PagePopup' class='refpageimage'></div>");
  7032. $('#' + elementId + "PagePopup").click(function() {
  7033. $ax.navigate({
  7034. url: dObj.referencePageUrl,
  7035. target: "new",
  7036. includeVariables: true
  7037. });
  7038. });
  7039. }
  7040. });
  7041. });
  7042. });
  7043. //***** variables.js *****//
  7044. // ******* GLOBAL VARIABLE PROVIDER ******** //
  7045. $axure.internal(function($ax) {
  7046. var _globalVariableValues = {};
  7047. var _globalVariableProvider = {};
  7048. $ax.globalVariableProvider = _globalVariableProvider;
  7049. var setVariableValue = function(variable, value, suppressBroadcast) {
  7050. if(!(value instanceof Object)) value = value.toString();
  7051. variable = variable.toLowerCase();
  7052. _globalVariableValues[variable] = value;
  7053. if(suppressBroadcast !== true) {
  7054. var varData = {
  7055. globalVarName: variable,
  7056. globalVarValue: value.toString()
  7057. };
  7058. $axure.messageCenter.postMessage('setGlobalVar', varData);
  7059. }
  7060. //Post global var values only if pageData is loaded (suppresses exception which occurs when page loads)
  7061. if($ax.pageData) {
  7062. _postGlobalVarVals();
  7063. }
  7064. };
  7065. _globalVariableProvider.setVariableValue = setVariableValue;
  7066. var getVariableValue = function(variable, eventInfo, ignoreDefaultsForLinkUrl) {
  7067. variable = variable.toLowerCase();
  7068. if(_globalVariableValues[variable] !== undefined) {
  7069. //If this is for the GetLinkUrl function and
  7070. //the current value of the global variable is the same as the default defined in the document, don't return it
  7071. if(ignoreDefaultsForLinkUrl == true && $ax.document.globalVariables[variable] == _globalVariableValues[variable]) {
  7072. return null;
  7073. }
  7074. return _globalVariableValues[variable];
  7075. }
  7076. if($ax.document.globalVariables[variable] !== undefined) return ignoreDefaultsForLinkUrl == true ? null : $ax.document.globalVariables[variable];
  7077. switch(variable) {
  7078. case "pagename": return $ax.pageData.page.name;
  7079. case "now": return eventInfo.now;
  7080. case "gendate": return $ax.pageData.generationDate;
  7081. case "dragx": return $ax.drag.GetDragX();
  7082. case "dragy": return $ax.drag.GetDragY();
  7083. case "totaldragx": return $ax.drag.GetTotalDragX();
  7084. case "totaldragy": return $ax.drag.GetTotalDragY();
  7085. case "dragtime": return $ax.drag.GetDragTime();
  7086. case "math": return Math;
  7087. case "date": return Date;
  7088. case "window": return eventInfo && eventInfo.window;
  7089. case "this": return eventInfo && eventInfo.thiswidget && $ax.getWidgetInfo(eventInfo.thiswidget.elementId);
  7090. case "item": return (eventInfo && eventInfo.item && eventInfo.item.valid && eventInfo.item) || getVariableValue('targetitem', eventInfo, ignoreDefaultsForLinkUrl);
  7091. case "targetitem": return eventInfo && eventInfo.targetElement && $ax.getItemInfo(eventInfo.targetElement);
  7092. case "repeater": return eventInfo && eventInfo.repeater;
  7093. case "target": return eventInfo && eventInfo.targetElement && $ax.getWidgetInfo(eventInfo.targetElement);
  7094. case "cursor": return eventInfo && eventInfo.cursor;
  7095. default:
  7096. var gen = variable.substr(0, 3) == "gen";
  7097. var date = gen ? $ax.pageData.generationDate : new Date();
  7098. var prop = gen ? variable.substr(3) : variable;
  7099. switch(prop) {
  7100. case "day": return date.getDate();
  7101. case "month": return date.getMonth() + 1;
  7102. case "monthname": return $ax.getMonthName(date.getMonth());
  7103. case "dayofweek": return $ax.getDayOfWeek(date.getDay());
  7104. case "year": return date.getFullYear();
  7105. case "time": return date.toLocaleTimeString();
  7106. case "hours": return date.getHours();
  7107. case "minutes": return date.getMinutes();
  7108. case "seconds": return date.getSeconds();
  7109. default: return '';
  7110. }
  7111. }
  7112. };
  7113. _globalVariableProvider.getVariableValue = getVariableValue;
  7114. var load = function() {
  7115. var csum = false;
  7116. var query = (window.location.href.split("#")[1] || ''); //hash.substring(1); Firefox decodes this so & in variables breaks
  7117. if(query.length > 0) {
  7118. var vars = query.split("&");
  7119. for(var i = 0; i < vars.length; i++) {
  7120. var pair = vars[i].split("=");
  7121. var varName = pair[0];
  7122. var varValue = pair[1];
  7123. if(varName) {
  7124. if(varName == 'CSUM') {
  7125. csum = true;
  7126. } else setVariableValue(varName, decodeURIComponent(varValue), true);
  7127. }
  7128. }
  7129. if(!csum && query.length > 250) {
  7130. window.alert('Axure Warning: The variable values were too long to pass to this page.\n\nIf you are using IE, using Chrome or Firefox will support more data.');
  7131. }
  7132. }
  7133. };
  7134. var getLinkUrl = function(baseUrl) {
  7135. var toAdd = '';
  7136. var definedVariables = _getDefinedVariables();
  7137. for(var i = 0; i < definedVariables.length; i++) {
  7138. var key = definedVariables[i];
  7139. var val = getVariableValue(key, undefined, true);
  7140. if(val != null) {
  7141. if(toAdd.length > 0) toAdd += '&';
  7142. toAdd += key + '=' + encodeURIComponent(val);
  7143. }
  7144. }
  7145. return toAdd.length > 0 ? baseUrl + ($axure.shouldSendVarsToServer() ? '?' : '#') + toAdd + "&CSUM=1" : baseUrl;
  7146. };
  7147. _globalVariableProvider.getLinkUrl = getLinkUrl;
  7148. var _getDefinedVariables = function() {
  7149. return $ax.pageData.variables;
  7150. };
  7151. _globalVariableProvider.getDefinedVariables = _getDefinedVariables;
  7152. var _postGlobalVarVals = function() {
  7153. var retVal = {};
  7154. var definedVariables = _getDefinedVariables();
  7155. for(var i = 0; i < definedVariables.length; i++) {
  7156. var key = definedVariables[i];
  7157. var val = getVariableValue(key);
  7158. if(val != null) {
  7159. retVal[key] = val;
  7160. }
  7161. }
  7162. $ax.messageCenter.postMessage('globalVariableValues', retVal);
  7163. };
  7164. $ax.messageCenter.addMessageListener(function(message, data) {
  7165. if(message == 'getGlobalVariables') {
  7166. _postGlobalVarVals();
  7167. } else if(message == 'resetGlobalVariables') {
  7168. _globalVariableValues = {};
  7169. _postGlobalVarVals();
  7170. }
  7171. });
  7172. load();
  7173. });
  7174. //***** drag.js *****//
  7175. $axure.internal(function($ax) {
  7176. var widgetDragInfo = new Object();
  7177. var _drag = {};
  7178. $ax.drag = _drag;
  7179. $ax.drag.GetWidgetDragInfo = function() {
  7180. return $.extend({}, widgetDragInfo);
  7181. };
  7182. $ax.drag.StartDragWidget = function(event, id) {
  7183. $ax.setjBrowserEvent(jQuery.Event(event));
  7184. if(event.donotdrag) return;
  7185. var x, y;
  7186. var tg;
  7187. if(IE_10_AND_BELOW) {
  7188. x = window.event.clientX + window.document.documentElement.scrollLeft + window.document.body.scrollLeft;
  7189. y = window.event.clientY + window.document.documentElement.scrollTop + window.document.body.scrollTop;
  7190. tg = window.event.srcElement;
  7191. } else {
  7192. if(event.changedTouches) {
  7193. x = event.changedTouches[0].pageX;
  7194. y = event.changedTouches[0].pageY;
  7195. } else {
  7196. x = event.pageX;
  7197. y = event.pageY;
  7198. event.preventDefault();
  7199. }
  7200. tg = event.target;
  7201. }
  7202. widgetDragInfo.hasStarted = false;
  7203. widgetDragInfo.widgetId = id;
  7204. widgetDragInfo.cursorStartX = x;
  7205. widgetDragInfo.cursorStartY = y;
  7206. widgetDragInfo.lastX = x;
  7207. widgetDragInfo.lastY = y;
  7208. widgetDragInfo.currentX = x;
  7209. widgetDragInfo.currentY = y;
  7210. widgetDragInfo.movedWidgets = new Object();
  7211. widgetDragInfo.startTime = (new Date()).getTime();
  7212. widgetDragInfo.targetWidget = tg;
  7213. var movedownName = IE_10_AND_BELOW && $ax.features.supports.windowsMobile ?
  7214. $ax.features.eventNames.mouseDownName : $ax.features.eventNames.mouseMoveName;
  7215. $ax.event.addEvent(document, movedownName, _dragWidget, true);
  7216. $ax.event.addEvent(document, $ax.features.eventNames.mouseUpName, _stopDragWidget, true);
  7217. // if(IE && BROWSER_VERSION < 9) {
  7218. // if($ax.features.supports.windowsMobile) {
  7219. // window.document.attachEvent($ax.features.eventNames.mouseDownName, _dragWidget);
  7220. // window.document.attachEvent($ax.features.eventNames.mouseUpName, _stopDragWidget);
  7221. // } else {
  7222. // window.document.attachEvent('on' + $ax.features.eventNames.mouseMoveName, _dragWidget);
  7223. // window.document.attachEvent('on' + $ax.features.eventNames.mouseUpName, _stopDragWidget);
  7224. // }
  7225. // } else {
  7226. // window.document.addEventListener($ax.features.eventNames.mouseMoveName, _dragWidget, true);
  7227. // window.document.addEventListener($ax.features.eventNames.mouseUpName, _stopDragWidget, true);
  7228. // }
  7229. $ax.legacy.SuppressBubble(event);
  7230. };
  7231. var _dragWidget = function(event) {
  7232. $ax.setjBrowserEvent(jQuery.Event(event));
  7233. var x, y;
  7234. if(IE_10_AND_BELOW) {
  7235. x = window.event.clientX + window.document.documentElement.scrollLeft + window.document.body.scrollLeft;
  7236. y = window.event.clientY + window.document.documentElement.scrollTop + window.document.body.scrollTop;
  7237. } else {
  7238. if(event.changedTouches) {
  7239. x = event.changedTouches[0].pageX;
  7240. y = event.changedTouches[0].pageY;
  7241. //allow scroll (defaults) if only swipe events have cases and delta x is less than 5px and not blocking scrolling
  7242. var deltaX = x - widgetDragInfo.currentX;
  7243. var target = window.document.getElementById(widgetDragInfo.widgetId);
  7244. if($ax.event.hasSyntheticEvent(widgetDragInfo.widgetId, "onDrag") || $ax.event.hasSyntheticEvent(widgetDragInfo.widgetId, "onSwipeUp") ||
  7245. $ax.event.hasSyntheticEvent(widgetDragInfo.widgetId, "onSwipeDown") || (deltaX * deltaX) > 25
  7246. || ($ax.document.configuration.preventScroll && $ax.legacy.GetScrollable(target) == window.document.body)) {
  7247. event.preventDefault();
  7248. }
  7249. } else {
  7250. x = event.pageX;
  7251. y = event.pageY;
  7252. }
  7253. }
  7254. widgetDragInfo.xDelta = x - widgetDragInfo.currentX;
  7255. widgetDragInfo.yDelta = y - widgetDragInfo.currentY;
  7256. widgetDragInfo.lastX = widgetDragInfo.currentX;
  7257. widgetDragInfo.lastY = widgetDragInfo.currentY;
  7258. widgetDragInfo.currentX = x;
  7259. widgetDragInfo.currentY = y;
  7260. widgetDragInfo.currentTime = (new Date()).getTime();
  7261. $ax.legacy.SuppressBubble(event);
  7262. if(!widgetDragInfo.hasStarted) {
  7263. widgetDragInfo.hasStarted = true;
  7264. $ax.event.raiseSyntheticEvent(widgetDragInfo.widgetId, "onDragStart");
  7265. widgetDragInfo.oldBodyCursor = window.document.body.style.cursor;
  7266. window.document.body.style.cursor = 'move';
  7267. var widget = window.document.getElementById(widgetDragInfo.widgetId);
  7268. widgetDragInfo.oldCursor = widget.style.cursor;
  7269. widget.style.cursor = 'move';
  7270. }
  7271. $ax.event.raiseSyntheticEvent(widgetDragInfo.widgetId, "onDrag");
  7272. };
  7273. var _suppressClickAfterDrag = function(event) {
  7274. _removeSuppressEvents();
  7275. $ax.legacy.SuppressBubble(event);
  7276. };
  7277. var _removeSuppressEvents = function () {
  7278. if(IE_10_AND_BELOW) {
  7279. $ax.event.removeEvent(event.srcElement, 'click', _suppressClickAfterDrag, undefined, true);
  7280. $ax.event.removeEvent(widgetDragInfo.targetWidget, 'mousemove', _removeSuppressEvents, undefined, true);
  7281. } else {
  7282. $ax.event.removeEvent(document, "click", _suppressClickAfterDrag, true);
  7283. $ax.event.removeEvent(document, 'mousemove', _removeSuppressEvents, true);
  7284. }
  7285. };
  7286. var _stopDragWidget = function(event) {
  7287. $ax.setjBrowserEvent(jQuery.Event(event));
  7288. var tg;
  7289. var movedownName = IE_10_AND_BELOW && $ax.features.supports.windowsMobile ?
  7290. $ax.features.eventNames.mouseDownName : $ax.features.eventNames.mouseMoveName;
  7291. $ax.event.removeEvent(document, movedownName, _dragWidget, true);
  7292. $ax.event.removeEvent(document, $ax.features.eventNames.mouseUpName, _stopDragWidget, true);
  7293. tg = IE_10_AND_BELOW ? window.event.srcElement : event.target;
  7294. //
  7295. //
  7296. // if(OLD_IE && BROWSER_VERSION < 9) {
  7297. // if($ax.features.supports.windowsMobile) {
  7298. // window.document.detachEvent($ax.features.eventNames.mouseDownName, _dragWidget);
  7299. // window.document.detachEvent($ax.features.eventNames.mouseUpName, _stopDragWidget);
  7300. //
  7301. // } else {
  7302. // window.document.detachEvent('on' + $ax.features.eventNames.mouseMoveName, _dragWidget);
  7303. // window.document.detachEvent('on' + $ax.features.eventNames.mouseUpName, _stopDragWidget);
  7304. // }
  7305. // tg = window.event.srcElement;
  7306. // } else {
  7307. // window.document.removeEventListener($ax.features.eventNames.mouseMoveName, _dragWidget, true);
  7308. // window.document.removeEventListener($ax.features.eventNames.mouseUpName, _stopDragWidget, true);
  7309. // tg = event.target;
  7310. // }
  7311. if(widgetDragInfo.hasStarted) {
  7312. widgetDragInfo.currentTime = (new Date()).getTime();
  7313. $ax.event.raiseSyntheticEvent(widgetDragInfo.widgetId, "onDragDrop");
  7314. if($ax.globalVariableProvider.getVariableValue('totaldragx') < -30 && $ax.globalVariableProvider.getVariableValue('dragtime') < 1000) {
  7315. $ax.event.raiseSyntheticEvent(widgetDragInfo.widgetId, "onSwipeLeft");
  7316. }
  7317. if($ax.globalVariableProvider.getVariableValue('totaldragx') > 30 && $ax.globalVariableProvider.getVariableValue('dragtime') < 1000) {
  7318. $ax.event.raiseSyntheticEvent(widgetDragInfo.widgetId, "onSwipeRight");
  7319. }
  7320. var totalDragY = $ax.globalVariableProvider.getVariableValue('totaldragy');
  7321. if(totalDragY < -30 && $ax.globalVariableProvider.getVariableValue('dragtime') < 1000) {
  7322. $ax.event.raiseSyntheticEvent(widgetDragInfo.widgetId, "onSwipeUp");
  7323. }
  7324. if(totalDragY > 30 && $ax.globalVariableProvider.getVariableValue('dragtime') < 1000) {
  7325. $ax.event.raiseSyntheticEvent(widgetDragInfo.widgetId, "onSwipeDown");
  7326. }
  7327. window.document.body.style.cursor = widgetDragInfo.oldBodyCursor;
  7328. var widget = window.document.getElementById(widgetDragInfo.widgetId);
  7329. // It may be null if OnDragDrop filtered out the widget
  7330. if(widget != null) widget.style.cursor = widgetDragInfo.oldCursor;
  7331. if(widgetDragInfo.targetWidget == tg && !event.changedTouches) {
  7332. // suppress the click after the drag on desktop browsers
  7333. if(IE_10_AND_BELOW && widgetDragInfo.targetWidget) {
  7334. $ax.event.addEvent(widgetDragInfo.targetWidget, 'click', _suppressClickAfterDrag, true, true);
  7335. $ax.event.addEvent(widgetDragInfo.targetWidget, "onmousemove", _removeSuppressEvents, true, true);
  7336. } else {
  7337. $ax.event.addEvent(document, "click", _suppressClickAfterDrag, true);
  7338. $ax.event.addEvent(document, "mousemove", _removeSuppressEvents, true);
  7339. }
  7340. //
  7341. //
  7342. // if(IE && BROWSER_VERSION < 9 && widgetDragInfo.targetWidget) {
  7343. // widgetDragInfo.targetWidget.attachEvent("onclick", _suppressClickAfterDrag);
  7344. // widgetDragInfo.targetWidget.attachEvent("onmousemove", _removeSuppressEvents);
  7345. // } else {
  7346. // window.document.addEventListener("click", _suppressClickAfterDrag, true);
  7347. // window.document.addEventListener("mousemove", _removeSuppressEvents, true);
  7348. // }
  7349. }
  7350. }
  7351. widgetDragInfo.hasStarted = false;
  7352. widgetDragInfo.movedWidgets = new Object();
  7353. return false;
  7354. };
  7355. $ax.drag.GetDragX = function() {
  7356. if(widgetDragInfo.hasStarted) return widgetDragInfo.xDelta;
  7357. return 0;
  7358. };
  7359. $ax.drag.GetDragY = function() {
  7360. if(widgetDragInfo.hasStarted) return widgetDragInfo.yDelta;
  7361. return 0;
  7362. };
  7363. $ax.drag.GetTotalDragX = function() {
  7364. if(widgetDragInfo.hasStarted) return widgetDragInfo.currentX - widgetDragInfo.cursorStartX;
  7365. return 0;
  7366. };
  7367. $ax.drag.GetTotalDragY = function() {
  7368. if(widgetDragInfo.hasStarted) return widgetDragInfo.currentY - widgetDragInfo.cursorStartY;
  7369. return 0;
  7370. };
  7371. $ax.drag.GetDragTime = function() {
  7372. if(widgetDragInfo.hasStarted) return widgetDragInfo.currentTime - widgetDragInfo.startTime;
  7373. return 600000;
  7374. };
  7375. // $ax.drag.GetCursorRectangles = function() {
  7376. // var rects = new Object();
  7377. // rects.lastRect = new rect($ax.lastMouseLocation.x, $ax.lastMouseLocation.y, 1, 1);
  7378. // rects.currentRect = new rect($ax.mouseLocation.x, $ax.mouseLocation.y, 1, 1);
  7379. // return rects;
  7380. // };
  7381. // $ax.drag.GetWidgetRectangles = function(id) {
  7382. // var widget = window.document.getElementById(id);
  7383. // var rects = new Object();
  7384. // rects.lastRect = new rect($ax.legacy.getAbsoluteLeft(widget), $ax.legacy.getAbsoluteTop(widget), Number($('#' + id).css('width').replace("px", "")), Number($('#' + id).css('height').replace("px", "")));
  7385. // rects.currentRect = rects.lastRect;
  7386. // return rects;
  7387. // };
  7388. // $ax.drag.IsEntering = function(movingRects, targetRects) {
  7389. // return !movingRects.lastRect.IntersectsWith(targetRects.currentRect) && movingRects.currentRect.IntersectsWith(targetRects.currentRect);
  7390. // };
  7391. // $ax.drag.IsLeaving = function(movingRects, targetRects) {
  7392. // return movingRects.lastRect.IntersectsWith(targetRects.currentRect) && !movingRects.currentRect.IntersectsWith(targetRects.currentRect);
  7393. // };
  7394. // function IsOver(movingRects, targetRects) {
  7395. // return movingRects.currentRect.IntersectsWith(targetRects.currentRect);
  7396. // }
  7397. // function IsNotOver(movingRects, targetRects) {
  7398. // return !IsOver(movingRects, targetRects);
  7399. // }
  7400. $ax.drag.LogMovedWidgetForDrag = function (id, dragInfo) {
  7401. dragInfo = dragInfo || widgetDragInfo;
  7402. if(dragInfo.hasStarted) {
  7403. var containerIndex = id.indexOf('_container');
  7404. if(containerIndex != -1) id = id.substring(0, containerIndex);
  7405. // If state or other non-widget id, this should not be dragged, and should exit out to avoid exceptions.
  7406. if(!$obj(id)) return;
  7407. var query = $ax('#' + id);
  7408. var x = query.left();
  7409. var y = query.top();
  7410. var movedWidgets = dragInfo.movedWidgets;
  7411. if(!movedWidgets[id]) {
  7412. movedWidgets[id] = new Location(x, y);
  7413. }
  7414. }
  7415. };
  7416. var Location = function(x, y) {
  7417. this.x = x;
  7418. this.y = y;
  7419. };
  7420. $ax.drag.location = Location;
  7421. var Rectangle = $ax.drag.Rectangle = function(x, y, width, height) {
  7422. this.x = x;
  7423. this.y = y;
  7424. this.width = width;
  7425. this.height = height;
  7426. this.right = x + width;
  7427. this.bottom = y + height;
  7428. };
  7429. Rectangle.prototype.IntersectsWith = function(rect) {
  7430. if(this.Invalid()) return false;
  7431. if(rect.length) {
  7432. for(var i = 0; i < rect.length; i++) if(!rect[i].Invalid && this.IntersectsWith(rect[i])) return true;
  7433. return false;
  7434. }
  7435. if(rect.Invalid()) return false;
  7436. return this.x < rect.right && this.right > rect.x && this.y < rect.bottom && this.bottom > rect.y;
  7437. };
  7438. Rectangle.prototype.Invalid = function() {
  7439. return this.x == -1 && this.y == -1 && this.width == -1 && this.height == -1;
  7440. };
  7441. Rectangle.prototype.Move = function(x, y) {
  7442. return new Rectangle(x, y, this.width, this.height);
  7443. };
  7444. });
  7445. //***** move.js *****//
  7446. $axure.internal(function($ax) {
  7447. var _move = {};
  7448. $ax.move = _move;
  7449. var widgetMoveInfo = {};
  7450. //register and return move info, also create container for rootlayer if needed
  7451. $ax.move.PrepareForMove = function (id, x, y, to, options, jobj, rootLayer, skipContainerForRootLayer) {
  7452. var fixedInfo = jobj ? {} : $ax.dynamicPanelManager.getFixedInfo(id);
  7453. var widget = $jobj(id);
  7454. var query = $ax('#' + id);
  7455. var isLayer = $ax.getTypeFromElementId(id) == $ax.constants.LAYER_TYPE;
  7456. if(!rootLayer) {
  7457. rootLayer = _move.getRootLayer(id);
  7458. if (rootLayer && !skipContainerForRootLayer) {
  7459. $ax.visibility.pushContainer(rootLayer, false);
  7460. if (isLayer) widget = $ax.visibility.applyWidgetContainer(id, true);
  7461. }
  7462. }
  7463. if (!jobj) jobj = widget;
  7464. var horzProp = 'left';
  7465. var vertProp = 'top';
  7466. var horzX = to ? x - query.locRelativeIgnoreLayer(false) : x;
  7467. var vertY = to ? y - query.locRelativeIgnoreLayer(true) : y;
  7468. if (fixedInfo.horizontal == 'right') {
  7469. horzProp = 'right';
  7470. horzX = to ? $(window).width() - x - Number(jobj.css('right').replace('px', '')) - query.width() : -x;
  7471. var leftChanges = -horzX;
  7472. } else if(fixedInfo.horizontal == 'center') {
  7473. horzProp = 'margin-left';
  7474. if (to) horzX = x - $(window).width() / 2;
  7475. }
  7476. if (fixedInfo.vertical == 'bottom') {
  7477. vertProp = 'bottom';
  7478. vertY = to ? $(window).height() - y - Number(jobj.css('bottom').replace('px', '')) - query.height() : -y;
  7479. var topChanges = -vertY;
  7480. } else if (fixedInfo.vertical == 'middle') {
  7481. vertProp = 'margin-top';
  7482. if (to) vertY = y - $(window).height() / 2;
  7483. }
  7484. //todo currently this always save the info, which is not needed for compound vector children and maybe some other cases
  7485. //let's optimize it later, only register if registerid is valid..
  7486. widgetMoveInfo[id] = {
  7487. x: leftChanges === undefined ? horzX : leftChanges,
  7488. y: topChanges === undefined ? vertY : topChanges,
  7489. options: options
  7490. };
  7491. return {
  7492. horzX: horzX,
  7493. vertY: vertY,
  7494. horzProp: horzProp,
  7495. vertProp: vertProp,
  7496. rootLayer: rootLayer,
  7497. jobj: jobj
  7498. };
  7499. };
  7500. $ax.move.GetWidgetMoveInfo = function() {
  7501. return $.extend({}, widgetMoveInfo);
  7502. };
  7503. _move.getRootLayer = function (id) {
  7504. var isLayer = $ax.getTypeFromElementId(id) == $ax.constants.LAYER_TYPE;
  7505. var rootLayer = isLayer ? id : '';
  7506. var parentIds = $ax('#' + id).getParents(true, '*')[0];
  7507. for(var i = 0; i < parentIds.length; i++) {
  7508. var parentId = parentIds[i];
  7509. // Keep climbing up layers until you hit a non-layer. At that point you have your root layer
  7510. if($ax.public.fn.IsLayer($ax.getTypeFromElementId(parentId))) rootLayer = parentId;
  7511. else break;
  7512. }
  7513. return rootLayer;
  7514. };
  7515. $ax.move.MoveWidget = function (id, x, y, options, to, animationCompleteCallback, shouldFire, jobj, skipOnMoveEvent) {
  7516. var moveInfo = $ax.move.PrepareForMove(id, x, y, to, options, jobj);
  7517. $ax.drag.LogMovedWidgetForDrag(id, options.dragInfo);
  7518. var object = $obj(id);
  7519. if(object && $ax.public.fn.IsLayer(object.type)) {
  7520. var childrenIds = $ax.public.fn.getLayerChildrenDeep(id, true);
  7521. //don't push container when register moveinfo for child
  7522. if(!skipOnMoveEvent) {
  7523. for(var i = 0; i < childrenIds.length; i++) $ax.move.PrepareForMove(childrenIds[i], x, y, to, options, null, moveInfo.rootLayer, true);
  7524. }
  7525. }
  7526. //if(!moveInfo) moveInfo = _getMoveInfo(id, x, y, to, options, jobj);
  7527. jobj = moveInfo.jobj;
  7528. _moveElement(id, options, animationCompleteCallback, shouldFire, jobj, moveInfo);
  7529. if(skipOnMoveEvent) return;
  7530. $ax.event.raiseSyntheticEvent(id, "onMove");
  7531. if(childrenIds) {
  7532. for(var i = 0; i < childrenIds.length; i++) $ax.event.raiseSyntheticEvent(childrenIds[i], 'onMove');
  7533. }
  7534. };
  7535. var _moveElement = function (id, options, animationCompleteCallback, shouldFire, jobj, moveInfo){
  7536. var cssStyles = {};
  7537. if(!$ax.dynamicPanelManager.isPercentWidthPanel($obj(id))) cssStyles[moveInfo.horzProp] = '+=' + moveInfo.horzX;
  7538. cssStyles[moveInfo.vertProp] = '+=' + moveInfo.vertY;
  7539. // I don't think root layer is necessary anymore after changes to layer container structure.
  7540. // Wait to try removing it until more stable.
  7541. var rootLayer = moveInfo.rootLayer;
  7542. var query = $addAll(jobj, id);
  7543. if(options.easing == 'none') {
  7544. query.animate(cssStyles, { duration: 0, queue: false });
  7545. if(rootLayer) $ax.visibility.popContainer(rootLayer, false);
  7546. if(animationCompleteCallback) animationCompleteCallback();
  7547. //if this widget is inside a layer, we should just remove the layer from the queue
  7548. if(shouldFire) $ax.action.fireAnimationFromQueue(id, $ax.action.queueTypes.move);
  7549. } else {
  7550. var completeCount = query.length;
  7551. query.animate(cssStyles, {
  7552. duration: options.duration, easing: options.easing, queue: false, complete: function () {
  7553. completeCount--;
  7554. if(completeCount == 0 && rootLayer) $ax.visibility.popContainer(rootLayer, false);
  7555. if(animationCompleteCallback) animationCompleteCallback();
  7556. if(shouldFire) $ax.action.fireAnimationFromQueue(id, $ax.action.queueTypes.move);
  7557. }});
  7558. }
  7559. // //moveinfo is used for moving 'with this'
  7560. // var moveInfo = new Object();
  7561. // moveInfo.x = horzX;
  7562. // moveInfo.y = vertY;
  7563. // moveInfo.options = options;
  7564. // widgetMoveInfo[id] = moveInfo;
  7565. };
  7566. _move.nopMove = function(id, options) {
  7567. var moveInfo = new Object();
  7568. moveInfo.x = 0;
  7569. moveInfo.y = 0;
  7570. moveInfo.options = {};
  7571. moveInfo.options.easing = 'none';
  7572. moveInfo.options.duration = 0;
  7573. widgetMoveInfo[id] = moveInfo;
  7574. // Layer move using container now.
  7575. var obj = $obj(id);
  7576. if($ax.public.fn.IsLayer(obj.type)) if(options.onComplete) options.onComplete();
  7577. $ax.event.raiseSyntheticEvent(id, "onMove");
  7578. };
  7579. //rotationDegree: total degree to rotate
  7580. //centerPoint: the center of the circular path
  7581. var _noRotateOnlyMove = function (id, moveDelta, rotatableMove, fireAnimationQueue, easing, duration, completionCallback) {
  7582. moveDelta.x += rotatableMove.x;
  7583. moveDelta.y += rotatableMove.y;
  7584. if (moveDelta.x == 0 && moveDelta.y == 0) {
  7585. if(fireAnimationQueue) {
  7586. $ax.action.fireAnimationFromQueue(id, $ax.action.queueTypes.rotate);
  7587. $ax.action.fireAnimationFromQueue(id, $ax.action.queueTypes.move);
  7588. }
  7589. } else {
  7590. $jobj(id).animate({ top: '+=' + moveDelta.y, left: '+=' + moveDelta.x }, {
  7591. duration: duration,
  7592. easing: easing,
  7593. queue: false,
  7594. complete: function () {
  7595. if(fireAnimationQueue) {
  7596. $ax.action.fireAnimationFromQueue(id, $ax.action.queueTypes.move);
  7597. $ax.action.fireAnimationFromQueue(id, $ax.action.queueTypes.rotate);
  7598. }
  7599. if (completionCallback) completionCallback();
  7600. }
  7601. });
  7602. }
  7603. }
  7604. _move.circularMove = function (id, degreeDelta, centerPoint, moveDelta, rotatableMove, resizeOffset, options, fireAnimationQueue, completionCallback, willDoRotation) {
  7605. var elem = $jobj(id);
  7606. if(!willDoRotation) elem = $addAll(elem, id);
  7607. var moveInfo = $ax.move.PrepareForMove(id, moveDelta.x, moveDelta.y, false, options);
  7608. // If not rotating, still need to check moveDelta and may need to handle that.
  7609. if (degreeDelta === 0) {
  7610. _noRotateOnlyMove(id, moveDelta, rotatableMove, fireAnimationQueue, options.easing, options.duration, completionCallback);
  7611. return;
  7612. }
  7613. var stepFunc = function(newDegree) {
  7614. var deg = newDegree - rotation.degree;
  7615. var widgetCenter = $ax.public.fn.getWidgetBoundingRect(id).centerPoint;
  7616. //console.log("widget center of " + id + " x " + widgetCenter.x + " y " + widgetCenter.y);
  7617. var widgetNewCenter = $axure.fn.getPointAfterRotate(deg, widgetCenter, centerPoint);
  7618. // Start by getting the move not related to rotation, and make sure to update center point to move with it.
  7619. var ratio = deg / degreeDelta;
  7620. var xdelta = (moveDelta.x + rotatableMove.x) * ratio;
  7621. var ydelta = (moveDelta.y + rotatableMove.y) * ratio;
  7622. if(resizeOffset) {
  7623. var resizeShift = {};
  7624. resizeShift.x = resizeOffset.x * ratio;
  7625. resizeShift.y = resizeOffset.y * ratio;
  7626. $axure.fn.getPointAfterRotate(rotation.degree, resizeShift, { x: 0, y: 0 });
  7627. xdelta += resizeShift.x;
  7628. ydelta += resizeShift.y;
  7629. }
  7630. centerPoint.x += xdelta;
  7631. centerPoint.y += ydelta;
  7632. // Now for the move that is rotatable, it must be rotated
  7633. rotatableMove = $axure.fn.getPointAfterRotate(deg, rotatableMove, { x: 0, y: 0 });
  7634. // Now add in circular move to the mix.
  7635. xdelta += widgetNewCenter.x - widgetCenter.x;
  7636. ydelta += widgetNewCenter.y - widgetCenter.y;
  7637. if(xdelta < 0) elem.css('left', '-=' + -xdelta);
  7638. else if(xdelta > 0) elem.css('left', '+=' + xdelta);
  7639. if(ydelta < 0) elem.css('top', '-=' + -ydelta);
  7640. else if(ydelta > 0) elem.css('top', '+=' + ydelta);
  7641. };
  7642. var onComplete = function() {
  7643. if(fireAnimationQueue) $ax.action.fireAnimationFromQueue(id, $ax.action.queueTypes.move);
  7644. if(completionCallback) completionCallback();
  7645. if(moveInfo.rootLayer) $ax.visibility.popContainer(moveInfo.rootLayer, false);
  7646. var isPercentWidthPanel = $ax.dynamicPanelManager.isPercentWidthPanel($obj(id));
  7647. if(isPercentWidthPanel) {
  7648. $ax.dynamicPanelManager.updatePanelPercentWidth(id);
  7649. $ax.dynamicPanelManager.updatePanelContentPercentWidth(id);
  7650. }
  7651. if(elem.css('position') == 'fixed') {
  7652. if(!isPercentWidthPanel) elem.css('left', '');
  7653. elem.css('top', '');
  7654. }
  7655. };
  7656. var rotation = { degree: 0 };
  7657. if(!options.easing || options.easing === 'none' || options.duration <= 0) {
  7658. stepFunc(degreeDelta);
  7659. onComplete();
  7660. } else {
  7661. $(rotation).animate({ degree: degreeDelta }, {
  7662. duration: options.duration,
  7663. easing: options.easing,
  7664. queue: false,
  7665. step: stepFunc,
  7666. complete: onComplete
  7667. });
  7668. }
  7669. };
  7670. //rotate a widget by degree, center is 50% 50%
  7671. _move.rotate = function (id, degree, easing, duration, to, shouldFire, completionCallback) {
  7672. var currentDegree = _move.getRotationDegree(id);
  7673. if(to) degree = degree - currentDegree;
  7674. if(degree === 0) {
  7675. if (shouldFire) $ax.action.fireAnimationFromQueue(id, $ax.action.queueTypes.rotate);
  7676. return;
  7677. }
  7678. var query = $jobj(id);
  7679. var stepFunc = function(now) {
  7680. var degreeDelta = now - rotation.degree;
  7681. var newDegree = currentDegree + degreeDelta;
  7682. query.css($ax.public.fn.setTransformHowever("rotate(" + newDegree + "deg)"));
  7683. currentDegree = newDegree;
  7684. };
  7685. var onComplete = function() {
  7686. if(shouldFire) {
  7687. $ax.action.fireAnimationFromQueue($ax.public.fn.compoundIdFromComponent(id), $ax.action.queueTypes.rotate);
  7688. }
  7689. if(completionCallback) completionCallback();
  7690. $ax.annotation.adjustIconLocation(id);
  7691. };
  7692. var rotation = { degree: 0 };
  7693. //if no animation, setting duration to 1, to prevent RangeError in rotation loops without animation
  7694. if(!easing || easing === 'none' || duration <= 0) {
  7695. stepFunc(degree);
  7696. onComplete();
  7697. } else {
  7698. $(rotation).animate({ degree: degree }, {
  7699. duration: duration,
  7700. easing: easing,
  7701. queue: false,
  7702. step: stepFunc,
  7703. complete: onComplete
  7704. });
  7705. }
  7706. };
  7707. _move.compoundRotateAround = function (id, degreeDelta, centerPoint, moveDelta, rotatableMove, resizeOffset, easing, duration, fireAnimationQueue, completionCallback) {
  7708. if (degreeDelta === 0) {
  7709. _noRotateOnlyMove($ax.public.fn.compoundIdFromComponent(id), moveDelta, rotatableMove, fireAnimationQueue, easing, duration, completionCallback, $ax.action.queueTypes.rotate);
  7710. return;
  7711. }
  7712. var elem = $jobj(id);
  7713. var rotation = { degree: 0 };
  7714. if (!easing || easing === 'none' || duration <= 0) {
  7715. duration = 1;
  7716. easing = 'linear'; //it doesn't matter anymore here...
  7717. }
  7718. var originalWidth = Number(elem.css('width').replace('px', ''));
  7719. var originalHeight = Number(elem.css('height').replace('px', ''));
  7720. var originalLeft = Number(elem.css('left').replace('px', ''));
  7721. var originalTop = Number(elem.css('top').replace('px', ''));
  7722. $(rotation).animate({ degree: degreeDelta }, {
  7723. duration: duration,
  7724. easing: easing,
  7725. queue: false,
  7726. step: function (newDegree) {
  7727. var transform = $ax.public.fn.transformFromElement(elem[0]);
  7728. var originalCenter = { x: originalLeft + 0.5 * originalWidth, y: originalTop + 0.5 * originalHeight};
  7729. var componentCenter = { x: originalCenter.x + transform[4], y: originalCenter.y + transform[5] };
  7730. var deg = newDegree - rotation.degree;
  7731. var ratio = deg / degreeDelta;
  7732. var xdelta = (moveDelta.x + rotatableMove.x) * ratio;
  7733. var ydelta = (moveDelta.y + rotatableMove.y) * ratio;
  7734. if (resizeOffset) {
  7735. var resizeShift = {};
  7736. resizeShift.x = resizeOffset.x * ratio;
  7737. resizeShift.y = resizeOffset.y * ratio;
  7738. $axure.fn.getPointAfterRotate(rotation.degree, resizeShift, { x: 0, y: 0 });
  7739. xdelta += resizeShift.x;
  7740. ydelta += resizeShift.y;
  7741. }
  7742. var rotationMatrix = $ax.public.fn.rotationMatrix(deg);
  7743. var compositionTransform = $ax.public.fn.matrixMultiplyMatrix(rotationMatrix,
  7744. { m11: transform[0], m21: transform[1], m12: transform[2], m22: transform[3] });
  7745. //console.log("widget center of " + id + " x " + widgetCenter.x + " y " + widgetCenter.y);
  7746. var widgetNewCenter = $axure.fn.getPointAfterRotate(deg, componentCenter, centerPoint);
  7747. var newMatrix = $ax.public.fn.matrixString(compositionTransform.m11, compositionTransform.m21, compositionTransform.m12, compositionTransform.m22,
  7748. widgetNewCenter.x - originalCenter.x + xdelta, widgetNewCenter.y - originalCenter.y + ydelta);
  7749. elem.css($ax.public.fn.setTransformHowever(newMatrix));
  7750. },
  7751. complete: function () {
  7752. if (fireAnimationQueue) {
  7753. $ax.action.fireAnimationFromQueue(elem.parent()[0].id, $ax.action.queueTypes.rotate);
  7754. }
  7755. if(completionCallback) completionCallback();
  7756. }
  7757. });
  7758. };
  7759. _move.getRotationDegreeFromElement = function(element) {
  7760. if(element == null) return NaN;
  7761. var transformString = element.style['transform'] ||
  7762. element.style['-o-transform'] ||
  7763. element.style['-ms-transform'] ||
  7764. element.style['-moz-transform'] ||
  7765. element.style['-webkit-transform'];
  7766. if(transformString) {
  7767. var rotateRegex = /rotate\(([-?0-9]+)deg\)/;
  7768. var degreeMatch = rotateRegex.exec(transformString);
  7769. if(degreeMatch && degreeMatch[1]) return parseFloat(degreeMatch[1]);
  7770. }
  7771. if(window.getComputedStyle) {
  7772. var st = window.getComputedStyle(element, null);
  7773. } else {
  7774. console.log('rotation is not supported for ie 8 and below in this version of axure rp');
  7775. return 0;
  7776. }
  7777. var tr = st.getPropertyValue("transform") ||
  7778. st.getPropertyValue("-o-transform") ||
  7779. st.getPropertyValue("-ms-transform") ||
  7780. st.getPropertyValue("-moz-transform") ||
  7781. st.getPropertyValue("-webkit-transform");
  7782. if(!tr || tr === 'none') return 0;
  7783. var values = tr.split('(')[1];
  7784. values = values.split(')')[0],
  7785. values = values.split(',');
  7786. var a = values[0];
  7787. var b = values[1];
  7788. var radians = Math.atan2(b, a);
  7789. if(radians < 0) {
  7790. radians += (2 * Math.PI);
  7791. }
  7792. return radians * (180 / Math.PI);
  7793. };
  7794. _move.getRotationDegree = function(elementId) {
  7795. if($ax.public.fn.IsLayer($obj(elementId).type)) {
  7796. return $jobj(elementId).data('layerDegree');
  7797. }
  7798. return _move.getRotationDegreeFromElement(document.getElementById(elementId));
  7799. }
  7800. });
  7801. //***** visibility.js *****//
  7802. $axure.internal(function($ax) {
  7803. var document = window.document;
  7804. var _visibility = {};
  7805. $ax.visibility = _visibility;
  7806. var _defaultHidden = {};
  7807. var _defaultLimbo = {};
  7808. // ****************** Visibility and State Functions ****************** //
  7809. var _isIdVisible = $ax.visibility.IsIdVisible = function(id) {
  7810. return $ax.visibility.IsVisible(window.document.getElementById(id));
  7811. };
  7812. $ax.visibility.IsVisible = function(element) {
  7813. //cannot use css('visibility') because that gets the effective visiblity
  7814. //e.g. won't be able to set visibility on panels inside hidden panels
  7815. return element.style.visibility != 'hidden';
  7816. };
  7817. $ax.visibility.SetIdVisible = function(id, visible) {
  7818. $ax.visibility.SetVisible(window.document.getElementById(id), visible);
  7819. // Hide lightbox if necessary
  7820. if(!visible) {
  7821. $jobj($ax.repeater.applySuffixToElementId(id, '_lightbox')).remove();
  7822. $ax.flyoutManager.unregisterPanel(id, true);
  7823. }
  7824. };
  7825. var _setAllVisible = function(query, visible) {
  7826. for(var i = 0; i < query.length; i++) {
  7827. _visibility.SetVisible(query[i], visible);
  7828. }
  7829. }
  7830. $ax.visibility.SetVisible = function (element, visible) {
  7831. //not setting display to none to optimize measuring
  7832. if(visible) {
  7833. if($(element).hasClass(HIDDEN_CLASS)) $(element).removeClass(HIDDEN_CLASS);
  7834. if($(element).hasClass(UNPLACED_CLASS)) $(element).removeClass(UNPLACED_CLASS);
  7835. element.style.display = '';
  7836. element.style.visibility = 'inherit';
  7837. } else {
  7838. element.style.display = 'none';
  7839. element.style.visibility = 'hidden';
  7840. }
  7841. };
  7842. var _setWidgetVisibility = $ax.visibility.SetWidgetVisibility = function (elementId, options) {
  7843. var visible = $ax.visibility.IsIdVisible(elementId);
  7844. // If limboed, just fire the next action then leave.
  7845. if(visible == options.value || _limboIds[elementId]) {
  7846. if(!_limboIds[elementId]) options.onComplete && options.onComplete();
  7847. $ax.action.fireAnimationFromQueue(elementId, $ax.action.queueTypes.fade);
  7848. return;
  7849. }
  7850. options.containInner = true;
  7851. var query = $jobj(elementId);
  7852. var parentId = query.parent().attr('id');
  7853. var axObj = $obj(elementId);
  7854. var preserveScroll = false;
  7855. var isPanel = $ax.public.fn.IsDynamicPanel(axObj.type);
  7856. var isLayer = $ax.public.fn.IsLayer(axObj.type);
  7857. if(!options.noContainer && (isPanel || isLayer)) {
  7858. //if dp has scrollbar, save its scroll position
  7859. if(isPanel && axObj.scrollbars != 'none') {
  7860. var shownState = $ax.dynamicPanelManager.getShownState(elementId);
  7861. preserveScroll = true;
  7862. //before hiding, try to save scroll location
  7863. if(!options.value && shownState) {
  7864. DPStateAndScroll[elementId] = {
  7865. shownId: shownState.attr('id'),
  7866. left: shownState.scrollLeft(),
  7867. top: shownState.scrollTop()
  7868. }
  7869. }
  7870. }
  7871. _pushContainer(elementId, isPanel);
  7872. if(isPanel && !options.value) _tryResumeScrollForDP(elementId);
  7873. var complete = options.onComplete;
  7874. options.onComplete = function () {
  7875. if(complete) complete();
  7876. _popContainer(elementId, isPanel);
  7877. //using containers stops mouseleave from firing on IE/Edge and FireFox
  7878. if(!options.value && $ax.event.mouseOverObjectId && (FIREFOX || $axure.browser.isEdge || IE)) {
  7879. var mouseOveredElement = $('#' + $ax.event.mouseOverObjectId);
  7880. if(mouseOveredElement && !mouseOveredElement.is(":visible")) {
  7881. var axObj = $obj($ax.event.mouseOverObjectId);
  7882. if(($ax.public.fn.IsDynamicPanel(axObj.type) || $ax.public.fn.IsLayer(axObj.type)) && axObj.propagate) {
  7883. mouseOveredElement.trigger('mouseleave');
  7884. } else mouseOveredElement.trigger('mouseleave.ixStyle');
  7885. }
  7886. }
  7887. //after showing dp, restore the scoll position
  7888. if(isPanel && options.value) _tryResumeScrollForDP(elementId, true);
  7889. }
  7890. options.containerExists = true;
  7891. }
  7892. _setVisibility(parentId, elementId, options, preserveScroll);
  7893. //set the visibility of the annotation box as well if it exists
  7894. var ann = document.getElementById(elementId + "_ann");
  7895. if(ann) _visibility.SetVisible(ann, options.value);
  7896. //set ref visibility for ref of flow shape, if that exists
  7897. var ref = document.getElementById(elementId + '_ref');
  7898. if(ref) _visibility.SetVisible(ref, options.value);
  7899. };
  7900. var _setVisibility = function(parentId, childId, options, preserveScroll) {
  7901. var wrapped = $jobj(childId);
  7902. var completeTotal = 1;
  7903. var visible = $ax.visibility.IsIdVisible(childId);
  7904. if(visible == options.value) {
  7905. options.onComplete && options.onComplete();
  7906. $ax.action.fireAnimationFromQueue(childId, $ax.action.queueTypes.fade);
  7907. return;
  7908. }
  7909. var child = $jobj(childId);
  7910. var size = options.size || (options.containerExists ? $(child.children()[0]) : child);
  7911. var isIdFitToContent = $ax.dynamicPanelManager.isIdFitToContent(parentId);
  7912. //fade and resize won't work together when there is a container... but we still needs the container for fit to content DPs
  7913. var needContainer = options.easing && options.easing != 'none' && (options.easing != 'fade' || isIdFitToContent);
  7914. var cullPosition = options.cull ? options.cull.css('position') : '';
  7915. var containerExists = options.containerExists;
  7916. var isFullWidth = $ax.dynamicPanelManager.isPercentWidthPanel($obj(childId));
  7917. // If fixed fit to content panel, then we must set size on it. It will be size of 0 otherwise, because container in it is absolute position.
  7918. var needSetSize = false;
  7919. var sizeObj = {};
  7920. if(needContainer) {
  7921. var sizeId = '';
  7922. if($ax.dynamicPanelManager.isIdFitToContent(childId)) sizeId = childId;
  7923. else {
  7924. var panelId = $ax.repeater.removeSuffixFromElementId(childId);
  7925. if($ax.dynamicPanelManager.isIdFitToContent(panelId)) sizeId = panelId;
  7926. }
  7927. if(sizeId) {
  7928. needSetSize = true;
  7929. sizeObj = $jobj(sizeId);
  7930. var newSize = options.cull || sizeObj;
  7931. var newAxSize = $ax('#' + newSize.attr('id'));
  7932. sizeObj.width(newAxSize.width());
  7933. sizeObj.height(newAxSize.height());
  7934. }
  7935. }
  7936. var wrappedOffset = { left: 0, top: 0 };
  7937. var visibleWrapped = wrapped;
  7938. if(needContainer) {
  7939. var childObj = $obj(childId);
  7940. if (options.cull) {
  7941. var axCull = $ax('#' + options.cull.attr('id'));
  7942. var containerWidth = axCull.width();
  7943. var containerHeight = axCull.height();
  7944. } else {
  7945. if(childObj && ($ax.public.fn.IsLayer(childObj.type))) {// || childObj.generateCompound)) {
  7946. var boundingRectangle = $ax.public.fn.getWidgetBoundingRect(childId);
  7947. wrappedOffset.left = boundingRectangle.left;
  7948. wrappedOffset.top = boundingRectangle.top;
  7949. containerWidth = boundingRectangle.width;
  7950. containerHeight = boundingRectangle.height;
  7951. } else if (childObj && childObj.generateCompound) {
  7952. var image = $jobj(childId + '_img');
  7953. containerWidth = $ax.getNumFromPx(image.css('width'));
  7954. containerHeight = $ax.getNumFromPx(image.css('height'));
  7955. wrappedOffset.left = $ax.getNumFromPx(image.css('left'));
  7956. wrappedOffset.top = $ax.getNumFromPx(image.css('top'));
  7957. } else {
  7958. containerWidth = $ax('#' + childId).width();
  7959. containerHeight = $ax('#' + childId).height();
  7960. }
  7961. }
  7962. var containerId = $ax.visibility.applyWidgetContainer(childId);
  7963. // var container = _makeContainer(containerId, options.cull || boundingRectangle, isFullWidth, options.easing == 'flip', wrappedOffset, options.containerExists);
  7964. var container = _makeContainer(containerId, containerWidth, containerHeight, isFullWidth, options.easing == 'flip', wrappedOffset, options.containerExists);
  7965. if(options.containInner) {
  7966. wrapped = _wrappedChildren(containerExists ? $(child.children()[0]) : child);
  7967. // Filter for visibile wrapped children
  7968. visibleWrapped = [];
  7969. for (var i = 0; i < wrapped.length; i++) if($ax.visibility.IsVisible(wrapped[i])) visibleWrapped.push(wrapped[i]);
  7970. visibleWrapped = $(visibleWrapped);
  7971. completeTotal = visibleWrapped.length;
  7972. if(!containerExists) container.prependTo(child);
  7973. // Offset items if necessary
  7974. if(!containerExists && (wrappedOffset.left != 0 || wrappedOffset.top != 0)) {
  7975. for(var i = 0; i < wrapped.length; i++) {
  7976. var inner = $(wrapped[i]);
  7977. inner.css('left', $ax.getNumFromPx(inner.css('left')) - wrappedOffset.left);
  7978. inner.css('top', $ax.getNumFromPx(inner.css('top')) - wrappedOffset.top);
  7979. // Parent layer is now size 0, so have to have to use conatiner since it's the real size.
  7980. // Should we use container all the time? This may make things easier for fit panels too.
  7981. size = container;
  7982. }
  7983. }
  7984. } else if(!containerExists) container.insertBefore(child);
  7985. if(!containerExists) wrapped.appendTo(container);
  7986. if (options.value && options.containInner) {
  7987. //has to set children first because flip to show needs children invisible
  7988. _setAllVisible(visibleWrapped, false);
  7989. _updateChildAlignment(childId);
  7990. _setAllVisible(child, true);
  7991. }
  7992. }
  7993. var completeCount = 0;
  7994. var onComplete = function () {
  7995. completeCount++;
  7996. if (needContainer && completeCount == completeTotal) {
  7997. if ($ax.public.fn.isCompoundVectorHtml(container.parent()[0])) {
  7998. wrappedOffset.left = $ax.getNumFromPx(container.css('left'));
  7999. wrappedOffset.top = $ax.getNumFromPx(container.css('top'));
  8000. }
  8001. if (options.containInner && !containerExists && (wrappedOffset.left != 0 || wrappedOffset.top != 0)) {
  8002. for (i = 0; i < wrapped.length; i++) {
  8003. inner = $(wrapped[i]);
  8004. //if ($ax.public.fn.isCompoundVectorComponentHtml(inner[0])) break;
  8005. inner.css('left', $ax.getNumFromPx(inner.css('left')) + wrappedOffset.left);
  8006. inner.css('top', $ax.getNumFromPx(inner.css('top')) + wrappedOffset.top);
  8007. }
  8008. }
  8009. if(options.containInner && !options.value) {
  8010. _setAllVisible(child, false);
  8011. _setAllVisible(visibleWrapped, true);
  8012. }
  8013. if(containerExists) {
  8014. if(!options.settingChild) container.css('position', 'relative;');
  8015. } else {
  8016. wrapped.insertBefore(container);
  8017. container.remove();
  8018. }
  8019. if(childObj && $ax.public.fn.IsDynamicPanel(childObj.type) && window.modifiedDynamicPanleParentOverflowProp) {
  8020. child.css('overflow', 'hidden');
  8021. window.modifiedDynamicPanleParentOverflowProp = false;
  8022. }
  8023. }
  8024. if(options.value) _updateChildAlignment(childId);
  8025. if(!needContainer || completeTotal == completeCount) {
  8026. if(options.cull) options.cull.css('position', cullPosition);
  8027. if(needSetSize) {
  8028. sizeObj.css('width', 'auto');
  8029. sizeObj.css('height', 'auto');
  8030. }
  8031. options.onComplete && options.onComplete();
  8032. if(options.fire) {
  8033. $ax.event.raiseSyntheticEvent(childId, options.value ? 'onShow' : 'onHide');
  8034. $ax.action.fireAnimationFromQueue(childId, $ax.action.queueTypes.fade);
  8035. }
  8036. }
  8037. };
  8038. // Nothing actually being animated, all wrapped elements invisible
  8039. if(!visibleWrapped.length) {
  8040. if(!options.easing || options.easing == 'none') {
  8041. $ax.visibility.SetIdVisible(childId, options.value);
  8042. completeTotal = 1;
  8043. onComplete();
  8044. } else {
  8045. window.setTimeout(function() {
  8046. completeCount = completeTotal - 1;
  8047. onComplete();
  8048. },options.duration);
  8049. }
  8050. return;
  8051. }
  8052. if(!options.easing || options.easing == 'none') {
  8053. $ax.visibility.SetIdVisible(childId, options.value);
  8054. completeTotal = 1;
  8055. onComplete();
  8056. } else if(options.easing == 'fade') {
  8057. if(options.value) {
  8058. if(preserveScroll) {
  8059. visibleWrapped.css('opacity', 0);
  8060. visibleWrapped.css('visibility', 'inherit');
  8061. visibleWrapped.css('display', 'block');
  8062. //was hoping we could just use fadein here, but need to set display before set scroll position
  8063. _tryResumeScrollForDP(childId);
  8064. visibleWrapped.animate({ opacity: 1 }, {
  8065. duration: options.duration,
  8066. easing: 'swing',
  8067. queue: false,
  8068. complete: function() {
  8069. $ax.visibility.SetIdVisible(childId, true);
  8070. visibleWrapped.css('opacity', '');
  8071. onComplete();
  8072. }
  8073. });
  8074. } else {
  8075. // Can't use $ax.visibility.SetIdVisible, because we only want to set visible, we don't want to set display, fadeIn will handle that.
  8076. visibleWrapped.css('visibility', 'inherit');
  8077. visibleWrapped.fadeIn({
  8078. queue: false,
  8079. duration: options.duration,
  8080. complete: onComplete
  8081. });
  8082. }
  8083. } else {
  8084. // Fading here is being strange...
  8085. visibleWrapped.animate({ opacity: 0 }, { duration: options.duration, easing: 'swing', queue: false, complete: function() {
  8086. $ax.visibility.SetIdVisible(childId, false);
  8087. visibleWrapped.css('opacity', '');
  8088. onComplete();
  8089. }});
  8090. }
  8091. } else if (options.easing == 'flip') {
  8092. //this container will hold
  8093. var trapScroll = _trapScrollLoc(childId);
  8094. var innerContainer = $('<div></div>');
  8095. innerContainer.attr('id', containerId + "_inner");
  8096. innerContainer.data('flip', options.direction == 'left' || options.direction == 'right' ? 'y' : 'x');
  8097. innerContainer.css({
  8098. position: 'relative',
  8099. 'width': containerWidth,
  8100. 'height': containerHeight
  8101. });
  8102. innerContainer.appendTo(container);
  8103. wrapped.appendTo(innerContainer);
  8104. if(childObj && $ax.public.fn.IsDynamicPanel(childObj.type)) var containerDiv = child;
  8105. else containerDiv = parentId ? $jobj(parentId) : child.parent();
  8106. completeTotal = 1;
  8107. var flipdegree;
  8108. var originForUpOrDown = '100% ' + containerHeight / 2 + 'px';
  8109. if(options.value) {
  8110. //options.value == true means in or show, note to get here, the element must be currently hidden to show,
  8111. // we need to first flip it +/- 90deg without animation (180 if we want to show the back of the flip)
  8112. switch(options.direction) {
  8113. case 'right':
  8114. case 'left':
  8115. _setRotateTransformation(innerContainer, _getRotateString(true, options.direction === 'right', options.showFlipBack));
  8116. flipdegree = 'rotateY(0deg)';
  8117. break;
  8118. case 'up':
  8119. case 'down':
  8120. innerContainer.css({
  8121. '-webkit-transform-origin': originForUpOrDown,
  8122. '-ms-transform-origin': originForUpOrDown,
  8123. 'transform-origin': originForUpOrDown,
  8124. });
  8125. _setRotateTransformation(innerContainer, _getRotateString(false, options.direction === 'up', options.showFlipBack));
  8126. flipdegree = 'rotateX(0deg)';
  8127. break;
  8128. }
  8129. var onFlipShowComplete = function() {
  8130. var trapScroll = _trapScrollLoc(childId);
  8131. $ax.visibility.SetIdVisible(childId, true);
  8132. wrapped.insertBefore(innerContainer);
  8133. innerContainer.remove();
  8134. trapScroll();
  8135. onComplete();
  8136. };
  8137. innerContainer.css({
  8138. '-webkit-backface-visibility': 'hidden',
  8139. 'backface-visibility': 'hidden'
  8140. });
  8141. child.css({
  8142. 'display': '',
  8143. 'visibility': 'inherit'
  8144. });
  8145. visibleWrapped.css({
  8146. 'display': '',
  8147. 'visibility': 'inherit'
  8148. });
  8149. innerContainer.css({
  8150. '-webkit-transition-duration': options.duration + 'ms',
  8151. 'transition-duration': options.duration + 'ms'
  8152. });
  8153. if(preserveScroll) _tryResumeScrollForDP(childId);
  8154. _setRotateTransformation(innerContainer, flipdegree, containerDiv, onFlipShowComplete, options.duration, true);
  8155. } else { //hide or out
  8156. switch(options.direction) {
  8157. case 'right':
  8158. case 'left':
  8159. flipdegree = _getRotateString(true, options.direction !== 'right', options.showFlipBack);
  8160. break;
  8161. case 'up':
  8162. case 'down':
  8163. //_setRotateTransformation(wrapped, 'rotateX(0deg)');
  8164. innerContainer.css({
  8165. '-webkit-transform-origin': originForUpOrDown,
  8166. '-ms-transform-origin': originForUpOrDown,
  8167. 'transform-origin': originForUpOrDown,
  8168. });
  8169. flipdegree = _getRotateString(false, options.direction !== 'up', options.showFlipBack);
  8170. break;
  8171. }
  8172. var onFlipHideComplete = function() {
  8173. var trapScroll = _trapScrollLoc(childId);
  8174. wrapped.insertBefore(innerContainer);
  8175. $ax.visibility.SetIdVisible(childId, false);
  8176. innerContainer.remove();
  8177. trapScroll();
  8178. onComplete();
  8179. };
  8180. innerContainer.css({
  8181. '-webkit-backface-visibility': 'hidden',
  8182. 'backface-visibility': 'hidden',
  8183. '-webkit-transition-duration': options.duration + 'ms',
  8184. 'transition-duration': options.duration + 'ms'
  8185. });
  8186. if(preserveScroll) _tryResumeScrollForDP(childId);
  8187. _setRotateTransformation(innerContainer, flipdegree, containerDiv, onFlipHideComplete, options.duration, true);
  8188. }
  8189. trapScroll();
  8190. } else {
  8191. // Because the move is gonna fire on annotation and ref too, need to update complete total
  8192. completeTotal = $addAll(visibleWrapped, childId).length;
  8193. if(options.value) {
  8194. _slideStateIn(childId, childId, options, size, false, onComplete, visibleWrapped, preserveScroll);
  8195. } else {
  8196. var tops = [];
  8197. var lefts = [];
  8198. for(var i = 0; i < visibleWrapped.length; i++) {
  8199. var currWrapped = $(visibleWrapped[i]);
  8200. tops.push(fixAuto(currWrapped, 'top'));
  8201. lefts.push(fixAuto(currWrapped, 'left'));
  8202. }
  8203. var onOutComplete = function () {
  8204. //bring back SetIdVisible on childId for hiding lightbox
  8205. $ax.visibility.SetIdVisible(childId, false);
  8206. for(i = 0; i < visibleWrapped.length; i++) {
  8207. currWrapped = $(visibleWrapped[i]);
  8208. $ax.visibility.SetVisible(currWrapped[0], false);
  8209. currWrapped.css('top', tops[i]);
  8210. currWrapped.css('left', lefts[i]);
  8211. }
  8212. onComplete();
  8213. };
  8214. _slideStateOut(size, childId, options, onOutComplete, visibleWrapped);
  8215. }
  8216. }
  8217. // If showing, go through all rich text objects inside you, and try to redo alignment of them
  8218. if(options.value && !options.containInner) {
  8219. _updateChildAlignment(childId);
  8220. }
  8221. };
  8222. // IE/Safari are giving auto here instead of calculating to for us. May need to calculate this eventually, but for now we can assume auto === 0px for the edge case found
  8223. var fixAuto = function (jobj, prop) {
  8224. var val = jobj.css(prop);
  8225. return val == 'auto' ? '0px' : val;
  8226. };
  8227. var _getRotateString = function (y, neg, showFlipBack) {
  8228. // y means flip on y axis, or left/right, neg means flipping it left/down, and show back is for set panel state
  8229. // and will show the back of the widget (transparent) for the first half of a show, or second half of a hide.
  8230. return 'rotate' + (y ? 'Y' : 'X') + '(' + (neg ? '-' : '') + (showFlipBack ? 180 : IE ? 91 : 90) + 'deg)';
  8231. }
  8232. var _updateChildAlignment = function(childId) {
  8233. var descendants = $jobj(childId).find('.text');
  8234. for(var i = 0; i < descendants.length; i++) $ax.style.updateTextAlignmentForVisibility(descendants[i].id);
  8235. };
  8236. var _wrappedChildren = function (child) {
  8237. return child.children();
  8238. //var children = child.children();
  8239. //var valid = [];
  8240. //for(var i = 0; i < children.length; i++) if($ax.visibility.IsVisible(children[i])) valid.push(children[i]);
  8241. //return $(valid);
  8242. };
  8243. var requestAnimationFrame = window.requestAnimationFrame ||
  8244. window.webkitRequestAnimationFrame ||
  8245. window.mozRequestAnimationFrame || window.msRequestAnimationFrame ||
  8246. function (callback) {
  8247. window.setTimeout(callback, 1000 / 60);
  8248. };
  8249. var _setRotateTransformation = function(elementsToSet, transformValue, elementParent, flipCompleteCallback, flipDurationMs, useAnimationFrame) {
  8250. if(flipCompleteCallback) {
  8251. //here we didn't use 'transitionend' event to fire callback
  8252. //when show/hide on one element, changing transition property will stop the event from firing
  8253. window.setTimeout(flipCompleteCallback, flipDurationMs);
  8254. }
  8255. var trasformCss = {
  8256. '-webkit-transform': transformValue,
  8257. '-moz-transform': transformValue,
  8258. '-ms-transform': transformValue,
  8259. '-o-transform': transformValue,
  8260. 'transform': transformValue
  8261. };
  8262. if(useAnimationFrame) {
  8263. requestAnimationFrame(function() {
  8264. elementsToSet.css(trasformCss);
  8265. });
  8266. } else elementsToSet.css(trasformCss);
  8267. //when deal with dynamic panel, we need to set it's parent's overflow to visible to have the 3d effect
  8268. //NOTE: we need to set this back when both flips finishes in DP, to prevents one animation finished first and set this back
  8269. if(elementParent && elementParent.css('overflow') === 'hidden') {
  8270. elementParent.css('overflow', 'visible');
  8271. window.modifiedDynamicPanleParentOverflowProp = true;
  8272. }
  8273. };
  8274. $ax.visibility.GetPanelState = function(id) {
  8275. var children = $ax.visibility.getRealChildren($jobj(id).children());
  8276. for(var i = 0; i < children.length; i++) {
  8277. if(children[i].style && $ax.visibility.IsVisible(children[i])) return children[i].id;
  8278. }
  8279. return '';
  8280. };
  8281. var containerCount = {};
  8282. $ax.visibility.SetPanelState = function(id, stateId, easingOut, directionOut, durationOut, easingIn, directionIn, durationIn, showWhenSet) {
  8283. var show = !$ax.visibility.IsIdVisible(id) && showWhenSet;
  8284. if(show) $ax.visibility.SetIdVisible(id, true);
  8285. // Exit here if already at desired state.
  8286. if($ax.visibility.IsIdVisible(stateId)) {
  8287. if(show) {
  8288. $ax.event.raiseSyntheticEvent(id, 'onShow');
  8289. // If showing size changes and need to update parent panels
  8290. $ax.dynamicPanelManager.fitParentPanel(id);
  8291. }
  8292. $ax.action.fireAnimationFromQueue(id, $ax.action.queueTypes.setState);
  8293. return;
  8294. }
  8295. _pushContainer(id, true);
  8296. var state = $jobj(stateId);
  8297. var oldStateId = $ax.visibility.GetPanelState(id);
  8298. var oldState = $jobj(oldStateId);
  8299. //pin to browser
  8300. $ax.dynamicPanelManager.adjustFixed(id, oldState.width(), oldState.height(), state.width(), state.height());
  8301. _bringPanelStateToFront(id, stateId, oldStateId, easingIn == 'none' || durationIn == '0');
  8302. var fitToContent = $ax.dynamicPanelManager.isIdFitToContent(id);
  8303. var resized = false;
  8304. if(fitToContent) {
  8305. // Set resized
  8306. resized = state.width() != oldState.width() || state.height() != oldState.height();
  8307. }
  8308. //edge case for sliding
  8309. var movement = (directionOut == 'left' || directionOut == 'up' || state.children().length == 0) && oldState.children().length != 0 ? oldState : state;
  8310. var onCompleteCount = 0;
  8311. var onComplete = function () {
  8312. //move this call from _setVisibility() for animate out.
  8313. //Because this will make the order of dp divs consistence: the showing panel is always in front after both animation finished
  8314. //tested in the cases where one panel is out/show slower/faster/same time/instantly.
  8315. _bringPanelStateToFront(id, stateId, oldStateId, false);
  8316. if (window.modifiedDynamicPanleParentOverflowProp) {
  8317. var parent = id ? $jobj(id) : child.parent();
  8318. parent.css('overflow', 'hidden');
  8319. window.modifiedDynamicPanleParentOverflowProp = false;
  8320. }
  8321. $ax.dynamicPanelManager.fitParentPanel(id);
  8322. $ax.dynamicPanelManager.updatePanelPercentWidth(id);
  8323. $ax.dynamicPanelManager.updatePanelContentPercentWidth(id);
  8324. $ax.action.fireAnimationFromQueue(id, $ax.action.queueTypes.setState);
  8325. $ax.event.raiseSyntheticEvent(id, "onPanelStateChange");
  8326. $ax.event.leavingState(oldStateId);
  8327. _popContainer(id, true);
  8328. };
  8329. // Must do state out first, so if we cull by new state, location is correct
  8330. _setVisibility(id, oldStateId, {
  8331. value: false,
  8332. easing: easingOut,
  8333. direction: directionOut,
  8334. duration: durationOut,
  8335. containerExists: true,
  8336. onComplete: function() {
  8337. // if(easingIn !== 'flip') _bringPanelStateToFront(id, stateId);
  8338. if (++onCompleteCount == 2) onComplete();
  8339. },
  8340. settingChild: true,
  8341. size: movement,
  8342. //cull for
  8343. cull: easingOut == 'none' || state.children().length == 0 ? oldState : state,
  8344. showFlipBack: true
  8345. });
  8346. _setVisibility(id, stateId, {
  8347. value: true,
  8348. easing: easingIn,
  8349. direction: directionIn,
  8350. duration: durationIn,
  8351. containerExists: true,
  8352. onComplete: function () {
  8353. // if (easingIn === 'flip') _bringPanelStateToFront(id, stateId);
  8354. if (++onCompleteCount == 2) onComplete();
  8355. },
  8356. settingChild: true,
  8357. //size for offset
  8358. size: movement,
  8359. showFlipBack: true
  8360. });
  8361. if(show) $ax.event.raiseSyntheticEvent(id, 'onShow');
  8362. if(resized) $ax.event.raiseSyntheticEvent(id, 'onResize');
  8363. };
  8364. var containedFixed = {};
  8365. var _pushContainer = _visibility.pushContainer = function(id, panel) {
  8366. var count = containerCount[id];
  8367. if(count) containerCount[id] = count + 1;
  8368. else {
  8369. var trapScroll = _trapScrollLoc(id);
  8370. var jobj = $jobj(id);
  8371. var children = jobj.children();
  8372. var css = {
  8373. position: 'relative',
  8374. top: 0,
  8375. left: 0
  8376. };
  8377. if(!panel) {
  8378. var boundingRect = $axure.fn.getWidgetBoundingRect(id);
  8379. css.top = boundingRect.top;
  8380. css.left = boundingRect.left;
  8381. }
  8382. var container = $('<div></div>');
  8383. container.attr('id', ''); // Placeholder id, so we won't try to recurse the container until it is ready
  8384. container.css(css);
  8385. //container.append(jobj.children());
  8386. jobj.append(container);
  8387. containerCount[id] = 1;
  8388. // Panel needs to wrap children
  8389. if(panel) {
  8390. for(var i = 0; i < children.length; i++) {
  8391. var child = $(children[i]);
  8392. var childContainer = $('<div></div>');
  8393. childContainer.attr('id', $ax.visibility.applyWidgetContainer(child.attr('id')));
  8394. childContainer.css(css);
  8395. child.after(childContainer);
  8396. childContainer.append(child);
  8397. container.append(childContainer);
  8398. }
  8399. } else {
  8400. var focus = _getCurrFocus();
  8401. if(focus) $ax.event.addSuppressedEvent($ax.repeater.removeSuffixFromElementId(focus), 'OnLostFocus');
  8402. // Layer needs to fix top left
  8403. var childIds = $ax('#' + id).getChildren()[0].children;
  8404. for(var i = 0; i < childIds.length; i++) {
  8405. var childId = childIds[i];
  8406. var childObj = $jobj(childId);
  8407. var fixedInfo = $ax.dynamicPanelManager.getFixedInfo(childId);
  8408. if(fixedInfo.fixed) {
  8409. var axObj = $ax('#' + childId);
  8410. var left = axObj.left();
  8411. var top = axObj.top();
  8412. containedFixed[childId] = { left: left, top: top, fixed: fixedInfo };
  8413. childObj.css('left', left);
  8414. childObj.css('top', top);
  8415. childObj.css('margin-left', 0);
  8416. childObj.css('margin-top', 0);
  8417. childObj.css('right', 'auto');
  8418. childObj.css('bottom', 'auto');
  8419. childObj.css('position', 'absolute');
  8420. }
  8421. var cssChange = {
  8422. left: '-=' + css.left,
  8423. top: '-=' + css.top
  8424. };
  8425. if($ax.getTypeFromElementId(childId) == $ax.constants.LAYER_TYPE) {
  8426. _pushContainer(childId, false);
  8427. $ax.visibility.applyWidgetContainer(childId, true).css(cssChange);
  8428. } else {
  8429. //if ($ax.public.fn.isCompoundVectorHtml(jobj[0])) {
  8430. // var grandChildren = jobj[0].children;
  8431. // //while (grandChildren.length > 0 && grandChildren[0].id.indexOf('container') >= 0) grandChildren = grandChildren[0].children;
  8432. // for (var j = 0; j < grandChildren.length; j++) {
  8433. // var grandChildId = grandChildren[j].id;
  8434. // if (grandChildId.indexOf(childId + 'p') >= 0 || grandChildId.indexOf('_container') >= 0) $jobj(grandChildId).css(cssChange);
  8435. // }
  8436. //} else
  8437. // Need to include ann and ref in move.
  8438. childObj = $addAll(childObj, childId);
  8439. childObj.css(cssChange);
  8440. }
  8441. container.append(childObj);
  8442. }
  8443. _setCurrFocus(focus);
  8444. }
  8445. container.attr('id', $ax.visibility.applyWidgetContainer(id)); // Setting the correct final id for the container
  8446. trapScroll();
  8447. }
  8448. };
  8449. var _popContainer = _visibility.popContainer = function (id, panel) {
  8450. var count = containerCount[id];
  8451. if(!count) return;
  8452. count--;
  8453. containerCount[id] = count;
  8454. if(count != 0) return;
  8455. var trapScroll = _trapScrollLoc(id);
  8456. var jobj = $jobj(id);
  8457. var container = $ax.visibility.applyWidgetContainer(id, true);
  8458. // If layer is at bottom or right of page, unwrapping could change scroll by temporarily reducting page size.
  8459. // To avoid this, we let container persist on page, with the size it is at this point, and don't remove container completely
  8460. // until the children are back to their proper locations.
  8461. var size = $ax('#' + id).size();
  8462. container.css('width', size.width);
  8463. container.css('height', size.height);
  8464. var focus = _getCurrFocus();
  8465. if(focus) $ax.event.addSuppressedEvent($ax.repeater.removeSuffixFromElementId(focus), 'OnLostFocus');
  8466. jobj.append(container.children());
  8467. _setCurrFocus(focus);
  8468. $('body').append(container);
  8469. // Layer doesn't have children containers to clean up
  8470. if(panel) {
  8471. var children = jobj.children();
  8472. for(var i = 0; i < children.length; i++) {
  8473. var childContainer = $(children[i]);
  8474. var child = $(childContainer.children()[0]);
  8475. childContainer.after(child);
  8476. childContainer.remove();
  8477. }
  8478. } else {
  8479. var left = container.css('left');
  8480. var top = container.css('top');
  8481. var childIds = $ax('#' + id).getChildren()[0].children;
  8482. for (var i = 0; i < childIds.length; i++) {
  8483. var childId = childIds[i];
  8484. var cssChange = {
  8485. left: '+=' + left,
  8486. top: '+=' + top
  8487. };
  8488. if($ax.getTypeFromElementId(childId) == $ax.constants.LAYER_TYPE) {
  8489. $ax.visibility.applyWidgetContainer(childId, true).css(cssChange);
  8490. _popContainer(childId, false);
  8491. } else {
  8492. var childObj = $jobj(childId);
  8493. // if ($ax.public.fn.isCompoundVectorHtml(jobj[0])) {
  8494. // var grandChildren = jobj[0].children;
  8495. // //while (grandChildren.length > 0 && grandChildren[0].id.indexOf('container') >= 0) grandChildren = grandChildren[0].children;
  8496. // for (var j = 0; j < grandChildren.length; j++) {
  8497. // var grandChildId = grandChildren[j].id;
  8498. // if (grandChildId.indexOf(childId + 'p') >= 0 || grandChildId.indexOf('_container') >= 0) $jobj(grandChildId).css(cssChange);
  8499. // }
  8500. //} else
  8501. var allObjs = $addAll(childObj, childId); // Just include other objects for initial css. Fixed panels need to be dealt with separately.
  8502. allObjs.css(cssChange);
  8503. var fixedInfo = containedFixed[childId];
  8504. if(fixedInfo) {
  8505. delete containedFixed[childId];
  8506. childObj.css('position', 'fixed');
  8507. var deltaX = $ax.getNumFromPx(childObj.css('left')) - fixedInfo.left;
  8508. var deltaY = $ax.getNumFromPx(childObj.css('top')) - fixedInfo.top;
  8509. fixedInfo = fixedInfo.fixed;
  8510. if(fixedInfo.horizontal == 'left') childObj.css('left', fixedInfo.x + deltaX);
  8511. else if(fixedInfo.horizontal == 'center') {
  8512. childObj.css('left', '50%');
  8513. childObj.css('margin-left', fixedInfo.x + deltaX);
  8514. } else {
  8515. childObj.css('left', 'auto');
  8516. childObj.css('right', fixedInfo.x - deltaX);
  8517. }
  8518. if(fixedInfo.vertical == 'top') childObj.css('top', fixedInfo.y + deltaY);
  8519. else if(fixedInfo.vertical == 'middle') {
  8520. childObj.css('top', '50%');
  8521. childObj.css('margin-top', fixedInfo.y + deltaY);
  8522. } else {
  8523. childObj.css('top', 'auto');
  8524. childObj.css('bottom', fixedInfo.y - deltaY);
  8525. }
  8526. $ax.dynamicPanelManager.updatePanelPercentWidth(childId);
  8527. $ax.dynamicPanelManager.updatePanelContentPercentWidth(childId);
  8528. }
  8529. }
  8530. }
  8531. }
  8532. container.remove();
  8533. trapScroll();
  8534. };
  8535. var _trapScrollLoc = function(id) {
  8536. var locs = {};
  8537. var states = $jobj(id).find('.panel_state');
  8538. for(var i = 0; i < states.length; i++) {
  8539. var state = $(states[i]);
  8540. locs[state.attr('id')] = { x: state.scrollLeft(), y: state.scrollTop() };
  8541. }
  8542. return function() {
  8543. for(var key in locs) {
  8544. var state = $jobj(key);
  8545. state.scrollLeft(locs[key].x);
  8546. state.scrollTop(locs[key].y);
  8547. }
  8548. };
  8549. }
  8550. var _getCurrFocus = function () {
  8551. // Only care about focused a tags and inputs
  8552. var id = window.lastFocusedClickable && window.lastFocusedClickable.id;
  8553. if(!id) return id;
  8554. var jobj = $(window.lastFocusedClickable);
  8555. return jobj.is('a') || jobj.is('input') ? id : '';
  8556. }
  8557. var _setCurrFocus = function(id) {
  8558. if(id) {
  8559. // This is really just needed for IE, so if this causes issues on other browsers, try adding that check here
  8560. var trap = $ax.event.blockEvent($ax.repeater.removeSuffixFromElementId(id), 'OnFocus');
  8561. window.setTimeout(function () {
  8562. $jobj(id).focus();
  8563. trap();
  8564. }, 0);
  8565. }
  8566. }
  8567. //use this to save & restore DP's scroll position when show/hide
  8568. //key => dp's id (not state's id, because it seems we can change state while hiding)
  8569. //value => first state's id & scroll position
  8570. //we only need to store one scroll position for one DP, and remove the key after shown.
  8571. var DPStateAndScroll = {}
  8572. var _tryResumeScrollForDP = function (dpId, deleteId) {
  8573. var scrollObj = DPStateAndScroll[dpId];
  8574. if(scrollObj) {
  8575. var shownState = document.getElementById(scrollObj.shownId);
  8576. if(scrollObj.left) shownState.scrollLeft = scrollObj.left;
  8577. if(scrollObj.top) shownState.scrollTop = scrollObj.top;
  8578. if(deleteId) delete DPStateAndScroll[dpId];
  8579. }
  8580. };
  8581. // var _makeContainer = function (containerId, rect, isFullWidth, isFlip, offset, containerExists) {
  8582. var _makeContainer = function (containerId, width, height, isFullWidth, isFlip, offset, containerExists) {
  8583. if(containerExists) var container = $jobj(containerId);
  8584. else {
  8585. container = $('<div></div>');
  8586. container.attr('id', containerId);
  8587. }
  8588. var css = {
  8589. position: 'absolute',
  8590. width: width,
  8591. height: height,
  8592. };
  8593. if(!containerExists) {
  8594. // If container exists, may be busy updating location. Will init and update it correctly.
  8595. css.top = offset.top;
  8596. css.left = offset.left;
  8597. }
  8598. if(isFlip) {
  8599. css.perspective = '800px';
  8600. css.webkitPerspective = "800px";
  8601. css.mozPerspective = "800px";
  8602. } else css.overflow = 'hidden';
  8603. //perspective on container will give us 3d effect when flip
  8604. //if(!isFlip) css.overflow = 'hidden';
  8605. // Rect should be a jquery not axquery obj
  8606. //_getFixedCss(css, rect.$ ? rect.$() : rect, fixedInfo, isFullWidth);
  8607. container.css(css);
  8608. return container;
  8609. };
  8610. var CONTAINER_SUFFIX = _visibility.CONTAINER_SUFFIX = '_container';
  8611. var CONTAINER_INNER = CONTAINER_SUFFIX + '_inner';
  8612. _visibility.getWidgetFromContainer = function(id) {
  8613. var containerIndex = id.indexOf(CONTAINER_SUFFIX);
  8614. if(containerIndex == -1) return id;
  8615. return id.substr(0, containerIndex) + id.substr(containerIndex + CONTAINER_SUFFIX.length);
  8616. };
  8617. // Apply container to widget id if necessary.
  8618. // returnJobj: True if you want the jquery object rather than id returned
  8619. // skipCheck: True if you want the query returned reguardless of container existing
  8620. // checkInner: True if inner container should be checked
  8621. _visibility.applyWidgetContainer = function (id, returnJobj, skipCheck, checkInner) {
  8622. // If container exists, just return (return query if requested)
  8623. if(id.indexOf(CONTAINER_SUFFIX) != -1) return returnJobj ? $jobj(id) : id;
  8624. // Get desired id, and return it if query is not desired
  8625. var containerId = $ax.repeater.applySuffixToElementId(id, checkInner ? CONTAINER_INNER : CONTAINER_SUFFIX);
  8626. if(!returnJobj) return containerId;
  8627. // If skipping check or container exists, just return innermost container requested
  8628. var container = $jobj(containerId);
  8629. if(skipCheck || container.length) return container;
  8630. // If inner container was not checked, then no more to check, return query for widget
  8631. if(!checkInner) return $jobj(id);
  8632. // If inner container was checked, check for regular container still
  8633. container = $jobj($ax.repeater.applySuffixToElementId(id, CONTAINER_SUFFIX));
  8634. return container.length ? container : $jobj(id);
  8635. };
  8636. _visibility.isContainer = function(id) {
  8637. return id.indexOf(CONTAINER_SUFFIX) != -1;
  8638. };
  8639. _visibility.getRealChildren = function(query) {
  8640. while(query.length && $(query[0]).attr('id').indexOf(CONTAINER_SUFFIX) != -1) query = query.children();
  8641. return query;
  8642. };
  8643. var _getFixedCss = function(css, rect, fixedInfo, isFullWidth) {
  8644. // todo: **mas** make sure this is ok
  8645. if(fixedInfo.fixed) {
  8646. css.position = 'fixed';
  8647. if(fixedInfo.horizontal == 'left') css.left = fixedInfo.x;
  8648. else if(fixedInfo.horizontal == 'center') {
  8649. css.left = isFullWidth ? '0px' : '50%';
  8650. css['margin-left'] = fixedInfo.x;
  8651. } else if(fixedInfo.horizontal == 'right') {
  8652. css.left = 'auto';
  8653. css.right = fixedInfo.x;
  8654. }
  8655. if(fixedInfo.vertical == 'top') css.top = fixedInfo.y;
  8656. else if(fixedInfo.vertical == 'middle') {
  8657. css.top = '50%';
  8658. css['margin-top'] = fixedInfo.y;
  8659. } else if(fixedInfo.vertical == 'bottom') {
  8660. css.top = 'auto';
  8661. css.bottom = fixedInfo.y;
  8662. }
  8663. } else {
  8664. css.left = Number(rect.css('left').replace('px', '')) || 0;
  8665. css.top = Number(rect.css('top').replace('px', '')) || 0;
  8666. }
  8667. };
  8668. var _slideStateOut = function (container, stateId, options, onComplete, jobj) {
  8669. var directionOut = options.direction;
  8670. var axObject = $ax('#' + container.attr('id'));
  8671. var width = axObject.width();
  8672. var height = axObject.height();
  8673. if(directionOut == "right") {
  8674. $ax.move.MoveWidget(stateId, width, 0, options, false, onComplete, false, jobj, true);
  8675. } else if(directionOut == "left") {
  8676. $ax.move.MoveWidget(stateId, -width, 0, options, false, onComplete, false, jobj, true);
  8677. } else if(directionOut == "up") {
  8678. $ax.move.MoveWidget(stateId, 0, -height, options, false, onComplete, false, jobj, true);
  8679. } else if(directionOut == "down") {
  8680. $ax.move.MoveWidget(stateId, 0, height, options, false, onComplete, false, jobj, true);
  8681. }
  8682. };
  8683. var _slideStateIn = function (id, stateId, options, container, makePanelVisible, onComplete, jobj, preserveScroll) {
  8684. var directionIn = options.direction;
  8685. var axObject = $ax('#' +container.attr('id'));
  8686. var width = axObject.width();
  8687. var height = axObject.height();
  8688. for(var i = 0; i < jobj.length; i++) {
  8689. var child = $(jobj[i]);
  8690. var oldTop = $ax.getNumFromPx(fixAuto(child, 'top'));
  8691. var oldLeft = $ax.getNumFromPx(fixAuto(child, 'left'));
  8692. if (directionIn == "right") {
  8693. child.css('left', oldLeft - width + 'px');
  8694. } else if(directionIn == "left") {
  8695. child.css('left', oldLeft + width + 'px');
  8696. } else if(directionIn == "up") {
  8697. child.css('top', oldTop + height + 'px');
  8698. } else if(directionIn == "down") {
  8699. child.css('top', oldTop - height + 'px');
  8700. }
  8701. }
  8702. if (makePanelVisible) $ax.visibility.SetIdVisible(id, true);
  8703. for(i = 0; i < jobj.length; i++) $ax.visibility.SetVisible(jobj[i], true);
  8704. if(preserveScroll) _tryResumeScrollForDP(id);
  8705. if(directionIn == "right") {
  8706. $ax.move.MoveWidget(stateId, width, 0, options, false, onComplete, false, jobj, true);
  8707. } else if(directionIn == "left") {
  8708. $ax.move.MoveWidget(stateId, -width, 0, options, false, onComplete, false, jobj, true);
  8709. } else if(directionIn == "up") {
  8710. $ax.move.MoveWidget(stateId, 0, -height, options, false, onComplete, false, jobj, true);
  8711. } else if(directionIn == "down") {
  8712. $ax.move.MoveWidget(stateId, 0, height, options, false, onComplete, false, jobj, true);
  8713. }
  8714. };
  8715. $ax.visibility.GetPanelStateId = function(dpId, index) {
  8716. var itemNum = $ax.repeater.getItemIdFromElementId(dpId);
  8717. var panelStateId = $ax.repeater.getScriptIdFromElementId(dpId) + '_state' + index;
  8718. return $ax.repeater.createElementId(panelStateId, itemNum);
  8719. };
  8720. $ax.visibility.GetPanelStateCount = function(id) {
  8721. return $ax.visibility.getRealChildren($jobj(id).children()).length;
  8722. };
  8723. var _bringPanelStateToFront = function (dpId, stateId, oldStateId, oldInFront) {
  8724. var panel = $jobj(dpId);
  8725. var frontId = oldInFront ? oldStateId : stateId;
  8726. if(containerCount[dpId]) {
  8727. frontId = $ax.visibility.applyWidgetContainer(frontId);
  8728. panel = $ax.visibility.applyWidgetContainer(dpId, true, false, true);
  8729. }
  8730. $jobj(frontId).appendTo(panel);
  8731. //when bring a panel to front, it will be focused, and the previous front panel should fire blur event if it's lastFocusedClickableSelector
  8732. //ie(currently 11) and firefox(currently 34) doesn't fire blur event, this is the hack to fire it manually
  8733. if((IE || FIREFOX) && window.lastFocusedClickable && $ax.event.getFocusableWidgetOrChildId(window.lastFocusedControl) == window.lastFocusedClickable.id) {
  8734. // Only need to do this if the currently focused widget is in the panel state that is being hidden.
  8735. if($jobj(oldStateId).find('#' + window.lastFocusedClickable.id.split('_')[0]).length) $(window.lastFocusedClickable).triggerHandler('blur');
  8736. }
  8737. };
  8738. var _limboIds = _visibility.limboIds = {};
  8739. // limboId's is a dictionary of id->true, essentially a set.
  8740. var _addLimboAndHiddenIds = $ax.visibility.addLimboAndHiddenIds = function(newLimboIds, newHiddenIds, query, skipRepeater) {
  8741. var limboedByMaster = {};
  8742. for(var key in newLimboIds) {
  8743. if (!$ax.public.fn.IsReferenceDiagramObject($ax.getObjectFromElementId(key).type)) continue;
  8744. var ids = $ax.model.idsInRdoToHideOrLimbo(key);
  8745. for(var i = 0; i < ids.length; i++) limboedByMaster[ids[i]] = true;
  8746. }
  8747. var hiddenByMaster = {};
  8748. for(key in newHiddenIds) {
  8749. if (!$ax.public.fn.IsReferenceDiagramObject($ax.getObjectFromElementId(key).type)) continue;
  8750. ids = $ax.model.idsInRdoToHideOrLimbo(key);
  8751. for(i = 0; i < ids.length; i++) hiddenByMaster[ids[i]] = true;
  8752. }
  8753. // Extend with children of rdos
  8754. newLimboIds = $.extend(newLimboIds, limboedByMaster);
  8755. newHiddenIds = $.extend(newHiddenIds, hiddenByMaster);
  8756. // something is only visible if it's not hidden and limboed
  8757. query.each(function(diagramObject, elementId) {
  8758. // Rdos already handled, contained widgets are limboed by the parent, and sub menus should be ignored
  8759. if(diagramObject.isContained || $ax.public.fn.IsReferenceDiagramObject(diagramObject.type) || $ax.public.fn.IsTableCell(diagramObject.type) || $jobj(elementId).hasClass('sub_menu')) return;
  8760. if(diagramObject.type == 'table' && $jobj(elementId).parent().hasClass('ax_menu')) return;
  8761. if(skipRepeater) {
  8762. // Any item in a repeater should return
  8763. if($ax.getParentRepeaterFromElementIdExcludeSelf(elementId)) return;
  8764. }
  8765. var scriptId = $ax.repeater.getScriptIdFromElementId(elementId);
  8766. var shouldBeVisible = Boolean(!newLimboIds[scriptId] && !newHiddenIds[scriptId]);
  8767. var isVisible = Boolean(_isIdVisible(elementId));
  8768. if(shouldBeVisible != isVisible) {
  8769. _setWidgetVisibility(elementId, { value: shouldBeVisible, noContainer: true });
  8770. }
  8771. });
  8772. _limboIds = _visibility.limboIds = $.extend(_limboIds, newLimboIds);
  8773. };
  8774. var _clearLimboAndHidden = $ax.visibility.clearLimboAndHidden = function(ids) {
  8775. _limboIds = _visibility.limboIds = {};
  8776. };
  8777. $ax.visibility.clearLimboAndHiddenIds = function(ids) {
  8778. for(var i = 0; i < ids.length; i++) {
  8779. var scriptId = $ax.repeater.getScriptIdFromElementId(ids[i]);
  8780. delete _limboIds[scriptId];
  8781. }
  8782. };
  8783. $ax.visibility.resetLimboAndHiddenToDefaults = function (query) {
  8784. if(!query) query = $ax('*');
  8785. _clearLimboAndHidden();
  8786. _addLimboAndHiddenIds(_defaultLimbo, _defaultHidden, query);
  8787. };
  8788. $ax.visibility.isScriptIdLimbo = function(scriptId) {
  8789. if(_limboIds[scriptId]) return true;
  8790. var repeater = $ax.getParentRepeaterFromScriptId(scriptId);
  8791. if(!repeater) return false;
  8792. var itemId = $ax.getItemIdsForRepeater(repeater)[0];
  8793. return _limboIds[$ax.repeater.createElementId(scriptId, itemId)];
  8794. }
  8795. $ax.visibility.isElementIdLimboOrInLimboContainer = function (elementId) {
  8796. var parent = document.getElementById(elementId);
  8797. while(parent) {
  8798. var scriptId = $ax.repeater.getScriptIdFromElementId($(parent).attr('id'));
  8799. if(_limboIds[scriptId]) return true;
  8800. parent = parent.parentElement;
  8801. }
  8802. return false;
  8803. }
  8804. $ax.visibility.initialize = function() {
  8805. // initialize initial visible states
  8806. $('.' + HIDDEN_CLASS).each(function (index, diagramObject) {
  8807. _defaultHidden[$ax.repeater.getScriptIdFromElementId(diagramObject.id)] = true;
  8808. });
  8809. $('.' + UNPLACED_CLASS).each(function (index, diagramObject) {
  8810. _defaultLimbo[$ax.repeater.getScriptIdFromElementId(diagramObject.id)] = true;
  8811. });
  8812. _addLimboAndHiddenIds(_defaultLimbo, _defaultHidden, $ax('*'), true);
  8813. };
  8814. _visibility.initRepeater = function(repeaterId) {
  8815. var html = $('<div></div>');
  8816. html.append($jobj(repeaterId + '_script').html());
  8817. html.find('.' + HIDDEN_CLASS).each(function (index, element) {
  8818. _defaultHidden[$ax.repeater.getScriptIdFromElementId(element.id)] = true;
  8819. });
  8820. html.find('.' + UNPLACED_CLASS).each(function (index, element) {
  8821. _defaultLimbo[$ax.repeater.getScriptIdFromElementId(element.id)] = true;
  8822. });
  8823. }
  8824. var HIDDEN_CLASS = _visibility.HIDDEN_CLASS = 'ax_default_hidden';
  8825. var UNPLACED_CLASS = _visibility.UNPLACED_CLASS = 'ax_default_unplaced';
  8826. });
  8827. //***** style.js *****//
  8828. $axure.internal(function($ax) {
  8829. var _style = {};
  8830. $ax.style = _style;
  8831. var _disabledWidgets = {};
  8832. var _selectedWidgets = {};
  8833. // A table to cache the outerHTML of the _rtf elements before the rollover state is applied.
  8834. var _originalTextCache = {};
  8835. // A table to exclude the normal style from adaptive overrides
  8836. var _shapesWithSetRichText = {};
  8837. // just a listing of shape ids
  8838. var _adaptiveStyledWidgets = {};
  8839. var _setLinkStyle = function(id, styleName) {
  8840. var parentId = $ax.GetParentIdFromLink(id);
  8841. var style = _computeAllOverrides(id, parentId, styleName, $ax.adaptive.currentViewId);
  8842. var textId = $ax.GetTextPanelId(parentId);
  8843. if(!_originalTextCache[textId]) {
  8844. $ax.style.CacheOriginalText(textId);
  8845. }
  8846. if($.isEmptyObject(style)) return;
  8847. var textCache = _originalTextCache[textId].styleCache;
  8848. _transformTextWithVerticalAlignment(textId, function() {
  8849. var cssProps = _getCssStyleProperties(style);
  8850. $('#' + id).find('*').andSelf().each(function(index, element) {
  8851. element.setAttribute('style', textCache[element.id]);
  8852. _applyCssProps(element, cssProps);
  8853. });
  8854. });
  8855. };
  8856. var _resetLinkStyle = function(id) {
  8857. var textId = $ax.GetTextPanelId($ax.GetParentIdFromLink(id));
  8858. var textCache = _originalTextCache[textId].styleCache;
  8859. _transformTextWithVerticalAlignment(textId, function() {
  8860. $('#' + id).find('*').andSelf().each(function(index, element) {
  8861. element.style.cssText = textCache[element.id];
  8862. });
  8863. });
  8864. if($ax.event.mouseDownObjectId) {
  8865. $ax.style.SetWidgetMouseDown($ax.event.mouseDownObjectId, true);
  8866. } else if($ax.event.mouseOverObjectId) {
  8867. $ax.style.SetWidgetHover($ax.event.mouseOverObjectId, true);
  8868. }
  8869. };
  8870. $ax.style.SetLinkHover = function(id) {
  8871. _setLinkStyle(id, MOUSE_OVER);
  8872. };
  8873. $ax.style.SetLinkNotHover = function(id) {
  8874. _resetLinkStyle(id);
  8875. };
  8876. $ax.style.SetLinkMouseDown = function(id) {
  8877. _setLinkStyle(id, MOUSE_DOWN);
  8878. };
  8879. $ax.style.SetLinkNotMouseDown = function(id) {
  8880. _resetLinkStyle(id);
  8881. var style = _computeAllOverrides(id, $ax.event.mouseOverObjectId, MOUSE_OVER, $ax.adaptive.currentViewId);
  8882. if(!$.isEmptyObject(style)) $ax.style.SetLinkHover(id);
  8883. //we dont do anything here because the widget not mouse down has taken over here
  8884. };
  8885. var _widgetHasState = function(id, state) {
  8886. if($ax.style.getElementImageOverride(id, state)) return true;
  8887. var diagramObject = $ax.getObjectFromElementId(id);
  8888. var adaptiveIdChain = $ax.adaptive.getAdaptiveIdChain($ax.adaptive.currentViewId);
  8889. for(var i = 0; i < adaptiveIdChain.length; i++) {
  8890. var viewId = adaptiveIdChain[i];
  8891. var adaptiveStyle = diagramObject.adaptiveStyles[viewId];
  8892. if(adaptiveStyle && adaptiveStyle.stateStyles && adaptiveStyle.stateStyles[state]) return true;
  8893. }
  8894. if(diagramObject.style.stateStyles) return diagramObject.style.stateStyles[state];
  8895. return false;
  8896. };
  8897. // Returns what overrides the hover, or false if nothing.
  8898. var _hoverOverride = function(id) {
  8899. if($ax.style.IsWidgetDisabled(id)) return DISABLED;
  8900. if($ax.style.IsWidgetSelected(id)) return SELECTED;
  8901. var obj = $ax.getObjectFromElementId(id);
  8902. if(!obj.isContained) return false;
  8903. var path = $ax.getPathFromScriptId($ax.repeater.getScriptIdFromElementId(id));
  8904. path[path.length - 1] = obj.parent.id;
  8905. var itemId = $ax.repeater.getItemIdFromElementId(id);
  8906. return _hoverOverride($ax.getElementIdFromPath(path, { itemNum: itemId }));
  8907. };
  8908. $ax.style.SetWidgetHover = function(id, value) {
  8909. var override = _hoverOverride(id);
  8910. if(override == DISABLED) return;
  8911. if(!_widgetHasState(id, MOUSE_OVER)) return;
  8912. var valToSet = value || _isRolloverOverride(id);
  8913. var state = _generateMouseState(id, valToSet ? MOUSE_OVER : NORMAL, override == SELECTED);
  8914. _applyImageAndTextJson(id, state);
  8915. _updateElementIdImageStyle(id, state);
  8916. };
  8917. var _rolloverOverrides = [];
  8918. var _isRolloverOverride = function(id) {
  8919. return _rolloverOverrides.indexOf(id) != -1;
  8920. };
  8921. $ax.style.AddRolloverOverride = function(id) {
  8922. if(_isRolloverOverride(id)) return;
  8923. _rolloverOverrides[_rolloverOverrides.length] = id;
  8924. if($ax.event.mouseOverIds.indexOf(id) == -1) $ax.style.SetWidgetHover(id, true);
  8925. };
  8926. $ax.style.RemoveRolloverOverride = function(id) {
  8927. var index = _rolloverOverrides.indexOf(id);
  8928. if(index == -1) return;
  8929. $ax.splice(_rolloverOverrides, index, 1);
  8930. if($ax.event.mouseOverIds.indexOf(id) == -1) $ax.style.SetWidgetHover(id, false);
  8931. };
  8932. // function GetWidgetCurrentState(id) {
  8933. // if($ax.style.IsWidgetDisabled(id)) return "disabled";
  8934. // if($ax.style.IsWidgetSelected(id)) return "selected";
  8935. // if($ax.event.mouseOverObjectId == id) return "mouseOver";
  8936. // if($ax.event.mouseDownObjectId == id) return "mouseDown";
  8937. // return "normal";
  8938. // }
  8939. $ax.style.ObjHasMouseDown = function(id) {
  8940. var obj = $obj(id);
  8941. if($ax.style.getElementImageOverride(id, 'mouseDown') || obj.style && obj.style.stateStyles && obj.style.stateStyles.mouseDown) return true;
  8942. var chain = $ax.adaptive.getAdaptiveIdChain($ax.adaptive.currentViewId);
  8943. for(var i = 0; i < chain.length; i++) {
  8944. var style = obj.adaptiveStyles[chain[i]];
  8945. if(style && style.stateStyles && style.stateStyles.mouseDown) return true;
  8946. }
  8947. return false;
  8948. };
  8949. $ax.style.SetWidgetMouseDown = function(id, value, checkMouseOver) {
  8950. if($ax.style.IsWidgetDisabled(id)) return;
  8951. if(!_widgetHasState(id, MOUSE_DOWN)) return;
  8952. //if set to value is true, it's mousedown, if check mouseover is true,
  8953. //check if element is currently mouseover and has mouseover state before setting mouseover
  8954. if(value) var state = MOUSE_DOWN;
  8955. else if(!checkMouseOver || $ax.event.mouseOverIds.indexOf(id) !== -1 && _widgetHasState(id, MOUSE_OVER)) state = MOUSE_OVER;
  8956. else state = NORMAL;
  8957. var mouseState = _generateMouseState(id, state, $ax.style.IsWidgetSelected(id));
  8958. _applyImageAndTextJson(id, mouseState);
  8959. _updateElementIdImageStyle(id, mouseState);
  8960. };
  8961. var _generateMouseState = function(id, mouseState, selected) {
  8962. if (selected) {
  8963. if (_style.getElementImageOverride(id, SELECTED)) return SELECTED;
  8964. var viewChain = $ax.adaptive.getAdaptiveIdChain($ax.adaptive.currentViewId);
  8965. viewChain[viewChain.length] = '';
  8966. var obj = $obj(id);
  8967. if($ax.IsDynamicPanel(obj.type) || $ax.IsLayer(obj.type)) return SELECTED;
  8968. var any = function(dict) {
  8969. for(var key in dict) return true;
  8970. return false;
  8971. };
  8972. for(var i = 0; i < viewChain.length; i++) {
  8973. var viewId = viewChain[i];
  8974. // Need to check seperately for images.
  8975. if(obj.adaptiveStyles && obj.adaptiveStyles[viewId] && any(obj.adaptiveStyles[viewId])
  8976. || obj.images && obj.images['selected~' + viewId]) return SELECTED;
  8977. }
  8978. var selectedStyle = obj.style && obj.style.stateStyles && obj.style.stateStyles.selected;
  8979. if(selectedStyle && any(selectedStyle)) return SELECTED;
  8980. }
  8981. // Not using selected
  8982. return mouseState;
  8983. };
  8984. $ax.style.SetWidgetSelected = function(id, value, alwaysApply) {
  8985. if(_isWidgetDisabled(id)) return;
  8986. //NOTE: not firing select events if state didn't change
  8987. var raiseSelectedEvents = $ax.style.IsWidgetSelected(id) != value;
  8988. if(value) {
  8989. var group = $('#' + id).attr('selectiongroup');
  8990. if(group) {
  8991. $("[selectiongroup='" + group + "']").each(function() {
  8992. var otherId = this.id;
  8993. if(otherId == id) return;
  8994. if ($ax.visibility.isScriptIdLimbo($ax.repeater.getScriptIdFromElementId(otherId))) return;
  8995. $ax.style.SetWidgetSelected(otherId, false);
  8996. });
  8997. }
  8998. }
  8999. var obj = $obj(id);
  9000. if(obj) {
  9001. var actionId = id;
  9002. if ($ax.public.fn.IsDynamicPanel(obj.type) || $ax.public.fn.IsLayer(obj.type)) {
  9003. if(!value) $jobj(id).removeClass('selected');
  9004. var children = $axure('#' + id).getChildren()[0].children;
  9005. for(var i = 0; i < children.length; i++) {
  9006. var childId = children[i];
  9007. // Special case for trees
  9008. var childObj = $jobj(childId);
  9009. if(childObj.hasClass('treeroot')) {
  9010. var treenodes = childObj.find('.treenode');
  9011. for(var j = 0; j < treenodes.length; j++) {
  9012. $axure('#' + treenodes[j].id).selected(value);
  9013. }
  9014. } else $axure('#' + childId).selected(value);
  9015. }
  9016. } else {
  9017. var widgetHasSelectedState = _widgetHasState(id, SELECTED);
  9018. while(obj.isContained && !widgetHasSelectedState) obj = obj.parent;
  9019. var itemId = $ax.repeater.getItemIdFromElementId(id);
  9020. var path = $ax.getPathFromScriptId($ax.repeater.getScriptIdFromElementId(id));
  9021. path[path.length - 1] = obj.id;
  9022. actionId = $ax.getElementIdFromPath(path, { itemNum: itemId });
  9023. if(alwaysApply || widgetHasSelectedState) {
  9024. var state = _generateSelectedState(actionId, value);
  9025. _applyImageAndTextJson(actionId, state);
  9026. _updateElementIdImageStyle(actionId, state);
  9027. }
  9028. //added actionId and this hacky logic because we set style state on child, but interaction on parent
  9029. //then the id saved in _selectedWidgets would be depended on widgetHasSelectedState... more see case 1818143
  9030. while(obj.isContained && !$ax.getObjectFromElementId(id).interactionMap) obj = obj.parent;
  9031. path = $ax.getPathFromScriptId($ax.repeater.getScriptIdFromElementId(id));
  9032. path[path.length - 1] = obj.id;
  9033. actionId = $ax.getElementIdFromPath(path, { itemNum: itemId });
  9034. }
  9035. }
  9036. // ApplyImageAndTextJson(id, value ? 'selected' : 'normal');
  9037. _selectedWidgets[id] = value;
  9038. if(raiseSelectedEvents) $ax.event.raiseSelectedEvents(actionId, value);
  9039. };
  9040. var _generateSelectedState = function(id, selected) {
  9041. var mouseState = $ax.event.mouseDownObjectId == id ? MOUSE_DOWN : $.inArray(id, $ax.event.mouseOverIds) != -1 ? MOUSE_OVER : NORMAL;
  9042. //var mouseState = $ax.event.mouseDownObjectId == id ? MOUSE_DOWN : $ax.event.mouseOverIds.indexOf(id) != -1 ? MOUSE_OVER : NORMAL;
  9043. return _generateMouseState(id, mouseState, selected);
  9044. };
  9045. $ax.style.IsWidgetSelected = function(id) {
  9046. return Boolean(_selectedWidgets[id]) || $('#'+id).hasClass('selected');
  9047. };
  9048. $ax.style.SetWidgetEnabled = function(id, value) {
  9049. _disabledWidgets[id] = !value;
  9050. $('#' + id).find('a').css('cursor', value ? 'pointer' : 'default');
  9051. if(!_widgetHasState(id, DISABLED)) return;
  9052. if(!value) {
  9053. _applyImageAndTextJson(id, DISABLED);
  9054. _updateElementIdImageStyle(id, DISABLED);
  9055. } else $ax.style.SetWidgetSelected(id, $ax.style.IsWidgetSelected(id), true);
  9056. };
  9057. $ax.style.SetWidgetPlaceholder = function(id, active, text, password) {
  9058. var inputId = $ax.repeater.applySuffixToElementId(id, '_input');
  9059. // Right now this is the only style on the widget. If other styles (ex. Rollover), are allowed
  9060. // on TextBox/TextArea, or Placeholder is applied to more widgets, this may need to do more.
  9061. var obj = $jobj(inputId);
  9062. var height = document.getElementById(inputId).style['height'];
  9063. var width = document.getElementById(inputId).style['width'];
  9064. obj.attr('style', '');
  9065. //removing all styles, but now we can change the size, so we should add them back
  9066. //this is more like a quick hack
  9067. if (height) obj.css('height', height);
  9068. if (width) obj.css('width', width);
  9069. if(!active) {
  9070. try { //ie8 and below error
  9071. if(password) document.getElementById(inputId).type = 'password';
  9072. } catch(e) { }
  9073. } else {
  9074. var element = $('#' + inputId)[0];
  9075. var style = _computeAllOverrides(id, undefined, HINT, $ax.adaptive.currentViewId);
  9076. var styleProperties = _getCssStyleProperties(style);
  9077. //moved this out of GetCssStyleProperties for now because it was breaking un/rollovers with gradient fills
  9078. if(style.fill) styleProperties.allProps.backgroundColor = _getColorFromFill(style.fill);
  9079. _applyCssProps(element, styleProperties, true);
  9080. try { //ie8 and below error
  9081. if(password && text) document.getElementById(inputId).type = 'text';
  9082. } catch(e) { }
  9083. }
  9084. obj.val(text);
  9085. };
  9086. var _isWidgetDisabled = $ax.style.IsWidgetDisabled = function(id) {
  9087. return Boolean(_disabledWidgets[id]);
  9088. };
  9089. var _elementIdsToImageOverrides = {};
  9090. $ax.style.mapElementIdToImageOverrides = function (elementId, override) {
  9091. for(var key in override) _addImageOverride(elementId, key, override[key]);
  9092. };
  9093. var _addImageOverride = function (elementId, state, val) {
  9094. if (!_elementIdsToImageOverrides[elementId]) _elementIdsToImageOverrides[elementId] = {};
  9095. _elementIdsToImageOverrides[elementId][state] = val;
  9096. }
  9097. $ax.style.deleteElementIdToImageOverride = function(elementId) {
  9098. delete _elementIdsToImageOverrides[elementId];
  9099. };
  9100. $ax.style.getElementImageOverride = function(elementId, state) {
  9101. var url = _elementIdsToImageOverrides[elementId] && _elementIdsToImageOverrides[elementId][state];
  9102. return url;
  9103. };
  9104. $ax.style.elementHasAnyImageOverride = function(elementId) {
  9105. return Boolean(_elementIdsToImageOverrides[elementId]);
  9106. };
  9107. var NORMAL = 'normal';
  9108. var MOUSE_OVER = 'mouseOver';
  9109. var MOUSE_DOWN = 'mouseDown';
  9110. var SELECTED = 'selected';
  9111. var DISABLED = 'disabled';
  9112. var HINT = 'hint';
  9113. var _generateState = _style.generateState = function(id) {
  9114. return $ax.placeholderManager.isActive(id) ? HINT : _style.IsWidgetDisabled(id) ? DISABLED : _generateSelectedState(id, _style.IsWidgetSelected(id));
  9115. };
  9116. var _progressState = _style.progessState = function(state) {
  9117. if(state == NORMAL) return false;
  9118. if(state == MOUSE_DOWN) return MOUSE_OVER;
  9119. return NORMAL;
  9120. };
  9121. var _unprogressState = function(state, goal) {
  9122. state = state || NORMAL;
  9123. if(state == goal) return undefined;
  9124. if(state == NORMAL && goal == MOUSE_DOWN) return MOUSE_OVER;
  9125. return goal;
  9126. };
  9127. var _updateElementIdImageStyle = _style.updateElementIdImageStyle = function(elementId, state) {
  9128. if(!_style.elementHasAnyImageOverride(elementId)) return;
  9129. if(!state) state = _generateState(elementId);
  9130. var style = _computeFullStyle(elementId, state, $ax.adaptive.currentViewId);
  9131. var query = $jobj($ax.repeater.applySuffixToElementId(elementId, '_img'));
  9132. style.size.width = query.width();
  9133. style.size.height = query.height();
  9134. var borderId = $ax.repeater.applySuffixToElementId(elementId, '_border');
  9135. var borderQuery = $jobj(borderId);
  9136. if(!borderQuery.length) {
  9137. borderQuery = $('<div></div>');
  9138. borderQuery.attr('id', borderId);
  9139. query.after(borderQuery);
  9140. }
  9141. borderQuery.attr('style', '');
  9142. borderQuery.css('position', 'absolute');
  9143. query.attr('style', '');
  9144. var borderWidth = Number(style.borderWidth);
  9145. var hasBorderWidth = borderWidth > 0;
  9146. if(hasBorderWidth) {
  9147. borderQuery.css('border-style', 'solid');
  9148. borderQuery.css('border-width', borderWidth + 'px'); // If images start being able to turn off borders on specific sides, need to update this.
  9149. borderQuery.css('width', style.size.width - borderWidth * 2);
  9150. borderQuery.css('height', style.size.height - borderWidth * 2);
  9151. }
  9152. var linePattern = style.linePattern;
  9153. if(hasBorderWidth && linePattern) borderQuery.css('border-style', linePattern);
  9154. var borderFill = style.borderFill;
  9155. if(hasBorderWidth && borderFill) {
  9156. var color = borderFill.fillType == 'solid' ? borderFill.color :
  9157. borderFill.fillType == 'linearGradient' ? borderFill.colors[0].color : 0;
  9158. var alpha = Math.floor(color / 256 / 256 / 256);
  9159. color -= alpha * 256 * 256 * 256;
  9160. alpha = alpha / 255;
  9161. var red = Math.floor(color / 256 / 256);
  9162. color -= red * 256 * 256;
  9163. var green = Math.floor(color / 256);
  9164. var blue = color - green * 256;
  9165. borderQuery.css('border-color', _rgbaToFunc(red, green, blue, alpha));
  9166. }
  9167. var cornerRadiusTopLeft = style.cornerRadius;
  9168. if(cornerRadiusTopLeft) {
  9169. query.css('border-radius', cornerRadiusTopLeft + 'px');
  9170. borderQuery.css('border-radius', cornerRadiusTopLeft + 'px');
  9171. }
  9172. var outerShadow = style.outerShadow;
  9173. if(outerShadow && outerShadow.on) {
  9174. var arg = '';
  9175. arg += outerShadow.offsetX + 'px' + ' ' + outerShadow.offsetY + 'px' + ' ';
  9176. var rgba = outerShadow.color;
  9177. arg += outerShadow.blurRadius + 'px' + ' 0px ' + _rgbaToFunc(rgba.r, rgba.g, rgba.b, rgba.a);
  9178. query.css('-moz-box-shadow', arg);
  9179. query.css('-wibkit-box-shadow', arg);
  9180. query.css('box-shadow', arg);
  9181. query.css('left', '0px');
  9182. query.css('top', '0px');
  9183. }
  9184. query.css({ width: style.size.width, height: style.size.height });
  9185. };
  9186. var _rgbaToFunc = function(red, green, blue, alpha) {
  9187. return 'rgba(' + red + ',' + green + ',' + blue + ',' + alpha + ')';
  9188. };
  9189. var _applyImageAndTextJson = function(id, event) {
  9190. var textId = $ax.GetTextPanelId(id);
  9191. if(textId) _resetTextJson(id, textId);
  9192. // This should never be the case
  9193. //if(event != '') {
  9194. var imgQuery = $jobj($ax.GetImageIdFromShape(id));
  9195. var e = imgQuery.data('events');
  9196. if(e && e[event]) imgQuery.trigger(event);
  9197. var imageUrl = $ax.adaptive.getImageForStateAndView(id, event);
  9198. if(imageUrl) _applyImage(id, imageUrl, event);
  9199. var style = _computeAllOverrides(id, undefined, event, $ax.adaptive.currentViewId);
  9200. if(!$.isEmptyObject(style) && textId) _applyTextStyle(textId, style);
  9201. _updateStateClasses(id, event);
  9202. _updateStateClasses($ax.repeater.applySuffixToElementId(id, '_div'), event);
  9203. };
  9204. var _updateStateClasses = function(id, event) {
  9205. var jobj = $jobj(id);
  9206. //if(jobj[0] && jobj[0].hasAttribute('widgetwidth')) {
  9207. // for (var x = 0; x < jobj[0].children.length; x++) {
  9208. // var childId = jobj[0].children[x].id;
  9209. // if (childId.indexOf('p') < 0) continue;
  9210. // _updateStateClasses(childId, event) ;
  9211. // }
  9212. //} else {
  9213. for (var i = 0; i < ALL_STATES.length; i++) jobj.removeClass(ALL_STATES[i]);
  9214. if (event == 'mouseDown') jobj.addClass('mouseOver');
  9215. if(event != 'normal') jobj.addClass(event);
  9216. //}
  9217. }
  9218. /* -------------------
  9219. here's the algorithm in a nutshell:
  9220. [DOWN] -- refers to navigation down the view inheritance heirarchy (default to most specific)
  9221. [UP] -- navigate up the heirarchy
  9222. ComputeAllOverrides (object):
  9223. All view styles [DOWN]
  9224. If hyperlink
  9225. - DO ComputeStateStyle for parent object
  9226. - if (MouseOver || MouseDown)
  9227. - linkMouseOver Style
  9228. - if (MouseDown)
  9229. - linkMouseDown style
  9230. - ComputeStateStyleForViewChain (parent, STATE)
  9231. if (MouseDown) DO ComputeStateStyleForViewChain for object, mouseOver
  9232. DO ComputeStateStyleForViewChain for object, style
  9233. ComputeStateStyleForViewChain (object, STATE)
  9234. FIRST STATE state style [UP] the chain OR default object STATE style
  9235. ------------------- */
  9236. var FONT_PROPS = {
  9237. 'typeface': true,
  9238. 'fontName': true,
  9239. 'fontWeight': true,
  9240. 'fontStyle': true,
  9241. 'fontStretch': true,
  9242. 'fontSize': true,
  9243. 'underline': true,
  9244. 'foreGroundFill': true,
  9245. 'horizontalAlignment': true
  9246. };
  9247. var _computeAllOverrides = $ax.style.computeAllOverrides = function(id, parentId, state, currentViewId) {
  9248. var computedStyle = {};
  9249. if(parentId) computedStyle = _computeAllOverrides(parentId, null, state, currentViewId);
  9250. var diagramObject = $ax.getObjectFromElementId(id);
  9251. var viewIdChain = $ax.adaptive.getAdaptiveIdChain(currentViewId);
  9252. var excludeFont = _shapesWithSetRichText[id];
  9253. for(var i = 0; i < viewIdChain.length; i++) {
  9254. var viewId = viewIdChain[i];
  9255. var style = diagramObject.adaptiveStyles[viewId];
  9256. if(style) {
  9257. // we want to exclude the normal font style for shapes where the rich text has been set with an interaction
  9258. // so we copy the style so we don't modify the original, then delete all the font props.
  9259. if(excludeFont) {
  9260. style = $ax.deepCopy(style);
  9261. for(var prop in FONT_PROPS) delete style[prop];
  9262. }
  9263. if(style) {
  9264. var customStyle = style.baseStyle && $ax.document.stylesheet.stylesById[style.baseStyle];
  9265. //make sure not to extend the customStyle this can mutate it for future use
  9266. $.extend(computedStyle, customStyle);
  9267. }
  9268. $.extend(computedStyle, style);
  9269. }
  9270. }
  9271. var currState = NORMAL;
  9272. while(currState) {
  9273. $.extend(computedStyle, _computeStateStyleForViewChain(diagramObject, currState, viewIdChain, true));
  9274. currState = _unprogressState(currState, state);
  9275. }
  9276. return _removeUnsupportedProperties(computedStyle, diagramObject.type);
  9277. };
  9278. var _computeStateStyleForViewChain = function(diagramObject, state, viewIdChain, excludeNormal) {
  9279. var styleObject = diagramObject;
  9280. while(styleObject.isContained) styleObject = styleObject.parent;
  9281. var adaptiveStyles = styleObject.adaptiveStyles;
  9282. for(var i = viewIdChain.length - 1; i >= 0; i--) {
  9283. var viewId = viewIdChain[i];
  9284. var viewStyle = adaptiveStyles[viewId];
  9285. var stateStyle = viewStyle && _getFullStateStyle(viewStyle, state, excludeNormal);
  9286. if(stateStyle) return $.extend({}, stateStyle);
  9287. }
  9288. // we dont want to actually include the object style because those are not overrides, hence the true for "excludeNormal" and not passing the val through
  9289. var stateStyleFromDefault = _getFullStateStyle(styleObject.style, state, true);
  9290. return $.extend({}, stateStyleFromDefault);
  9291. };
  9292. // returns the full effective style for an object in a state state and view
  9293. var _computeFullStyle = function(id, state, currentViewId) {
  9294. var obj = $obj(id);
  9295. var overrides = _computeAllOverrides(id, undefined, state, currentViewId);
  9296. // todo: account for image box
  9297. var objStyle = obj.style;
  9298. var customStyle = objStyle.baseStyle && $ax.document.stylesheet.stylesById[objStyle.baseStyle];
  9299. var returnVal = $.extend({}, $ax.document.stylesheet.defaultStyle, customStyle, objStyle, overrides);
  9300. return _removeUnsupportedProperties(returnVal, obj.type);
  9301. };
  9302. var _removeUnsupportedProperties = function(style, objectType) {
  9303. // for now all we need to do is remove padding from checkboxes and radio buttons
  9304. if ($ax.public.fn.IsRadioButton(objectType) || $ax.public.fn.IsCheckBox(objectType)) {
  9305. style.paddingTop = 0;
  9306. style.paddingLeft = 0;
  9307. style.paddingRight = 0;
  9308. style.paddingBottom = 0;
  9309. }
  9310. return style;
  9311. };
  9312. var _getFullStateStyle = function(style, state, excludeNormal) {
  9313. //'normal' is needed because now DiagramObjects get their image from the Style and unapplying a rollover needs the image
  9314. var stateStyle = state == 'normal' && !excludeNormal ? style : style && style.stateStyles && style.stateStyles[state];
  9315. if(stateStyle) {
  9316. var customStyle = stateStyle.baseStyle && $ax.document.stylesheet.stylesById[stateStyle.baseStyle];
  9317. //make sure not to extend the customStyle this can mutate it for future use
  9318. return $.extend({}, customStyle, stateStyle);
  9319. }
  9320. return undefined;
  9321. };
  9322. // commented this out for now... we actually will probably need it for ie
  9323. var _applyOpacityFromStyle = $ax.style.applyOpacityFromStyle = function(id, style) {
  9324. return;
  9325. var opacity = style.opacity || '';
  9326. $jobj(id).children().css('opacity', opacity);
  9327. };
  9328. var _initialize = function() {
  9329. //being handled at on window.load
  9330. //$ax.style.initializeObjectTextAlignment($ax('*'));
  9331. };
  9332. $ax.style.initialize = _initialize;
  9333. var _initTextAlignment = function(elementId) {
  9334. var textId = $ax.GetTextPanelId(elementId);
  9335. if(textId) {
  9336. _storeIdToAlignProps(textId);
  9337. // now handle vertical alignment
  9338. if(_getObjVisible(textId)) {
  9339. _setTextAlignment(textId, _idToAlignProps[textId], false);
  9340. }
  9341. }
  9342. };
  9343. $ax.style.initializeObjectTextAlignment = function(query) {
  9344. query.filter(function(diagramObject) {
  9345. return $ax.public.fn.IsVector(diagramObject.type) || $ax.public.fn.IsImageBox(diagramObject.type);
  9346. }).each(function(diagramObject, elementId) {
  9347. if($jobj(elementId).length == 0) return;
  9348. _initTextAlignment(elementId);
  9349. });
  9350. };
  9351. var _storeIdToAlignProps = function(textId) {
  9352. var shapeId = $ax.GetShapeIdFromText(textId);
  9353. var shapeObj = $obj(shapeId);
  9354. var state = _generateState(shapeId);
  9355. var style = _computeFullStyle(shapeId, state, $ax.adaptive.currentViewId);
  9356. var vAlign = style.verticalAlignment || 'middle';
  9357. var paddingLeft = Number(style.paddingLeft) || 0;
  9358. paddingLeft += (Number(shapeObj && shapeObj.extraLeft) || 0);
  9359. var paddingTop = style.paddingTop || 0;
  9360. var paddingRight = style.paddingRight || 0;
  9361. var paddingBottom = style.paddingBottom || 0;
  9362. _idToAlignProps[textId] = { vAlign: vAlign, paddingLeft: paddingLeft, paddingTop: paddingTop, paddingRight: paddingRight, paddingBottom: paddingBottom };
  9363. };
  9364. var ALL_STATES = ['mouseOver', 'mouseDown', 'selected', 'disabled'];
  9365. var _applyImage = $ax.style.applyImage = function (id, imgUrl, state) {
  9366. var object = $obj(id);
  9367. if (object.generateCompound) {
  9368. for (var i = 0; i < object.compoundChildren.length; i++) {
  9369. var componentId = object.compoundChildren[i];
  9370. var childId = $ax.public.fn.getComponentId(id, componentId);
  9371. var childImgQuery = $jobj(childId + '_img');
  9372. var childQuery = $jobj(childId);
  9373. childImgQuery.attr('src', imgUrl[componentId]);
  9374. for (var j = 0; j < ALL_STATES.length; j++) {
  9375. childImgQuery.removeClass(ALL_STATES[j]);
  9376. childQuery.removeClass(ALL_STATES[j]);
  9377. }
  9378. if (state != 'normal') {
  9379. childImgQuery.addClass(state);
  9380. childQuery.addClass(state);
  9381. }
  9382. }
  9383. } else {
  9384. var imgQuery = $jobj($ax.GetImageIdFromShape(id));
  9385. var idQuery = $jobj(id);
  9386. //it is hard to tell if setting the image or the class first causing less flashing when adding shadows.
  9387. imgQuery.attr('src', imgUrl);
  9388. for (var i = 0; i < ALL_STATES.length; i++) {
  9389. idQuery.removeClass(ALL_STATES[i]);
  9390. imgQuery.removeClass(ALL_STATES[i]);
  9391. }
  9392. if (state != 'normal') {
  9393. idQuery.addClass(state);
  9394. imgQuery.addClass(state);
  9395. }
  9396. if (imgQuery.parents('a.basiclink').length > 0) imgQuery.css('border', 'none');
  9397. if (imgUrl.indexOf(".png") > -1) $ax.utils.fixPng(imgQuery[0]);
  9398. }
  9399. };
  9400. $ax.public.fn.getComponentId = function (id, componentId) {
  9401. var idParts = id.split('-');
  9402. idParts[0] = idParts[0] + componentId;
  9403. return idParts.join('-');
  9404. }
  9405. var _resetTextJson = function(id, textid) {
  9406. // reset the opacity
  9407. $jobj(id).children().css('opacity', '');
  9408. var cacheObject = _originalTextCache[textid];
  9409. if(cacheObject) {
  9410. _transformTextWithVerticalAlignment(textid, function() {
  9411. var styleCache = cacheObject.styleCache;
  9412. var textQuery = $('#' + textid);
  9413. textQuery.find('*').each(function(index, element) {
  9414. element.style.cssText = styleCache[element.id];
  9415. });
  9416. });
  9417. }
  9418. };
  9419. // Preserves the alingment for the element textid after executing transformFn
  9420. var _getRtfElementHeight = function(rtfElement) {
  9421. if(rtfElement.innerHTML == '') rtfElement.innerHTML = '&nbsp;';
  9422. // To handle render text as image
  9423. var images = $(rtfElement).children('img');
  9424. if(images.length) return images.height();
  9425. return rtfElement.offsetHeight;
  9426. };
  9427. // why microsoft decided to default to round to even is beyond me...
  9428. var _roundToEven = function(number) {
  9429. var numString = number.toString();
  9430. var parts = numString.split('.');
  9431. if(parts.length == 1) return number;
  9432. if(parts[1].length == 1 && parts[1] == '5') {
  9433. var wholePart = Number(parts[0]);
  9434. return wholePart % 2 == 0 ? wholePart : wholePart + 1;
  9435. } else return Math.round(number);
  9436. };
  9437. var _transformTextWithVerticalAlignment = $ax.style.transformTextWithVerticalAlignment = function(textId, transformFn) {
  9438. if(!_originalTextCache[textId]) {
  9439. $ax.style.CacheOriginalText(textId);
  9440. }
  9441. var rtfElement = window.document.getElementById(textId);
  9442. if(!rtfElement) return;
  9443. transformFn();
  9444. _storeIdToAlignProps(textId);
  9445. $ax.style.updateTextAlignmentForVisibility(textId);
  9446. };
  9447. // this is for vertical alignments set on hidden objects
  9448. var _idToAlignProps = {};
  9449. $ax.style.updateTextAlignmentForVisibility = function (textId) {
  9450. var textObj = $jobj(textId);
  9451. // must check if parent id exists. Doesn't exist for text objs in check boxes, and potentially elsewhere.
  9452. var parentId = textObj.parent().attr('id');
  9453. if (parentId && $ax.visibility.isContainer(parentId)) return;
  9454. var alignProps = _idToAlignProps[textId];
  9455. if(!alignProps || !_getObjVisible(textId)) return;
  9456. _setTextAlignment(textId, alignProps);
  9457. };
  9458. var _getObjVisible = _style.getObjVisible = function (id) {
  9459. var element = document.getElementById(id);
  9460. return element && (element.offsetWidth || element.offsetHeight);
  9461. };
  9462. var _setTextAlignment = function(textId, alignProps, updateProps) {
  9463. if(updateProps) _storeIdToAlignProps(textId);
  9464. if(!alignProps) return;
  9465. var vAlign = alignProps.vAlign;
  9466. var paddingTop = Number(alignProps.paddingTop);
  9467. var paddingBottom = Number(alignProps.paddingBottom);
  9468. var paddingLeft = Number(alignProps.paddingLeft);
  9469. var paddingRight = Number(alignProps.paddingRight);
  9470. var topParam = 0.0;
  9471. var bottomParam = 1.0;
  9472. var leftParam = 0.0;
  9473. var rightParam = 1.0;
  9474. var textObj = $jobj(textId);
  9475. var textObjParent = textObj.offsetParent();
  9476. var parentId = textObjParent.attr('id');
  9477. if(!parentId) {
  9478. // Only case should be for radio/checkbox that get the label now because it must be absolute positioned for animate (offset parent ignored it before)
  9479. textObjParent = textObjParent.parent();
  9480. parentId = textObjParent.attr('id');
  9481. }
  9482. parentId = $ax.visibility.getWidgetFromContainer(textObjParent.attr('id'));
  9483. textObjParent = $jobj(parentId);
  9484. var parentObj = $obj(parentId);
  9485. if(parentObj['bottomTextPadding']) bottomParam = parentObj['bottomTextPadding'];
  9486. if(parentObj['topTextPadding']) topParam = parentObj['topTextPadding'];
  9487. if(parentObj['leftTextPadding']) leftParam = parentObj['leftTextPadding'];
  9488. if(parentObj['rightTextPadding']) rightParam = parentObj['rightTextPadding'];
  9489. // smart shapes are mutually exclusive from compound vectors.
  9490. var isConnector = parentObj.type == $ax.constants.CONNECTOR_TYPE;
  9491. if(isConnector) return;
  9492. var axTextObjectParent = $ax('#' + textObjParent.attr('id'));
  9493. var oldWidth = $ax.getNumFromPx(textObj.css('width'));
  9494. var oldLeft = $ax.getNumFromPx(textObj.css('left'));
  9495. var oldTop = $ax.getNumFromPx(textObj.css('top'));
  9496. var newTop = 0;
  9497. var newLeft = 0.0;
  9498. var width = axTextObjectParent.width();
  9499. var height = axTextObjectParent.height();
  9500. // If text rotated need to handle getting the correct width for text based on bounding rect of rotated parent.
  9501. var boundingRotation = -$ax.move.getRotationDegreeFromElement(textObj[0]);
  9502. var boundingParent = $axure.fn.getBoundingSizeForRotate(width, height, boundingRotation);
  9503. var extraLeftPadding = (width - boundingParent.width) / 2;
  9504. width = boundingParent.width;
  9505. var relativeTop = 0.0;
  9506. relativeTop = height * topParam;
  9507. var containerHeight = height * bottomParam - relativeTop;
  9508. newLeft = paddingLeft + extraLeftPadding + width * leftParam;
  9509. var newWidth = width * (rightParam - leftParam) - paddingLeft - paddingRight;
  9510. var horizChange = newWidth != oldWidth || newLeft != oldLeft;
  9511. if(horizChange) {
  9512. textObj.css('left', newLeft);
  9513. textObj.width(newWidth);
  9514. }
  9515. var textHeight = _getRtfElementHeight(textObj[0]);
  9516. if(vAlign == "middle") newTop = _roundToEven(relativeTop + (containerHeight - textHeight + paddingTop - paddingBottom) / 2);
  9517. else if(vAlign == "bottom") newTop = _roundToEven(relativeTop + containerHeight - textHeight - paddingBottom);
  9518. else newTop = _roundToEven(paddingTop + relativeTop);
  9519. var vertChange = oldTop != newTop;
  9520. if(vertChange) textObj.css('top', newTop + 'px');
  9521. if((vertChange || horizChange)) _updateTransformOrigin(textId);
  9522. };
  9523. var _updateTransformOrigin = function(textId) {
  9524. var textObj = $jobj(textId);
  9525. var transformOrigin = textObj.css('-webkit-transform-origin') ||
  9526. textObj.css('-moz-transform-origin') ||
  9527. textObj.css('-ms-transform-origin') ||
  9528. textObj.css('transform-origin');
  9529. if(transformOrigin) {
  9530. var textObjParent = $ax('#' + textObj.parent().attr('id'));
  9531. var newX = (textObjParent.width() / 2 - textObj.css('left').replace('px', ''));
  9532. var newY = (textObjParent.height() / 2 - textObj.css('top').replace('px', ''));
  9533. var newOrigin = newX + 'px ' + newY + 'px';
  9534. textObj.css('-webkit-transform-origin', newOrigin);
  9535. textObj.css('-moz-transform-origin', newOrigin);
  9536. textObj.css('-ms-transform-origin', newOrigin);
  9537. textObj.css('transform-origin', newOrigin);
  9538. }
  9539. };
  9540. $ax.style.reselectElements = function() {
  9541. for(var id in _selectedWidgets) {
  9542. // Only looking for the selected widgets that don't have their class set
  9543. if(!_selectedWidgets[id] || $jobj(id).hasClass('selected')) continue;
  9544. $jobj(id).addClass('selected');
  9545. _applyImageAndTextJson(id, $ax.style.generateState(id));
  9546. }
  9547. for(id in _disabledWidgets) {
  9548. // Only looking for the disabled widgets that don't have their class yet
  9549. if (!_disabledWidgets[id] || $jobj(id).hasClass('disabled')) continue;
  9550. $jobj(id).addClass('disabled');
  9551. _applyImageAndTextJson(id, $ax.style.generateState(id));
  9552. }
  9553. }
  9554. $ax.style.clearStateForRepeater = function(repeaterId) {
  9555. var children = $ax.getChildElementIdsForRepeater(repeaterId);
  9556. for(var i = 0; i < children.length; i++) {
  9557. var id = children[i];
  9558. delete _selectedWidgets[id];
  9559. delete _disabledWidgets[id];
  9560. }
  9561. }
  9562. _style.updateStateClass = function (repeaterId) {
  9563. var subElementIds = $ax.getChildElementIdsForRepeater(repeaterId);
  9564. for (var i = 0; i < subElementIds.length; i++) {
  9565. _applyImageAndTextJson(subElementIds[i], $ax.style.generateState(subElementIds[i]));
  9566. }
  9567. }
  9568. $ax.style.clearAdaptiveStyles = function() {
  9569. for(var shapeId in _adaptiveStyledWidgets) {
  9570. var repeaterId = $ax.getParentRepeaterFromScriptId(shapeId);
  9571. if(repeaterId) continue;
  9572. var elementId = $ax.GetButtonShapeId(shapeId);
  9573. if(elementId) _applyImageAndTextJson(elementId, $ax.style.generateState(elementId));
  9574. }
  9575. _adaptiveStyledWidgets = {};
  9576. };
  9577. $ax.style.setAdaptiveStyle = function(shapeId, style) {
  9578. _adaptiveStyledWidgets[$ax.repeater.getScriptIdFromElementId(shapeId)] = style;
  9579. var textId = $ax.GetTextPanelId(shapeId);
  9580. if(textId) _applyTextStyle(textId, style);
  9581. $ax.placeholderManager.refreshPlaceholder(shapeId);
  9582. // removing this for now
  9583. // if(style.location) {
  9584. // $jobj(shapeId).css('top', style.location.x + "px")
  9585. // .css('left', style.location.y + "px");
  9586. // }
  9587. };
  9588. //-------------------------------------------------------------------------
  9589. // _applyTextStyle
  9590. //
  9591. // Applies a rollover style to a text element.
  9592. // id : the id of the text object to set.
  9593. // styleProperties : an object mapping style properties to values. eg:
  9594. // { 'fontWeight' : 'bold',
  9595. // 'fontStyle' : 'italic' }
  9596. //-------------------------------------------------------------------------
  9597. var _applyTextStyle = function(id, style) {
  9598. _transformTextWithVerticalAlignment(id, function() {
  9599. var styleProperties = _getCssStyleProperties(style);
  9600. $('#' + id).find('*').each(function(index, element) {
  9601. _applyCssProps(element, styleProperties);
  9602. });
  9603. });
  9604. };
  9605. var _applyCssProps = function(element, styleProperties, applyAllStyle) {
  9606. if(applyAllStyle) {
  9607. var allProps = styleProperties.allProps;
  9608. for(var prop in allProps) element.style[prop] = allProps[prop];
  9609. } else {
  9610. var nodeName = element.nodeName.toLowerCase();
  9611. if(nodeName == 'p') {
  9612. var parProps = styleProperties.parProps;
  9613. for(prop in parProps) element.style[prop] = parProps[prop];
  9614. } else if(nodeName != 'a') {
  9615. var runProps = styleProperties.runProps;
  9616. for(prop in runProps) element.style[prop] = runProps[prop];
  9617. }
  9618. }
  9619. };
  9620. var _getCssShadow = function(shadow) {
  9621. return !shadow.on ? "none"
  9622. : shadow.offsetX + "px " + shadow.offsetY + "px " + shadow.blurRadius + "px " + _getCssColor(shadow.color);
  9623. };
  9624. var _getCssStyleProperties = function(style) {
  9625. var toApply = {};
  9626. toApply.runProps = {};
  9627. toApply.parProps = {};
  9628. toApply.allProps = {};
  9629. if(style.fontName) toApply.allProps.fontFamily = toApply.runProps.fontFamily = style.fontName;
  9630. // we need to set font size on both runs and pars because otherwise it well mess up the measure and thereby vertical alignment
  9631. if(style.fontSize) toApply.allProps.fontSize = toApply.runProps.fontSize = toApply.parProps.fontSize = style.fontSize;
  9632. if(style.fontWeight !== undefined) toApply.allProps.fontWeight = toApply.runProps.fontWeight = style.fontWeight;
  9633. if(style.fontStyle !== undefined) toApply.allProps.fontStyle = toApply.runProps.fontStyle = style.fontStyle;
  9634. if(style.underline !== undefined) toApply.allProps.textDecoration = toApply.runProps.textDecoration = style.underline ? 'underline' : 'none';
  9635. if(style.foreGroundFill) {
  9636. toApply.allProps.color = toApply.runProps.color = _getColorFromFill(style.foreGroundFill);
  9637. //if(style.foreGroundFill.opacity) toApply.allProps.opacity = toApply.runProps.opacity = style.foreGroundFill.opacity;
  9638. }
  9639. if(style.horizontalAlignment) toApply.allProps.textAlign = toApply.parProps.textAlign = toApply.runProps.textAlign = style.horizontalAlignment;
  9640. if(style.lineSpacing) toApply.allProps.lineHeight = toApply.parProps.lineHeight = style.lineSpacing;
  9641. if(style.textShadow) toApply.allProps.textShadow = toApply.parProps.textShadow = _getCssShadow(style.textShadow);
  9642. return toApply;
  9643. };
  9644. var _getColorFromFill = function(fill) {
  9645. //var fillString = '00000' + fill.color.toString(16);
  9646. //return '#' + fillString.substring(fillString.length - 6);
  9647. var val = fill.color;
  9648. var color = {};
  9649. color.b = val % 256;
  9650. val = Math.floor(val / 256);
  9651. color.g = val % 256;
  9652. val = Math.floor(val / 256);
  9653. color.r = val % 256;
  9654. color.a = typeof (fill.opacity) == 'number' ? fill.opacity : 1;
  9655. return _getCssColor(color);
  9656. };
  9657. var _getCssColor = function(rgbaObj) {
  9658. return "rgba(" + rgbaObj.r + ", " + rgbaObj.g + ", " + rgbaObj.b + ", " + rgbaObj.a + ")";
  9659. };
  9660. // //--------------------------------------------------------------------------
  9661. // // ApplyStyleRecursive
  9662. // //
  9663. // // Applies a style recursively to all span and div tags including elementNode
  9664. // // and all of its children.
  9665. // //
  9666. // // element : the element to apply the style to
  9667. // // styleName : the name of the style property to set (eg. 'font-weight')
  9668. // // styleValue : the value of the style to set (eg. 'bold')
  9669. // //--------------------------------------------------------------------------
  9670. // function ApplyStyleRecursive(element, styleName, styleValue) {
  9671. // var nodeName = element.nodeName.toLowerCase();
  9672. // if (nodeName == 'div' || nodeName == 'span' || nodeName == 'p') {
  9673. // element.style[styleName] = styleValue;
  9674. // }
  9675. // for (var i = 0; i < element.childNodes.length; i++) {
  9676. // ApplyStyleRecursive(element.childNodes[i], styleName, styleValue);
  9677. // }
  9678. // }
  9679. // //---------------------------------------------------------------------------
  9680. // // ApplyTextProperty
  9681. // //
  9682. // // Applies a text property to rtfElement.
  9683. // //
  9684. // // rtfElement : the the root text element of the rtf object (this is the
  9685. // // element named <id>_rtf
  9686. // // prop : the style property to set.
  9687. // // value : the style value to set.
  9688. // //---------------------------------------------------------------------------
  9689. // function ApplyTextProperty(rtfElement, prop, value) {
  9690. // /*
  9691. // var oldHtml = rtfElement.innerHTML;
  9692. // if (prop == 'fontWeight') {
  9693. // rtfElement.innerHTML = oldHtml.replace(/< *b *\/?>/gi, "");
  9694. // } else if (prop == 'fontStyle') {
  9695. // rtfElement.innerHTML = oldHtml.replace(/< *i *\/?>/gi, "");
  9696. // } else if (prop == 'textDecoration') {
  9697. // rtfElement.innerHTML = oldHtml.replace(/< *u *\/?>/gi, "");
  9698. // }
  9699. // */
  9700. // for (var i = 0; i < rtfElement.childNodes.length; i++) {
  9701. // ApplyStyleRecursive(rtfElement.childNodes[i], prop, value);
  9702. // }
  9703. // }
  9704. //}
  9705. //---------------------------------------------------------------------------
  9706. // GetAndCacheOriginalText
  9707. //
  9708. // Gets the html for the pre-rollover state and returns the Html representing
  9709. // the Rich text.
  9710. //---------------------------------------------------------------------------
  9711. var CACHE_COUNTER = 0;
  9712. $ax.style.CacheOriginalText = function(textId, hasRichTextBeenSet) {
  9713. var rtfQuery = $('#' + textId);
  9714. if(rtfQuery.length > 0) {
  9715. var styleCache = {};
  9716. rtfQuery.find('*').each(function(index, element) {
  9717. var elementId = element.id;
  9718. if(!elementId) element.id = elementId = 'cache' + CACHE_COUNTER++;
  9719. styleCache[elementId] = element.style.cssText;
  9720. });
  9721. _originalTextCache[textId] = {
  9722. styleCache: styleCache
  9723. };
  9724. if(hasRichTextBeenSet) {
  9725. var shapeId = $ax.GetShapeIdFromText(textId);
  9726. _shapesWithSetRichText[shapeId] = true;
  9727. }
  9728. }
  9729. };
  9730. $ax.style.ClearCacheForRepeater = function(repeaterId) {
  9731. for(var elementId in _originalTextCache) {
  9732. var scriptId = $ax.repeater.getScriptIdFromElementId(elementId);
  9733. if($ax.getParentRepeaterFromScriptId(scriptId) == repeaterId) delete _originalTextCache[elementId];
  9734. }
  9735. };
  9736. $ax.style.prefetch = function() {
  9737. var scriptIds = $ax.getAllScriptIds();
  9738. var image = new Image();
  9739. for(var i = 0; i < scriptIds.length; i++) {
  9740. var obj = $obj(scriptIds[i]);
  9741. if (!$ax.public.fn.IsImageBox(obj.type)) continue;
  9742. var images = obj.images;
  9743. for (var key in images) image.src = images[key];
  9744. var imageOverrides = obj.imageOverrides;
  9745. for(var elementId in imageOverrides) {
  9746. var override = imageOverrides[elementId];
  9747. for (var state in override) {
  9748. _addImageOverride(elementId, state, override[state]);
  9749. image.src = override[state];
  9750. }
  9751. }
  9752. }
  9753. };
  9754. });
  9755. //***** adaptive.js *****//
  9756. $axure.internal(function($ax) {
  9757. $ax.adaptive = {};
  9758. $axure.utils.makeBindable($ax.adaptive, ["viewChanged"]);
  9759. var _auto = true;
  9760. var _autoIsHandledBySidebar = false;
  9761. var _views;
  9762. var _idToView;
  9763. var _enabledViews = [];
  9764. var _initialViewToLoad;
  9765. var _initialViewSizeToLoad;
  9766. var _loadFinished = false;
  9767. $ax.adaptive.loadFinished = function() {
  9768. if(_loadFinished) return;
  9769. _loadFinished = true;
  9770. if($ax.adaptive.currentViewId) $ax.viewChangePageAndMasters();
  9771. else $ax.postAdaptiveViewChanged();
  9772. };
  9773. var _handleResize = function(forceSwitchTo) {
  9774. if(!_auto) return;
  9775. if(_auto && _autoIsHandledBySidebar && !forceSwitchTo) return;
  9776. var $window = $(window);
  9777. var height = $window.height();
  9778. var width = $window.width();
  9779. var toView = _getAdaptiveView(width, height);
  9780. var toViewId = toView && toView.id;
  9781. _switchView(toViewId, forceSwitchTo);
  9782. };
  9783. var _setAuto = $ax.adaptive.setAuto = function(val) {
  9784. if(_auto != val) {
  9785. _auto = Boolean(val);
  9786. }
  9787. };
  9788. var _setLineImage = function(id, imageUrl) {
  9789. var imageQuery = $jobj(id).attr('src', imageUrl);
  9790. if(imageUrl.indexOf(".png") > -1) $ax.utils.fixPng(imageQuery[0]);
  9791. };
  9792. var _switchView = function (viewId, forceSwitchTo) {
  9793. if(!$ax.pageData.isAdaptiveEnabled) return;
  9794. var previousViewId = $ax.adaptive.currentViewId;
  9795. if(typeof previousViewId == 'undefined') previousViewId = '';
  9796. if(typeof viewId == 'undefined') viewId = '';
  9797. if (viewId == previousViewId) {
  9798. if(forceSwitchTo) $ax.postAdaptiveViewChanged(forceSwitchTo);
  9799. return;
  9800. }
  9801. $ax('*').each(function(obj, elementId) {
  9802. if (!$ax.public.fn.IsTreeNodeObject(obj.type)) return;
  9803. if(!obj.hasOwnProperty('isExpanded')) return;
  9804. var query = $ax('#' + elementId);
  9805. var defaultExpanded = obj.isExpanded;
  9806. query.expanded(defaultExpanded);
  9807. });
  9808. // reset all the inline positioning from move and rotate actions including size and transformation
  9809. $axure('*').each(function (diagramObject, elementId) {
  9810. if(diagramObject.isContained) return;
  9811. if($ax.getParentRepeaterFromElementIdExcludeSelf(elementId)) return;
  9812. var element = document.getElementById(elementId);
  9813. if(element) {
  9814. var resetCss = {
  9815. top: "", left: "", width: "", height: "", opacity: "",
  9816. transform: "", webkitTransform: "", MozTransform: "", msTransform: "", OTransform: ""
  9817. };
  9818. var query = $(element);
  9819. query.css(resetCss);
  9820. var isPanel = $ax.public.fn.IsDynamicPanel(diagramObject.type);
  9821. if(!isPanel || diagramObject.fitToContent) { //keeps size on the panel states when switching adaptive views to optimize fit to panel
  9822. if(diagramObject.fitToContent) $ax.dynamicPanelManager.setFitToContentCss(elementId, true);
  9823. var children = query.children();
  9824. if(children.length) children.css(resetCss);
  9825. }
  9826. $ax.dynamicPanelManager.resetFixedPanel(diagramObject, element);
  9827. $ax.dynamicPanelManager.resetAdaptivePercentPanel(diagramObject, element);
  9828. }
  9829. });
  9830. $ax.adaptive.currentViewId = viewId; // we need to set this so the enabled and selected styles will apply properly
  9831. if(previousViewId) {
  9832. $ax.style.clearAdaptiveStyles();
  9833. $('*').removeClass(previousViewId);
  9834. } else {
  9835. $ax.style.reselectElements();
  9836. }
  9837. $axure('*').each(function (obj, elementId) {
  9838. if($ax.getParentRepeaterFromElementIdExcludeSelf(elementId)) return;
  9839. $ax.style.updateElementIdImageStyle(elementId); // When image override exists, fix styling/borders
  9840. });
  9841. // reset all the images only if we're going back to the default view
  9842. if(!viewId) {
  9843. _updateInputVisibility('', $axure('*'));
  9844. $axure('*').each(function (diagramObject, elementId) {
  9845. if($ax.getParentRepeaterFromElementIdExcludeSelf(elementId)) return;
  9846. $ax.placeholderManager.refreshPlaceholder(elementId);
  9847. var images = diagramObject.images;
  9848. if(diagramObject.type == 'horizontalLine' || diagramObject.type == 'verticalLine') {
  9849. var startImg = images['start~'];
  9850. _setLineImage(elementId + "_start", startImg);
  9851. var endImg = images['end~'];
  9852. _setLineImage(elementId + "_end", endImg);
  9853. var lineImg = images['line~'];
  9854. _setLineImage(elementId + "_line", lineImg);
  9855. } else if(diagramObject.type == $ax.constants.CONNECTOR_TYPE) {
  9856. _setAdaptiveConnectorImages(elementId, images, '');
  9857. } else if(images) {
  9858. if (diagramObject.generateCompound) {
  9859. if($ax.style.IsWidgetDisabled(elementId)) {
  9860. disabledImage = _getImageWithTag(images, 'disabled~');
  9861. if(disabledImage) $ax.style.applyImage(elementId, disabledImage, 'disabled');
  9862. return;
  9863. }
  9864. if($ax.style.IsWidgetSelected(elementId)) {
  9865. selectedImage = _getImageWithTag(images, 'selected~');
  9866. if(selectedImage) $ax.style.applyImage(elementId, selectedImage, 'selected');
  9867. return;
  9868. }
  9869. $ax.style.applyImage(elementId, _getImageWithTag(images, 'normal~'));
  9870. } else {
  9871. if ($ax.style.IsWidgetDisabled(elementId)) {
  9872. var disabledImage = $ax.style.getElementImageOverride(elementId, 'disabled') || images['disabled~'];
  9873. if (disabledImage) $ax.style.applyImage(elementId, disabledImage, 'disabled');
  9874. return;
  9875. }
  9876. if ($ax.style.IsWidgetSelected(elementId)) {
  9877. var selectedImage = $ax.style.getElementImageOverride(elementId, 'selected') || images['selected~'];
  9878. if (selectedImage) $ax.style.applyImage(elementId, selectedImage, 'selected');
  9879. return;
  9880. }
  9881. $ax.style.applyImage(elementId, $ax.style.getElementImageOverride(elementId, 'normal') || images['normal~']);
  9882. }
  9883. }
  9884. //align all text
  9885. var child = $jobj(elementId).children('.text');
  9886. if(child.length) $ax.style.transformTextWithVerticalAlignment(child[0].id, function() { });
  9887. });
  9888. // we have to reset visibility if we aren't applying a new view
  9889. $ax.visibility.resetLimboAndHiddenToDefaults();
  9890. $ax.repeater.refreshAllRepeaters();
  9891. $ax.dynamicPanelManager.updateParentsOfNonDefaultFitPanels();
  9892. $ax.dynamicPanelManager.updatePercentPanelCache($ax('*'));
  9893. } else {
  9894. $ax.visibility.clearLimboAndHidden();
  9895. _applyView(viewId);
  9896. $ax.repeater.refreshAllRepeaters();
  9897. $ax.dynamicPanelManager.updateParentsOfNonDefaultFitPanels();
  9898. }
  9899. $ax.adaptive.triggerEvent('viewChanged', {});
  9900. if(_loadFinished) $ax.viewChangePageAndMasters(forceSwitchTo);
  9901. };
  9902. var _getImageWithTag = function(image, tag) {
  9903. var flattened = {};
  9904. for (var component in image) {
  9905. var componentImage = image[component][tag];
  9906. if(componentImage) flattened[component] = componentImage;
  9907. }
  9908. return flattened;
  9909. }
  9910. // gets if input is hidden due to sketch
  9911. var BORDER_WIDTH = "borderWidth";
  9912. var COLOR_STYLE = "colorStyle";
  9913. var SKETCH_FACTOR = "sketchFactor";
  9914. var _areInputsHidden = function(viewId) {
  9915. var chain = _getAdaptiveIdChain(viewId);
  9916. var page = $ax.pageData.page;
  9917. var adaptiveStyles = page.adaptiveStyles;
  9918. // keep track of props that are not sketchy, as you continue to climb up your parents;
  9919. var notSketch = [];
  9920. for(var i = chain.length - 1; i >= -1; i--) {
  9921. var style = i == -1 ? page.style : adaptiveStyles[chain[i]];
  9922. if(notSketch.indexOf(BORDER_WIDTH) == -1 && style.hasOwnProperty(BORDER_WIDTH)) {
  9923. if(style[BORDER_WIDTH] != 0) return true;
  9924. notSketch.push(BORDER_WIDTH);
  9925. }
  9926. if(notSketch.indexOf(COLOR_STYLE) == -1 && style.hasOwnProperty(COLOR_STYLE)) {
  9927. if(style[COLOR_STYLE] != 'appliedColor') return true;
  9928. notSketch.push(COLOR_STYLE);
  9929. }
  9930. if(notSketch.indexOf(SKETCH_FACTOR) == -1 && style.hasOwnProperty(SKETCH_FACTOR)) {
  9931. if(style[SKETCH_FACTOR] != 0) return true;
  9932. notSketch.push(SKETCH_FACTOR);
  9933. }
  9934. }
  9935. return false;
  9936. };
  9937. var _updateInputVisibility = function(viewId, query) {
  9938. var func = _areInputsHidden(viewId) ? 'addClass' : 'removeClass';
  9939. query.each(function(obj, elementId) {
  9940. var input = $jobj($ax.repeater.applySuffixToElementId(elementId, '_input'));
  9941. if(input.length == 0) return;
  9942. input[func]('form_sketch');
  9943. });
  9944. };
  9945. // gets the inheritance chain of a particular view.
  9946. var _getAdaptiveIdChain = $ax.adaptive.getAdaptiveIdChain = function(viewId) {
  9947. if(!viewId) return [];
  9948. var view = _idToView[viewId];
  9949. var chain = [];
  9950. var current = view;
  9951. while(current) {
  9952. chain[chain.length] = current.id;
  9953. current = _idToView[current.baseViewId];
  9954. }
  9955. return chain.reverse();
  9956. };
  9957. var _getPageStyle = $ax.adaptive.getPageStyle = function() {
  9958. var currentViewId = $ax.adaptive.currentViewId;
  9959. var adaptiveChain = _getAdaptiveIdChain(currentViewId);
  9960. var currentStyle = $.extend({}, $ax.pageData.page.style);
  9961. for(var i = 0; i < adaptiveChain.length; i++) {
  9962. var viewId = adaptiveChain[i];
  9963. $.extend(currentStyle, $ax.pageData.page.adaptiveStyles[viewId]);
  9964. }
  9965. return currentStyle;
  9966. };
  9967. var _setAdaptiveLineImages = function(elementId, images, viewIdChain) {
  9968. for(var i = viewIdChain.length - 1; i >= 0; i--) {
  9969. var viewId = viewIdChain[i];
  9970. var startImg = images['start~' + viewId];
  9971. if(startImg) {
  9972. _setLineImage(elementId + "_start", startImg);
  9973. var endImg = images['end~' + viewId];
  9974. _setLineImage(elementId + "_end", endImg);
  9975. var lineImg = images['line~' + viewId];
  9976. _setLineImage(elementId + "_line", lineImg);
  9977. break;
  9978. }
  9979. }
  9980. };
  9981. var _setAdaptiveConnectorImages = function (elementId, images, view) {
  9982. var conn = $jobj(elementId);
  9983. var count = conn.children().length-1; // -1 for rich text panel
  9984. for(var i = 0; i < count; i++) {
  9985. var img = images['' + i + '~' + view];
  9986. $jobj(elementId + '_seg' + i).attr('src', img);
  9987. }
  9988. };
  9989. var _applyView = $ax.adaptive.applyView = function(viewId, query) {
  9990. var limboIds = {};
  9991. var hiddenIds = {};
  9992. var jquery;
  9993. if(query) {
  9994. jquery = query.jQuery();
  9995. jquery = jquery.add(jquery.find('*'));
  9996. var jqueryAnn = $ax.annotation.jQueryAnn(query);
  9997. jquery = jquery.add(jqueryAnn);
  9998. } else {
  9999. jquery = $('*');
  10000. query = $ax('*');
  10001. }
  10002. jquery.addClass(viewId);
  10003. _updateInputVisibility(viewId, query);
  10004. var viewIdChain = _getAdaptiveIdChain(viewId);
  10005. // this could be made more efficient by computing it only once per object
  10006. query.each(function(diagramObject, elementId) {
  10007. _applyAdaptiveViewOnObject(diagramObject, elementId, viewIdChain, viewId, limboIds, hiddenIds);
  10008. });
  10009. $ax.visibility.addLimboAndHiddenIds(limboIds, hiddenIds, query);
  10010. //$ax.dynamicPanelManager.updateAllFitPanelsAndLayerSizeCaches();
  10011. $ax.dynamicPanelManager.updatePercentPanelCache(query);
  10012. };
  10013. var _applyAdaptiveViewOnObject = function(diagramObject, elementId, viewIdChain, viewId, limboIds, hiddenIds) {
  10014. var adaptiveChain = [];
  10015. for(var i = 0; i < viewIdChain.length; i++) {
  10016. var viewId = viewIdChain[i];
  10017. var viewStyle = diagramObject.adaptiveStyles[viewId];
  10018. if(viewStyle) {
  10019. adaptiveChain[adaptiveChain.length] = viewStyle;
  10020. if (viewStyle.size) $ax.public.fn.convertToSingleImage($jobj(elementId));
  10021. }
  10022. }
  10023. var state = $ax.style.generateState(elementId);
  10024. // set the image
  10025. var images = diagramObject.images;
  10026. if(images) {
  10027. if(diagramObject.type == 'horizontalLine' || diagramObject.type == 'verticalLine') {
  10028. _setAdaptiveLineImages(elementId, images, viewIdChain);
  10029. } else if (diagramObject.type == $ax.constants.CONNECTOR_TYPE) {
  10030. _setAdaptiveConnectorImages(elementId, images, viewId);
  10031. } else if (diagramObject.generateCompound) {
  10032. var compoundUrl = _matchImageCompound(diagramObject, elementId, viewIdChain, state);
  10033. if (compoundUrl) $ax.style.applyImage(elementId, compoundUrl, state);
  10034. }else {
  10035. var imgUrl = _matchImage(elementId, images, viewIdChain, state);
  10036. if(imgUrl) $ax.style.applyImage(elementId, imgUrl, state);
  10037. }
  10038. // for(var i = viewIdChain.length - 1; i >= 0; i--) {
  10039. // var viewId = viewIdChain[i];
  10040. // var imgUrl = $ax.style.getElementImageOverride(elementId, state) || images[state + '~' + viewId] || images['normal~' + viewId];
  10041. // if(imgUrl) {
  10042. // $ax.style.applyImage(elementId, imgUrl, state);
  10043. // break;
  10044. // }
  10045. // }
  10046. // }
  10047. }
  10048. // addaptive override style (not including default style props)
  10049. var adaptiveStyle = $ax.style.computeAllOverrides(elementId, undefined, state, viewId);
  10050. // this style INCLUDES the object's my style
  10051. var compoundStyle = $.extend({}, diagramObject.style, adaptiveStyle);
  10052. //$ax.style.setAdaptiveStyle(elementId, adaptiveStyle);
  10053. if(!diagramObject.isContained) {
  10054. $ax.style.setAdaptiveStyle(elementId, adaptiveStyle);
  10055. }
  10056. var scriptId = $ax.repeater.getScriptIdFromElementId(elementId);
  10057. if(compoundStyle.limbo && !diagramObject.isContained) limboIds[scriptId] = true;
  10058. // sigh, javascript. we need the === here because undefined means not overriden
  10059. if(compoundStyle.visible === false) hiddenIds[scriptId] = true;
  10060. };
  10061. var _matchImage = function(id, images, viewIdChain, state) {
  10062. var override = $ax.style.getElementImageOverride(id, state);
  10063. if(override) return override;
  10064. if(!images) return undefined;
  10065. // first check all the images for this state
  10066. for(var i = viewIdChain.length - 1; i >= 0; i--) {
  10067. var viewId = viewIdChain[i];
  10068. var img = images[state + "~" + viewId];
  10069. if(img) return img;
  10070. }
  10071. // check for the default state style
  10072. var defaultStateImage = images[state + '~'];
  10073. if(defaultStateImage) return defaultStateImage;
  10074. state = $ax.style.progessState(state);
  10075. if(state) return _matchImage(id, images, viewIdChain, state);
  10076. // SHOULD NOT REACH HERE! NORMAL SHOULD ALWAYS CATCH AT THE DEFAULT!
  10077. return images['normal~']; // this is the default
  10078. };
  10079. var _matchImageCompound = function(diagramObject, id, viewIdChain, state) {
  10080. var images = [];
  10081. for(var i = 0; i < diagramObject.compoundChildren.length; i++) {
  10082. var component = diagramObject.compoundChildren[i];
  10083. images[component] = _matchImage(id, diagramObject.images[component], viewIdChain, state);
  10084. }
  10085. return images;
  10086. };
  10087. $ax.adaptive.getImageForStateAndView = function(id, state) {
  10088. var viewIdChain = _getAdaptiveIdChain($ax.adaptive.currentViewId);
  10089. var diagramObject = $ax.getObjectFromElementId(id);
  10090. if (diagramObject.generateCompound) return _matchImageCompound(diagramObject, id, viewIdChain, state);
  10091. else return _matchImage(id, diagramObject.images, viewIdChain, state);
  10092. };
  10093. var _getAdaptiveView = function(winWidth, winHeight) {
  10094. var _isViewOneGreaterThanTwo = function(view1, view2) {
  10095. return view1.size.width > view2.size.width || (view1.size.width == view2.size.width && view1.size.height > view2.size.height);
  10096. };
  10097. var _isViewOneLessThanTwo = function(view1, view2) {
  10098. var width2 = view2.size.width || 1000000; // artificially large number
  10099. var height2 = view2.size.height || 1000000;
  10100. var width1 = view1.size.width || 1000000;
  10101. var height1 = view1.size.height || 1000000;
  10102. return width1 < width2 || (width1 == width2 && height1 < height2);
  10103. };
  10104. var _isWindowGreaterThanView = function(view, width, height) {
  10105. return width >= view.size.width && height >= view.size.height;
  10106. };
  10107. var _isWindowLessThanView = function(view1, width, height) {
  10108. var viewWidth = view1.size.width || 1000000;
  10109. var viewHeight = view1.size.height || 1000000;
  10110. return width <= viewWidth && height <= viewHeight;
  10111. };
  10112. var greater = undefined;
  10113. var less = undefined;
  10114. for(var i = 0; i < _enabledViews.length; i++) {
  10115. var view = _enabledViews[i];
  10116. if(view.condition == ">=") {
  10117. if(_isWindowGreaterThanView(view, winWidth, winHeight)) {
  10118. if(!greater || _isViewOneGreaterThanTwo(view, greater)) greater = view;
  10119. }
  10120. } else {
  10121. if(_isWindowLessThanView(view, winWidth, winHeight)) {
  10122. if(!less || _isViewOneLessThanTwo(view, less)) less = view;
  10123. }
  10124. }
  10125. }
  10126. return less || greater;
  10127. };
  10128. var _isAdaptiveInitialized = function() {
  10129. return typeof _idToView != 'undefined';
  10130. };
  10131. $ax.messageCenter.addMessageListener(function(message, data) {
  10132. //If the adaptive plugin hasn't been initialized yet then
  10133. //save the view to load so that it can get set when initialize occurs
  10134. if(message == 'switchAdaptiveView') {
  10135. var href = window.location.href.split('#')[0];
  10136. var lastSlash = href.lastIndexOf('/');
  10137. href = href.substring(lastSlash + 1);
  10138. if(href != data.src) return;
  10139. var view = data.view == 'auto' ? undefined : (data.view == 'default' ? '' : data.view);
  10140. if(!_isAdaptiveInitialized()) {
  10141. _initialViewToLoad = view;
  10142. } else _handleLoadViewId(view);
  10143. } else if(message == 'setAdaptiveViewForSize') {
  10144. _autoIsHandledBySidebar = true;
  10145. if(!_isAdaptiveInitialized()) {
  10146. _initialViewSizeToLoad = data;
  10147. } else _handleSetViewForSize(data.width, data.height);
  10148. }
  10149. });
  10150. $ax.adaptive.setAdaptiveView = function(view) {
  10151. var viewIdForSitemapToUnderstand = view == 'auto' ? undefined : (view == 'default' ? '' : view);
  10152. if(!_isAdaptiveInitialized()) {
  10153. _initialViewToLoad = viewIdForSitemapToUnderstand;
  10154. } else _handleLoadViewId(viewIdForSitemapToUnderstand);
  10155. };
  10156. $ax.adaptive.initialize = function() {
  10157. _views = $ax.document.adaptiveViews;
  10158. _idToView = {};
  10159. if(_views && _views.length > 0) {
  10160. for(var i = 0; i < _views.length; i++) {
  10161. var view = _views[i];
  10162. _idToView[view.id] = view;
  10163. }
  10164. var enabledViewIds = $ax.document.configuration.enabledViewIds;
  10165. for(var i = 0; i < enabledViewIds.length; i++) {
  10166. _enabledViews[_enabledViews.length] = _idToView[enabledViewIds[i]];
  10167. }
  10168. if(_autoIsHandledBySidebar && _initialViewSizeToLoad) _handleSetViewForSize(_initialViewSizeToLoad.width, _initialViewSizeToLoad.height);
  10169. else _handleLoadViewId(_initialViewToLoad);
  10170. }
  10171. $axure.resize(function(e) {
  10172. _handleResize();
  10173. $ax.postResize(e); //window resize fires after view changed
  10174. });
  10175. };
  10176. var _handleLoadViewId = function (loadViewId, forceSwitchTo) {
  10177. if(typeof loadViewId != 'undefined') {
  10178. _setAuto(false);
  10179. _switchView(loadViewId != 'default' ? loadViewId : '', forceSwitchTo);
  10180. } else {
  10181. _setAuto(true);
  10182. _handleResize(forceSwitchTo);
  10183. }
  10184. };
  10185. var _handleSetViewForSize = function (width, height) {
  10186. if(!_auto) return;
  10187. var toView = _getAdaptiveView(width, height);
  10188. var toViewId = toView && toView.id;
  10189. _switchView(toViewId);
  10190. };
  10191. $ax.adaptive.getSketchKey = function() {
  10192. return $ax.pageData.sketchKeys[$ax.adaptive.currentViewId || ''];
  10193. }
  10194. });
  10195. //***** tree.js *****//
  10196. // This is actually for BOTH trees and menus
  10197. $axure.internal(function($ax) {
  10198. var _tree = $ax.tree = {};
  10199. var _menu = $ax.menu = {};
  10200. $ax.menu.InitializeSubmenu = function(subMenuId, cellId) {
  10201. var $submenudiv = $('#' + subMenuId);
  10202. //mouseenter and leave for parent table cell
  10203. $('#' + cellId).mouseenter(function(e) {
  10204. //show current submenu
  10205. // var submenuElement = document.getElementById(subMenuId);
  10206. // if($ax.visibility.IsVisible(submenuElement) && submenuElement.style.display !== 'none') return;
  10207. $ax.visibility.SetIdVisible(subMenuId, true);
  10208. $ax.legacy.BringToFront(subMenuId);
  10209. $submenudiv.find('.menu_item').each(function() {
  10210. $ax.style.updateTextAlignmentForVisibility($ax.GetTextPanelId($(this).attr('id')));
  10211. });
  10212. _fireEventForSubmenu(subMenuId, "onShow");
  10213. }).mouseleave(function (e) {
  10214. var offset = $submenudiv.offset();
  10215. var subcontwidth = $submenudiv.width();
  10216. var subcontheight = $submenudiv.height();
  10217. //If mouse is not within the submenu (added 3 pixel margin to top and left calculations), then close the submenu...
  10218. if(e.pageX + 3 < offset.left || e.pageX > offset.left + subcontwidth || e.pageY + 3 < offset.top || e.pageY > offset.top + subcontheight) {
  10219. $submenudiv.find('.sub_menu').andSelf().each(function () {
  10220. // if(!$ax.visibility.IsVisible(this)) return;
  10221. $ax.visibility.SetVisible(this, false);
  10222. _fireEventForSubmenu(subMenuId, "onHide");
  10223. });
  10224. $ax.style.SetWidgetHover(cellId, false);
  10225. }
  10226. });
  10227. $submenudiv.css('display', 'none');
  10228. //mouseleave for submenu
  10229. $submenudiv.mouseleave(function(e) {
  10230. //close this menu and all menus below it
  10231. $(this).find('.sub_menu').andSelf().css({ 'visibility': 'hidden', 'display': 'none' }).each(function () {
  10232. // if(!$ax.visibility.IsVisible(this)) return;
  10233. _fireEventForSubmenu(this.id, "onHide");
  10234. });
  10235. $ax.style.SetWidgetHover(cellId, false);
  10236. });
  10237. };
  10238. var _fireEventForSubmenu = function(targetId, eventName) {
  10239. var diagramObject = $ax.getObjectFromElementId(targetId);
  10240. var event = diagramObject.interactionMap && diagramObject.interactionMap[eventName];
  10241. if(event) {
  10242. var eventInfo = $ax.getEventInfoFromEvent($ax.getjBrowserEvent(), false, targetId);
  10243. $ax.event.handleEvent(targetId, eventInfo, event, false, true);
  10244. }
  10245. }
  10246. function IsNodeVisible(nodeId) {
  10247. var current = window.document.getElementById(nodeId);
  10248. var parent = current.parentNode;
  10249. //move all the parent's children that are below the node and their annotations
  10250. while(!$(current).hasClass("treeroot")) {
  10251. if(!$ax.visibility.IsVisible(parent)) return false;
  10252. current = parent;
  10253. parent = parent.parentNode;
  10254. }
  10255. return true;
  10256. }
  10257. $ax.tree.ExpandNode = function(nodeId, childContainerId, plusMinusId) {
  10258. var container = window.document.getElementById(childContainerId);
  10259. if(!container || $ax.visibility.IsVisible(container)) return;
  10260. $ax.visibility.SetVisible(container, true);
  10261. if(plusMinusId != '') $ax.style.SetWidgetSelected(plusMinusId, true);
  10262. var delta = _getExpandCollapseDelta(nodeId, childContainerId);
  10263. var isVisible = IsNodeVisible(nodeId);
  10264. var current = window.document.getElementById(nodeId);
  10265. var parent = current.parentNode;
  10266. //move all the parent's children that are below the node and their annotations
  10267. while(!$(current).hasClass("treeroot")) {
  10268. var after = false;
  10269. var i = 0;
  10270. for(i = 0; i < parent.childNodes.length; i++) {
  10271. var child = parent.childNodes[i];
  10272. if(after && child.id && $(child).hasClass("treenode")) {
  10273. var elementId = child.id;
  10274. child.style.top = Number($(child).css('top').replace("px", "")) + delta + 'px';
  10275. var ann = window.document.getElementById(elementId + "_ann");
  10276. if(ann) ann.style.top = Number($(ann).css('top').replace("px", "")) + delta + 'px';
  10277. }
  10278. if(child == current) after = true;
  10279. }
  10280. current = parent;
  10281. parent = parent.parentNode;
  10282. if(!isVisible && $ax.visibility.IsVisible(parent)) break;
  10283. }
  10284. };
  10285. $ax.tree.CollapseNode = function(nodeId, childContainerId, plusMinusId) {
  10286. var container = window.document.getElementById(childContainerId);
  10287. if(!container || !$ax.visibility.IsVisible(container)) return;
  10288. if(plusMinusId != '') $ax.style.SetWidgetSelected(plusMinusId, false);
  10289. var delta = _getExpandCollapseDelta(nodeId, childContainerId);
  10290. //hide it after getting the delta, otherwise the delta can't be calculated (offsetParent is null)
  10291. $ax.visibility.SetVisible(container, false);
  10292. var isVisible = IsNodeVisible(nodeId);
  10293. var current = window.document.getElementById(nodeId);
  10294. var parent = current.parentNode;
  10295. //move all the parent's children that are below the node and their annotations
  10296. while(!$(current).hasClass("treeroot")) {
  10297. var after = false;
  10298. var i = 0;
  10299. for(i = 0; i < parent.childNodes.length; i++) {
  10300. var child = parent.childNodes[i];
  10301. if(after && child.id && $(child).hasClass("treenode")) {
  10302. var elementId = child.id;
  10303. child.style.top = Number($(child).css('top').replace("px", "")) - delta + 'px';
  10304. var ann = window.document.getElementById(elementId + "_ann");
  10305. if(ann) ann.style.top = Number($(ann).css('top').replace("px", "")) - delta + 'px';
  10306. }
  10307. if(child == current) after = true;
  10308. }
  10309. current = parent;
  10310. parent = current.parentNode;
  10311. if(!isVisible && $ax.visibility.IsVisible(parent)) break;
  10312. }
  10313. };
  10314. var _getExpandCollapseDelta = function(nodeId, childContainerId) {
  10315. return _getChildContainerHeightHelper(childContainerId);
  10316. };
  10317. var _getChildContainerHeightHelper = function(childContainerId) {
  10318. var height = 0;
  10319. $('#' + childContainerId).children().each(function() {
  10320. if($(this).hasClass("treenode")) {
  10321. height += $(this).height();
  10322. var subContainer = window.document.getElementById(this.id + '_children');
  10323. if(subContainer && $ax.visibility.IsVisible(subContainer)) {
  10324. height += _getChildContainerHeightHelper(subContainer.id);
  10325. }
  10326. }
  10327. });
  10328. return height;
  10329. };
  10330. $ax.tree.InitializeTreeNode = function(nodeId, plusminusid, childContainerId, selectText) {
  10331. var childContainer = window.document.getElementById(childContainerId);
  10332. if(childContainer) {
  10333. //relying on the html generator to put this inline so we know to collapse by default
  10334. var isCollapsed = childContainer.style.visibility == "hidden";
  10335. if(isCollapsed) $ax.visibility.SetVisible(childContainer, false);
  10336. if(!isCollapsed && plusminusid != '') $ax.style.SetWidgetSelected(plusminusid, true);
  10337. }
  10338. if(plusminusid != '') {
  10339. $jobj(plusminusid).click(function() {
  10340. var visibleSet = $ax.visibility.IsIdVisible(childContainerId);
  10341. if(visibleSet) $ax.tree.CollapseNode(nodeId, childContainerId, plusminusid);
  10342. else $ax.tree.ExpandNode(nodeId, childContainerId, plusminusid);
  10343. $ax.tree.SelectTreeNode(nodeId, true);
  10344. return false;
  10345. }).css('cursor', 'default');
  10346. }
  10347. };
  10348. var _getButtonShapeId = function(id) {
  10349. var obj = $obj(id);
  10350. return $ax.public.fn.IsTreeNodeObject(obj.type) ? $ax.getElementIdFromPath([obj.buttonShapeId], { relativeTo: id }) : id;
  10351. };
  10352. $ax.tree.SelectTreeNode = function(id, selected) {
  10353. $ax.style.SetWidgetSelected(_getButtonShapeId(id), selected);
  10354. };
  10355. });
  10356. //***** init.temp.js *****//
  10357. $axure.internal(function($ax) {
  10358. $(window.document).ready(function() {
  10359. var readyStart = (new Date()).getTime();
  10360. //this is because the page id is not formatted as a guid
  10361. var pageId = $ax.pageData.page.packageId;
  10362. var pageData = {
  10363. id: pageId,
  10364. pageName: $ax.pageData.page.name,
  10365. location: window.location.toString(),
  10366. notes: $ax.pageData.page.notes
  10367. };
  10368. var anns = [];
  10369. $ax('*').each(function (dObj, elementId) {
  10370. pushAnnotation(dObj, elementId);
  10371. });
  10372. function pushAnnotation(dObj, elementId) {
  10373. var ann = dObj.annotation;
  10374. if(ann) {
  10375. ann = $ax.deepCopy(ann);
  10376. ann["id"] = elementId;
  10377. ann["label"] = dObj.label + " (" + dObj.friendlyType + ")";
  10378. anns.push(ann);
  10379. }
  10380. if(dObj.type === 'repeater' && dObj.objects) {
  10381. //if it's repeater, save the id as repeaterId@scriptId
  10382. for(var i = 0, len = dObj.objects.length; i < len; i++) {
  10383. var child = dObj.objects[i];
  10384. var scriptId = $ax.getScriptIdFromPath([child.id], elementId);
  10385. pushAnnotation(child, elementId + '@' + scriptId);
  10386. }
  10387. }
  10388. }
  10389. pageData.widgetNotes = anns;
  10390. //only trigger the page.data setting if the window is on the mainframe
  10391. var isMainFrame = false;
  10392. try {
  10393. if(window.name == 'mainFrame' ||
  10394. (!CHROME_5_LOCAL && window.parent.$ && window.parent.$('#mainFrame').length > 0)) {
  10395. isMainFrame = true;
  10396. $ax.messageCenter.addMessageListener(function(message, data) {
  10397. if(message == 'finishInit') {
  10398. _processTempInit();
  10399. }
  10400. });
  10401. $axure.messageCenter.setState('page.data', pageData);
  10402. window.focus();
  10403. }
  10404. } catch(e) { }
  10405. //attach here for chrome local
  10406. $(window).load(function() {
  10407. $ax.style.initializeObjectTextAlignment($ax('*'));
  10408. });
  10409. if(!isMainFrame) _processTempInit();
  10410. });
  10411. var _processTempInit = function() {
  10412. //var start = (new Date()).getTime();
  10413. //var end = (new Date()).getTime();
  10414. //window.alert('elapsed ' + (end - start));
  10415. $('iframe').each(function() {
  10416. var origSrc = $(this).attr('basesrc');
  10417. var $this = $(this);
  10418. if(origSrc) {
  10419. var newSrcUrl = origSrc.toLowerCase().indexOf('http://') == -1 ? $ax.globalVariableProvider.getLinkUrl(origSrc) : origSrc;
  10420. $this.attr('src', newSrcUrl);
  10421. }
  10422. if(IOS) {
  10423. $this.parent().css('overflow', 'auto').css('-webkit-overflow-scrolling', 'touch').css('-ms-overflow-x', 'hidden').css('overflow-x', 'hidden');
  10424. }
  10425. });
  10426. $axure.messageCenter.addMessageListener(function(message, data) {
  10427. if(message == 'setGlobalVar') {
  10428. $ax.globalVariableProvider.setVariableValue(data.globalVarName, data.globalVarValue, true);
  10429. }
  10430. });
  10431. window.lastFocusedClickable = null;
  10432. var _lastFocusedClickableSelector = 'input, a';
  10433. var shouldOutline = true;
  10434. $ax(function (dObj) { return dObj.tabbable; }).each(function (dObj, elementId) {
  10435. if ($ax.public.fn.IsLayer(dObj.type)) $ax.event.layerMapFocus(dObj, elementId);
  10436. var focusableId = $ax.event.getFocusableWidgetOrChildId(elementId);
  10437. var $focusable = $('#' + focusableId);
  10438. $focusable.attr("tabIndex", 0);
  10439. if($focusable.is('div') || $focusable.is('img')) {
  10440. $focusable.bind($ax.features.eventNames.mouseDownName, function() {
  10441. shouldOutline = false;
  10442. });
  10443. attachFocusAndBlur($focusable);
  10444. }
  10445. });
  10446. $(window.document).bind($ax.features.eventNames.mouseUpName, function() {
  10447. shouldOutline = true;
  10448. });
  10449. attachFocusAndBlur($(_lastFocusedClickableSelector));
  10450. function attachFocusAndBlur($query) {
  10451. $query.focus(function () {
  10452. if(shouldOutline) {
  10453. $(this).css('outline', '');
  10454. } else {
  10455. $(this).css('outline', 'none');
  10456. }
  10457. window.lastFocusedClickable = this;
  10458. }).blur(function () {
  10459. if(window.lastFocusedClickable == this) window.lastFocusedClickable = null;
  10460. });
  10461. }
  10462. $(window.document).bind('keyup', function(e) {
  10463. if(e.keyCode == '13' || e.keyCode == '32') {
  10464. if(window.lastFocusedClickable) $(window.lastFocusedClickable).click();
  10465. }
  10466. });
  10467. if($ax.document.configuration.hideAddress) {
  10468. $(window).load(function() {
  10469. window.setTimeout(function() {
  10470. window.scrollTo(0, 0.9);
  10471. }, 0);
  10472. });
  10473. }
  10474. if($ax.document.configuration.preventScroll) {
  10475. $(window.document).bind('touchmove', function(e) {
  10476. var inScrollable = $ax.legacy.GetScrollable(e.target) != window.document.body;
  10477. if(!inScrollable) {
  10478. e.preventDefault();
  10479. }
  10480. });
  10481. $ax(function(diagramObject) {
  10482. return $ax.public.fn.IsDynamicPanel(diagramObject.type) && diagramObject.scrollbars != 'none';
  10483. }).$().children().bind('touchstart', function() {
  10484. var target = this;
  10485. var top = target.scrollTop;
  10486. if(top <= 0) target.scrollTop = 1;
  10487. if(top + target.offsetHeight >= target.scrollHeight) target.scrollTop = target.scrollHeight - target.offsetHeight - 1;
  10488. });
  10489. }
  10490. if(OS_MAC && WEBKIT) {
  10491. $ax(function(diagramObject) {
  10492. return $ax.public.fn.IsComboBox(diagramObject.type);
  10493. }).each(function(obj, id) {
  10494. $jobj($ax.INPUT(id)).css('-webkit-appearance', 'menulist-button');
  10495. });
  10496. }
  10497. $ax.legacy.BringFixedToFront();
  10498. $ax.event.initialize();
  10499. $ax.style.initialize();
  10500. $ax.visibility.initialize();
  10501. $ax.repeater.initialize();
  10502. $ax.dynamicPanelManager.initialize(); //needs to be called after visibility is initialized
  10503. $ax.adaptive.initialize();
  10504. $ax.loadDynamicPanelsAndMasters();
  10505. $ax.adaptive.loadFinished();
  10506. var start = (new Date()).getTime();
  10507. $ax.repeater.initRefresh();
  10508. var end = (new Date()).getTime();
  10509. console.log('loadTime: ' + (end - start) / 1000);
  10510. $ax.style.prefetch();
  10511. $(window).resize();
  10512. //var readyEnd = (new Date()).getTime();
  10513. //window.alert('elapsed ' + (readyEnd - readyStart));
  10514. };
  10515. });
  10516. /* extend canvas */
  10517. var gv_hasCanvas = false;
  10518. (function() {
  10519. var _canvas = document.createElement('canvas'), proto, abbrev;
  10520. if(gv_hasCanvas = !!(_canvas.getContext && _canvas.getContext('2d')) && typeof (CanvasGradient) !== 'undefined') {
  10521. function chain(func) {
  10522. return function() {
  10523. return func.apply(this, arguments) || this;
  10524. };
  10525. }
  10526. with(proto = CanvasRenderingContext2D.prototype) for(var func in abbrev = {
  10527. a: arc,
  10528. b: beginPath,
  10529. n: clearRect,
  10530. c: clip,
  10531. p: closePath,
  10532. g: createLinearGradient,
  10533. f: fill,
  10534. j: fillRect,
  10535. z: function(s) { this.fillStyle = s; },
  10536. l: lineTo,
  10537. w: function(w) { this.lineWidth = w; },
  10538. m: moveTo,
  10539. q: quadraticCurveTo,
  10540. h: rect,
  10541. r: restore,
  10542. o: rotate,
  10543. s: save,
  10544. x: scale,
  10545. y: function(s) { this.strokeStyle = s; },
  10546. u: setTransform,
  10547. k: stroke,
  10548. i: strokeRect,
  10549. t: translate
  10550. }) proto[func] = chain(abbrev[func]);
  10551. CanvasGradient.prototype.a = chain(CanvasGradient.prototype.addColorStop);
  10552. }
  10553. })();
  10554. //***** legacy.js *****//
  10555. //stored on each browser event
  10556. var windowEvent;
  10557. $axure.internal(function($ax) {
  10558. var _legacy = {};
  10559. $ax.legacy = _legacy;
  10560. // ************************** GLOBAL VARS *********************************//
  10561. // ************************************************************************//
  10562. //Check if IE
  10563. //var bIE = false;
  10564. //if ((index = navigator.userAgent.indexOf("MSIE")) >= 0) {
  10565. // bIE = true;
  10566. //}
  10567. var Forms = window.document.getElementsByTagName("FORM");
  10568. for(var i = 0; i < Forms.length; i++) {
  10569. var Form = Forms[i];
  10570. Form.onclick = $ax.legacy.SuppressBubble;
  10571. }
  10572. $ax.legacy.SuppressBubble = function(event) {
  10573. if(IE_10_AND_BELOW) {
  10574. window.event.cancelBubble = true;
  10575. window.event.returnValue = false;
  10576. } else {
  10577. if(event) {
  10578. event.stopPropagation();
  10579. }
  10580. }
  10581. };
  10582. // function InsertAfterBegin(dom, html) {
  10583. // if(!IE) {
  10584. // var phtml;
  10585. // var range = dom.ownerDocument.createRange();
  10586. // range.selectNodeContents(dom);
  10587. // range.collapse(true);
  10588. // phtml = range.createContextualFragment(html);
  10589. // dom.insertBefore(phtml, dom.firstChild);
  10590. // } else {
  10591. // dom.insertAdjacentHTML("afterBegin", html);
  10592. // }
  10593. // }
  10594. // function InsertBeforeEnd(dom, html) {
  10595. // if(!IE) {
  10596. // var phtml;
  10597. // var range = dom.ownerDocument.createRange();
  10598. // range.selectNodeContents(dom);
  10599. // range.collapse(dom);
  10600. // phtml = range.createContextualFragment(html);
  10601. // dom.appendChild(phtml);
  10602. // } else {
  10603. // dom.insertAdjacentHTML("beforeEnd", html);
  10604. // }
  10605. // }
  10606. //Get the id of the Workflow Dialog belonging to element with id = id
  10607. // function Workflow(id) {
  10608. // return id + 'WF';
  10609. // }
  10610. $ax.legacy.BringToFront = function(id, skipFixed) {
  10611. _bringToFrontHelper(id);
  10612. if(!skipFixed) $ax.legacy.BringFixedToFront();
  10613. };
  10614. var _bringToFrontHelper = function(id) {
  10615. var target = window.document.getElementById(id);
  10616. if(target == null) return;
  10617. $ax.globals.MaxZIndex = $ax.globals.MaxZIndex + 1;
  10618. target.style.zIndex = $ax.globals.MaxZIndex;
  10619. };
  10620. $ax.legacy.BringFixedToFront = function() {
  10621. $ax(function(diagramObject) { return diagramObject.fixedKeepInFront; }).each(function(diagramObject, scriptId) {
  10622. _bringToFrontHelper(scriptId);
  10623. });
  10624. };
  10625. $ax.legacy.SendToBack = function(id) {
  10626. var target = window.document.getElementById(id);
  10627. if(target == null) return;
  10628. target.style.zIndex = $ax.globals.MinZIndex = $ax.globals.MinZIndex - 1;
  10629. };
  10630. $ax.legacy.RefreshScreen = function() {
  10631. var oldColor = window.document.body.style.backgroundColor;
  10632. var setColor = (oldColor == "rgb(0,0,0)") ? "#FFFFFF" : "#000000";
  10633. window.document.body.style.backgroundColor = setColor;
  10634. window.document.body.style.backgroundColor = oldColor;
  10635. };
  10636. $ax.legacy.getAbsoluteLeft = function(currentNode, elementId) {
  10637. var oldDisplay = currentNode.css('display');
  10638. var displaySet = false;
  10639. if(oldDisplay == 'none') {
  10640. currentNode.css('display', '');
  10641. displaySet = true;
  10642. }
  10643. var left = currentNode.offset().left;
  10644. // Special Layer code
  10645. if($ax.getTypeFromElementId(elementId) == 'layer') {
  10646. var first = true;
  10647. var children = currentNode.children();
  10648. for(var i = 0; i < children.length; i++) {
  10649. var child = $(children[i]);
  10650. var subDisplaySet = false;
  10651. if(child.css('display') == 'none') {
  10652. child.css('display', '');
  10653. subDisplaySet = true;
  10654. }
  10655. if(first) left = child.offset().left;
  10656. else left = Math.min(child.offset().left, left);
  10657. first = false;
  10658. if(subDisplaySet) child.css('display', 'none');
  10659. }
  10660. }
  10661. if (displaySet) currentNode.css('display', oldDisplay);
  10662. return $axure.fn.bodyToWorld(left, true);
  10663. };
  10664. $ax.legacy.getAbsoluteTop = function(currentNode, elementId) {
  10665. var oldDisplay = currentNode.css('display');
  10666. var displaySet = false;
  10667. if(oldDisplay == 'none') {
  10668. currentNode.css('display', '');
  10669. displaySet = true;
  10670. }
  10671. var top = currentNode.offset().top;
  10672. // Special Layer code
  10673. if ($ax.getTypeFromElementId(elementId) == 'layer') {
  10674. var first = true;
  10675. var children = currentNode.children();
  10676. for (var i = 0; i < children.length; i++) {
  10677. var child = $(children[i]);
  10678. var subDisplaySet = false;
  10679. if (child.css('display') == 'none') {
  10680. child.css('display', '');
  10681. subDisplaySet = true;
  10682. }
  10683. if (first) top = child.offset().top;
  10684. else top = Math.min(child.offset().top, top);
  10685. first = false;
  10686. if (subDisplaySet) child.css('display', 'none');
  10687. }
  10688. }
  10689. if(displaySet) currentNode.css('display', oldDisplay);
  10690. return top;
  10691. };
  10692. // ****************** Annotation and Link Functions ****************** //
  10693. $ax.legacy.GetAnnotationHtml = function(annJson) {
  10694. var retVal = "";
  10695. for(var noteName in annJson) {
  10696. if(noteName != "label" && noteName != "id") {
  10697. retVal += "<div class='annotationName'>" + noteName + "</div>";
  10698. retVal += "<div class='annotationValue'>" + linkify(annJson[noteName]) + "</div>";
  10699. }
  10700. }
  10701. return retVal;
  10702. function linkify(text) {
  10703. var urlRegex = /(\b(((https?|ftp|file):\/\/)|(www\.))[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;
  10704. return text.replace(urlRegex, function (url, b, c) {
  10705. var url2 = (c == 'www.') ? 'http://' + url : url;
  10706. return '<a href="' + url2 + '" target="_blank" class="noteLink">' + url + '</a>';
  10707. });
  10708. }
  10709. };
  10710. $ax.legacy.GetScrollable = function(target) {
  10711. var $target = $(target);
  10712. var last = $target;
  10713. // Start past inital target. Can't scroll to target in itself, must be some ancestor.
  10714. var current = last.parent();
  10715. while(!current.is('body') && !current.is('html')) {
  10716. var elementId = current.attr('id');
  10717. var diagramObject = elementId && $ax.getObjectFromElementId(elementId);
  10718. if(diagramObject && $ax.public.fn.IsDynamicPanel(diagramObject.type) && diagramObject.scrollbars != 'none') {
  10719. //returns the panel diagram div which handles scrolling
  10720. return $ax.dynamicPanelManager.getShownState(current.attr('id'))[0];
  10721. }
  10722. last = current;
  10723. current = current.parent();
  10724. }
  10725. // Need to do this because of ie
  10726. if(IE_10_AND_BELOW) return window.document.documentElement;
  10727. else return window.document.body;
  10728. };
  10729. });
  10730. //***** viewer.js *****//
  10731. // ******* SITEMAP TOOLBAR VIEWER ACTIONS ******** //
  10732. $axure.internal(function ($ax) {
  10733. var userTriggeredEventNames = ['onClick', 'onDoubleClick', 'onMouseOver', 'onMouseMove', 'onMouseOut', 'onMouseDown', 'onMouseUp',
  10734. 'onKeyDown', 'onKeyUp', 'onFocus', 'onLostFocus', 'onTextChange', 'onSelectionChange', 'onSelectedChange', 'onSelect', 'onUnselect',
  10735. 'onSwipeLeft', 'onSwipeRight', 'onSwipeUp', 'onSwipeDown', 'onDragStart', 'onDrag', 'onDragDrop', 'onScroll', 'onContextMenu', 'onMouseHover', 'onLongClick'];
  10736. $ax.messageCenter.addMessageListener(function(message, data) {
  10737. //If annotation toggle message received from sitemap, toggle footnotes
  10738. if(message == 'annotationToggle') {
  10739. if(data == true) {
  10740. $('div.annotation').show();
  10741. $('div.annnotelabel').show();
  10742. $('div.annnoteimage').show();
  10743. } else {
  10744. $('div.annotation').hide();
  10745. $('div.annnotelabel').hide();
  10746. $('div.annnoteimage').hide();
  10747. }
  10748. }
  10749. });
  10750. var _toggleSelectWidgetNoteForRepeater = function (repeaterId, scriptId, select) {
  10751. var itemIds = $ax.getItemIdsForRepeater(repeaterId);
  10752. for(var i = 0; i < itemIds.length; i++) {
  10753. var itemId = itemIds[i];
  10754. var elementId = $ax.repeater.createElementId(scriptId, itemId);
  10755. if(select) $('#' + elementId).addClass('widgetNoteSelected');
  10756. else $('#' + elementId).removeClass('widgetNoteSelected');
  10757. }
  10758. }
  10759. var lastSelectedWidgetNote;
  10760. $ax.messageCenter.addMessageListener(function (message, data) {
  10761. //If annotation toggle message received from sitemap, toggle footnotes
  10762. if(message == 'toggleSelectWidgetNote') {
  10763. var dataSplit = data.split('@');
  10764. if(lastSelectedWidgetNote == data) {
  10765. if(dataSplit.length === 2) {
  10766. _toggleSelectWidgetNoteForRepeater(dataSplit[0], dataSplit[1], false);
  10767. } else {
  10768. $('#' + lastSelectedWidgetNote).removeClass('widgetNoteSelected');
  10769. }
  10770. lastSelectedWidgetNote = null;
  10771. return;
  10772. }
  10773. if(lastSelectedWidgetNote) {
  10774. var lastDataSplit = lastSelectedWidgetNote.split('@');
  10775. if(lastDataSplit.length === 2) {
  10776. _toggleSelectWidgetNoteForRepeater(lastDataSplit[0], lastDataSplit[1], false);
  10777. } else {
  10778. $('#' + lastSelectedWidgetNote).removeClass('widgetNoteSelected');
  10779. }
  10780. }
  10781. if(dataSplit.length > 1) {
  10782. _toggleSelectWidgetNoteForRepeater(dataSplit[0], dataSplit[1], true);
  10783. } else {
  10784. $('#' + data).addClass('widgetNoteSelected');
  10785. }
  10786. lastSelectedWidgetNote = data;
  10787. }
  10788. });
  10789. var highlightEnabled = false;
  10790. $ax.messageCenter.addMessageListener(function(message, data) {
  10791. if(message == 'highlightInteractive') {
  10792. highlightEnabled = data == true;
  10793. _applyHighlight($ax('*'));
  10794. }
  10795. });
  10796. var _applyHighlight = $ax.applyHighlight = function(query, ignoreUnset) {
  10797. if(ignoreUnset && !highlightEnabled) return;
  10798. var pulsateClassName = 'legacyPulsateBorder';
  10799. //Determine if the widget has a defined userTriggeredEventName specified in the array above
  10800. var _isInteractive = function(diagramObject) {
  10801. if(diagramObject && diagramObject.interactionMap) {
  10802. for(var index in userTriggeredEventNames) {
  10803. if(diagramObject.interactionMap[userTriggeredEventNames[index]]) return true;
  10804. }
  10805. }
  10806. return false;
  10807. };
  10808. //Traverse through parent layers (if any) of an element and see if any have a defined userTriggeredEventName
  10809. var _findMatchInParent = function(id) {
  10810. var parents = $ax('#' + id).getParents(true, ['layer'])[0];
  10811. for(var i in parents) {
  10812. var parentId = parents[i];
  10813. var parentObj = $ax.getObjectFromScriptId(parentId);
  10814. if(_isInteractive(parentObj)) return true;
  10815. }
  10816. return false;
  10817. };
  10818. //Find all widgets with a defined userTriggeredEventName specified in the array above
  10819. var $matchingElements = query.filter(function (obj, id) {
  10820. //This prevents the top left corner of the page from highlighting with everything else
  10821. if($ax.public.fn.IsLayer(obj.type)) return false;
  10822. if(_isInteractive(obj)) return true;
  10823. else if($ax.public.fn.IsVector(obj.type) && obj.referencePageUrl) return true;
  10824. //Last check on the object's parent layer(s), if a layer has a defined userTriggeredEventName
  10825. //then we shall highlight each member of that layer TODO This is a design decision and is subject to change
  10826. return _findMatchInParent(id);
  10827. }).$();
  10828. var isHighlighted = $matchingElements.is('.' + pulsateClassName);
  10829. //Toggle the pulsate class on the matched elements
  10830. if(highlightEnabled && !isHighlighted) {
  10831. $matchingElements.addClass(pulsateClassName);
  10832. } else if(!highlightEnabled && isHighlighted) {
  10833. $matchingElements.removeClass(pulsateClassName);
  10834. }
  10835. };
  10836. });
  10837. //***** math.js *****//
  10838. $axure.internal(function($ax) {
  10839. $ax.public.fn.matrixMultiply = function(matrix, vector) {
  10840. if(!matrix.tx) matrix.tx = 0;
  10841. if(!matrix.ty) matrix.ty = 0;
  10842. var outX = matrix.m11 * vector.x + matrix.m12 * vector.y + matrix.tx;
  10843. var outY = matrix.m21 * vector.x + matrix.m22 * vector.y + matrix.ty;
  10844. return { x: outX, y: outY };
  10845. }
  10846. $ax.public.fn.matrixInverse = function(matrix) {
  10847. if(!matrix.tx) matrix.tx = 0;
  10848. if(!matrix.ty) matrix.ty = 0;
  10849. var determinant = matrix.m11*matrix.m22 - matrix.m12*matrix.m21;
  10850. //var threshold = (M11 * M11 + M22 *M22 + M12 *M12+ M21 *M21) / 100000;
  10851. //if(determinant.DeltaEquals(0, threshold) && determinant < 0.01) {
  10852. // return Invalid;
  10853. //}
  10854. return {
  10855. m11 : matrix.m22/determinant,
  10856. m12 : -matrix.m12/determinant,
  10857. tx : (matrix.ty*matrix.m12 - matrix.tx*matrix.m22)/determinant,
  10858. m21: -matrix.m21 / determinant,
  10859. m22: matrix.m11 / determinant,
  10860. ty: (matrix.tx * matrix.m21 - matrix.ty * matrix.m11) / determinant
  10861. };
  10862. }
  10863. $ax.public.fn.matrixMultiplyMatrix = function (matrix1, matrix2) {
  10864. if (!matrix1.tx) matrix1.tx = 0;
  10865. if (!matrix1.ty) matrix1.ty = 0;
  10866. if (!matrix2.tx) matrix2.tx = 0;
  10867. if (!matrix2.ty) matrix2.ty = 0;
  10868. return {
  10869. m11: matrix1.m12*matrix2.m21 + matrix1.m11*matrix2.m11,
  10870. m12: matrix1.m12*matrix2.m22 + matrix1.m11*matrix2.m12,
  10871. tx: matrix1.m12 * matrix2.ty + matrix1.m11 * matrix2.tx + matrix1.tx,
  10872. m21: matrix1.m22 * matrix2.m21 + matrix1.m21 * matrix2.m11,
  10873. m22: matrix1.m22 * matrix2.m22 + matrix1.m21 * matrix2.m12,
  10874. ty: matrix1.m22 * matrix2.ty + matrix1.m21 * matrix2.tx + matrix1.ty,
  10875. };
  10876. }
  10877. $ax.public.fn.transformFromElement = function (element) {
  10878. var st = window.getComputedStyle(element, null);
  10879. var tr = st.getPropertyValue("-webkit-transform") ||
  10880. st.getPropertyValue("-moz-transform") ||
  10881. st.getPropertyValue("-ms-transform") ||
  10882. st.getPropertyValue("-o-transform") ||
  10883. st.getPropertyValue("transform");
  10884. if (tr.indexOf('none') < 0) {
  10885. var matrix = tr.split('(')[1];
  10886. matrix = matrix.split(')')[0];
  10887. matrix = matrix.split(',');
  10888. for (var l = 0; l < matrix.length; l++) {
  10889. matrix[l] = Number(matrix[l]);
  10890. }
  10891. } else { matrix = [1.0, 0.0, 0.0, 1.0, 0.0, 0.0]; }
  10892. return matrix;
  10893. // matrix[0] = cosine, matrix[1] = sine.
  10894. // Assuming the element is still orthogonal.
  10895. }
  10896. $ax.public.fn.vectorMinus = function(vector1, vector2) { return { x: vector1.x - vector2.x, y: vector1.y - vector2.y }; }
  10897. $ax.public.fn.vectorPlus = function (vector1, vector2) { return { x: vector1.x + vector2.x, y: vector1.y + vector2.y }; }
  10898. $ax.public.fn.vectorMidpoint = function (vector1, vector2) { return { x: (vector1.x + vector2.x) / 2.0, y: (vector1.y + vector2.y) / 2.0 }; }
  10899. $ax.public.fn.fourCornersToBasis = function (fourCorners) {
  10900. return {
  10901. widthVector: $ax.public.fn.vectorMinus(fourCorners.widgetTopRight, fourCorners.widgetTopLeft),
  10902. heightVector: $ax.public.fn.vectorMinus(fourCorners.widgetBottomLeft, fourCorners.widgetTopLeft)
  10903. };
  10904. }
  10905. $ax.public.fn.matrixString = function(m11, m21, m12, m22, tx, ty) {
  10906. return "Matrix(" + m11 + "," + m21 + "," + m12 + "," + m22 + ", " + tx + ", " + ty + ")";
  10907. }
  10908. $ax.public.fn.getWidgetBoundingRect = function (widgetId) {
  10909. var emptyRect = { left: 0, top: 0, centerPoint: { x: 0, y: 0 }, width: 0, height: 0 };
  10910. var element = document.getElementById(widgetId);
  10911. if (!element) return emptyRect;
  10912. var object = $obj(widgetId);
  10913. if (object && object.type && $ax.public.fn.IsLayer(object.type)) {
  10914. var layerChildren = _getLayerChildrenDeep(widgetId);
  10915. if (!layerChildren) return emptyRect;
  10916. else return _getBoundingRectForMultipleWidgets(layerChildren);
  10917. }
  10918. return _getBoundingRectForSingleWidget(widgetId);
  10919. };
  10920. var _getLayerChildrenDeep = $ax.public.fn.getLayerChildrenDeep = function (layerId, includeLayers, includeHidden) {
  10921. var deep = [];
  10922. var children = $ax('#' + layerId).getChildren()[0].children;
  10923. for (var index = 0; index < children.length; index++) {
  10924. var childId = children[index];
  10925. if(!includeHidden && !$ax.visibility.IsIdVisible(childId)) continue;
  10926. if ($ax.public.fn.IsLayer($obj(childId).type)) {
  10927. if (includeLayers) deep.push(childId);
  10928. var recursiveChildren = _getLayerChildrenDeep(childId, includeLayers, includeHidden);
  10929. for (var j = 0; j < recursiveChildren.length; j++) deep.push(recursiveChildren[j]);
  10930. } else deep.push(childId);
  10931. }
  10932. return deep;
  10933. };
  10934. var _getBoundingRectForMultipleWidgets = function (widgetsIdArray, relativeToPage) {
  10935. if (!widgetsIdArray || widgetsIdArray.constructor !== Array) return undefined;
  10936. if (widgetsIdArray.length == 0) return { left: 0, top: 0, centerPoint: { x: 0, y: 0 }, width: 0, height: 0 };
  10937. var widgetRect = _getBoundingRectForSingleWidget(widgetsIdArray[0], relativeToPage, true);
  10938. var boundingRect = { left: widgetRect.left, right: widgetRect.right, top: widgetRect.top, bottom: widgetRect.bottom };
  10939. for (var index = 1; index < widgetsIdArray.length; index++) {
  10940. widgetRect = _getBoundingRectForSingleWidget(widgetsIdArray[index], relativeToPage);
  10941. boundingRect.left = Math.min(boundingRect.left, widgetRect.left);
  10942. boundingRect.top = Math.min(boundingRect.top, widgetRect.top);
  10943. boundingRect.right = Math.max(boundingRect.right, widgetRect.right);
  10944. boundingRect.bottom = Math.max(boundingRect.bottom, widgetRect.bottom);
  10945. }
  10946. boundingRect.centerPoint = { x: (boundingRect.right + boundingRect.left) / 2.0, y: (boundingRect.bottom + boundingRect.top) / 2.0 };
  10947. boundingRect.width = boundingRect.right - boundingRect.left;
  10948. boundingRect.height = boundingRect.bottom - boundingRect.top;
  10949. return boundingRect;
  10950. };
  10951. var _getBoundingRectForSingleWidget = function (widgetId, relativeToPage, justSides) {
  10952. var element = document.getElementById(widgetId);
  10953. var boundingRect, tempBoundingRect, position;
  10954. var displayChanged = _displayHackStart(element);
  10955. if (_isCompoundVectorHtml(element)) {
  10956. //tempBoundingRect = _getCompoundImageBoundingClientSize(widgetId);
  10957. //position = { left: tempBoundingRect.left, top: tempBoundingRect.top };
  10958. position = $(element).position();
  10959. tempBoundingRect = {};
  10960. tempBoundingRect.left = position.left; //= _getCompoundImageBoundingClientSize(widgetId);
  10961. tempBoundingRect.top = position.top;
  10962. tempBoundingRect.width = Number(element.getAttribute('WidgetWidth'));
  10963. tempBoundingRect.height = Number(element.getAttribute('WidgetHeight'));
  10964. } else {
  10965. var boundingElement = element;
  10966. if($ax.dynamicPanelManager.isIdFitToContent(widgetId)) {
  10967. var stateId = $ax.visibility.GetPanelState(widgetId);
  10968. if(stateId != '') boundingElement = document.getElementById(stateId);
  10969. }
  10970. tempBoundingRect = boundingElement.getBoundingClientRect();
  10971. var jElement = $(element);
  10972. position = jElement.position();
  10973. if(jElement.css('position') == 'fixed') {
  10974. position.left += Number(jElement.css('margin-left').replace("px", ""));
  10975. position.top += Number(jElement.css('margin-top').replace("px", ""));
  10976. }
  10977. }
  10978. var layers = $ax('#' + widgetId).getParents(true, ['layer'])[0];
  10979. var flip = '';
  10980. var mirrorWidth = 0;
  10981. var mirrorHeight = 0;
  10982. for (var i = 0; i < layers.length; i++) {
  10983. //should always be 0,0
  10984. var layerPos = $jobj(layers[i]).position();
  10985. position.left += layerPos.left;
  10986. position.top += layerPos.top;
  10987. var outer = $ax.visibility.applyWidgetContainer(layers[i], true, true);
  10988. if (outer.length) {
  10989. var outerPos = outer.position();
  10990. position.left += outerPos.left;
  10991. position.top += outerPos.top;
  10992. }
  10993. //when a group is flipped we find the unflipped position
  10994. var inner = $jobj(layers[i] + '_container_inner');
  10995. var taggedFlip = inner.data('flip');
  10996. if (inner.length && taggedFlip) {
  10997. //only account for flip if transform is applied
  10998. var matrix = taggedFlip && (inner.css("-webkit-transform") || inner.css("-moz-transform") ||
  10999. inner.css("-ms-transform") || inner.css("-o-transform") || inner.css("transform"));
  11000. if (matrix !== 'none') {
  11001. flip = taggedFlip;
  11002. mirrorWidth = $ax.getNumFromPx(inner.css('width'));
  11003. mirrorHeight = $ax.getNumFromPx(inner.css('height'));
  11004. }
  11005. }
  11006. }
  11007. //Now account for flip
  11008. if (flip == 'x') position.top = mirrorHeight - position.top - element.getBoundingClientRect().height;
  11009. else if (flip == 'y') position.left = mirrorWidth - position.left - element.getBoundingClientRect().width;
  11010. boundingRect = {
  11011. left: position.left,
  11012. right: position.left + tempBoundingRect.width,
  11013. top: position.top,
  11014. bottom: position.top + tempBoundingRect.height
  11015. };
  11016. _displayHackEnd(displayChanged);
  11017. if (justSides) return boundingRect;
  11018. boundingRect.width = boundingRect.right - boundingRect.left;
  11019. boundingRect.height = boundingRect.bottom - boundingRect.top;
  11020. boundingRect.centerPoint = {
  11021. x: boundingRect.width / 2 + boundingRect.left,
  11022. y: boundingRect.height / 2 + boundingRect.top
  11023. };
  11024. return boundingRect;
  11025. };
  11026. var _getPointAfterRotate = $ax.public.fn.getPointAfterRotate = function (angleInDegrees, pointToRotate, centerPoint) {
  11027. var displacement = $ax.public.fn.vectorMinus(pointToRotate, centerPoint);
  11028. var rotationMatrix = $ax.public.fn.rotationMatrix(angleInDegrees);
  11029. rotationMatrix.tx = centerPoint.x;
  11030. rotationMatrix.ty = centerPoint.y;
  11031. return $ax.public.fn.matrixMultiply(rotationMatrix, displacement);
  11032. };
  11033. $ax.public.fn.getBoundingSizeForRotate = function(width, height, rotation) {
  11034. // point to rotate around doesn't matter since we just care about size, if location matter we need more args and location matters.
  11035. var origin = { x: 0, y: 0 };
  11036. var corner1 = { x: width, y: 0 };
  11037. var corner2 = { x: 0, y: height };
  11038. var corner3 = { x: width, y: height };
  11039. corner1 = _getPointAfterRotate(rotation, corner1, origin);
  11040. corner2 = _getPointAfterRotate(rotation, corner2, origin);
  11041. corner3 = _getPointAfterRotate(rotation, corner3, origin);
  11042. var left = Math.min(0, corner1.x, corner2.x, corner3.x);
  11043. var right = Math.max(0, corner1.x, corner2.x, corner3.x);
  11044. var top = Math.min(0, corner1.y, corner2.y, corner3.y);
  11045. var bottom = Math.max(0, corner1.y, corner2.y, corner3.y);
  11046. return { width: right - left, height: bottom - top };
  11047. }
  11048. $ax.public.fn.getPositionRelativeToParent = function (elementId) {
  11049. var element = document.getElementById(elementId);
  11050. var list = _displayHackStart(element);
  11051. var position = $(element).position();
  11052. _displayHackEnd(list);
  11053. return position;
  11054. };
  11055. var _displayHackStart = $ax.public.fn.displayHackStart = function (element) {
  11056. // TODO: Options: 1) stop setting display none. Big change for this late in the game. 2) Implement our own bounding.
  11057. // TODO: 3) Current method is look for any parents that are set to none, and and temporarily unblock. Don't like it, but it works.
  11058. var parent = element;
  11059. var displays = [];
  11060. while (parent) {
  11061. if (parent.style.display == 'none') {
  11062. displays.push(parent);
  11063. //use block to overwrites default hidden objects' display
  11064. parent.style.display = 'block';
  11065. }
  11066. parent = parent.parentElement;
  11067. }
  11068. return displays;
  11069. };
  11070. var _displayHackEnd = $ax.public.fn.displayHackEnd = function (displayChangedList) {
  11071. for (var i = 0; i < displayChangedList.length; i++) displayChangedList[i].style.display = 'none';
  11072. };
  11073. var _isCompoundVectorHtml = $ax.public.fn.isCompoundVectorHtml = function(hElement) {
  11074. return hElement.hasAttribute('compoundmode') && hElement.getAttribute('compoundmode') == "true";
  11075. }
  11076. $ax.public.fn.removeCompound = function (jobj) { if(_isCompoundVectorHtml(jobj[0])) jobj.removeClass('compound'); }
  11077. $ax.public.fn.restoreCompound = function (jobj) { if (_isCompoundVectorHtml(jobj[0])) jobj.addClass('compound'); }
  11078. $ax.public.fn.compoundIdFromComponent = function(id) {
  11079. var pPos = id.indexOf('p');
  11080. var dashPos = id.indexOf('-');
  11081. if (pPos < 1) return id;
  11082. else if (dashPos < 0) return id.substring(0, pPos);
  11083. else return id.substring(0, pPos) + id.substring(dashPos);
  11084. }
  11085. $ax.public.fn.l2 = function (x, y) { return Math.sqrt(x * x + y * y); }
  11086. $ax.public.fn.convertToSingleImage = function (jobj) {
  11087. if(!jobj[0]) return;
  11088. var widgetId = jobj[0].id;
  11089. var object = $obj(widgetId);
  11090. if ($ax.public.fn.IsLayer(object.type)) {
  11091. var recursiveChildren = _getLayerChildrenDeep(widgetId, true);
  11092. for (var j = 0; j < recursiveChildren.length; j++)
  11093. $ax.public.fn.convertToSingleImage($jobj(recursiveChildren[j]));
  11094. return;
  11095. }
  11096. //var layer =
  11097. if(!_isCompoundVectorHtml(jobj[0])) return;
  11098. $('#' + widgetId).removeClass("compound");
  11099. $('#' + widgetId + '_img').removeClass("singleImg");
  11100. jobj[0].setAttribute('compoundmode', 'false');
  11101. var components = object.compoundChildren;
  11102. delete object.generateCompound;
  11103. for (var i = 0; i < components.length; i++) {
  11104. var componentJobj = $jobj($ax.public.fn.getComponentId(widgetId, components[i]));
  11105. componentJobj.css('display', 'none');
  11106. componentJobj.css('visibility', 'hidden');
  11107. }
  11108. }
  11109. $ax.public.fn.getContainerDimensions = function(query) {
  11110. // returns undefined if no containers found.
  11111. var containerDimensions;
  11112. for (var i = 0; i < query[0].children.length; i++) {
  11113. var node = query[0].children[i];
  11114. if (node.id.indexOf(query[0].id) >= 0 && node.id.indexOf('container') >= 0) {
  11115. containerDimensions = node.style;
  11116. }
  11117. }
  11118. return containerDimensions;
  11119. }
  11120. $ax.public.fn.rotationMatrix = function (angleInDegrees) {
  11121. var angleInRadians = angleInDegrees * (Math.PI / 180);
  11122. var cosTheta = Math.cos(angleInRadians);
  11123. var sinTheta = Math.sin(angleInRadians);
  11124. return { m11: cosTheta, m12: -sinTheta, m21: sinTheta, m22: cosTheta, tx: 0.0, ty: 0.0 };
  11125. }
  11126. $ax.public.fn.GetFieldFromStyle = function (query, field) {
  11127. var raw = query[0].style[field];
  11128. if (!raw) raw = query.css(field);
  11129. return Number(raw.replace('px', ''));
  11130. }
  11131. $ax.public.fn.setTransformHowever = function (transformString) {
  11132. return {
  11133. '-webkit-transform': transformString,
  11134. '-moz-transform': transformString,
  11135. '-ms-transform': transformString,
  11136. '-o-transform': transformString,
  11137. 'transform': transformString
  11138. };
  11139. }
  11140. $ax.public.fn.getCornersFromComponent = function (id) {
  11141. var element = document.getElementById(id);
  11142. var matrix = $ax.public.fn.transformFromElement(element);
  11143. var currentMatrix = { m11: matrix[0], m21: matrix[1], m12: matrix[2], m22: matrix[3], tx: matrix[4], ty: matrix[5] };
  11144. var dimensions = {};
  11145. var axObj = $ax('#' + id);
  11146. dimensions.left = axObj.left(true);
  11147. dimensions.top = axObj.top(true);
  11148. var size = axObj.size();
  11149. dimensions.width = size.width;
  11150. dimensions.height = size.height;
  11151. //var transformMatrix1 = { m11: 1, m12: 0, m21: 0, m22: 1, tx: -invariant.x, ty: -invariant.y };
  11152. //var transformMatrix2 = { m11: 1, m12: 0, m21: 0, m22: 1, tx: 500, ty: 500 };
  11153. var halfWidth = dimensions.width * 0.5;
  11154. var halfHeight = dimensions.height * 0.5;
  11155. //var preTransformTopLeft = { x: -halfWidth, y: -halfHeight };
  11156. //var preTransformBottomLeft = { x: -halfWidth, y: halfHeight };
  11157. var preTransformTopRight = { x: halfWidth, y: -halfHeight };
  11158. var preTransformBottomRight = { x: halfWidth, y: halfHeight };
  11159. return {
  11160. //relativeTopLeft: $ax.public.fn.matrixMultiply(currentMatrix, preTransformTopLeft),
  11161. //relativeBottomLeft: $ax.public.fn.matrixMultiply(currentMatrix, preTransformBottomLeft),
  11162. relativeTopRight: $ax.public.fn.matrixMultiply(currentMatrix, preTransformTopRight),
  11163. relativeBottomRight: $ax.public.fn.matrixMultiply(currentMatrix, preTransformBottomRight),
  11164. centerPoint: { x: dimensions.left + halfWidth, y: dimensions.top + halfHeight }
  11165. //originalDimensions: dimensions,
  11166. //transformShift: { x: matrix[4], y: matrix[5] }
  11167. }
  11168. }
  11169. });