prototypePost.js 556 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048
  1. // 8.0.0.3338. Generated 4/28/2017 12:22:57 AM 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 _showCaseDescriptions = function(elementId, eventInfo, axEventObject, synthetic) {
  566. if(axEventObject.cases.length == 0) return true;
  567. var linksId = elementId + "linkBox";
  568. $('#' + linksId).remove();
  569. var $container = $("<div class='intcases' id='" + linksId + "'></div>");
  570. if(!_isEventSimulating(axEventObject)) {
  571. var copy = $ax.eventCopy(eventInfo);
  572. for(var i = 0; i < axEventObject.cases.length; i++) {
  573. var $link = $("<div class='intcaselink'>" + axEventObject.cases[i].description + "</div>");
  574. $link.click(function(j) {
  575. return function () {
  576. var currentCase = axEventObject.cases[j];
  577. $ax.messageCenter.postMessage('axCase', { 'description': currentCase.description });
  578. for(var k = 0; k < currentCase.actions.length; k++) {
  579. $ax.messageCenter.postMessage('axAction', { 'description': currentCase.actions[k].description });
  580. }
  581. $ax.messageCenter.postMessage('axEventComplete');
  582. var bubble = $ax.action.dispatchAction(copy, axEventObject.cases[j].actions);
  583. $ax.action.flushAllResizeMoveActions(copy);
  584. $('#' + linksId).remove();
  585. return bubble;
  586. };
  587. } (i)
  588. );
  589. $container.append($link);
  590. }
  591. } else {
  592. var fullDescription = axEventObject.description + ":<br>";
  593. for(var i = 0; i < axEventObject.cases.length; i++) {
  594. var currentCase = axEventObject.cases[i];
  595. fullDescription += "&nbsp;&nbsp;" + currentCase.description.replace(/<br>/g, '<br>&nbsp;&nbsp;') + ":<br>";
  596. for(var j = 0; j < currentCase.actions.length; j++) {
  597. fullDescription += "&nbsp;&nbsp;&nbsp;&nbsp;" + currentCase.actions[j].description.replace(/<br>/g, '<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;') + "<br>";
  598. }
  599. }
  600. fullDescription = fullDescription.substring(0, fullDescription.length - 4);
  601. var $link = $("<div class='intcaselink'>" + fullDescription + "</div>");
  602. $link.click(function() {
  603. _handleEvent(elementId, eventInfo, axEventObject, true, synthetic);
  604. $ax.messageCenter.postMessage('axEventComplete');
  605. $('#' + linksId).remove();
  606. return;
  607. });
  608. $container.append($link);
  609. }
  610. $container.mouseleave(function(e) { $ax.legacy.SuppressBubble(e); });
  611. $('body').append($container);
  612. _showCaseLinks(eventInfo, linksId);
  613. };
  614. var _showCaseLinks = function(eventInfo, linksId) {
  615. var links = window.document.getElementById(linksId);
  616. links.style.top = eventInfo.pageY;
  617. var left = eventInfo.pageX;
  618. links.style.left = left;
  619. $ax.visibility.SetVisible(links, true);
  620. $ax.legacy.BringToFront(linksId, true);
  621. // Switch to using jquery if this is still needed. Really old legacy code, likely for a browser no longer supported.
  622. //$ax.legacy.RefreshScreen();
  623. };
  624. var _shouldShowCaseDescriptions = function(axEventObject) {
  625. if($ax.document.configuration.linkStyle == "alwaysDisplayTargets") return true;
  626. if($ax.document.configuration.linkStyle == "neverDisplayTargets") return false;
  627. if(axEventObject.cases.length == 0) return false;
  628. if(_isEventSimulating(axEventObject)) return false;
  629. if(axEventObject.cases.length >= 2) return true;
  630. return false;
  631. };
  632. var _isEventSimulating = function(axEventObject) {
  633. for(var i = 0; i < axEventObject.cases.length; i++) {
  634. if(axEventObject.cases[i].condition) return true;
  635. }
  636. return false;
  637. };
  638. var _handleCaseGroup = function(eventInfo, caseGroup, groupRefreshes) {
  639. for(var i = 0; i < caseGroup.length; i++) {
  640. var currentCase = caseGroup[i];
  641. if(!currentCase.condition || _processCondition(currentCase.condition, eventInfo)) {
  642. $ax.messageCenter.postMessage('axCase', { 'description': currentCase.description });
  643. for(var j = 0; j < currentCase.actions.length; j++) {
  644. if(currentCase.actions[j].action != 'refreshRepeater') $ax.messageCenter.postMessage('axAction', { 'description': currentCase.actions[j].description });
  645. }
  646. for(var j = 0; j < currentCase.actions.length; j++) {
  647. var action = currentCase.actions[j];
  648. if(action.action == 'wait') break;
  649. if(action.action != 'refreshRepeater') continue;
  650. for(var k = 0; k < action.repeatersToRefresh.length; k++) {
  651. var id = $ax.getElementIdsFromPath(action.repeatersToRefresh[i], eventInfo)[i];
  652. if(id) {
  653. var index = groupRefreshes.indexOf(id);
  654. if(index != -1) $ax.splice(groupRefreshes, index);
  655. }
  656. }
  657. }
  658. // Any guaranteed refreshes that aren't accounted for must be run still.
  659. $ax.action.tryRefreshRepeaters(groupRefreshes, eventInfo);
  660. $ax.action.dispatchAction(eventInfo, currentCase.actions);
  661. return false;
  662. }
  663. }
  664. // Any guaranteed refreshes that aren't accounted for must be run still.
  665. $ax.action.tryRefreshRepeaters(groupRefreshes, eventInfo);
  666. return true;
  667. };
  668. var _processCondition = function(expr, eventInfo) {
  669. return $ax.expr.evaluateExpr(expr, eventInfo);
  670. };
  671. var _attachTreeNodeEvent = function(elementId, eventName, fn) {
  672. //we need to set the cursor here because we want to make sure that every tree node has the default
  673. //cursor set and then it's overridden if it has a click
  674. if(eventName == 'click') window.document.getElementById(elementId).style.cursor = 'pointer';
  675. _attachCustomObjectEvent(elementId, eventName, fn);
  676. };
  677. var _attachDefaultObjectEvent = function(elementIdQuery, elementId, eventName, fn) {
  678. var func = function() {
  679. if(!$ax.style.IsWidgetDisabled(elementId)) return fn.apply(this, arguments);
  680. return true;
  681. };
  682. var bind = !elementIdQuery[eventName];
  683. if(bind) elementIdQuery.bind(eventName, func);
  684. else elementIdQuery[eventName](func);
  685. };
  686. var _attachCustomObjectEvent = function(elementId, eventName, fn) {
  687. var handlers = _objectIdToEventHandlers[elementId];
  688. if(!handlers) _objectIdToEventHandlers[elementId] = handlers = {};
  689. var fnList = handlers[eventName];
  690. if(!fnList) handlers[eventName] = fnList = [];
  691. fnList[fnList.length] = fn;
  692. };
  693. var _fireObjectEvent = function(elementId, event, originalArgs) {
  694. var element = window.document.getElementById(elementId);
  695. var handlerList = _objectIdToEventHandlers[elementId] && _objectIdToEventHandlers[elementId][event];
  696. if(handlerList) {
  697. for(var i = 0; i < handlerList.length; i++) handlerList[i].apply(element, originalArgs);
  698. }
  699. eventNesting -= 1;
  700. };
  701. var _layerToFocusableWidget = {};
  702. var _widgetToFocusParent = {};
  703. _event.layerMapFocus = function(layer, elementId) {
  704. var mainObj = layer.objs[0];
  705. // If first child non existant return
  706. if (!mainObj) return;
  707. var mainId = $ax.getElementIdFromPath([mainObj.id], { relativeTo: elementId });
  708. _widgetToFocusParent[mainId] = elementId;
  709. // If first child is a layer, call recursively
  710. if ($ax.public.fn.IsLayer(mainObj.type)) {
  711. _event.layerMapFocus(mainObj, mainId);
  712. var baseId = _layerToFocusableWidget[mainId];
  713. if(baseId) _layerToFocusableWidget[elementId] = baseId;
  714. return;
  715. }
  716. _layerToFocusableWidget[elementId] = mainId;
  717. }
  718. var _needsProxy = function(obj, id, proxyName) {
  719. // layers don't need on focus ever, proxies will handle them
  720. if ($ax.public.fn.IsLayer(obj.type)) return false;
  721. // If you already focus you don't need to force yourself to proxy.
  722. if(obj.interactionMap && obj.interactionMap[proxyName]) return false;
  723. var parentId = _widgetToFocusParent[id];
  724. if(parentId) return _needsProxyHelper(parentId, proxyName);
  725. return false;
  726. }
  727. var _needsProxyHelper = function(id, proxyName) {
  728. var obj = $obj(id);
  729. if(obj.interactionMap && obj.interactionMap[proxyName]) return true;
  730. var parentId = _widgetToFocusParent[id];
  731. if(parentId) return _needsProxyHelper(parentId, proxyName);
  732. return false;
  733. }
  734. //for button shapes and images the img is focusable instead of the div to get better outlines
  735. // For layers, we remember who their proxy is.
  736. $ax.event.getFocusableWidgetOrChildId = function (elementId) {
  737. var mappedId = _layerToFocusableWidget[elementId];
  738. if (mappedId) elementId = mappedId;
  739. var inputId = $ax.repeater.applySuffixToElementId(elementId, '_input');
  740. var inputQuery = $jobj(inputId);
  741. if(inputQuery.length > 0) return inputId;
  742. var imgId = $ax.repeater.applySuffixToElementId(elementId, '_img');
  743. var imgQuery = $jobj(imgId);
  744. if (imgQuery.length > 0) return imgId;
  745. var divId = $ax.repeater.applySuffixToElementId(elementId, '_div');
  746. var divQuery = $jobj(divId);
  747. if (divQuery.length > 0) return divId;
  748. return elementId;
  749. };
  750. var _enteredWidgets = {};
  751. // key is the suppressing event, and the value is the event that is supressed
  752. var suppressingEvents = {};
  753. // key is the event that will cancel the suppression, and value is the event that was being suppressed
  754. var cancelSuppressions = {};
  755. // suppressed event maps to true if it is supressed
  756. var suppressedEventStatus = {};
  757. var initSuppressingEvents = function () {
  758. suppressingEvents['OnLongClick'] = 'OnClick';
  759. cancelSuppressions['onMouseDown'] = 'OnClick';
  760. // Have to cancel suppressed event here. Only works for non-synthetic events currently
  761. for(var key in cancelSuppressions) {
  762. var jEventName = AXURE_TO_JQUERY_EVENT_NAMES[key];
  763. if(!jEventName) continue;
  764. $('body').bind(jEventName, function () {
  765. suppressedEventStatus[cancelSuppressions[key]] = false;
  766. });
  767. }
  768. };
  769. // TODO: It may be a good idea to split this into multiple functions, or at least pull out more similar functions into private methods
  770. var _initializeObjectEvents = function(query, allowItem) {
  771. query.each(function(dObj, elementId) {
  772. var $element = $jobj(elementId);
  773. var itemId = $ax.repeater.getItemIdFromElementId(elementId);
  774. // Focus has to be done before on focus fires
  775. // Set up focus
  776. 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) ||
  777. $ax.public.fn.IsListBox(dObj.type) || $ax.public.fn.IsComboBox(dObj.type) || $ax.public.fn.IsButton(dObj.type) ||
  778. (dObj.tabbable && ($ax.public.fn.IsImageBox(dObj.type) || $ax.public.fn.IsVector(dObj.type) || $ax.IsTreeNodeObject(dObj.type) || $ax.public.fn.IsTableCell(dObj.type)))) {
  779. var focusObj = $jobj($ax.event.getFocusableWidgetOrChildId(elementId));
  780. focusObj.focus(function() {
  781. window.lastFocusedControl = elementId;
  782. });
  783. }
  784. // [MAS: Supressing events were here]
  785. _createProxies(dObj, elementId);
  786. var isDynamicPanel = $ax.public.fn.IsDynamicPanel(dObj.type);
  787. if(dObj.interactionMap) {
  788. _attachEvents(dObj, elementId, isDynamicPanel);
  789. };
  790. if (IE || $axure.browser.isEdge) {
  791. $element.mouseenter(function() {
  792. _enteredWidgets[elementId] = true;
  793. }).mouseleave(function() {
  794. _enteredWidgets[elementId] = false;
  795. });
  796. }
  797. _attachIxStyleEvents(dObj, elementId, $element);
  798. var $axElement = undefined;
  799. // Unless you are pre eval - don't allow item and have an item id - then set enabled/selected through js as usual
  800. if(allowItem || !itemId) {
  801. //initialize disabled elements, do this first before selected, cause if a widget is disabled, we don't want to apply selected style anymore
  802. if(($ax.public.fn.IsVector(dObj.type) || $ax.public.fn.IsImageBox(dObj.type) || isDynamicPanel || $ax.public.fn.IsLayer(dObj.type)) && dObj.disabled) {
  803. if(!$axElement) $axElement = $ax('#' + elementId);
  804. $axElement.enabled(false);
  805. }
  806. // Initialize selected elements if not in repeater
  807. if(($ax.public.fn.IsVector(dObj.type) || $ax.public.fn.IsImageBox(dObj.type) || isDynamicPanel || $ax.public.fn.IsLayer(dObj.type)) && dObj.selected) {
  808. if(!$axElement) $axElement = $ax('#' + elementId);
  809. $axElement.selected(true);
  810. }
  811. } else {
  812. // Otherwise everything should be set up correctly by pre-eval, except disabled is needed
  813. if($element.hasClass('disabled')) {
  814. $axElement = $ax('#' + elementId);
  815. $axElement.enabled(false);
  816. }
  817. }
  818. if(OS_MAC && WEBKIT) {
  819. if ($ax.public.fn.IsComboBox(dObj.type) && dObj.disabled) {
  820. $jobj($ax.INPUT(elementId)).css('color', 'grayText');
  821. }
  822. };
  823. // Initialize Placeholders. Right now this is text boxes and text areas.
  824. // Also, the assuption is being made that these widgets with the placeholder, have no other styles (this may change...)
  825. var hasPlaceholder = dObj.placeholderText == '' ? true : Boolean(dObj.placeholderText);
  826. if(($ax.public.fn.IsTextArea(dObj.type) || $ax.public.fn.IsTextBox(dObj.type)) && hasPlaceholder) {
  827. // This is needed to initialize the placeholder state
  828. var inputJobj = $jobj($ax.INPUT(elementId));
  829. inputJobj.bind('focus', function () {
  830. if(dObj.HideHintOnFocused) {
  831. var id = this.id;
  832. var inputIndex = id.indexOf('_input');
  833. if (inputIndex == -1) return;
  834. var inputId = id.substring(0, inputIndex);
  835. if (!$ax.placeholderManager.isActive(inputId)) return;
  836. $ax.placeholderManager.updatePlaceholder(inputId, false, true);
  837. }
  838. $ax.placeholderManager.moveCaret(this.id);
  839. }).bind('mouseup', function() {
  840. $ax.placeholderManager.moveCaret(this.id);
  841. }).bind('blur', function() {
  842. var id = this.id;
  843. var inputIndex = id.indexOf('_input');
  844. if(inputIndex == -1) return;
  845. var inputId = id.substring(0, inputIndex);
  846. if($jobj(id).val()) return;
  847. $ax.placeholderManager.updatePlaceholder(inputId, true);
  848. });
  849. if(ANDROID) {
  850. //input fires before keyup, to avoid flicker, supported in ie9 and above
  851. inputJobj.bind('input', function() {
  852. if(!dObj.HideHintOnFocused) { //hide on type
  853. var id = this.id;
  854. var inputIndex = id.indexOf('_input');
  855. if(inputIndex == -1) return;
  856. var inputId = id.substring(0, inputIndex);
  857. if($ax.placeholderManager.isActive(inputId)) {
  858. $ax.placeholderManager.updatePlaceholder(inputId, false, true);
  859. } else if(!$jobj(id).val()) {
  860. $ax.placeholderManager.updatePlaceholder(inputId, true, false);
  861. $ax.placeholderManager.moveCaret(id, 0);
  862. }
  863. }
  864. });
  865. } else {
  866. inputJobj.bind('keydown', function() {
  867. if(!dObj.HideHintOnFocused) {
  868. var id = this.id;
  869. var inputIndex = id.indexOf('_input');
  870. if(inputIndex == -1) return;
  871. var inputId = id.substring(0, inputIndex);
  872. if(!$ax.placeholderManager.isActive(inputId)) return;
  873. $ax.placeholderManager.updatePlaceholder(inputId, false, true);
  874. }
  875. }).bind('keyup', function() {
  876. var id = this.id;
  877. var inputIndex = id.indexOf('_input');
  878. if(inputIndex == -1) return;
  879. var inputId = id.substring(0, inputIndex);
  880. if($ax.placeholderManager.isActive(inputId)) return;
  881. if(!dObj.HideHintOnFocused && !$jobj(id).val()) {
  882. $ax.placeholderManager.updatePlaceholder(inputId, true);
  883. $ax.placeholderManager.moveCaret(id, 0);
  884. }
  885. });
  886. }
  887. $ax.placeholderManager.registerPlaceholder(elementId, dObj.placeholderText, inputJobj.attr('type') == 'password');
  888. $ax.placeholderManager.updatePlaceholder(elementId, !($jobj($ax.repeater.applySuffixToElementId(elementId, '_input')).val()));
  889. }
  890. // Initialize assigned submit buttons
  891. if(dObj.submitButton) {
  892. $element.keyup(function(e) {
  893. if(e.keyCode == '13') {
  894. var scriptId = $ax.repeater.getScriptIdFromElementId(elementId);
  895. var path = $ax.deepCopy(dObj.submitButton.path);
  896. path[path.length] = dObj.submitButton.id;
  897. var itemNum = $ax.repeater.getItemIdFromElementId(elementId);
  898. var submitId = $ax.getScriptIdFromPath(path, scriptId);
  899. if(itemNum && $ax.getParentRepeaterFromScriptId(submitId) == $ax.getParentRepeaterFromScriptId(scriptId)) {
  900. submitId = $ax.repeater.createElementId(submitId, itemNum);
  901. }
  902. var inputId = $ax.INPUT(submitId);
  903. if($jobj(inputId).length) submitId = inputId;
  904. $ax.setjBrowserEvent(e);
  905. $ax.event.fireClick(submitId);
  906. }
  907. }).keydown(function(e) {
  908. if(e.keyCode == '13') {
  909. e.preventDefault();
  910. }
  911. });
  912. }
  913. // Don't drag after mousing down on a plain text object
  914. if ($ax.public.fn.IsTextArea(dObj.type) || $ax.public.fn.IsTextBox(dObj.type) || $ax.public.fn.IsListBox(dObj.type) ||
  915. $ax.public.fn.IsComboBox(dObj.type) || $ax.public.fn.IsCheckBox(dObj.type) || $ax.public.fn.IsRadioButton(dObj.type)) {
  916. $element.bind($ax.features.eventNames.mouseDownName, function(event) {
  917. event.originalEvent.donotdrag = true;
  918. });
  919. }
  920. if($ax.features.supports.mobile) {
  921. $element.bind($ax.features.eventNames.mouseDownName, function() { _setCanClick(true); });
  922. if (isDynamicPanel) {
  923. $element.scroll(function() { _setCanClick(false); });
  924. }
  925. }
  926. //initialize tree node cursors to default so they will override their parent
  927. if ($ax.public.fn.IsTreeNodeObject(dObj.type) && !(dObj.interactionMap && dObj.interactionMap.onClick)) {
  928. $element.css('cursor', 'default');
  929. }
  930. //initialize widgets that are clickable to have the pointer over them when hovering
  931. if($ax.event.HasClick(dObj)) {
  932. if($element) $element.css('cursor', 'pointer');
  933. }
  934. // TODO: not sure if we need this. It appears to be working without
  935. //initialize panels for DynamicPanels
  936. if (isDynamicPanel) {
  937. $element.children().each(function() {
  938. var parts = this.id.split('_');
  939. var state = parts[parts.length - 1].substring(5);
  940. if(state != 0) $ax.visibility.SetVisible(this, false);
  941. });
  942. }
  943. //initialize TreeNodes
  944. if ($ax.public.fn.IsTreeNodeObject(dObj.type)) {
  945. if($element.hasClass('treeroot')) return;
  946. var childrenId = elementId + '_children';
  947. var children = $element.children('[id="' + childrenId + '"]:first');
  948. if(children.length > 0) {
  949. var plusMinusId = 'u' + (parseInt($ax.repeater.getScriptIdFromElementId(elementId).substring(1)) + 1);
  950. if(itemId) plusMinusId = $ax.repeater.createElementId(plusMinusId, itemId);
  951. if(!$jobj(plusMinusId).children().first().is('img')) plusMinusId = '';
  952. $ax.tree.InitializeTreeNode(elementId, plusMinusId, childrenId);
  953. }
  954. $element.click(function() { $ax.tree.SelectTreeNode(elementId, true); });
  955. }
  956. //initialize submenus
  957. if ($ax.public.fn.IsMenuObject(dObj.type)) {
  958. if($element.hasClass('sub_menu')) {
  959. var tableCellElementId = $ax.getElementIdFromPath([dObj.parentCellId], { relativeTo: elementId });
  960. $ax.menu.InitializeSubmenu(elementId, tableCellElementId);
  961. }
  962. }
  963. // Attach handles for dynamic panels that propagate styles to inner items.
  964. if ((isDynamicPanel || $ax.public.fn.IsLayer(dObj.type)) && dObj.propagate) {
  965. $element.mouseenter(function() {
  966. dynamicPanelMouseOver(this.id);
  967. }).mouseleave(function() {
  968. dynamicPanelMouseLeave(this.id);
  969. }).bind($ax.features.eventNames.mouseDownName, function() {
  970. dynamicPanelMouseDown(this.id);
  971. }).bind($ax.features.eventNames.mouseUpName, function() {
  972. dynamicPanelMouseUp(this.id);
  973. });
  974. }
  975. // These are the dynamic panel functions for propagating rollover styles and mouse down styles to inner objects
  976. var dynamicPanelMouseOver = function(elementId, fromChild) {
  977. var parent = $ax.dynamicPanelManager.parentHandlesStyles(elementId);
  978. if(parent) {
  979. dynamicPanelMouseOver(parent.id, true);
  980. if(parent.direct) return;
  981. }
  982. if($.inArray(elementId, _event.mouseOverIds) != -1) return;
  983. // If this event is coming from a child, don't mark that it's actually entered.
  984. // Only mark that this has been entered if this event has naturally been triggered. (For reason see mouseleave)
  985. if(!fromChild) _event.mouseOverIds[_event.mouseOverIds.length] = elementId;
  986. if(elementId == _event.mouseOverObjectId) return;
  987. _event.mouseOverObjectId = elementId;
  988. $ax.dynamicPanelManager.propagateMouseOver(elementId, true);
  989. };
  990. var dynamicPanelMouseLeave = function(elementId, fromChild) {
  991. var parent = $ax.dynamicPanelManager.parentHandlesStyles(elementId);
  992. if(parent) {
  993. dynamicPanelMouseLeave(parent.id, true);
  994. if(parent.direct) return;
  995. }
  996. var index = $.inArray(elementId, _event.mouseOverIds);
  997. // If index != -1, this has been natuarally entered. If naturally entered, then leaving child should not trigger leaving,
  998. // but instead wait for natural mouse leave. If natural mouse enter never triggered, natural mouse leave won't so do this now.
  999. if((index != -1) && fromChild) return;
  1000. $ax.splice(_event.mouseOverIds, index, 1);
  1001. if(elementId == _event.mouseOverObjectId) {
  1002. _event.mouseOverObjectId = '';
  1003. }
  1004. $ax.dynamicPanelManager.propagateMouseOver(elementId, false);
  1005. };
  1006. //attach handlers for button shape and tree node mouse over styles
  1007. // TODO: Can this really be removed? Trees seem to work with out (the generic hover case works for it).
  1008. // query.filter(function(obj) {
  1009. // return $ax.public.fn.IsVector(obj.type) && $ax.public.fn.IsTreeNodeObject(obj.parent.type) &&
  1010. // obj.parent.style && obj.parent.style.stateStyles &&
  1011. // obj.parent.style.stateStyles.mouseOver;
  1012. // }).mouseenter(function() {
  1013. // $ax.style.SetWidgetHover(this.id, true);
  1014. // }).mouseleave(function() {
  1015. // $ax.style.SetWidgetHover(this.id, false);
  1016. // });
  1017. //handle treeNodeObject events and prevent them from bubbling up. this is necessary because otherwise
  1018. //both a sub menu and it's parent would get a click
  1019. if ($ax.public.fn.IsTreeNodeObject(dObj.type)) {
  1020. $element.click(function() {
  1021. //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)
  1022. _fireObjectEvent(this.id, 'click', arguments);
  1023. return false;
  1024. }).each(function() {
  1025. if(!this.style.cursor) {
  1026. this.style.cursor = 'default';
  1027. }
  1028. });
  1029. }
  1030. // Synthetic events
  1031. var map = dObj.interactionMap;
  1032. // Attach dynamic panel synthetic drag and swipe events
  1033. if(dObj.type == "dynamicPanel" && map && (
  1034. map.onDragStart || map.onDrag ||
  1035. map.onDragDrop || map.onSwipeLeft || map.onSwipeRight || map.onSwipeUp || map.onSwipeDown)) {
  1036. $element.bind($ax.features.eventNames.mouseDownName, function(e) { $ax.drag.StartDragWidget(e.originalEvent, elementId); });
  1037. }
  1038. // Attach dynamic panel synthetic scroll event
  1039. if (isDynamicPanel && map && (map.onScroll || map.onScrollUp || map.onScrollDown)) {
  1040. var diagrams = dObj.diagrams;
  1041. for(var i = 0; i < diagrams.length; i++) {
  1042. var panelId = $ax.repeater.applySuffixToElementId(elementId, '_state' + i);
  1043. (function(id) {
  1044. if ($('#' + id).data('lastScrollTop') == undefined) $('#' + id).data('lastScrollTop', '0');
  1045. _attachDefaultObjectEvent($('#' + id), elementId, 'scroll', function(e) {
  1046. $ax.setjBrowserEvent(e);
  1047. var currentEvent = $ax.getjBrowserEvent();
  1048. var eventInfoFromEvent = $ax.getEventInfoFromEvent($ax.getjBrowserEvent(), false, elementId);
  1049. if(map.onScroll) _handleEvent(elementId, eventInfoFromEvent, map.onScroll);
  1050. var currentTop = $('#' + id).scrollTop();
  1051. var wasHandled = currentEvent.originalEvent.handled;
  1052. if (map.onScrollUp && currentTop < $('#' + id).data('lastScrollTop')) {
  1053. currentEvent.originalEvent.handled = false;
  1054. _handleEvent(elementId, eventInfoFromEvent, map.onScrollUp);
  1055. } else if (map.onScrollDown && currentTop > $('#' + id).data('lastScrollTop')) {
  1056. currentEvent.originalEvent.handled = false;
  1057. _handleEvent(elementId, eventInfoFromEvent, map.onScrollDown);
  1058. }
  1059. currentEvent.originalEvent.handled |= wasHandled;
  1060. $('#' + id).data('lastScrollTop', currentTop);
  1061. });
  1062. })(panelId);
  1063. }
  1064. }
  1065. // Attach synthetic hover event
  1066. if (map && map.onMouseHover) {
  1067. var MIN_HOVER_HOLD_TIME = 1000;
  1068. // So when the timeout fires, you know whether it is the same mouseenter that is active or not.
  1069. var hoverMouseCount = 0;
  1070. // Update eventInfo regularly, so position is accurate.
  1071. var hoverEventInfo;
  1072. $element.mouseenter(function(e) {
  1073. $ax.setjBrowserEvent(e);
  1074. hoverEventInfo = $ax.getEventInfoFromEvent($ax.getjBrowserEvent(), false, elementId);
  1075. (function(currCount) {
  1076. window.setTimeout(function() {
  1077. if(currCount == hoverMouseCount) _raiseSyntheticEvent(elementId, 'onMouseHover', false, hoverEventInfo, true);
  1078. }, MIN_HOVER_HOLD_TIME);
  1079. })(hoverMouseCount);
  1080. }).mouseleave(function(e) {
  1081. $ax.setjBrowserEvent(e);
  1082. hoverMouseCount++;
  1083. }).mousemove(function(e) {
  1084. $ax.setjBrowserEvent(e);
  1085. hoverEventInfo = $ax.getEventInfoFromEvent($ax.getjBrowserEvent(), false, elementId);
  1086. });
  1087. }
  1088. // Attach synthetic tap and hold event.
  1089. if (map && map.onLongClick) {
  1090. var MIN_LONG_CLICK_HOLD_TIME = 750;
  1091. // So when the timeout fires, you know whether it is the same mousedown that is active or not.
  1092. var longClickMouseCount = 0;
  1093. $element.bind($ax.features.eventNames.mouseDownName, function(e) {
  1094. (function(currCount) {
  1095. $ax.setjBrowserEvent(e);
  1096. var eventInfo = $ax.getEventInfoFromEvent($ax.getjBrowserEvent(), false, elementId);
  1097. window.setTimeout(function() {
  1098. if(currCount == longClickMouseCount) _raiseSyntheticEvent(elementId, 'onLongClick', false, eventInfo, true);
  1099. }, MIN_LONG_CLICK_HOLD_TIME);
  1100. if(e.preventDefault) e.preventDefault();
  1101. })(longClickMouseCount);
  1102. }).bind($ax.features.eventNames.mouseUpName, function(e) {
  1103. $ax.setjBrowserEvent(e);
  1104. longClickMouseCount++;
  1105. });
  1106. };
  1107. // Attach synthetic onSelectionChange event to droplist and listbox elements
  1108. if ($ax.event.HasSelectionChanged(dObj)) {
  1109. $element.bind('change', function(e) {
  1110. $ax.setjBrowserEvent(e);
  1111. _raiseSyntheticEvent(elementId, 'onSelectionChange');
  1112. });
  1113. };
  1114. // Highjack key up and key down to keep track of state of keyboard.
  1115. if($ax.event.HasKeyUpOrDown(dObj)) _event.initKeyEvents($element);
  1116. // Attach synthetic onTextChange event to textbox and textarea elements
  1117. if ($ax.event.HasTextChanged(dObj)) {
  1118. var element = $jobj($ax.INPUT(elementId));
  1119. $ax.updateElementText(elementId, element.val());
  1120. //Key down needed because when holding a key down, key up only fires once, but keydown fires repeatedly.
  1121. //Key up because last mouse down will only show the state before the last character.
  1122. element.bind('keydown', function(e) {
  1123. $ax.setjBrowserEvent(e);
  1124. $ax.event.TryFireTextChanged(elementId);
  1125. }).bind('keyup', function(e) {
  1126. $ax.setjBrowserEvent(e);
  1127. $ax.event.TryFireTextChanged(elementId);
  1128. });
  1129. };
  1130. // Attach synthetic onCheckedChange event to radiobutton and checkbox elements
  1131. if ($ax.public.fn.IsCheckBox(dObj.type) || $ax.public.fn.IsRadioButton(dObj.type)) {
  1132. var input = $jobj($ax.INPUT(elementId));
  1133. if ($ax.public.fn.IsRadioButton(dObj.type) && input.prop('checked')) {
  1134. $ax.updateRadioButtonSelected(input.attr('name'), elementId);
  1135. }
  1136. $element.bind('change', function(e) {
  1137. $ax.setjBrowserEvent(e);
  1138. var eTarget = e.target || e.srcElement;
  1139. _tryFireCheckedChanged(elementId, eTarget.checked);
  1140. });
  1141. };
  1142. var hasTap = map && (map.onClick || map.onDoubleClick);
  1143. var hasMove = map && map.onMouseMove;
  1144. _event.initMobileEvents(hasTap ? $element : $(),
  1145. hasMove ? $element : $(), elementId);
  1146. //attach link alternate styles
  1147. if(dObj.type == 'hyperlink') {
  1148. $element.mouseenter(function() {
  1149. var elementId = this.id;
  1150. if(_event.mouseOverIds.indexOf(elementId) != -1) return true;
  1151. _event.mouseOverIds[_event.mouseOverIds.length] = elementId;
  1152. var mouseOverObjectId = _event.mouseOverObjectId;
  1153. if(mouseOverObjectId && $ax.style.IsWidgetDisabled(mouseOverObjectId)) return true;
  1154. $ax.style.SetLinkHover(elementId);
  1155. var bubble = _fireObjectEvent(elementId, 'mouseenter', arguments);
  1156. $ax.annotation.updateLinkLocations($ax.style.GetTextIdFromLink(elementId));
  1157. return bubble;
  1158. }).mouseleave(function() {
  1159. var elementId = this.id;
  1160. $ax.splice(_event.mouseOverIds, _event.mouseOverIds.indexOf(elementId), 1);
  1161. var mouseOverObjectId = _event.mouseOverObjectId;
  1162. if(mouseOverObjectId && $ax.style.IsWidgetDisabled(mouseOverObjectId)) return true;
  1163. $ax.style.SetLinkNotHover(elementId);
  1164. var bubble = _fireObjectEvent(elementId, 'mouseleave', arguments);
  1165. $ax.annotation.updateLinkLocations($ax.style.GetTextIdFromLink(elementId));
  1166. return bubble;
  1167. }).bind($ax.features.eventNames.mouseDownName, function() {
  1168. var elementId = this.id;
  1169. var mouseOverObjectId = _event.mouseOverObjectId;
  1170. if($ax.style.IsWidgetDisabled(mouseOverObjectId)) return undefined;
  1171. if(mouseOverObjectId) $ax.style.SetWidgetMouseDown(mouseOverObjectId, true);
  1172. $ax.style.SetLinkMouseDown(elementId);
  1173. $ax.annotation.updateLinkLocations($ax.style.GetTextIdFromLink(elementId));
  1174. return false;
  1175. }).bind($ax.features.eventNames.mouseUpName, function() {
  1176. var elementId = this.id;
  1177. var mouseOverObjectId = _event.mouseOverObjectId;
  1178. if(mouseOverObjectId && $ax.style.IsWidgetDisabled(mouseOverObjectId)) return;
  1179. if(mouseOverObjectId) $ax.style.SetWidgetMouseDown(mouseOverObjectId, false);
  1180. $ax.style.SetLinkNotMouseDown(elementId);
  1181. $ax.annotation.updateLinkLocations($ax.style.GetTextIdFromLink(elementId));
  1182. }).click(function() {
  1183. var elementId = this.id;
  1184. var mouseOverObjectId = _event.mouseOverObjectId;
  1185. if(mouseOverObjectId && $ax.style.IsWidgetDisabled(mouseOverObjectId)) return undefined;
  1186. return _fireObjectEvent(elementId, 'click', arguments);
  1187. });
  1188. }
  1189. // Init inline frames
  1190. if (dObj.type == 'inlineFrame') {
  1191. var target = dObj.target;
  1192. var url = '';
  1193. if(target.includeVariables && target.url) {
  1194. var origSrc = target.url;
  1195. url = origSrc.toLowerCase().indexOf('http://') == -1 ? $ax.globalVariableProvider.getLinkUrl(origSrc) : origSrc;
  1196. } else if(target.urlLiteral) {
  1197. url = $ax.expr.evaluateExpr(target.urlLiteral, $ax.getEventInfoFromEvent(undefined, true, elementId), true);
  1198. }
  1199. if(url) $jobj($ax.INPUT(elementId)).attr('src', url);
  1200. };
  1201. });
  1202. }
  1203. $ax.initializeObjectEvents = _initializeObjectEvents;
  1204. $ax.event.updateIxStyleEvents = function(elementId) {
  1205. _dettachIxStyleEvents(elementId);
  1206. _attachIxStyleEvents($ax.getObjectFromElementId(elementId), elementId, $jobj(elementId), true);
  1207. }
  1208. var _dettachIxStyleEvents = function(elementId) {
  1209. var $element = $jobj(elementId);
  1210. $element.off('mouseenter.ixStyle')
  1211. .off('mouseleave.ixStyle')
  1212. .off($ax.features.eventNames.mouseDownName + '.ixStyle')
  1213. .off($ax.features.eventNames.mouseUpName + '.ixStyle');
  1214. }
  1215. var _attachIxStyleEvents = function(dObj, elementId, $element, ignoreHasIxStyles) {
  1216. //attach button shape alternate styles
  1217. var isDynamicPanel = $ax.public.fn.IsDynamicPanel(dObj.type);
  1218. var needsMouseFilter = (ignoreHasIxStyles || $ax.event.HasIxStyles(dObj))
  1219. && dObj.type != 'hyperlink' && !$ax.public.fn.IsLayer(dObj.type) && !isDynamicPanel && dObj.type != 'richTextPanel' &&
  1220. !$ax.public.fn.IsRepeater(dObj.type) && !$ax.public.fn.IsCheckBox(dObj.type) && !$ax.public.fn.IsRadioButton(dObj.type)
  1221. && !$ax.public.fn.IsTreeNodeObject(dObj.type);
  1222. if(needsMouseFilter) {
  1223. //$element.mouseenter(function () {
  1224. $element.on('mouseenter.ixStyle', function () {
  1225. var elementId = this.id;
  1226. var parent = $ax.dynamicPanelManager.parentHandlesStyles(elementId);
  1227. if(parent && parent.direct) return;
  1228. if($.inArray(elementId, _event.mouseOverIds) != -1) return;
  1229. _event.mouseOverIds[_event.mouseOverIds.length] = elementId;
  1230. if(elementId == _event.mouseOverObjectId) return;
  1231. _event.mouseOverObjectId = elementId;
  1232. $ax.style.SetWidgetHover(elementId, true);
  1233. var textId = $ax.style.GetTextIdFromShape(elementId);
  1234. if(textId) $ax.annotation.updateLinkLocations(textId);
  1235. //}).mouseleave(function () {
  1236. }).on('mouseleave.ixStyle', function () {
  1237. var elementId = this.id;
  1238. var parent = $ax.dynamicPanelManager.parentHandlesStyles(elementId);
  1239. if(parent && parent.direct) return;
  1240. $ax.splice(_event.mouseOverIds, $.inArray(elementId, _event.mouseOverIds), 1);
  1241. if(elementId == _event.mouseOverObjectId) {
  1242. _event.mouseOverObjectId = '';
  1243. }
  1244. $ax.style.SetWidgetHover(elementId, false);
  1245. var textId = $ax.style.GetTextIdFromShape(elementId);
  1246. if(textId) $ax.annotation.updateLinkLocations(textId);
  1247. });
  1248. //$element.bind($ax.features.eventNames.mouseDownName, function () {
  1249. $element.on($ax.features.eventNames.mouseDownName + '.ixStyle', function () {
  1250. var elementId = this.id;
  1251. var parent = $ax.dynamicPanelManager.parentHandlesStyles(elementId);
  1252. if(parent) {
  1253. dynamicPanelMouseDown(parent.id);
  1254. if(parent.direct) return;
  1255. }
  1256. _event.mouseDownObjectId = elementId;
  1257. $ax.style.SetWidgetMouseDown(this.id, true);
  1258. $ax.annotation.updateLinkLocations($ax.style.GetTextIdFromShape(elementId));
  1259. //}).bind($ax.features.eventNames.mouseUpName, function () {
  1260. }).on($ax.features.eventNames.mouseUpName + '.ixStyle', function () {
  1261. var elementId = this.id;
  1262. var parent = $ax.dynamicPanelManager.parentHandlesStyles(elementId);
  1263. if(parent) {
  1264. dynamicPanelMouseUp(parent.id);
  1265. if(parent.direct) return;
  1266. }
  1267. _event.mouseDownObjectId = '';
  1268. if(!$ax.style.ObjHasMouseDown(elementId)) return;
  1269. $ax.style.SetWidgetMouseDown(elementId, false);
  1270. $ax.annotation.updateLinkLocations($ax.style.GetTextIdFromShape(elementId));
  1271. //there used to be something we needed to make images click, because swapping out the images prevents the click
  1272. // this is a note that we can eventually delete.
  1273. });
  1274. }
  1275. };
  1276. var dynamicPanelMouseDown = function (elementId) {
  1277. var parent = $ax.dynamicPanelManager.parentHandlesStyles(elementId);
  1278. if(parent) {
  1279. dynamicPanelMouseDown(parent.id);
  1280. if(parent.direct) return;
  1281. }
  1282. _event.mouseDownObjectId = elementId;
  1283. $ax.dynamicPanelManager.propagateMouseDown(elementId, true);
  1284. };
  1285. var dynamicPanelMouseUp = function (elementId) {
  1286. var parent = $ax.dynamicPanelManager.parentHandlesStyles(elementId);
  1287. if(parent) {
  1288. dynamicPanelMouseUp(parent.id);
  1289. if(parent.direct) return;
  1290. }
  1291. _event.mouseDownObjectId = '';
  1292. $ax.dynamicPanelManager.propagateMouseDown(elementId, false);
  1293. };
  1294. // Handle key up and key down events
  1295. (function() {
  1296. var _keyState = {};
  1297. _keyState.ctrl = false;
  1298. _keyState.alt = false;
  1299. _keyState.shift = false;
  1300. _keyState.keyCode = 0;
  1301. $ax.event.keyState = function() {
  1302. return $ax.deepCopy(_keyState);
  1303. };
  1304. var modifierCodes = [16, 17, 18];
  1305. var clearKeyCode = false;
  1306. $ax.event.initKeyEvents = function($query) {
  1307. $query.keydown(function (e) {
  1308. if(clearKeyCode) {
  1309. clearKeyCode = false;
  1310. _keyState.keyCode = 0;
  1311. }
  1312. var elementId = this.id;
  1313. _keyState.ctrl = e.ctrlKey;
  1314. _keyState.alt = e.altKey;
  1315. _keyState.shift = e.shiftKey;
  1316. // If a modifier was pressed, then don't set the keyCode;
  1317. if(modifierCodes.indexOf(e.keyCode) == -1) _keyState.keyCode = e.keyCode;
  1318. $ax.setjBrowserEvent(e);
  1319. if (!elementId) fireEventThroughContainers('onKeyDown', undefined, false, [$ax.constants.PAGE_TYPE, $ax.constants.REFERENCE_DIAGRAM_OBJECT_TYPE, $ax.constants.DYNAMIC_PANEL_TYPE, $ax.constants.REPEATER],
  1320. [$ax.constants.PAGE_TYPE, $ax.constants.REFERENCE_DIAGRAM_OBJECT_TYPE, $ax.constants.LAYER_TYPE]);
  1321. else _raiseSyntheticEvent(elementId, 'onKeyDown', false, undefined, true);
  1322. });
  1323. $query.keyup(function(e) {
  1324. var elementId = this.id;
  1325. if (modifierCodes.indexOf(e.keyCode) == -1) clearKeyCode = true;
  1326. else if (clearKeyCode) {
  1327. clearKeyCode = false;
  1328. _keyState.keyCode = 0;
  1329. }
  1330. $ax.setjBrowserEvent(e);
  1331. // Fire event before updating modifiers.
  1332. if (!elementId) fireEventThroughContainers('onKeyUp', undefined, false, [$ax.constants.PAGE_TYPE, $ax.constants.REFERENCE_DIAGRAM_OBJECT_TYPE, $ax.constants.DYNAMIC_PANEL_TYPE, $ax.constants.REPEATER],
  1333. [$ax.constants.PAGE_TYPE, $ax.constants.REFERENCE_DIAGRAM_OBJECT_TYPE, $ax.constants.LAYER_TYPE]);
  1334. else _raiseSyntheticEvent(elementId, 'onKeyUp', false, undefined, true);
  1335. //_keyState.ctrl = e.ctrlKey;
  1336. //_keyState.alt = e.altKey;
  1337. //_keyState.shift = e.shiftKey;
  1338. //// If a non-modifier was lifted, clear the keycode
  1339. ///if(modifierCodes.indexOf(e.keyCode) == -1) _keyState.keyCode = 0;
  1340. });
  1341. };
  1342. })();
  1343. // Handle adding mobile events
  1344. (function() {
  1345. // NOTE: Multi touch is NOT handled currently.
  1346. var CLICK_THRESHOLD_PX = 25;
  1347. var CLICK_THRESHOLD_PX_SQ = CLICK_THRESHOLD_PX * CLICK_THRESHOLD_PX;
  1348. var DBLCLICK_THRESHOLD_MS = 500;
  1349. // Location in page cooridinates
  1350. var tapDownLoc;
  1351. var lastClickEventTime;
  1352. _event.initMobileEvents = function($tapQuery, $moveQuery, elementId) {
  1353. if(!$ax.features.supports.mobile) return;
  1354. // Handle touch start
  1355. $tapQuery.bind('touchstart', function(e) {
  1356. // We do NOT support multiple touches. This isn't necessarily the touch we want.
  1357. var touch = e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0];
  1358. if(!touch) return;
  1359. tapDownLoc = [touch.pageX, touch.pageY];
  1360. var time = (new Date()).getTime();
  1361. if(time - lastClickEventTime < DBLCLICK_THRESHOLD_MS) {
  1362. var dObj = elementId === '' ? $ax.pageData.page : $ax.getObjectFromElementId(elementId);
  1363. var axEventObject = dObj && dObj.interactionMap && dObj.interactionMap['onDoubleClick'];
  1364. if(axEventObject) e.preventDefault(); //for Chrome on Android
  1365. }
  1366. }).bind('touchend', function(e) {
  1367. var touch = e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0];
  1368. if(!touch || !tapDownLoc) return;
  1369. var tapUpLoc = [touch.pageX, touch.pageY];
  1370. var xDiff = tapUpLoc[0] - tapDownLoc[0];
  1371. var yDiff = tapUpLoc[1] - tapDownLoc[1];
  1372. if((xDiff * xDiff + yDiff * yDiff) < CLICK_THRESHOLD_PX_SQ) {
  1373. $ax.setjBrowserEvent(e);
  1374. _raiseSyntheticEvent(elementId, 'onClick', false, undefined, true);
  1375. var time = (new Date()).getTime();
  1376. if(time - lastClickEventTime < DBLCLICK_THRESHOLD_MS) {
  1377. _raiseSyntheticEvent(elementId, 'onDoubleClick', false, undefined, true);
  1378. if(e.originalEvent && e.originalEvent.handled) e.preventDefault(); //for iOS
  1379. }
  1380. lastClickEventTime = time;
  1381. }
  1382. });
  1383. // Handles touch move
  1384. $moveQuery.bind('touchmove', function(e) {
  1385. $ax.setjBrowserEvent(e);
  1386. _raiseSyntheticEvent(elementId, 'onMouseMove', false, undefined, true);
  1387. if(e.originalEvent && e.originalEvent.handled) e.preventDefault();
  1388. });
  1389. };
  1390. })();
  1391. // Handle adding device independent click events to non-widgets
  1392. (function() {
  1393. var CLICK_THRESHOLD_PX = 25;
  1394. var CLICK_THRESHOLD_PX_SQ = CLICK_THRESHOLD_PX * CLICK_THRESHOLD_PX;
  1395. // Location in page cooridinates
  1396. var tapDownLoc;
  1397. _event.attachClick = function(query, clickHandler) {
  1398. if(!$ax.features.supports.mobile) {
  1399. query.click(clickHandler);
  1400. return;
  1401. }
  1402. $(query).bind('touchstart', function(e) {
  1403. // We do NOT support multiple touches. This isn't necessarily the touch we want.
  1404. var touch = e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0];
  1405. if(!touch) return;
  1406. tapDownLoc = [touch.pageX, touch.pageY];
  1407. });
  1408. $(query).bind('touchend', function(e) {
  1409. var touch = e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0];
  1410. if(!touch) return;
  1411. var tapUpLoc = [touch.pageX, touch.pageY];
  1412. var xDiff = tapUpLoc[0] - tapDownLoc[0];
  1413. var yDiff = tapUpLoc[1] - tapDownLoc[1];
  1414. if((xDiff * xDiff + yDiff * yDiff) < CLICK_THRESHOLD_PX_SQ) {
  1415. clickHandler();
  1416. }
  1417. });
  1418. };
  1419. })();
  1420. // Handle firing device independent click events on widgets
  1421. (function() {
  1422. _event.fireClick = function(elementId) {
  1423. if(!$ax.features.supports.mobile) {
  1424. $('#' + elementId).click();
  1425. return;
  1426. }
  1427. _raiseSyntheticEvent(elementId, 'onClick', false, undefined, true);
  1428. };
  1429. })();
  1430. var _mouseLocation = $ax.mouseLocation = { x: 0, y: 0 };
  1431. var _lastmouseLocation = $ax.lastMouseLocation = { x: 0, y: 0 };
  1432. var _updateMouseLocation = function(e, end) {
  1433. if(!e) return;
  1434. if(IE_10_AND_BELOW && typeof (e.type) == 'unknown') return;
  1435. if(e.type != 'mousemove' && e.type != 'touchstart' && e.type != 'touchmove' && e.type != 'touchend') return;
  1436. var newX;
  1437. var newY;
  1438. if(IE_10_AND_BELOW) {
  1439. newX = e.clientX + $('html').scrollLeft();
  1440. newY = e.clientY + $('html').scrollTop();
  1441. } else {
  1442. newX = e.pageX;
  1443. newY = e.pageY;
  1444. }
  1445. //var body = $('body');
  1446. //if(body.css('position') == 'relative') newX = Math.round(newX - Number(body.css('left').replace('px', '')) - Math.max(0, ($(window).width() - body.width()) / 2));
  1447. if(_mouseLocation.x == newX && _mouseLocation.y == newY) return;
  1448. _lastmouseLocation.x = _mouseLocation.x;
  1449. _lastmouseLocation.y = _mouseLocation.y;
  1450. _mouseLocation.x = newX;
  1451. _mouseLocation.y = newY;
  1452. $ax.geometry.tick(_mouseLocation.x, _mouseLocation.y, end);
  1453. };
  1454. _event.updateMouseLocation = _updateMouseLocation;
  1455. var _leavingState = function(stateId) {
  1456. var mouseOverIds = _event.mouseOverIds;
  1457. if(mouseOverIds.length == 0) return;
  1458. var stateQuery = $jobj(stateId);
  1459. for(var i = mouseOverIds.length - 1; i >= 0; i--) {
  1460. var id = mouseOverIds[i];
  1461. if(stateQuery.find('#' + id).length) {
  1462. $ax.splice(mouseOverIds, $.inArray(id, mouseOverIds), 1);
  1463. $ax.style.SetWidgetMouseDown(id, false);
  1464. $ax.style.SetWidgetHover(id, false);
  1465. }
  1466. }
  1467. };
  1468. _event.leavingState = _leavingState;
  1469. var _raiseSelectedEvents = function(elementId, value) {
  1470. $ax.event.raiseSyntheticEvent(elementId, 'onSelectedChange');
  1471. if(value) $ax.event.raiseSyntheticEvent(elementId, 'onSelect');
  1472. else $ax.event.raiseSyntheticEvent(elementId, 'onUnselect');
  1473. };
  1474. $ax.event.raiseSelectedEvents = _raiseSelectedEvents;
  1475. var _raiseSyntheticEvent = function(elementId, eventName, skipShowDescription, eventInfo, nonSynthetic) {
  1476. // Empty string used when this is an event directly on the page.
  1477. var dObj = elementId === '' ? $ax.pageData.page : $ax.getObjectFromElementId(elementId);
  1478. var axEventObject = dObj && dObj.interactionMap && dObj.interactionMap[eventName];
  1479. if(!axEventObject) return;
  1480. eventInfo = eventInfo || $ax.getEventInfoFromEvent($ax.getjBrowserEvent(), skipShowDescription, elementId);
  1481. // $ax.recording.maybeRecordEvent(elementId, eventInfo, axEventObject, new Date().getTime());
  1482. _handleEvent(elementId, eventInfo, axEventObject, false, !nonSynthetic);
  1483. };
  1484. $ax.event.raiseSyntheticEvent = _raiseSyntheticEvent;
  1485. var _hasSyntheticEvent = function(scriptId, eventName) {
  1486. var dObj = $ax.getObjectFromScriptId(scriptId);
  1487. var axEventObject = dObj && dObj.interactionMap && dObj.interactionMap[eventName];
  1488. return Boolean(axEventObject);
  1489. };
  1490. $ax.event.hasSyntheticEvent = _hasSyntheticEvent;
  1491. var _addEvent = function (target, eventType, handler, useCapture) {
  1492. //this return value is only for debug purpose
  1493. var succeed = undefined;
  1494. if(target.attachEvent) {
  1495. if($ax.features.supports.windowsMobile) {
  1496. succeed = target.attachEvent(eventType, handler);
  1497. } else {
  1498. succeed = target.attachEvent('on' + eventType, handler);
  1499. }
  1500. } else if(target.addEventListener) {
  1501. target.addEventListener(eventType, handler, useCapture);
  1502. succeed = true;
  1503. }
  1504. return succeed;
  1505. }
  1506. $ax.event.addEvent = _addEvent;
  1507. var _removeEvent = function(target, eventType, handler, useCapture, skipCheckingWindowsMobile) {
  1508. //this return value is only for debug purpose
  1509. var succeed = undefined;
  1510. if(target.detachEvent) {
  1511. if(!skipCheckingWindowsMobile && $ax.features.supports.windowsMobile) {
  1512. succeed = target.detachEvent(eventType, handler);
  1513. } else {
  1514. succeed = target.detachEvent('on' + eventType, handler);
  1515. }
  1516. } else if(target.removeEventListener) {
  1517. target.removeEventListener(eventType, handler, useCapture);
  1518. succeed = true;
  1519. }
  1520. return succeed;
  1521. }
  1522. $ax.event.removeEvent = _removeEvent;
  1523. var _initialize = function() {
  1524. $ax.repeater.load();
  1525. // Make sure key events for page are initialized first. That way they will update the value of key pressed before any other events occur.
  1526. _event.initKeyEvents($(window));
  1527. initSuppressingEvents();
  1528. // Anything with an item id is in a repeater and should be handled by that repeater.
  1529. _initializeObjectEvents($ax(function(obj, elementId) { return !$ax.repeater.getItemIdFromElementId(elementId); }));
  1530. //finally, process the pageload
  1531. _pageLoad();
  1532. // _loadDynamicPanelsAndMasters();
  1533. // $ax.repeater.init();
  1534. // and wipe out the basic links.
  1535. $('.basiclink').click(function() {
  1536. return false;
  1537. });
  1538. };
  1539. _event.initialize = _initialize;
  1540. $ax.event.HasIxStyles = function(diagramObject) {
  1541. if(diagramObject.style.stateStyles) return true;
  1542. if(diagramObject.adaptiveStyles) {
  1543. for(var viewId in diagramObject.adaptiveStyles) {
  1544. if(diagramObject.adaptiveStyles[viewId].stateStyles) return true;
  1545. }
  1546. }
  1547. return false;
  1548. };
  1549. $ax.event.HasTextChanged = function(diagramObject) {
  1550. if (!$ax.public.fn.IsTextBox(diagramObject.type) && !$ax.public.fn.IsTextArea(diagramObject.type)) return false;
  1551. var map = diagramObject.interactionMap;
  1552. return map && map.onTextChange;
  1553. };
  1554. $ax.event.TryFireTextChanged = function(elementId) {
  1555. var query = $jobj($ax.repeater.applySuffixToElementId(elementId, '_input'));
  1556. if(!$ax.hasElementTextChanged(elementId, query.val())) return;
  1557. $ax.updateElementText(elementId, query.val());
  1558. $ax.event.raiseSyntheticEvent(elementId, 'onTextChange');
  1559. };
  1560. $ax.event.HasSelectionChanged = function(diagramObject) {
  1561. if (!$ax.public.fn.IsListBox(diagramObject.type) && !$ax.public.fn.IsComboBox(diagramObject.type)) return false;
  1562. var map = diagramObject.interactionMap;
  1563. return map && map.onSelectionChange;
  1564. };
  1565. $ax.event.HasKeyUpOrDown = function (diagramObject) {
  1566. if($ax.public.fn.IsTextBox(diagramObject.type) || $ax.public.fn.IsTextArea(diagramObject.type)) return true;
  1567. var map = diagramObject.interactionMap;
  1568. return map && (map.onKeyUp || map.onKeyDown);
  1569. };
  1570. $ax.event.HasCheckedChanged = function(diagramObject) {
  1571. if (!$ax.public.fn.IsCheckBox(diagramObject.type) && !$ax.public.fn.IsRadioButton(diagramObject.type)) return false;
  1572. var map = diagramObject.interactionMap;
  1573. return map && map.onSelectedChange;
  1574. };
  1575. $ax.event.HasClick = function (diagramObject) {
  1576. var map = diagramObject.interactionMap;
  1577. return map && map.onClick;
  1578. };
  1579. var _tryFireCheckedChanged = $ax.event.TryFireCheckChanged = function(elementId, value) {
  1580. var isRadio = $ax.public.fn.IsRadioButton($obj(elementId).type);
  1581. if(isRadio) {
  1582. if(!value) {
  1583. $ax.updateRadioButtonSelected($jobj($ax.INPUT(elementId)).attr('name'), undefined);
  1584. } else {
  1585. var last = $ax.updateRadioButtonSelected($jobj($ax.INPUT(elementId)).attr('name'), elementId);
  1586. // If no change, this should not fire
  1587. if(last == elementId) return;
  1588. // Initially selecting one, last may be undefined
  1589. if(last) {
  1590. //here last is the previouse selected elementid
  1591. $ax.event.raiseSelectedEvents(last, false);
  1592. }
  1593. }
  1594. }
  1595. $ax.event.raiseSelectedEvents(elementId, value);
  1596. };
  1597. //onload everything now, not only dp and master
  1598. var _loadDynamicPanelsAndMasters = function(objects, path, itemId) {
  1599. fireEventThroughContainers('onLoad', objects, true, [$ax.constants.PAGE_TYPE, $ax.constants.REFERENCE_DIAGRAM_OBJECT_TYPE, $ax.constants.DYNAMIC_PANEL_TYPE],
  1600. [$ax.constants.ALL_TYPE], path, itemId);
  1601. };
  1602. $ax.loadDynamicPanelsAndMasters = _loadDynamicPanelsAndMasters;
  1603. var _viewChangePageAndMasters = function(forceSwitchTo) {
  1604. fireEventThroughContainers('onAdaptiveViewChange', undefined, true, [$ax.constants.PAGE_TYPE, $ax.constants.REFERENCE_DIAGRAM_OBJECT_TYPE, $ax.constants.DYNAMIC_PANEL_TYPE],
  1605. [$ax.constants.PAGE_TYPE, $ax.constants.REFERENCE_DIAGRAM_OBJECT_TYPE]);
  1606. _postAdaptiveViewChanged(forceSwitchTo);
  1607. };
  1608. $ax.viewChangePageAndMasters = _viewChangePageAndMasters;
  1609. //if forceSwitchTo is true, we will also update the checkmark in sitemap.js
  1610. var _postAdaptiveViewChanged = function(forceSwitchTo) {
  1611. //only trigger adaptive view changed if the window is on the mainframe. Also triggered on init, even if default.
  1612. try {
  1613. if(window.name == 'mainFrame' ||
  1614. (!CHROME_5_LOCAL && window.parent.$ && window.parent.$('#mainFrame').length > 0)) {
  1615. var data = {
  1616. viewId: $ax.adaptive.currentViewId,
  1617. forceSwitchTo: forceSwitchTo
  1618. };
  1619. $axure.messageCenter.postMessage('adaptiveViewChange', data);
  1620. }
  1621. } catch(e) { }
  1622. };
  1623. $ax.postAdaptiveViewChanged = _postAdaptiveViewChanged;
  1624. var _postResize = $ax.postResize = function(e) {
  1625. $ax.setjBrowserEvent(e);
  1626. return fireEventThroughContainers('onResize', undefined, false, [$ax.constants.PAGE_TYPE, $ax.constants.REFERENCE_DIAGRAM_OBJECT_TYPE, $ax.constants.DYNAMIC_PANEL_TYPE, $ax.constants.REPEATER],
  1627. [$ax.constants.PAGE_TYPE, $ax.constants.REFERENCE_DIAGRAM_OBJECT_TYPE]);
  1628. };
  1629. //fire events for table, menu and tree, including its sub items
  1630. var _fireEventsForTableMenuAndTree = function (object, event, skipShowDescription, eventInfo, path, synthetic) {
  1631. if (!path) path = [];
  1632. var pathCopy = path.slice();
  1633. pathCopy[path.length] = object.id;
  1634. var scriptId = $ax.getScriptIdFromPath(pathCopy);
  1635. $ax.event.raiseSyntheticEvent(scriptId, event, skipShowDescription, eventInfo, !synthetic);
  1636. if(object.objects) {
  1637. for(var index = 0; index < object.objects.length; index++) {
  1638. var subObj = object.objects[index];
  1639. if ($ax.public.fn.IsTableCell(subObj.type)) {
  1640. pathCopy[path.length] = subObj.id;
  1641. scriptId = $ax.getScriptIdFromPath(pathCopy);
  1642. $ax.event.raiseSyntheticEvent(scriptId, event, skipShowDescription, eventInfo, !synthetic);
  1643. } else if ($ax.public.fn.IsTable(object.type) || $ax.public.fn.IsMenuObject(object.type) || $ax.public.fn.IsTreeNodeObject(object.type)) {
  1644. _fireEventsForTableMenuAndTree(subObj, event, skipShowDescription, eventInfo, path, synthetic);
  1645. }
  1646. }
  1647. }
  1648. }
  1649. // if ($('#' + id).data('lastScrollTop') == undefined) $('#' + id).data('lastScrollTop', '0');
  1650. // _attachDefaultObjectEvent($('#' + id), elementId, 'scroll', function (e) {
  1651. // $ax.setjBrowserEvent(e);
  1652. // var currentEvent = $ax.getjBrowserEvent();
  1653. // var eventInfoFromEvent = $ax.getEventInfoFromEvent($ax.getjBrowserEvent(), false, elementId);
  1654. // if (map.onScroll) _handleEvent(elementId, eventInfoFromEvent, map.onScroll);
  1655. //
  1656. // var currentTop = $('#' + id).scrollTop();
  1657. // var wasHandled = currentEvent.originalEvent.handled;
  1658. // if (map.onScrollUp && currentTop < $('#' + id).data('lastScrollTop')) {
  1659. // currentEvent.originalEvent.handled = false;
  1660. // _handleEvent(elementId, eventInfoFromEvent, map.onScrollUp);
  1661. // } else if (map.onScrollDown && currentTop > $('#' + id).data('lastScrollTop')) {
  1662. // currentEvent.originalEvent.handled = false;
  1663. // _handleEvent(elementId, eventInfoFromEvent, map.onScrollDown);
  1664. // }
  1665. // currentEvent.originalEvent.handled |= wasHandled;
  1666. // $('#' + id).data('lastScrollTop', currentTop);
  1667. // });
  1668. //remember the scroll bar position, so we can detect scroll up/down
  1669. var lastScrollTop;
  1670. // Filters include page, referenceDiagramObject, dynamicPanel, and repeater.
  1671. var fireEventThroughContainers = function(eventName, objects, synthetic, searchFilter, callFilter, path, itemId) {
  1672. // 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
  1673. var skipShowDescription = eventName == 'onLoad';
  1674. // If objects undefined, load page
  1675. if(!objects) {
  1676. if(_callFilterCheck(callFilter, $ax.constants.PAGE_TYPE)) {
  1677. var map = $ax.pageData.page.interactionMap;
  1678. var currentEvent = $ax.getjBrowserEvent();
  1679. var pageEvent = map && map[eventName];
  1680. var scrolling = currentEvent && currentEvent.type === "scroll";
  1681. if (scrolling && !pageEvent && map) pageEvent = map.onScrollUp || map.onScrollDown;
  1682. if(pageEvent) {
  1683. var pageEventInfo = $ax.getEventInfoFromEvent(currentEvent, skipShowDescription, '');
  1684. pageEventInfo.label = $ax.pageData.page.name;
  1685. pageEventInfo.friendlyType = 'Page';
  1686. if (!scrolling || map.onScroll) _handleEvent('', pageEventInfo, pageEvent, skipShowDescription, synthetic);
  1687. if (scrolling) {
  1688. var wasHandled = currentEvent.originalEvent.handled;
  1689. var currentScrollTop = $(window).scrollTop();
  1690. if(map.onScrollUp && currentScrollTop < lastScrollTop) {
  1691. currentEvent.originalEvent.handled = false;
  1692. _handleEvent('', pageEventInfo, map.onScrollUp, skipShowDescription, synthetic);
  1693. } else if (map.onScrollDown && currentScrollTop > lastScrollTop) {
  1694. currentEvent.originalEvent.handled = false;
  1695. _handleEvent('', pageEventInfo, map.onScrollDown, skipShowDescription, synthetic);
  1696. }
  1697. currentEvent.originalEvent.handled |= wasHandled;
  1698. lastScrollTop = currentScrollTop;
  1699. }
  1700. }
  1701. }
  1702. if (searchFilter.indexOf($ax.constants.PAGE_TYPE) != -1) fireEventThroughContainers(eventName, $ax.pageData.page.diagram.objects, synthetic, searchFilter, callFilter);
  1703. return;
  1704. }
  1705. if(!path) path = [];
  1706. var pathCopy = [];
  1707. for(var j = 0; j < path.length; j++) pathCopy[j] = path[j];
  1708. for(var i = 0; i < objects.length; i++) {
  1709. var obj = objects[i];
  1710. pathCopy[path.length] = obj.id;
  1711. 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)) {
  1712. if(_callFilterCheck(callFilter)) { //fire current event for all types
  1713. if ($ax.public.fn.IsTable(obj.type) || $ax.public.fn.IsMenuObject(obj.type) || $ax.public.fn.IsTreeNodeObject(obj.type)) {
  1714. _fireEventsForTableMenuAndTree(obj, eventName, skipShowDescription, undefined, path, !synthetic);
  1715. } else {
  1716. var scriptId = $ax.getScriptIdFromPath(pathCopy);
  1717. if(scriptId && itemId) scriptId = $ax.repeater.createElementId(scriptId, itemId);
  1718. $ax.event.raiseSyntheticEvent(scriptId, eventName, skipShowDescription, undefined, !synthetic);
  1719. }
  1720. }
  1721. continue;
  1722. }
  1723. var objId = $ax.getScriptIdFromPath(pathCopy);
  1724. // If limboed, move on to next item
  1725. if(!objId) continue;
  1726. if(itemId) objId = $ax.repeater.createElementId(objId, itemId);
  1727. if($ax.public.fn.IsReferenceDiagramObject(obj.type)) {
  1728. if(_callFilterCheck(callFilter, $ax.constants.REFERENCE_DIAGRAM_OBJECT_TYPE)) {
  1729. var axEvent = $ax.pageData.masters[obj.masterId].interactionMap[eventName];
  1730. if(axEvent) {
  1731. var eventInfo = $ax.getEventInfoFromEvent($ax.getjBrowserEvent(), skipShowDescription, objId);
  1732. eventInfo.isMasterEvent = true;
  1733. _handleEvent(objId, eventInfo, axEvent, skipShowDescription, synthetic);
  1734. }
  1735. }
  1736. if(searchFilter.indexOf($ax.constants.REFERENCE_DIAGRAM_OBJECT_TYPE) != -1) fireEventThroughContainers(eventName, $ax.pageData.masters[obj.masterId].diagram.objects, synthetic, searchFilter, callFilter, pathCopy, itemId);
  1737. } else if($ax.public.fn.IsDynamicPanel(obj.type)) {
  1738. if(_callFilterCheck(callFilter, $ax.constants.DYNAMIC_PANEL_TYPE)) $ax.event.raiseSyntheticEvent(objId, eventName, skipShowDescription, undefined, !synthetic);
  1739. if(searchFilter.indexOf($ax.constants.DYNAMIC_PANEL_TYPE) != -1) {
  1740. var diagrams = obj.diagrams;
  1741. for(var j = 0; j < diagrams.length; j++) {
  1742. fireEventThroughContainers(eventName, diagrams[j].objects, synthetic, searchFilter, callFilter, path, itemId);
  1743. }
  1744. }
  1745. } else if($ax.public.fn.IsRepeater(obj.type)) {
  1746. // TODO: possible an option for repeater item? Now fires overall for the repeater
  1747. if(_callFilterCheck(callFilter, $ax.constants.REPEATER)) $ax.event.raiseSyntheticEvent(objId, eventName, skipShowDescription, undefined, !synthetic);
  1748. if(searchFilter.indexOf($ax.constants.REPEATER) != -1) {
  1749. var itemIds = $ax.getItemIdsForRepeater(objId);
  1750. for(var j = 0; j < itemIds.length; j++) {
  1751. fireEventThroughContainers(eventName, obj.objects, synthetic, searchFilter, callFilter, path, itemIds[j]);
  1752. }
  1753. }
  1754. } else if($ax.public.fn.IsLayer(obj.type)) {
  1755. if(_callFilterCheck(callFilter, $ax.constants.LAYER_TYPE)) $ax.event.raiseSyntheticEvent(objId, eventName, skipShowDescription, undefined, !synthetic);
  1756. }
  1757. }
  1758. eventNesting -= 1;
  1759. };
  1760. var _callFilterCheck = function(callFilter, type) {
  1761. for(var index = 0; index < callFilter.length; index++) {
  1762. var currentType = callFilter[index];
  1763. if(currentType === $ax.constants.ALL_TYPE || currentType === type) return true;
  1764. }
  1765. return false;
  1766. };
  1767. // FOCUS stuff
  1768. (function() {
  1769. })();
  1770. var _pageLoad = function() {
  1771. // Map of axure event names to pair of what it should attach to, and what the jquery event name is.
  1772. var PAGE_AXURE_TO_JQUERY_EVENT_NAMES = {
  1773. 'onScroll': [window, 'scroll'],
  1774. 'onScrollUp': [window, 'scrollup'],
  1775. 'onScrollDown': [window, 'scrolldown'],
  1776. //'onResize': [window, 'resize'],
  1777. 'onContextMenu': [window, 'contextmenu']
  1778. };
  1779. var $win = $(window);
  1780. if(!$ax.features.supports.mobile) {
  1781. PAGE_AXURE_TO_JQUERY_EVENT_NAMES.onClick = ['html', 'click'];
  1782. PAGE_AXURE_TO_JQUERY_EVENT_NAMES.onDoubleClick = ['html', 'dblclick'];
  1783. PAGE_AXURE_TO_JQUERY_EVENT_NAMES.onMouseMove = ['html', 'mousemove'];
  1784. } else {
  1785. _event.initMobileEvents($win, $win, '');
  1786. $win.bind($ax.features.eventNames.mouseDownName, _updateMouseLocation);
  1787. $win.bind($ax.features.eventNames.mouseUpName, function(e) { _updateMouseLocation(e, true); });
  1788. $win.scroll(function() { _setCanClick(false); });
  1789. $win.bind($ax.features.eventNames.mouseDownName, (function() {
  1790. _setCanClick(true);
  1791. }));
  1792. }
  1793. $win.bind($ax.features.eventNames.mouseMoveName, _updateMouseLocation);
  1794. $win.scroll($ax.flyoutManager.reregisterAllFlyouts);
  1795. for(key in PAGE_AXURE_TO_JQUERY_EVENT_NAMES) {
  1796. if(!PAGE_AXURE_TO_JQUERY_EVENT_NAMES.hasOwnProperty(key)) continue;
  1797. (function(axureName) {
  1798. var jqueryEventNamePair = PAGE_AXURE_TO_JQUERY_EVENT_NAMES[axureName];
  1799. var actionName = jqueryEventNamePair[1];
  1800. if(actionName == "scrollup" || actionName == "scrolldown") return;
  1801. $(jqueryEventNamePair[0])[actionName](function (e) {
  1802. $ax.setjBrowserEvent(e);
  1803. return fireEventThroughContainers(axureName, undefined, false, [$ax.constants.PAGE_TYPE, $ax.constants.REFERENCE_DIAGRAM_OBJECT_TYPE, $ax.constants.DYNAMIC_PANEL_TYPE, $ax.constants.REPEATER],
  1804. [$ax.constants.PAGE_TYPE, $ax.constants.REFERENCE_DIAGRAM_OBJECT_TYPE]);
  1805. });
  1806. })(key);
  1807. }
  1808. eventNesting -= 1;
  1809. lastScrollTop = 0;
  1810. };
  1811. _event.pageLoad = _pageLoad;
  1812. });
  1813. //***** recording.js *****//
  1814. // ******* Recording MANAGER ******** //
  1815. $axure.internal(function($ax) {
  1816. var _recording = $ax.recording = {};
  1817. $ax.recording.recordEvent = function(element, eventInfo, axEventObject, timeStamp) {
  1818. var elementHtml = $jobj(element);
  1819. var className = elementHtml.attr('class');
  1820. var inputValue;
  1821. if(className === 'ax_checkbox') {
  1822. inputValue = elementHtml.find('#' + element + '_input')[0].checked;
  1823. eventInfo.inputType = className;
  1824. eventInfo.inputValue = inputValue;
  1825. }
  1826. if(className === 'ax_text_field') {
  1827. inputValue = elementHtml.find('#' + element + '_input').val();
  1828. eventInfo.inputType = className;
  1829. eventInfo.inputValue = inputValue;
  1830. }
  1831. var scriptId = $ax.repeater.getScriptIdFromElementId(element);
  1832. var diagramObjectPath = $ax.getPathFromScriptId(scriptId);
  1833. var form = {
  1834. recordingId: $ax.recording.recordingId,
  1835. elementID: element,
  1836. eventType: axEventObject.description,
  1837. 'eventInfo': eventInfo,
  1838. // eventObject: axEventObject,
  1839. 'timeStamp': timeStamp,
  1840. 'path': diagramObjectPath
  1841. // ,
  1842. // 'trigger': function() {
  1843. // $ax.event.handleEvent(element, eventInfo, axEventObject);
  1844. // return false;
  1845. // }
  1846. };
  1847. $ax.messageCenter.postMessage('logEvent', form);
  1848. };
  1849. $ax.recording.maybeRecordEvent = function(element, eventInfo, axEventObject, timeStamp) {
  1850. };
  1851. $ax.recording.recordingId = "";
  1852. $ax.recording.recordingName = "";
  1853. $ax.messageCenter.addMessageListener(function(message, data) {
  1854. if(message === 'startRecording') {
  1855. $ax.recording.maybeRecordEvent = $ax.recording.recordEvent;
  1856. $ax.recording.recordingId = data.recordingId;
  1857. $ax.recording.recordingName = data.recordingName;
  1858. } else if(message === 'stopRecording') {
  1859. $ax.recording.maybeRecordEvent = function(element, eventInfo, axEventObject, timeStamp) {
  1860. };
  1861. }
  1862. else if(message === 'playEvent') {
  1863. var eventType = makeFirstLetterLower(data.eventType);
  1864. var inputElement;
  1865. var dObj = data.element === '' ? $ax.pageData.page : $ax.getObjectFromElementId(data.element);
  1866. if(!data.axEventObject) {
  1867. data.axEventObject = dObj && dObj.interactionMap && dObj.interactionMap[eventType];
  1868. }
  1869. data.eventInfo.thiswidget = $ax.getWidgetInfo(data.element);
  1870. data.eventInfo.item = $ax.getItemInfo(data.element);
  1871. if(data.eventInfo.inputType && data.eventInfo.inputType === 'ax_checkbox') {
  1872. inputElement = $jobj(data.element + '_input');
  1873. inputElement[0].checked = data.eventInfo.inputValue;
  1874. }
  1875. if(data.eventInfo.inputType && data.eventInfo.inputType === 'ax_text_field') {
  1876. inputElement = $jobj(data.element + '_input');
  1877. inputElement.val(data.eventInfo.inputValue);
  1878. }
  1879. $ax.event.handleEvent(data.element, data.eventInfo, data.axEventObject, false, true);
  1880. }
  1881. });
  1882. var makeFirstLetterLower = function(eventName) {
  1883. return eventName.substr(0, 1).toLowerCase() + eventName.substr(1);
  1884. };
  1885. });
  1886. //***** action.js *****//
  1887. $axure.internal(function($ax) {
  1888. var _actionHandlers = {};
  1889. var _action = $ax.action = {};
  1890. var queueTypes = _action.queueTypes = {
  1891. none: 0,
  1892. move: 1,
  1893. setState: 2,
  1894. fade: 3,
  1895. resize: 4,
  1896. rotate: 5
  1897. };
  1898. var animationQueue = {};
  1899. // using array as the key doesn't play nice
  1900. var nextAnimationId = 1;
  1901. var animationsToCount = {};
  1902. var actionToActionGroups = {};
  1903. var getAnimation = function(id, type) {
  1904. return animationQueue[id] && animationQueue[id][type] && animationQueue[id][type][0];
  1905. };
  1906. var _addAnimation = _action.addAnimation = function (id, type, func, suppressFire) {
  1907. var wasEmpty = !getAnimation(id, type);
  1908. // Add the func to the queue. Create the queue if necessary.
  1909. var idQueue = animationQueue[id];
  1910. if(!idQueue) animationQueue[id] = idQueue = {};
  1911. var queue = idQueue[type];
  1912. if(!queue) idQueue[type] = queue = [];
  1913. queue[queue.length] = func;
  1914. // If it was empty, there isn't a callback waiting to be called on this. You have to fire it manually.
  1915. // If this is waiting on something, suppress it, and it will fire when it's ready
  1916. if(wasEmpty && !suppressFire) func();
  1917. };
  1918. var _addAnimations = function (animations) {
  1919. if(animations.length == 1) {
  1920. _addAnimation(animations[0].id, animations[0].type, animations[0].func);
  1921. return;
  1922. }
  1923. var allReady = true;
  1924. var readyCount = 0;
  1925. for(var i = 0; i < animations.length; i++) {
  1926. var animation = animations[i];
  1927. var thisReady = !getAnimation(animation.id, animation.type);
  1928. allReady = allReady && thisReady;
  1929. if (thisReady) readyCount++;
  1930. else {
  1931. var typeToGroups = actionToActionGroups[animation.id];
  1932. if (!typeToGroups) actionToActionGroups[animation.id] = typeToGroups = {};
  1933. var groups = typeToGroups[animation.type];
  1934. if (!groups) typeToGroups[animation.type] = groups = [];
  1935. groups[groups.length] = animations;
  1936. }
  1937. }
  1938. for(i = 0; i < animations.length; i++) {
  1939. animation = animations[i];
  1940. _addAnimation(animation.id, animation.type, animation.func, true);
  1941. }
  1942. if (allReady) {
  1943. for (i = 0; i < animations.length; i++) animations[i].func();
  1944. } else {
  1945. animations.id = nextAnimationId++;
  1946. animationsToCount[animations.id] = readyCount;
  1947. }
  1948. }
  1949. var _fireAnimationFromQueue = _action.fireAnimationFromQueue = function (id, type) {
  1950. // Remove the function that was just fired
  1951. if (animationQueue[id] && animationQueue[id][type]) $ax.splice(animationQueue[id][type], 0, 1);
  1952. // Fire the next func if there is one
  1953. var func = getAnimation(id, type);
  1954. if(func && !_checkFireActionGroup(id, type, func)) func();
  1955. };
  1956. var _checkFireActionGroup = function(id, type, func) {
  1957. var group = actionToActionGroups[id];
  1958. group = group && group[type];
  1959. if (!group || group.length == 0) return false;
  1960. var animations = group[0];
  1961. var found = false;
  1962. for (var i = 0; i < animations.length; i++) {
  1963. var animation = animations[i];
  1964. if (animation.id == id && animation.type == type) {
  1965. found = func == animation.func;
  1966. break;
  1967. }
  1968. }
  1969. // if found then update this action group, otherwise, keep waiting for right action to fire
  1970. if(!found) return false;
  1971. $ax.splice(group, 0, 1);
  1972. var count = animationsToCount[animations.id] + 1;
  1973. if(count != animations.length) {
  1974. animationsToCount[animations.id] = count;
  1975. return true;
  1976. }
  1977. delete animationsToCount[animations.id];
  1978. // 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
  1979. // 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.
  1980. var funcs = [];
  1981. for(i = 0; i < animations.length; i++) {
  1982. animation = animations[i];
  1983. funcs.push(getAnimation(animation.id, animation.type));
  1984. }
  1985. for(i = 0; i < funcs.length; i++) {
  1986. funcs[i]();
  1987. }
  1988. return true;
  1989. }
  1990. var _refreshing = [];
  1991. _action.refreshStart = function(repeaterId) { _refreshing.push(repeaterId); };
  1992. _action.refreshEnd = function() { _refreshing.pop(); };
  1993. // TODO: [ben] Consider moving this to repeater.js
  1994. var _repeatersToRefresh = _action.repeatersToRefresh = [];
  1995. var _ignoreAction = function(repeaterId) {
  1996. for(var i = 0; i < _refreshing.length; i++) if(_refreshing[i] == repeaterId) return true;
  1997. return false;
  1998. };
  1999. var _addRefresh = function(repeaterId) {
  2000. if(_repeatersToRefresh.indexOf(repeaterId) == -1) _repeatersToRefresh.push(repeaterId);
  2001. };
  2002. var _getIdToResizeMoveState = function(eventInfo) {
  2003. if(!eventInfo.idToResizeMoveState) eventInfo.idToResizeMoveState = {};
  2004. return eventInfo.idToResizeMoveState;
  2005. }
  2006. var _queueResizeMove = function (id, type, eventInfo, actionInfo) {
  2007. if (type == queueTypes.resize || type == queueTypes.rotate) $ax.public.fn.convertToSingleImage($jobj(id));
  2008. var idToResizeMoveState = _getIdToResizeMoveState(eventInfo);
  2009. if(!idToResizeMoveState[id]) {
  2010. idToResizeMoveState[id] = {};
  2011. idToResizeMoveState[id][queueTypes.move] = { queue: [], used: 0 };
  2012. idToResizeMoveState[id][queueTypes.resize] = { queue: [], used: 0 };
  2013. idToResizeMoveState[id][queueTypes.rotate] = { queue: [], used: 0 };
  2014. }
  2015. var state = idToResizeMoveState[id];
  2016. // 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.
  2017. var myOptions = type == queueTypes.resize ? actionInfo : actionInfo.options;
  2018. if(!state[type].queue.length && (!myOptions.easing || myOptions.easing == 'none' || !myOptions.duration)) {
  2019. var func = type == queueTypes.resize ? _addResize : type == queueTypes.rotate ? _addRotate : _addMove;
  2020. func(id, eventInfo, actionInfo, { easing: 'none', duration: 0, stop: { instant: true } });
  2021. return;
  2022. }
  2023. // Check other 2 types to see if either is empty, if so, we can't do anything, so just queue it up
  2024. var otherType1 = type == queueTypes.move ? queueTypes.resize : queueTypes.move;
  2025. var otherType2 = type == queueTypes.rotate ? queueTypes.resize : queueTypes.rotate;
  2026. if (!state[otherType1].queue.length || !state[otherType2].queue.length) {
  2027. state[type].queue.push({ eventInfo: eventInfo, actionInfo: actionInfo });
  2028. } else {
  2029. var duration = myOptions.duration;
  2030. var used1 = state[otherType1].used;
  2031. var used2 = state[otherType2].used;
  2032. while(state[otherType1].queue.length && state[otherType2].queue.length && duration != 0) {
  2033. var other1 = state[otherType1].queue[0];
  2034. var otherOptions1 = otherType1 == queueTypes.resize ? other1.actionInfo : other1.actionInfo.options;
  2035. // If queue up action is a non animation, then don't combo it, just queue it and move on
  2036. if(!otherOptions1.easing || otherOptions1.easing == 'none' || !otherOptions1.duration) {
  2037. func = otherType1 == queueTypes.resize ? _addResize : otherType1 == queueTypes.rotate ? _addRotate : _addMove;
  2038. func(id, eventInfo, actionInfo, { easing: 'none', duration: 0, stop: { instant: true } });
  2039. continue;
  2040. }
  2041. var other2 = state[otherType2].queue[0];
  2042. var otherOptions2 = otherType2 == queueTypes.resize ? other2.actionInfo : other2.actionInfo.options;
  2043. // If queue up action is a non animation, then don't combo it, just queue it and move on
  2044. if(!otherOptions2.easing || otherOptions2.easing == 'none' || !otherOptions2.duration) {
  2045. func = otherType2 == queueTypes.resize ? _addResize : otherType2 == queueTypes.rotate ? _addRotate : _addMove;
  2046. func(id, eventInfo, actionInfo, { easing: 'none', duration: 0, stop: { instant: true } });
  2047. continue;
  2048. }
  2049. // Other duration is what is left over. When in queue it may be partly finished already
  2050. var otherDuration1 = otherOptions1.duration - used1;
  2051. var otherDuration2 = otherOptions2.duration - used2;
  2052. var resizeInfo = type == queueTypes.resize ? actionInfo : otherType1 == queueTypes.resize ? other1.actionInfo : other2.actionInfo;
  2053. var rotateInfo = type == queueTypes.rotate ? actionInfo : otherType1 == queueTypes.rotate ? other1.actionInfo : other2.actionInfo;
  2054. var moveInfo = type == queueTypes.move ? actionInfo : otherType1 == queueTypes.move ? other1.actionInfo : other2.actionInfo;
  2055. var options = { easing: moveInfo.options.easing, duration: Math.min(duration, otherDuration1, otherDuration2) };
  2056. // Start for self is whole duration - duration left, end is start plus duration of combo to be queued, length is duration
  2057. var stop = { start: myOptions.duration - duration, len: myOptions.duration };
  2058. stop.end = stop.start + options.duration;
  2059. // 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
  2060. var otherStop1 = { start: used1, end: options.duration + used1, len: otherOptions1.duration };
  2061. var otherStop2 = { start: used2, end: options.duration + used2, len: otherOptions2.duration };
  2062. options.stop = type == queueTypes.resize ? stop : otherType1 == queueTypes.resize ? otherStop1 : otherStop2;
  2063. options.moveStop = type == queueTypes.move ? stop : otherType1 == queueTypes.move ? otherStop1 : otherStop2;
  2064. options.rotateStop = type == queueTypes.rotate ? stop : otherType1 == queueTypes.rotate ? otherStop1 : otherStop2;
  2065. _addResize(id, eventInfo, resizeInfo, options, moveInfo, rotateInfo);
  2066. // Update duration for this animation
  2067. duration -= options.duration;
  2068. // For others update used and remove from queue if necessary
  2069. if(otherDuration1 == options.duration) {
  2070. $ax.splice(state[otherType1].queue, 0, 1);
  2071. used1 = 0;
  2072. } else used1 += options.duration;
  2073. if(otherDuration2 == options.duration) {
  2074. $ax.splice(state[otherType2].queue, 0, 1);
  2075. used2 = 0;
  2076. } else used2 += options.duration;
  2077. }
  2078. // Start queue for new type if necessary
  2079. if(duration) {
  2080. state[type].queue.push({ eventInfo: eventInfo, actionInfo: actionInfo });
  2081. state[type].used = myOptions.duration - duration;
  2082. }
  2083. // Update used for others
  2084. state[otherType1].used = used1;
  2085. state[otherType2].used = used2;
  2086. }
  2087. };
  2088. _action.flushAllResizeMoveActions = function (eventInfo) {
  2089. var idToResizeMoveState = _getIdToResizeMoveState(eventInfo);
  2090. for(var id in idToResizeMoveState) _flushResizeMoveActions(id, idToResizeMoveState);
  2091. };
  2092. var _flushResizeMoveActions = function(id, idToResizeMoveState) {
  2093. var state = idToResizeMoveState[id];
  2094. var move = state[queueTypes.move];
  2095. var moveInfo = move.queue[0];
  2096. var resize = state[queueTypes.resize];
  2097. var resizeInfo = resize.queue[0];
  2098. var rotate = state[queueTypes.rotate];
  2099. var rotateInfo = rotate.queue[0];
  2100. while (moveInfo || resizeInfo || rotateInfo) {
  2101. var eventInfo = moveInfo ? moveInfo.eventInfo : resizeInfo ? resizeInfo.eventInfo : rotateInfo.eventInfo;
  2102. moveInfo = moveInfo && moveInfo.actionInfo;
  2103. resizeInfo = resizeInfo && resizeInfo.actionInfo;
  2104. rotateInfo = rotateInfo && rotateInfo.actionInfo;
  2105. // Resize is used by default, then rotate
  2106. if(resizeInfo) {
  2107. // Check for instant resize
  2108. if(!resizeInfo.duration || resizeInfo.easing == 'none') {
  2109. _addResize(id, resize.queue[0].eventInfo, resizeInfo, { easing: 'none', duration: 0, stop: { instant: true } });
  2110. _updateResizeMoveUsed(id, queueTypes.resize, 0, idToResizeMoveState);
  2111. resizeInfo = resize.queue[0];
  2112. continue;
  2113. }
  2114. var duration = resizeInfo.duration - resize.used;
  2115. if(moveInfo) duration = Math.min(duration, moveInfo.options.duration - move.used);
  2116. if(rotateInfo) duration = Math.min(duration, rotateInfo.options.duration - rotate.used);
  2117. var baseOptions = moveInfo ? moveInfo.options : resizeInfo;
  2118. var options = { easing: baseOptions.easing, duration: duration };
  2119. options.stop = { start: resize.used, end: resize.used + duration, len: resizeInfo.duration };
  2120. if(moveInfo) options.moveStop = { start: move.used, end: move.used + duration, len: moveInfo.options.duration };
  2121. if(rotateInfo) options.rotateStop = { start: rotate.used, end: rotate.used + duration, len: rotateInfo.options.duration };
  2122. _addResize(id, eventInfo, resizeInfo, options, moveInfo, rotateInfo);
  2123. _updateResizeMoveUsed(id, queueTypes.resize, duration, idToResizeMoveState);
  2124. resizeInfo = resize.queue[0];
  2125. if(rotateInfo) {
  2126. _updateResizeMoveUsed(id, queueTypes.rotate, duration, idToResizeMoveState);
  2127. rotateInfo = rotate.queue[0];
  2128. }
  2129. if(moveInfo) {
  2130. _updateResizeMoveUsed(id, queueTypes.move, duration, idToResizeMoveState);
  2131. moveInfo = move.queue[0];
  2132. }
  2133. } else if (rotateInfo) {
  2134. // Check for instant rotate
  2135. if(!rotateInfo.options.duration || rotateInfo.options.easing == 'none') {
  2136. _addRotate(id, rotate.queue[0].eventInfo, rotateInfo, { easing: 'none', duration: 0, stop: { instant: true } });
  2137. _updateResizeMoveUsed(id, queueTypes.rotate, 0, idToResizeMoveState);
  2138. rotateInfo = rotate.queue[0];
  2139. continue;
  2140. }
  2141. duration = rotateInfo.options.duration - rotate.used;
  2142. if(moveInfo) duration = Math.min(duration, moveInfo.options.duration - move.used);
  2143. baseOptions = moveInfo ? moveInfo.options : rotateInfo.options;
  2144. options = { easing: baseOptions.easing, duration: duration };
  2145. options.stop = { start: rotate.used, end: rotate.used + duration, len: rotateInfo.options.duration };
  2146. if(moveInfo) options.moveStop = { start: move.used, end: move.used + duration, len: moveInfo.options.duration };
  2147. _addRotate(id, eventInfo, rotateInfo, options, moveInfo);
  2148. _updateResizeMoveUsed(id, queueTypes.rotate, duration, idToResizeMoveState);
  2149. rotateInfo = rotate.queue[0];
  2150. if(moveInfo) {
  2151. _updateResizeMoveUsed(id, queueTypes.move, duration, idToResizeMoveState);
  2152. moveInfo = move.queue[0];
  2153. }
  2154. } else {
  2155. if(!moveInfo.options.duration || moveInfo.options.easing == 'none') {
  2156. _addMove(id, eventInfo, moveInfo, { easing: 'none', duration: 0, stop: { instant: true } });
  2157. _updateResizeMoveUsed(id, queueTypes.move, 0, idToResizeMoveState);
  2158. moveInfo = move.queue[0];
  2159. continue;
  2160. }
  2161. duration = moveInfo.options.duration - move.used;
  2162. options = { easing: moveInfo.options.easing, duration: duration };
  2163. options.stop = { start: move.used, end: moveInfo.options.duration, len: moveInfo.options.duration };
  2164. _addMove(id, eventInfo, moveInfo, options);
  2165. _updateResizeMoveUsed(id, queueTypes.move, duration, idToResizeMoveState);
  2166. moveInfo = move.queue[0];
  2167. }
  2168. }
  2169. };
  2170. var _updateResizeMoveUsed = function(id, type, duration, idToResizeMoveState) {
  2171. var state = idToResizeMoveState[id][type];
  2172. state.used += duration;
  2173. var options = state.queue[0].actionInfo;
  2174. if(options.options) options = options.options;
  2175. var optionDur = (options.easing && options.easing != 'none' && options.duration) || 0;
  2176. if(optionDur <= state.used) {
  2177. $ax.splice(state.queue, 0, 1);
  2178. state.used = 0;
  2179. }
  2180. }
  2181. var _dispatchAction = $ax.action.dispatchAction = function(eventInfo, actions, currentIndex) {
  2182. currentIndex = currentIndex || 0;
  2183. //If no actions, you can bubble
  2184. if(currentIndex >= actions.length) return;
  2185. //actions are responsible for doing their own dispatching
  2186. _actionHandlers[actions[currentIndex].action](eventInfo, actions, currentIndex);
  2187. };
  2188. _actionHandlers.wait = function(eventInfo, actions, index) {
  2189. var action = actions[index];
  2190. var infoCopy = $ax.eventCopy(eventInfo);
  2191. window.setTimeout(function() {
  2192. infoCopy.now = new Date();
  2193. infoCopy.idToResizeMoveState = undefined;
  2194. _dispatchAction(infoCopy, actions, index + 1);
  2195. _action.flushAllResizeMoveActions(infoCopy);
  2196. }, action.waitTime);
  2197. };
  2198. _actionHandlers.expr = function(eventInfo, actions, index) {
  2199. var action = actions[index];
  2200. $ax.expr.evaluateExpr(action.expr, eventInfo); //this should be a block
  2201. _dispatchAction(eventInfo, actions, index + 1);
  2202. };
  2203. _actionHandlers.setFunction = _actionHandlers.expr;
  2204. _actionHandlers.linkWindow = function(eventInfo, actions, index) {
  2205. linkActionHelper(eventInfo, actions, index);
  2206. };
  2207. _actionHandlers.closeCurrent = function(eventInfo, actions, index) {
  2208. $ax.closeWindow();
  2209. _dispatchAction(eventInfo, actions, index + 1);
  2210. };
  2211. _actionHandlers.linkFrame = function(eventInfo, actions, index) {
  2212. linkActionHelper(eventInfo, actions, index);
  2213. };
  2214. _actionHandlers.setAdaptiveView = function(eventInfo, actions, index) {
  2215. var action = actions[index];
  2216. var view = action.setAdaptiveViewTo;
  2217. if(view) $ax.adaptive.setAdaptiveView(view);
  2218. };
  2219. var linkActionHelper = function(eventInfo, actions, index) {
  2220. var action = actions[index];
  2221. eventInfo.link = true;
  2222. if(action.linkType != 'frame') {
  2223. var includeVars = _includeVars(action.target, eventInfo);
  2224. if(action.target.targetType == "reloadPage") {
  2225. $ax.reload(action.target.includeVariables);
  2226. } else if(action.target.targetType == "backUrl") {
  2227. $ax.back();
  2228. }
  2229. var url = action.target.url;
  2230. if(!url && action.target.urlLiteral) {
  2231. url = $ax.expr.evaluateExpr(action.target.urlLiteral, eventInfo, true);
  2232. }
  2233. if(url) {
  2234. if(action.linkType == "popup") {
  2235. $ax.navigate({
  2236. url: url,
  2237. target: action.linkType,
  2238. includeVariables: includeVars,
  2239. popupOptions: action.popup
  2240. });
  2241. } else {
  2242. $ax.navigate({
  2243. url: url,
  2244. target: action.linkType,
  2245. includeVariables: includeVars
  2246. });
  2247. }
  2248. }
  2249. } else linkFrame(eventInfo, action);
  2250. eventInfo.link = false;
  2251. _dispatchAction(eventInfo, actions, index + 1);
  2252. };
  2253. var _includeVars = function(target, eventInfo) {
  2254. if(target.includeVariables) return true;
  2255. // 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.
  2256. if(target.urlLiteral) {
  2257. var literal = target.urlLiteral;
  2258. var sto = literal.stos[0];
  2259. if(literal.exprType == 'stringLiteral' && literal.value.indexOf('[[') == 0 && literal.value.indexOf(']]' == literal.value.length - 2) && literal.stos.length == 1 && sto.sto == 'item' && eventInfo.item) {
  2260. var data = $ax.repeater.getData(eventInfo, eventInfo.item.repeater.elementId, eventInfo.item.index, sto.name, 'data');
  2261. if (data && $ax.public.fn.IsPage(data.type)) return true;
  2262. }
  2263. }
  2264. return false;
  2265. };
  2266. var linkFrame = function(eventInfo, action) {
  2267. for(var i = 0; i < action.framesToTargets.length; i++) {
  2268. var framePath = action.framesToTargets[i].framePath;
  2269. var target = action.framesToTargets[i].target;
  2270. var includeVars = _includeVars(target, eventInfo);
  2271. var url = target.url;
  2272. if(!url && target.urlLiteral) {
  2273. url = $ax.expr.evaluateExpr(target.urlLiteral, eventInfo, true);
  2274. }
  2275. var id = $ax.getElementIdsFromPath(framePath, eventInfo)[0];
  2276. if(id) $ax('#' + $ax.INPUT(id)).openLink(url, includeVars);
  2277. }
  2278. };
  2279. var _repeatPanelMap = {};
  2280. _actionHandlers.setPanelState = function(eventInfo, actions, index) {
  2281. var action = actions[index];
  2282. for(var i = 0; i < action.panelsToStates.length; i++) {
  2283. var panelToState = action.panelsToStates[i];
  2284. var stateInfo = panelToState.stateInfo;
  2285. var elementIds = $ax.getElementIdsFromPath(panelToState.panelPath, eventInfo);
  2286. for(var j = 0; j < elementIds.length; j++) {
  2287. var elementId = elementIds[j];
  2288. // Need new scope for elementId and info
  2289. (function(elementId, stateInfo) {
  2290. _addAnimation(elementId, queueTypes.setState, function() {
  2291. var stateNumber = stateInfo.stateNumber;
  2292. if(stateInfo.setStateType == "value") {
  2293. var oldTarget = eventInfo.targetElement;
  2294. eventInfo.targetElement = elementId;
  2295. var stateName = $ax.expr.evaluateExpr(stateInfo.stateValue, eventInfo);
  2296. eventInfo.targetElement = oldTarget;
  2297. // Try for state name first
  2298. var states = $ax.getObjectFromElementId(elementId).diagrams;
  2299. var stateNameFound = false;
  2300. for(var k = 0; k < states.length; k++) {
  2301. if(states[k].label == stateName) {
  2302. stateNumber = k + 1;
  2303. stateNameFound = true;
  2304. }
  2305. }
  2306. // Now check for index
  2307. if(!stateNameFound) {
  2308. stateNumber = Number(stateName);
  2309. var panelCount = $('#' + elementId).children().length;
  2310. // Make sure number is not NaN, is in range, and is a whole number.
  2311. // Wasn't a state name or number, so return
  2312. if(isNaN(stateNumber) || stateNumber <= 0 || stateNumber > panelCount || Math.round(stateNumber) != stateNumber) return _fireAnimationFromQueue(elementId, queueTypes.setState);
  2313. }
  2314. } else if(stateInfo.setStateType == 'next' || stateInfo.setStateType == 'previous') {
  2315. var info = $ax.deepCopy(stateInfo);
  2316. var repeat = info.repeat;
  2317. // Only map it, if repeat exists.
  2318. if(typeof (repeat) == 'number') _repeatPanelMap[elementId] = info;
  2319. return _progessPanelState(elementId, info, info.repeatSkipFirst);
  2320. }
  2321. delete _repeatPanelMap[elementId];
  2322. // If setting to current (to stop repeat) break here
  2323. if(stateInfo.setStateType == 'current') return _fireAnimationFromQueue(elementId, queueTypes.setState);
  2324. $ax('#' + elementId).SetPanelState(stateNumber, stateInfo.options, stateInfo.showWhenSet);
  2325. });
  2326. })(elementId, stateInfo);
  2327. }
  2328. }
  2329. _dispatchAction(eventInfo, actions, index + 1);
  2330. };
  2331. var _progessPanelState = function(id, info, skipFirst) {
  2332. var direction = info.setStateType;
  2333. var loop = info.loop;
  2334. var repeat = info.repeat;
  2335. var options = info.options;
  2336. var hasRepeat = typeof (repeat) == 'number';
  2337. var currentStateId = $ax.visibility.GetPanelState(id);
  2338. var stateNumber = '';
  2339. if(currentStateId != '') {
  2340. currentStateId = $ax.repeater.getScriptIdFromElementId(currentStateId);
  2341. var currentStateNumber = Number(currentStateId.substr(currentStateId.indexOf('state') + 5));
  2342. if(direction == "next") {
  2343. stateNumber = currentStateNumber + 2;
  2344. if(stateNumber > $ax.visibility.GetPanelStateCount(id)) {
  2345. if(loop) stateNumber = 1;
  2346. else {
  2347. delete _repeatPanelMap[id];
  2348. return _fireAnimationFromQueue(id, queueTypes.setState);
  2349. }
  2350. }
  2351. } else if(direction == "previous") {
  2352. stateNumber = currentStateNumber;
  2353. if(stateNumber <= 0) {
  2354. if(loop) stateNumber = $ax.visibility.GetPanelStateCount(id);
  2355. else {
  2356. delete _repeatPanelMap[id];
  2357. return _fireAnimationFromQueue(id, queueTypes.setState);
  2358. }
  2359. }
  2360. }
  2361. if(hasRepeat && _repeatPanelMap[id] != info) return _fireAnimationFromQueue(id, queueTypes.setState);
  2362. if (!skipFirst) $ax('#' + id).SetPanelState(stateNumber, options, info.showWhenSet);
  2363. else _fireAnimationFromQueue(id, queueTypes.setState);
  2364. if(hasRepeat) {
  2365. var animate = options && options.animateIn;
  2366. if(animate && animate.easing && animate.easing != 'none' && animate.duration > repeat) repeat = animate.duration;
  2367. animate = options && options.animateOut;
  2368. if(animate && animate.easing && animate.easing != 'none' && animate.duration > repeat) repeat = animate.duration;
  2369. window.setTimeout(function() {
  2370. // Either new repeat, or no repeat anymore.
  2371. if(_repeatPanelMap[id] != info) return;
  2372. _addAnimation(id, queueTypes.setState, function() {
  2373. _progessPanelState(id, info, false);
  2374. });
  2375. }, repeat);
  2376. } else delete _repeatPanelMap[id];
  2377. }
  2378. };
  2379. _actionHandlers.fadeWidget = function(eventInfo, actions, index) {
  2380. var action = actions[index];
  2381. for(var i = 0; i < action.objectsToFades.length; i++) {
  2382. var fadeInfo = action.objectsToFades[i].fadeInfo;
  2383. var elementIds = $ax.getElementIdsFromPath(action.objectsToFades[i].objectPath, eventInfo);
  2384. for(var j = 0; j < elementIds.length; j++) {
  2385. var elementId = elementIds[j];
  2386. // Need new scope for elementId and info
  2387. (function(elementId, fadeInfo) {
  2388. _addAnimation(elementId, queueTypes.fade, function() {
  2389. if(fadeInfo.fadeType == "hide") {
  2390. $ax('#' + elementId).hide(fadeInfo.options);
  2391. } else if(fadeInfo.fadeType == "show") {
  2392. $ax('#' + elementId).show(fadeInfo.options, eventInfo);
  2393. } else if(fadeInfo.fadeType == "toggle") {
  2394. $ax('#' + elementId).toggleVisibility(fadeInfo.options);
  2395. }
  2396. });
  2397. })(elementId, fadeInfo);
  2398. }
  2399. }
  2400. _dispatchAction(eventInfo, actions, index + 1);
  2401. };
  2402. _actionHandlers.setOpacity = function(eventInfo, actions, index) {
  2403. var action = actions[index];
  2404. for(var i = 0; i < action.objectsToSetOpacity.length; i++) {
  2405. var opacityInfo = action.objectsToSetOpacity[i].opacityInfo;
  2406. var elementIds = $ax.getElementIdsFromPath(action.objectsToSetOpacity[i].objectPath, eventInfo);
  2407. for(var j = 0; j < elementIds.length; j++) {
  2408. var elementId = elementIds[j];
  2409. (function(elementId, opacityInfo) {
  2410. _addAnimation(elementId, queueTypes.fade, function () {
  2411. var oldTarget = eventInfo.targetElement;
  2412. eventInfo.targetElement = elementId;
  2413. var opacity = $ax.expr.evaluateExpr(opacityInfo.opacity, eventInfo);
  2414. eventInfo.targetElement = oldTarget;
  2415. opacity = Math.min(100, Math.max(0, opacity));
  2416. $ax('#' + elementId).setOpacity(opacity/100, opacityInfo.easing, opacityInfo.duration);
  2417. })
  2418. })(elementId, opacityInfo);
  2419. }
  2420. }
  2421. _dispatchAction(eventInfo, actions, index + 1);
  2422. }
  2423. _actionHandlers.moveWidget = function(eventInfo, actions, index) {
  2424. var action = actions[index];
  2425. for(var i = 0; i < action.objectsToMoves.length; i++) {
  2426. var moveInfo = action.objectsToMoves[i].moveInfo;
  2427. var elementIds = $ax.getElementIdsFromPath(action.objectsToMoves[i].objectPath, eventInfo);
  2428. for(var j = 0; j < elementIds.length; j++) {
  2429. var elementId = elementIds[j];
  2430. _queueResizeMove(elementId, queueTypes.move, eventInfo, moveInfo);
  2431. //_addMove(eventInfo, elementId, moveInfo, eventInfo.dragInfo);
  2432. }
  2433. }
  2434. _dispatchAction(eventInfo, actions, index + 1);
  2435. };
  2436. var _compoundChildrenShallow = function (id) {
  2437. var deep = [];
  2438. var children = $ax('#' + id).getChildren()[0].children;
  2439. var piecePrefix = id + 'p';
  2440. for (var i = 0; i < children.length; i++) {
  2441. if(children[i].substring(0, id.length + 1) == piecePrefix) {
  2442. deep.push(children[i]);
  2443. }
  2444. }
  2445. return deep;
  2446. };
  2447. var _addMove = function (elementId, eventInfo, moveInfo, optionsOverride) {
  2448. var eventInfoCopy = $ax.eventCopy(eventInfo);
  2449. var idToResizeMoveState = _getIdToResizeMoveState(eventInfoCopy);
  2450. eventInfoCopy.targetElement = elementId;
  2451. var options = $ax.deepCopy(moveInfo.options);
  2452. options.easing = optionsOverride.easing;
  2453. options.duration = optionsOverride.duration;
  2454. options.dragInfo = eventInfo.dragInfo;
  2455. if($ax.public.fn.IsLayer($obj(elementId).type)) {
  2456. var childrenIds = $ax.public.fn.getLayerChildrenDeep(elementId, true);
  2457. if(childrenIds.length == 0) return;
  2458. var animations = [];
  2459. // Get move delta once, then apply to all children
  2460. animations.push({
  2461. id: elementId,
  2462. type: queueTypes.move,
  2463. func: function() {
  2464. var layerInfo = $ax.public.fn.getWidgetBoundingRect(elementId);
  2465. var deltaLoc = _getMoveLoc(elementId, moveInfo, eventInfoCopy, optionsOverride.stop, idToResizeMoveState[elementId], options, layerInfo);
  2466. // $ax.event.raiseSyntheticEvent(elementId, "onMove");
  2467. $ax.visibility.pushContainer(elementId, false);
  2468. options.onComplete = function () {
  2469. _fireAnimationFromQueue(elementId, queueTypes.move);
  2470. $ax.visibility.popContainer(elementId, false);
  2471. };
  2472. $ax('#' + elementId).moveBy(deltaLoc.x, deltaLoc.y, options);
  2473. }
  2474. });
  2475. //for(var i = 0; i < childrenIds.length; i++) {
  2476. // (function(childId) {
  2477. // animations.push({
  2478. // id: childId,
  2479. // type: queueTypes.move,
  2480. // func: function () {
  2481. // // Nop, while trying to move as container
  2482. // //$ax.event.raiseSyntheticEvent(childId, "onMove");
  2483. // //if($ax.public.fn.IsLayer($obj(childId).type)) _fireAnimationFromQueue(childId, queueTypes.move);
  2484. // //else $ax('#' + childId).moveBy(deltaLoc.x, deltaLoc.y, moveInfo.options);
  2485. // }
  2486. // });
  2487. // })(childrenIds[i]);
  2488. //}
  2489. _addAnimations(animations);
  2490. } else {
  2491. _addAnimation(elementId, queueTypes.move, function() {
  2492. var loc = _getMoveLoc(elementId, moveInfo, eventInfoCopy, optionsOverride.stop, idToResizeMoveState[elementId], options);
  2493. // $ax.event.raiseSyntheticEvent(elementId, "onMove");
  2494. if(loc.moveTo) $ax('#' + elementId).moveTo(loc.x, loc.y, options);
  2495. else $ax('#' + elementId).moveBy(loc.x, loc.y, options);
  2496. });
  2497. }
  2498. };
  2499. var _moveSingleWidget = function (elementId, delta, options, onComplete) {
  2500. var fixedInfo = $ax.dynamicPanelManager.getFixedInfo(elementId);
  2501. var xProp = 'left';
  2502. var xDiff = '+=';
  2503. if(fixedInfo) {
  2504. if(fixedInfo.horizontal == 'right') {
  2505. xProp = 'right';
  2506. xDiff = '-=';
  2507. } else if(fixedInfo.horizontal == 'center') {
  2508. xProp = 'margin-left';
  2509. }
  2510. }
  2511. var yProp = 'top';
  2512. var yDiff = '+=';
  2513. if(fixedInfo) {
  2514. if(fixedInfo.vertical == 'bottom') {
  2515. yProp = 'bottom';
  2516. yDiff = '-=';
  2517. } else if(fixedInfo.vertical == 'middle') {
  2518. yProp = 'margin-top';
  2519. }
  2520. }
  2521. var css = {};
  2522. css[xProp] = xDiff + delta.x;
  2523. css[yProp] = yDiff + delta.y;
  2524. var moveInfo = $ax.move.PrepareForMove(elementId, delta.x, delta.y,false, options);
  2525. $jobj(elementId).animate(css, {
  2526. duration: options.duration,
  2527. easing: options.easing,
  2528. queue: false,
  2529. complete: function () {
  2530. if(onComplete) onComplete();
  2531. if(moveInfo.rootLayer) $ax.visibility.popContainer(moveInfo.rootLayer, false);
  2532. $ax.action.fireAnimationFromQueue(elementId, $ax.action.queueTypes.move);
  2533. }
  2534. });
  2535. }
  2536. var _getMoveLoc = function (elementId, moveInfo, eventInfoCopy, stopInfo, comboState, options, layerInfo) {
  2537. var moveTo = false;
  2538. var moveWithThis = false;
  2539. var xValue = 0;
  2540. var yValue = 0;
  2541. var moveResult = comboState.moveResult;
  2542. var widgetDragInfo = eventInfoCopy.dragInfo;
  2543. var jobj = $jobj(elementId);
  2544. var startX;
  2545. var startY;
  2546. switch(moveInfo.moveType) {
  2547. case "location":
  2548. // toRatio is ignoring anything before start since that has already taken effect we just know whe have from start to len to finish
  2549. // getting to the location we want to get to.
  2550. var toRatio = stopInfo.instant ? 1 : (stopInfo.end - stopInfo.start) / (stopInfo.len - stopInfo.start);
  2551. // If result already caluculated, don't recalculate again, other calculate and save
  2552. if (moveResult) {
  2553. xValue = moveResult.x;
  2554. yValue = moveResult.y;
  2555. } else {
  2556. comboState.moveResult = moveResult = { x: $ax.expr.evaluateExpr(moveInfo.xValue, eventInfoCopy), y: $ax.expr.evaluateExpr(moveInfo.yValue, eventInfoCopy) };
  2557. xValue = moveResult.x;
  2558. yValue = moveResult.y;
  2559. }
  2560. // If this is final stop for this move, then clear out the result so next move won't use it
  2561. if(stopInfo.instant || stopInfo.end == stopInfo.len) comboState.moveResult = undefined;
  2562. if (layerInfo) {
  2563. startX = layerInfo.left;
  2564. startY = layerInfo.top;
  2565. //} else if ($ax.public.fn.isCompoundVectorHtml(jobj[0])) {
  2566. // var dimensions = $ax.public.fn.compoundWidgetDimensions(jobj);
  2567. // startX = dimensions.left;
  2568. // startY = dimensions.top;
  2569. } else {
  2570. startX = $ax('#' + elementId).locRelativeIgnoreLayer(false);
  2571. startY = $ax('#' + elementId).locRelativeIgnoreLayer(true);
  2572. if(jobj.css('position') == 'fixed') {
  2573. startX -= $(window).scrollLeft();
  2574. startY -= $(window).scrollTop();
  2575. }
  2576. }
  2577. xValue = xValue == '' ? 0 : (xValue - startX) * toRatio;
  2578. yValue = yValue == '' ? 0 : (yValue - startY) * toRatio;
  2579. break;
  2580. case "delta":
  2581. var ratio = stopInfo.instant ? 1 : (stopInfo.end - stopInfo.start) / stopInfo.len;
  2582. // See case location above
  2583. if(moveResult) {
  2584. xValue = moveResult.x * ratio;
  2585. yValue = moveResult.y * ratio;
  2586. } else {
  2587. comboState.moveResult = moveResult = { x: $ax.expr.evaluateExpr(moveInfo.xValue, eventInfoCopy), y: $ax.expr.evaluateExpr(moveInfo.yValue, eventInfoCopy) };
  2588. xValue = moveResult.x * ratio;
  2589. yValue = moveResult.y * ratio;
  2590. }
  2591. if (stopInfo.instant || stopInfo.end == stopInfo.len) comboState.moveResult = undefined;
  2592. break;
  2593. case "drag":
  2594. xValue = widgetDragInfo.xDelta;
  2595. yValue = widgetDragInfo.yDelta;
  2596. break;
  2597. case "dragX":
  2598. xValue = widgetDragInfo.xDelta;
  2599. yValue = 0;
  2600. break;
  2601. case "dragY":
  2602. xValue = 0;
  2603. yValue = widgetDragInfo.yDelta;
  2604. break;
  2605. case "locationBeforeDrag":
  2606. var location = widgetDragInfo.movedWidgets[eventInfoCopy.targetElement];
  2607. if (location) {
  2608. var axObj = $ax('#' + eventInfoCopy.targetElement);
  2609. xValue = location.x - axObj.left();
  2610. yValue = location.y - axObj.top();
  2611. } else {
  2612. _fireAnimationFromQueue(eventInfoCopy.srcElement, queueTypes.move);
  2613. return { x: 0, y: 0 };
  2614. }
  2615. //moveTo = true;
  2616. break;
  2617. case "withThis":
  2618. moveWithThis = true;
  2619. var widgetMoveInfo = $ax.move.GetWidgetMoveInfo();
  2620. var srcElementId = $ax.getElementIdsFromEventAndScriptId(eventInfoCopy, eventInfoCopy.srcElement)[0];
  2621. var delta = widgetMoveInfo[srcElementId];
  2622. options.easing = delta.options.easing;
  2623. options.duration = delta.options.duration;
  2624. xValue = delta.x;
  2625. yValue = delta.y;
  2626. break;
  2627. }
  2628. if (options && options.boundaryExpr) {
  2629. //$ax.public.fn.removeCompound(jobj);
  2630. if(jobj.css('position') == 'fixed') {
  2631. //swap page coordinates with fixed coordinates
  2632. options.boundaryExpr.leftExpr.value = options.boundaryExpr.leftExpr.value.replace('.top', '.topfixed').replace('.left', '.leftfixed').replace('.bottom', '.bottomfixed').replace('.right', '.rightfixed');
  2633. options.boundaryExpr.leftExpr.stos[0].leftSTO.prop = options.boundaryExpr.leftExpr.stos[0].leftSTO.prop + 'fixed';
  2634. options.boundaryStos.boundaryScope.direcval0.value = options.boundaryStos.boundaryScope.direcval0.value.replace('.top', '.topfixed').replace('.left', '.leftfixed').replace('.bottom', '.bottomfixed').replace('.right', '.rightfixed');
  2635. options.boundaryStos.boundaryScope.direcval0.stos[0].leftSTO.prop = options.boundaryStos.boundaryScope.direcval0.stos[0].leftSTO.prop + 'fixed';
  2636. }
  2637. if(moveWithThis && (xValue || yValue)) {
  2638. _updateLeftExprVariable(options.boundaryExpr, xValue.toString(), yValue.toString());
  2639. }
  2640. if(!$ax.expr.evaluateExpr(options.boundaryExpr, eventInfoCopy)) {
  2641. var boundaryStoInfo = options.boundaryStos;
  2642. if(boundaryStoInfo) {
  2643. if(moveWithThis) {
  2644. var stoScopes = boundaryStoInfo.boundaryScope;
  2645. if(stoScopes) {
  2646. for(var s in stoScopes) {
  2647. var boundaryScope = stoScopes[s];
  2648. if(!boundaryScope.localVariables) continue;
  2649. if(boundaryScope.localVariables.withx) boundaryScope.localVariables.withx.value = xValue.toString();
  2650. if(boundaryScope.localVariables.withy) boundaryScope.localVariables.withy.value = yValue.toString();
  2651. }
  2652. }
  2653. }
  2654. if(layerInfo) {
  2655. startX = layerInfo.left;
  2656. startY = layerInfo.top;
  2657. } else {
  2658. startX = $ax('#' + elementId).locRelativeIgnoreLayer(false);
  2659. startY = $ax('#' + elementId).locRelativeIgnoreLayer(true);
  2660. if(jobj.css('position') == 'fixed') {
  2661. startX -= $(window).scrollLeft();
  2662. startY -= $(window).scrollTop();
  2663. }
  2664. }
  2665. if(boundaryStoInfo.ySto) {
  2666. var currentTop = layerInfo ? layerInfo.top : startY;
  2667. var newTop = $ax.evaluateSTO(boundaryStoInfo.ySto, boundaryStoInfo.boundaryScope, eventInfoCopy);
  2668. if(moveTo) yValue = newTop;
  2669. else yValue = newTop - currentTop;
  2670. }
  2671. if(boundaryStoInfo.xSto) {
  2672. var currentLeft = layerInfo ? layerInfo.left : startX;
  2673. var newLeft = $ax.evaluateSTO(boundaryStoInfo.xSto, boundaryStoInfo.boundaryScope, eventInfoCopy);
  2674. if(moveTo) xValue = newLeft;
  2675. else xValue = newLeft - currentLeft;
  2676. }
  2677. }
  2678. }
  2679. //$ax.public.fn.restoreCompound(jobj);
  2680. }
  2681. return { x: Number(xValue), y: Number(yValue), moveTo: moveTo };
  2682. };
  2683. //we will have something like [[Target.right + withX]] for leftExpr, and this function set the value of withX
  2684. var _updateLeftExprVariable = function (exprTree, xValue, yValue) {
  2685. if(exprTree.leftExpr && !exprTree.leftExpr.op) {
  2686. var localVars = exprTree.leftExpr.localVariables;
  2687. if(localVars) {
  2688. if(localVars.withx) localVars.withx.value = xValue;
  2689. if(localVars.withy) localVars.withy.value = yValue;
  2690. }
  2691. }
  2692. //traversal
  2693. if(exprTree.op) {
  2694. if(exprTree.leftExpr) _updateLeftExprVariable(exprTree.leftExpr, xValue, yValue);
  2695. if(exprTree.rightExpr) _updateLeftExprVariable(exprTree.rightExpr, xValue, yValue);
  2696. }
  2697. }
  2698. var widgetRotationFilter = [
  2699. $ax.constants.IMAGE_BOX_TYPE, $ax.constants.IMAGE_MAP_REGION_TYPE, $ax.constants.DYNAMIC_PANEL_TYPE,
  2700. $ax.constants.VECTOR_SHAPE_TYPE, $ax.constants.VERTICAL_LINE_TYPE, $ax.constants.HORIZONTAL_LINE_TYPE
  2701. ];
  2702. _actionHandlers.rotateWidget = function(eventInfo, actions, index) {
  2703. var action = actions[index];
  2704. for(var i = 0; i < action.objectsToRotate.length; i++) {
  2705. var rotateInfo = action.objectsToRotate[i].rotateInfo;
  2706. var elementIds = $ax.getElementIdsFromPath(action.objectsToRotate[i].objectPath, eventInfo);
  2707. for(var j = 0; j < elementIds.length; j++) {
  2708. var elementId = elementIds[j];
  2709. _queueResizeMove(elementId, queueTypes.rotate, eventInfo, rotateInfo);
  2710. }
  2711. }
  2712. _dispatchAction(eventInfo, actions, index + 1);
  2713. };
  2714. var _addRotate = function (elementId, eventInfo, rotateInfo, options, moveInfo) {
  2715. var idToResizeMoveState = _getIdToResizeMoveState(eventInfo);
  2716. rotateInfo = $ax.deepCopy(rotateInfo);
  2717. rotateInfo.options.easing = options.easing;
  2718. rotateInfo.options.duration = options.duration;
  2719. var eventInfoCopy = $ax.eventCopy(eventInfo);
  2720. eventInfoCopy.targetElement = elementId;
  2721. //calculate degree value at start of animation
  2722. var rotateDegree;
  2723. var offset = {};
  2724. var eval = function(boundingRect) {
  2725. rotateDegree = parseFloat($ax.expr.evaluateExpr(rotateInfo.degree, eventInfoCopy));
  2726. offset.x = Number($ax.expr.evaluateExpr(rotateInfo.offsetX, eventInfoCopy));
  2727. offset.y = Number($ax.expr.evaluateExpr(rotateInfo.offsetY, eventInfoCopy));
  2728. if(!rotateInfo.options.clockwise) rotateDegree = -rotateDegree;
  2729. _updateOffset(offset, rotateInfo.anchor, boundingRect);
  2730. }
  2731. if(moveInfo) {
  2732. var moveOptions = { dragInfo: eventInfoCopy.dragInfo, duration: options.duration, easing: options.easing, boundaryExpr: moveInfo.options.boundaryExpr, boundaryStos: moveInfo.options.boundaryStos };
  2733. }
  2734. var obj = $obj(elementId);
  2735. if($ax.public.fn.IsLayer(obj.type)) {
  2736. var childrenIds = $ax.public.fn.getLayerChildrenDeep(elementId, true, true);
  2737. if(childrenIds.length == 0) return;
  2738. var animations = [];
  2739. //get center point of the group, and degree delta
  2740. var centerPoint, degreeDelta, moveDelta;
  2741. animations.push({
  2742. id: elementId,
  2743. type: queueTypes.rotate,
  2744. func: function () {
  2745. var boundingRect = $axure.fn.getWidgetBoundingRect(elementId);
  2746. eval(boundingRect);
  2747. centerPoint = boundingRect.centerPoint;
  2748. centerPoint.x += offset.x;
  2749. centerPoint.y += offset.y;
  2750. degreeDelta = _initRotateLayer(elementId, rotateInfo, rotateDegree, options, options.stop);
  2751. _fireAnimationFromQueue(elementId, queueTypes.rotate);
  2752. moveDelta = { x: 0, y: 0 };
  2753. if (moveInfo) {
  2754. moveDelta = _getMoveLoc(elementId, moveInfo, eventInfoCopy, options.moveStop, idToResizeMoveState[elementId], moveOptions, boundingRect);
  2755. if (moveDelta.moveTo) {
  2756. moveDelta.x -= $ax.getNumFromPx($jobj(elementId).css('left'));
  2757. moveDelta.y -= $ax.getNumFromPx($jobj(elementId).css('top'));
  2758. }
  2759. $ax.event.raiseSyntheticEvent(elementId, 'onMove');
  2760. }
  2761. }
  2762. });
  2763. for(var idIndex = 0; idIndex < childrenIds.length; idIndex++) {
  2764. var childId = childrenIds[idIndex];
  2765. (function(id) {
  2766. var childObj = $obj(id);
  2767. var rotate = $.inArray(childObj.type, widgetRotationFilter) != -1;
  2768. var isLayer = $ax.public.fn.IsLayer(childObj.type);
  2769. animations.push({
  2770. id: id,
  2771. type: queueTypes.rotate,
  2772. func: function() {
  2773. $ax.event.raiseSyntheticEvent(id, "onRotate");
  2774. if(isLayer) _fireAnimationFromQueue(id, queueTypes.rotate);
  2775. else $ax('#' + id).circularMoveAndRotate(degreeDelta, options, centerPoint.x, centerPoint.y, rotate, moveDelta);
  2776. }
  2777. });
  2778. if(!isLayer) animations.push({ id: id, type: queueTypes.move, func: function() {} });
  2779. })(childId);
  2780. }
  2781. _addAnimations(animations);
  2782. } else {
  2783. animations = [];
  2784. animations.push({
  2785. id: elementId,
  2786. type: queueTypes.rotate,
  2787. func: function () {
  2788. var jobj = $jobj(elementId);
  2789. var unrotatedDim = { width: $ax.getNumFromPx(jobj.css('width')), height: $ax.getNumFromPx(jobj.css('height')) };
  2790. eval(unrotatedDim);
  2791. var delta = { x: 0, y: 0 };
  2792. if(moveInfo) {
  2793. delta = _getMoveLoc(elementId, moveInfo, eventInfoCopy, options.moveStop, idToResizeMoveState[elementId], moveOptions);
  2794. if(delta.moveTo) {
  2795. delta.x -= $ax.getNumFromPx($jobj(elementId).css('left'));
  2796. delta.y -= $ax.getNumFromPx($jobj(elementId).css('top'));
  2797. }
  2798. }
  2799. $ax.event.raiseSyntheticEvent(elementId, 'onRotate');
  2800. if(offset.x == 0 && offset.y == 0) {
  2801. _rotateSingle(elementId, rotateDegree, rotateInfo.rotateType == 'location', delta, options, options.stop);
  2802. _fireAnimationFromQueue(elementId, queueTypes.move);
  2803. if(moveInfo) $ax.event.raiseSyntheticEvent(elementId, 'onMove');
  2804. return;
  2805. }
  2806. _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) {
  2821. var degreeDelta = _applyRotateStop(rotateDegree, $ax.move.getRotationDegree(elementId), rotateTo, stop);
  2822. $ax('#' + elementId).rotate(degreeDelta, options.easing, options.duration, false, true);
  2823. if(delta.x || delta.y) _moveSingleWidget(elementId, delta, options);
  2824. };
  2825. var _rotateSingleOffset = function (elementId, rotateDegree, rotateTo, delta, offset, options, stop, resizeOffset) {
  2826. var obj = $obj(elementId);
  2827. var currRotation = $ax.move.getRotationDegree(elementId);
  2828. // 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.
  2829. if(currRotation) {
  2830. offset = $axure.fn.getPointAfterRotate(currRotation, offset, { x: 0, y: 0 });
  2831. }
  2832. var degreeDelta = _applyRotateStop(rotateDegree, currRotation, rotateTo, stop);
  2833. var widgetCenter = $axure.fn.getWidgetBoundingRect(elementId).centerPoint;
  2834. var rotate = $.inArray(obj.type, widgetRotationFilter) != -1;
  2835. $ax('#' + elementId).circularMoveAndRotate(degreeDelta, options, widgetCenter.x + offset.x, widgetCenter.y + offset.y, rotate, delta, resizeOffset);
  2836. }
  2837. var _applyRotateStop = function(rotateDegree, currRotation, to, stop) {
  2838. var degreeDelta;
  2839. var ratio;
  2840. if(to) {
  2841. degreeDelta = rotateDegree - currRotation;
  2842. ratio = stop.instant ? 1 : (stop.end - stop.start) / (stop.len - stop.start);
  2843. } else {
  2844. degreeDelta = rotateDegree;
  2845. ratio = stop.instant ? 1 : (stop.end - stop.start) / stop.len;
  2846. }
  2847. return degreeDelta * ratio;
  2848. }
  2849. var _initRotateLayer = function(elementId, rotateInfo, rotateDegree, options, stop) {
  2850. var layerDegree = $jobj(elementId).data('layerDegree');
  2851. if (layerDegree === undefined) layerDegree = 0;
  2852. else layerDegree = parseFloat(layerDegree);
  2853. var to = rotateInfo.rotateType == 'location';
  2854. var newDegree = to ? rotateDegree : layerDegree + rotateDegree;
  2855. var degreeDelta = newDegree - layerDegree;
  2856. var ratio = stop.instant ? 1 : (stop.end - stop.start) / (stop.len - stop.start);
  2857. degreeDelta *= ratio;
  2858. $jobj(elementId).data('layerDegree', newDegree);
  2859. $ax.event.raiseSyntheticEvent(elementId, "onRotate");
  2860. return degreeDelta;
  2861. }
  2862. _actionHandlers.setWidgetSize = function(eventInfo, actions, index) {
  2863. var action = actions[index];
  2864. for(var i = 0; i < action.objectsToResize.length; i++) {
  2865. var resizeInfo = action.objectsToResize[i].sizeInfo;
  2866. var objPath = action.objectsToResize[i].objectPath;
  2867. if(objPath == 'thisItem') {
  2868. var thisId = eventInfo.srcElement;
  2869. var repeaterId = $ax.getParentRepeaterFromElementId(thisId);
  2870. var itemId = $ax.repeater.getItemIdFromElementId(thisId);
  2871. var currSize = $ax.repeater.getItemSize(repeaterId, itemId);
  2872. var newSize = _getSizeFromInfo(resizeInfo, eventInfo, currSize.width, currSize.height);
  2873. $ax.repeater.setItemSize(repeaterId, itemId, newSize.width, newSize.height);
  2874. continue;
  2875. }
  2876. var elementIds = $ax.getElementIdsFromPath(objPath, eventInfo);
  2877. for(var j = 0; j < elementIds.length; j++) {
  2878. var elementId = elementIds[j];
  2879. _queueResizeMove(elementId, queueTypes.resize, eventInfo, resizeInfo);
  2880. //_addResize(elementId, resizeInfo);
  2881. }
  2882. }
  2883. _dispatchAction(eventInfo, actions, index + 1);
  2884. };
  2885. // Move info undefined unless this move/resize actions are being merged
  2886. var _addResize = function(elementId, eventInfo, resizeInfo, options, moveInfo, rotateInfo) {
  2887. var axObject = $obj(elementId);
  2888. resizeInfo = $ax.deepCopy(resizeInfo);
  2889. resizeInfo.easing = options.easing;
  2890. resizeInfo.duration = options.duration;
  2891. var eventInfoCopy = $ax.eventCopy(eventInfo);
  2892. eventInfoCopy.targetElement = elementId;
  2893. var moves = moveInfo || resizeInfo.anchor != "top left" || ($ax.public.fn.IsDynamicPanel(axObject.type) &&
  2894. ((axObject.fixedHorizontal && axObject.fixedHorizontal == 'center') || (axObject.fixedVertical && axObject.fixedVertical == 'middle'))) ||
  2895. (rotateInfo && (rotateInfo.offsetX || rotateInfo.offsetY));
  2896. if(moveInfo) {
  2897. var moveOptions = { dragInfo: eventInfoCopy.dragInfo, duration: options.duration, easing: options.easing, boundaryExpr: moveInfo.options.boundaryExpr, boundaryStos: moveInfo.options.boundaryStos };
  2898. }
  2899. var idToResizeMoveState = _getIdToResizeMoveState(eventInfoCopy);
  2900. var animations = [];
  2901. if($ax.public.fn.IsLayer(axObject.type)) {
  2902. moves = true; // Assume widgets will move will layer, even though not all widgets may move
  2903. var childrenIds = $ax.public.fn.getLayerChildrenDeep(elementId, true, true);
  2904. if(childrenIds.length === 0) return;
  2905. // Need to wait to calculate new size, until time to animate, but animates are in separate queues
  2906. // best option seems to be to calculate in a "animate" for the layer itself and all children will use that.
  2907. // May just have to be redundant if this doesn't work well.
  2908. var boundingRect, widthChangedPercent, heightChangedPercent, unchanged, deltaLoc, degreeDelta, resizeOffset;
  2909. animations.push({
  2910. id: elementId,
  2911. type: queueTypes.resize,
  2912. func: function () {
  2913. $ax.visibility.pushContainer(elementId, false);
  2914. boundingRect = $ax.public.fn.getWidgetBoundingRect(elementId);
  2915. var size = _getSizeFromInfo(resizeInfo, eventInfoCopy, boundingRect.width, boundingRect.height, elementId);
  2916. deltaLoc = { x: 0, y: 0 };
  2917. var stop = options.stop;
  2918. var ratio = stop.instant ? 1 : (stop.end - stop.start) / (stop.len - stop.start);
  2919. widthChangedPercent = Math.round(size.width - boundingRect.width) / boundingRect.width * ratio;
  2920. heightChangedPercent = Math.round(size.height - boundingRect.height) / boundingRect.height * ratio;
  2921. resizeOffset = _applyAnchorToResizeOffset(widthChangedPercent * boundingRect.width, heightChangedPercent * boundingRect.height, resizeInfo.anchor);
  2922. if(stop.instant || stop.end == stop.len) idToResizeMoveState[elementId].resizeResult = undefined;
  2923. unchanged = widthChangedPercent === 0 && heightChangedPercent === 0;
  2924. $ax.event.raiseSyntheticEvent(elementId, 'onResize');
  2925. _fireAnimationFromQueue(elementId, queueTypes.resize);
  2926. }
  2927. });
  2928. if(moveInfo) animations.push({
  2929. id: elementId,
  2930. type: queueTypes.move,
  2931. func: function() {
  2932. deltaLoc = _getMoveLoc(elementId, moveInfo, eventInfoCopy, options.moveStop, idToResizeMoveState[elementId], moveOptions, boundingRect);
  2933. $ax.visibility.pushContainer(elementId, false);
  2934. _fireAnimationFromQueue(elementId, queueTypes.move);
  2935. $ax.event.raiseSyntheticEvent(elementId, 'onMove');
  2936. }
  2937. });
  2938. if (rotateInfo) animations.push({
  2939. id: elementId,
  2940. type: queueTypes.rotate,
  2941. func: function () {
  2942. resizeOffset = _applyAnchorToResizeOffset(widthChangedPercent * boundingRect.width, heightChangedPercent * boundingRect.height, resizeInfo.anchor);
  2943. var rotateDegree = parseFloat($ax.expr.evaluateExpr(rotateInfo.degree, eventInfoCopy));
  2944. degreeDelta = _initRotateLayer(elementId, rotateInfo, rotateDegree, options, options.rotateStop);
  2945. _fireAnimationFromQueue(elementId, queueTypes.rotate);
  2946. $ax.event.raiseSyntheticEvent(elementId, 'onRotate');
  2947. }
  2948. });
  2949. var completeCount = childrenIds.length*2; // Because there is a resize and move complete, it needs to be doubled
  2950. for(var idIndex = 0; idIndex < childrenIds.length; idIndex++) {
  2951. // Need to use scoping trick here to make sure childId doesn't change on next loop
  2952. (function(childId) {
  2953. //use ax obj to get width and height, jquery css give us the value without border
  2954. var isLayer = $ax.public.fn.IsLayer($obj(childId).type);
  2955. var rotate = $.inArray($obj(childId).type, widgetRotationFilter) != -1;
  2956. animations.push({
  2957. id: childId,
  2958. type: queueTypes.resize,
  2959. func: function() {
  2960. //$ax.event.raiseSyntheticEvent(childId, 'onResize');
  2961. if(isLayer) {
  2962. completeCount -= 2;
  2963. _fireAnimationFromQueue(childId, queueTypes.resize);
  2964. $ax.event.raiseSyntheticEvent(childId, 'onResize');
  2965. } else {
  2966. var currDeltaLoc = { x: deltaLoc.x, y: deltaLoc.y };
  2967. var resizeDeltaMove = { x: 0, y: 0 };
  2968. var css = _getCssForResizingLayerChild(childId, resizeInfo.anchor, boundingRect, widthChangedPercent, heightChangedPercent, resizeDeltaMove);
  2969. var onComplete = function() {
  2970. if(--completeCount == 0) $ax.visibility.popContainer(elementId, false);
  2971. };
  2972. $ax('#' + childId).resize(css, resizeInfo, true, moves, onComplete);
  2973. if(rotateInfo) {
  2974. var offset = { x: Number($ax.expr.evaluateExpr(rotateInfo.offsetX, eventInfoCopy)), y: Number($ax.expr.evaluateExpr(rotateInfo.offsetY, eventInfo)) };
  2975. _updateOffset(offset, resizeInfo.anchor, boundingRect);
  2976. var centerPoint = { x: boundingRect.centerPoint.x + offset.x, y: boundingRect.centerPoint.y + offset.y };
  2977. $ax('#' + childId).circularMoveAndRotate(degreeDelta, options, centerPoint.x, centerPoint.y, rotate, currDeltaLoc, resizeOffset, resizeDeltaMove, onComplete);
  2978. } else {
  2979. currDeltaLoc.x += resizeDeltaMove.x;
  2980. currDeltaLoc.y += resizeDeltaMove.y;
  2981. _moveSingleWidget(childId, currDeltaLoc, options, onComplete);
  2982. }
  2983. }
  2984. }
  2985. });
  2986. if(!isLayer && moves) animations.push({ id: childId, type: queueTypes.move, func: function () {} });
  2987. if(!isLayer && rotateInfo) animations.push({ id: childId, type: queueTypes.rotate, func: function () {} });
  2988. })(childrenIds[idIndex]);
  2989. }
  2990. } else {
  2991. // Not func, obj with func
  2992. animations.push({
  2993. id: elementId,
  2994. type: queueTypes.resize,
  2995. func: function() {
  2996. //textarea can be resized manully by the user, but doesn't update div size yet, so doing this for now.
  2997. //alternatively axquery get for size can account for this
  2998. var sizeId = $ax.public.fn.IsTextArea(axObject.type) ? $jobj(elementId).children('textarea').attr('id') : elementId;
  2999. var oldSize = $ax('#' + sizeId).size();
  3000. var oldWidth = oldSize.width;
  3001. var oldHeight = oldSize.height;
  3002. var stop = options.stop;
  3003. var ratio = stop.instant ? 1 : (stop.end - stop.start) / (stop.len - stop.start);
  3004. var size = _getSizeFromInfo(resizeInfo, eventInfoCopy, oldWidth, oldHeight, elementId);
  3005. var newWidth = size.width;
  3006. var newHeight = size.height;
  3007. var deltaWidth = Math.round(newWidth - oldWidth) * ratio;
  3008. var deltaHeight = Math.round(newHeight - oldHeight) * ratio;
  3009. newWidth = oldWidth + deltaWidth;
  3010. newHeight = oldHeight + deltaHeight;
  3011. var delta = { x: 0, y: 0 };
  3012. if(moveInfo) {
  3013. delta = _getMoveLoc(elementId, moveInfo, eventInfoCopy, options.moveStop, idToResizeMoveState[elementId], moveOptions);
  3014. if (delta.moveTo) {
  3015. delta.x -= $ax.getNumFromPx($jobj(elementId).css('left'));
  3016. delta.y -= $ax.getNumFromPx($jobj(elementId).css('top'));
  3017. }
  3018. }
  3019. var rotateHandlesMove = false;
  3020. var offset = { x: 0, y: 0 };
  3021. if(rotateInfo) {
  3022. offset.x = Number($ax.expr.evaluateExpr(rotateInfo.offsetX, eventInfoCopy));
  3023. offset.y = Number($ax.expr.evaluateExpr(rotateInfo.offsetY, eventInfoCopy));
  3024. _updateOffset(offset, rotateInfo.anchor, $axure.fn.getWidgetBoundingRect(elementId));
  3025. rotateHandlesMove = Boolean(rotateInfo && (offset.x || offset.y || rotateInfo.anchor != 'center'));
  3026. $ax.event.raiseSyntheticEvent(elementId, 'onRotate');
  3027. }
  3028. var css = null;
  3029. var rootLayer = null;
  3030. if(deltaHeight != 0 || deltaWidth != 0) {
  3031. rootLayer = $ax.move.getRootLayer(elementId);
  3032. if(rootLayer) $ax.visibility.pushContainer(rootLayer, false);
  3033. css = _getCssForResizingWidget(elementId, eventInfoCopy, resizeInfo.anchor, newWidth, newHeight, oldWidth, oldHeight, delta, options.stop, !rotateHandlesMove);
  3034. idToResizeMoveState[elementId].resizeResult = undefined;
  3035. }
  3036. if(rotateInfo) {
  3037. var rotateDegree = parseFloat($ax.expr.evaluateExpr(rotateInfo.degree, eventInfoCopy));
  3038. if(rotateHandlesMove) {
  3039. var resizeOffset = _applyAnchorToResizeOffset(deltaWidth, deltaHeight, rotateInfo.anchor);
  3040. _rotateSingleOffset(elementId, rotateDegree, rotateInfo.rotateType == 'location', delta, offset, options, options.rotateStop, resizeOffset);
  3041. } else {
  3042. // Not handling move so pass in nop delta
  3043. _rotateSingle(elementId, rotateDegree, rotateInfo.rotateType == 'location', { x: 0, y: 0 }, options, options.rotateStop);
  3044. }
  3045. } else _moveSingleWidget(elementId, delta, options);
  3046. // Have to do it down here to make sure move info is registered
  3047. if(moveInfo) $ax.event.raiseSyntheticEvent(elementId, 'onMove');
  3048. //$ax.event.raiseSyntheticEvent(elementId, 'onResize');
  3049. if (css) {
  3050. $ax('#' + elementId).resize(css, resizeInfo, true, moves, function () {
  3051. if(rootLayer) $ax.visibility.popContainer(rootLayer, false);
  3052. });
  3053. } else {
  3054. _fireAnimationFromQueue(elementId, queueTypes.resize);
  3055. if(moves && !rotateHandlesMove) _fireAnimationFromQueue(elementId, queueTypes.move);
  3056. $ax.event.raiseSyntheticEvent(elementId, 'onResize');
  3057. }
  3058. }
  3059. });
  3060. // Nop move (move handled by resize)
  3061. if(rotateInfo) animations.push({ id: elementId, type: queueTypes.rotate, func: function () { } });
  3062. if(moves) animations.push({ id: elementId, type: queueTypes.move, func: function () { } });
  3063. }
  3064. _addAnimations(animations);
  3065. };
  3066. var _applyAnchorToResizeOffset = function (deltaWidth, deltaHeight, anchor) {
  3067. var offset = {};
  3068. if (anchor.indexOf('left') != -1) offset.x = -deltaWidth / 2;
  3069. else if (anchor.indexOf('right') != -1) offset.x = deltaWidth / 2;
  3070. if (anchor.indexOf('top') != -1) offset.y = -deltaHeight / 2;
  3071. else if (anchor.indexOf('bottom') != -1) offset.y = deltaHeight / 2;
  3072. return offset;
  3073. }
  3074. //var _getOldAndNewSize = function (resizeInfo, eventInfo, targetElement) {
  3075. // var axObject = $obj(targetElement);
  3076. // var oldWidth, oldHeight;
  3077. // //textarea can be resized manully by the user, use the textarea child to get the current size
  3078. // //because this new size may not be reflected on its parents yet
  3079. // if ($ax.public.fn.IsTextArea(axObject.type)) {
  3080. // var jObject = $jobj(elementId);
  3081. // var textObj = $ax('#' + jObject.children('textarea').attr('id'));
  3082. // //maybe we shouldn't use ax obj to get width and height here anymore...
  3083. // oldWidth = textObj.width();
  3084. // oldHeight = textObj.height();
  3085. // } else {
  3086. // oldWidth = $ax('#' + elementId).width();
  3087. // oldHeight = $ax('#' + elementId).height();
  3088. // }
  3089. // var size = _getSizeFromInfo(resizeInfo, eventInfo, oldHeight, oldWidth, elementId);
  3090. // return { oldWidth: oldWidth, oldHeight: oldHeight, newWidth: size.width, newHeight: size.height, change: oldWidth != size.width || oldHeight != size.height };
  3091. //}
  3092. var _getSizeFromInfo = function(resizeInfo, eventInfo, oldWidth, oldHeight, targetElement) {
  3093. var oldTarget = eventInfo.targetElement;
  3094. eventInfo.targetElement = targetElement;
  3095. var state = _getIdToResizeMoveState(eventInfo)[targetElement];
  3096. if(state && state.resizeResult) return state.resizeResult;
  3097. var width = $ax.expr.evaluateExpr(resizeInfo.width, eventInfo);
  3098. var height = $ax.expr.evaluateExpr(resizeInfo.height, eventInfo);
  3099. eventInfo.targetElement = oldTarget;
  3100. // If either one is not a number, use the old value
  3101. width = width != "" ? Number(width) : oldWidth;
  3102. height = height != "" ? Number(height) : oldHeight;
  3103. width = isNaN(width) ? oldWidth : width;
  3104. height = isNaN(height) ? oldHeight : height;
  3105. // can't be negative
  3106. var result = { width: Math.max(width, 0), height: Math.max(height, 0) };
  3107. if(state) state.resizeResult = result;
  3108. return result;
  3109. }
  3110. //var _queueResize = function (elementId, css, resizeInfo) {
  3111. // var resizeFunc = function() {
  3112. // $ax('#' + elementId).resize(css, resizeInfo, true);
  3113. // //$ax.public.fn.resize(elementId, css, resizeInfo, true);
  3114. // };
  3115. // var obj = $obj(elementId);
  3116. // var moves = resizeInfo.anchor != "top left" || ($ax.public.fn.IsDynamicPanel(obj.type) && ((obj.fixedHorizontal && obj.fixedHorizontal == 'center') || (obj.fixedVertical && obj.fixedVertical == 'middle')))
  3117. // if(!moves) {
  3118. // _addAnimation(elementId, queueTypes.resize, resizeFunc);
  3119. // } else {
  3120. // var animations = [];
  3121. // animations[0] = { id: elementId, type: queueTypes.resize, func: resizeFunc };
  3122. // animations[1] = { id: elementId, type: queueTypes.move, func: function() {}}; // Nop func - resize handles move and firing from queue
  3123. // _addAnimations(animations);
  3124. // }
  3125. //};
  3126. //should clean this function and
  3127. var _getCssForResizingWidget = function (elementId, eventInfo, anchor, newWidth, newHeight, oldWidth, oldHeight, delta, stop, handleMove) {
  3128. var ratio = stop.instant ? 1 : (stop.end - stop.start) / (stop.len - stop.start);
  3129. var deltaWidth = (newWidth - oldWidth) * ratio;
  3130. var deltaHeight = (newHeight - oldHeight) * ratio;
  3131. if(stop.instant || stop.end == stop.len) {
  3132. var idToResizeMoveState = _getIdToResizeMoveState(eventInfo);
  3133. if(idToResizeMoveState[elementId]) idToResizeMoveState[elementId].resizeResult = undefined;
  3134. }
  3135. var css = {};
  3136. css.height = oldHeight + deltaHeight;
  3137. var obj = $obj(elementId);
  3138. //if it's 100% width, don't change its width
  3139. if($ax.dynamicPanelManager.isPercentWidthPanel(obj)) var is100Dp = true;
  3140. else css.width = oldWidth + deltaWidth;
  3141. var jobj = $jobj(elementId);
  3142. //if this is pinned dp, we will mantain the pin, no matter how you resize it; so no need changes left or top
  3143. //NOTE: currently only pinned DP has position == fixed
  3144. if(jobj.css('position') == 'fixed') return css;
  3145. //use position relative to parents
  3146. //var position = obj.generateCompound ? $ax.public.fn.getWidgetBoundingRect(elementId) : $ax.public.fn.getPositionRelativeToParent(elementId);
  3147. var locationShift;
  3148. switch(anchor) {
  3149. case "top left":
  3150. locationShift = { x: 0, y: 0 }; break;
  3151. case "top":
  3152. locationShift = { x: -deltaWidth / 2.0, y: 0.0 }; break;
  3153. case "top right":
  3154. locationShift = { x: -deltaWidth, y: 0.0 }; break;
  3155. case "left":
  3156. locationShift = { x: 0.0, y: -deltaHeight / 2.0 }; break;
  3157. case "center":
  3158. locationShift = { x: -deltaWidth / 2.0, y: -deltaHeight / 2.0 }; break;
  3159. case "right":
  3160. locationShift = { x: -deltaWidth, y: -deltaHeight / 2.0 }; break;
  3161. case "bottom left":
  3162. locationShift = { x: 0.0, y: -deltaHeight }; break;
  3163. case "bottom":
  3164. locationShift = { x: -deltaWidth/2.0, y: -deltaHeight }; break;
  3165. case "bottom right":
  3166. locationShift = { x: -deltaWidth, y: -deltaHeight }; break;
  3167. }
  3168. if(handleMove) {
  3169. if(jobj.css('position') === 'absolute') {
  3170. css.left = $ax.getNumFromPx(jobj.css('left')) + locationShift.x + delta.x;
  3171. css.top = $ax.getNumFromPx(jobj.css('top')) + locationShift.y + delta.y;
  3172. } else {
  3173. var axQuery = $ax('#' + elementId);
  3174. css.left = axQuery.left(true) + locationShift.x + delta.x;
  3175. css.top = axQuery.top(true) + locationShift.y + delta.y;
  3176. }
  3177. } else {
  3178. delta.x += locationShift.x;
  3179. delta.y += locationShift.y;
  3180. }
  3181. return css;
  3182. };
  3183. var _getCssForResizingLayerChild = function (elementId, anchor, layerBoundingRect, widthChangedPercent, heightChangedPercent, deltaLoc) {
  3184. var boundingRect = $ax.public.fn.getWidgetBoundingRect(elementId);
  3185. var childCenterPoint = boundingRect.centerPoint;
  3186. var currentSize = $ax('#' + elementId).size();
  3187. var newWidth = currentSize.width + currentSize.width * widthChangedPercent;
  3188. var newHeight = currentSize.height + currentSize.height * heightChangedPercent;
  3189. var css = {};
  3190. css.height = newHeight;
  3191. var obj = $obj(elementId);
  3192. //if it's 100% width, don't change its width and left
  3193. var changeLeft = true;
  3194. if($ax.dynamicPanelManager.isPercentWidthPanel(obj)) changeLeft = false;
  3195. else css.width = newWidth;
  3196. var jobj = $jobj(elementId);
  3197. //if this is pinned dp, we will mantain the pin, no matter how you resize it; so no need changes left or top
  3198. //NOTE: currently only pinned DP has position == fixed
  3199. if(jobj.css('position') == 'fixed') return css;
  3200. //use bounding rect position relative to parents to calculate delta
  3201. var axObj = $ax('#' + elementId);
  3202. // This will be absolute world coordinates, but we want body coordinates.
  3203. var currentLeft = axObj.locRelativeIgnoreLayer(false);
  3204. var currentTop = axObj.locRelativeIgnoreLayer(true);
  3205. if(anchor.indexOf("center") > -1) {
  3206. var topDelta = (childCenterPoint.y - layerBoundingRect.centerPoint.y) * heightChangedPercent - currentSize.height * heightChangedPercent / 2;
  3207. if(changeLeft) var leftDelta = (childCenterPoint.x - layerBoundingRect.centerPoint.x) * widthChangedPercent - currentSize.width * widthChangedPercent / 2;
  3208. } else {
  3209. if(anchor.indexOf("top") > -1) {
  3210. topDelta = (currentTop - layerBoundingRect.top) * heightChangedPercent;
  3211. } else if(anchor.indexOf("bottom") > -1) {
  3212. topDelta = (currentTop - layerBoundingRect.bottom) * heightChangedPercent;
  3213. } else {
  3214. topDelta = (childCenterPoint.y - layerBoundingRect.centerPoint.y) * heightChangedPercent - currentSize.height * heightChangedPercent / 2;
  3215. }
  3216. if(changeLeft) {
  3217. if(anchor.indexOf("left") > -1) {
  3218. leftDelta = (currentLeft - layerBoundingRect.left) * widthChangedPercent;
  3219. } else if(anchor.indexOf("right") > -1) {
  3220. leftDelta = (currentLeft - layerBoundingRect.right) * widthChangedPercent;
  3221. } else {
  3222. leftDelta = (childCenterPoint.x - layerBoundingRect.centerPoint.x) * widthChangedPercent - currentSize.width * widthChangedPercent / 2;
  3223. }
  3224. }
  3225. }
  3226. if(topDelta) deltaLoc.y += topDelta;
  3227. if(leftDelta && changeLeft) deltaLoc.x += leftDelta;
  3228. return css;
  3229. };
  3230. _actionHandlers.setPanelOrder = function(eventInfo, actions, index) {
  3231. var action = actions[index];
  3232. for(var i = 0; i < action.panelPaths.length; i++) {
  3233. var func = action.panelPaths[i].setOrderInfo.bringToFront ? 'bringToFront' : 'sendToBack';
  3234. var elementIds = $ax.getElementIdsFromPath(action.panelPaths[i].panelPath, eventInfo);
  3235. for(var j = 0; j < elementIds.length; j++) $ax('#' + elementIds[j])[func]();
  3236. }
  3237. _dispatchAction(eventInfo, actions, index + 1);
  3238. };
  3239. _actionHandlers.modifyDataSetEditItems = function(eventInfo, actions, index) {
  3240. var action = actions[index];
  3241. var add = action.repeatersToAddTo;
  3242. var repeaters = add || action.repeatersToRemoveFrom;
  3243. var itemId;
  3244. for(var i = 0; i < repeaters.length; i++) {
  3245. var data = repeaters[i];
  3246. // Grab the first one because repeaters must have only element id, as they cannot be inside repeaters
  3247. // or none if unplaced
  3248. var id = $ax.getElementIdsFromPath(data.path, eventInfo)[0];
  3249. if(!id) continue;
  3250. if(data.addType == 'this') {
  3251. var scriptId = $ax.repeater.getScriptIdFromElementId(eventInfo.srcElement);
  3252. itemId = $ax.repeater.getItemIdFromElementId(eventInfo.srcElement);
  3253. var repeaterId = $ax.getParentRepeaterFromScriptId(scriptId);
  3254. if(add) $ax.repeater.addEditItems(repeaterId, [itemId]);
  3255. else $ax.repeater.removeEditItems(repeaterId, [itemId]);
  3256. } else if(data.addType == 'all') {
  3257. var allItems = $ax.repeater.getAllItemIds(id);
  3258. if(add) $ax.repeater.addEditItems(id, allItems);
  3259. else $ax.repeater.removeEditItems(id, allItems);
  3260. } else {
  3261. var oldTarget = eventInfo.targetElement;
  3262. var itemIds = $ax.repeater.getAllItemIds(id);
  3263. var itemIdsToAdd = [];
  3264. for(var j = 0; j < itemIds.length; j++) {
  3265. itemId = itemIds[j];
  3266. eventInfo.targetElement = $ax.repeater.createElementId(id, itemId);
  3267. if($ax.expr.evaluateExpr(data.query, eventInfo) == "true") {
  3268. itemIdsToAdd[itemIdsToAdd.length] = String(itemId);
  3269. }
  3270. eventInfo.targetElement = oldTarget;
  3271. }
  3272. if(add) $ax.repeater.addEditItems(id, itemIdsToAdd);
  3273. else $ax.repeater.removeEditItems(id, itemIdsToAdd);
  3274. }
  3275. }
  3276. _dispatchAction(eventInfo, actions, index + 1);
  3277. };
  3278. _action.repeaterInfoNames = { addItemsToDataSet: 'dataSetsToAddTo', deleteItemsFromDataSet: 'dataSetItemsToRemove', updateItemsInDataSet: 'dataSetsToUpdate',
  3279. addFilterToRepeater: 'repeatersToAddFilter', removeFilterFromRepeater: 'repeatersToRemoveFilter',
  3280. addSortToRepeater: 'repeaterToAddSort', removeSortFromRepeater: 'repeaterToRemoveSort',
  3281. setRepeaterToPage: 'repeatersToSetPage', setItemsPerRepeaterPage: 'repeatersToSetItemCount'
  3282. };
  3283. _actionHandlers.addItemsToDataSet = function(eventInfo, actions, index) {
  3284. var action = actions[index];
  3285. for(var i = 0; i < action.dataSetsToAddTo.length; i++) {
  3286. var datasetInfo = action.dataSetsToAddTo[i];
  3287. // Grab the first one because repeaters must have only element id, as they cannot be inside repeaters
  3288. // or none if unplaced
  3289. var id = $ax.getElementIdsFromPath(datasetInfo.path, eventInfo)[0];
  3290. if(!id || _ignoreAction(id)) continue;
  3291. var dataset = datasetInfo.data;
  3292. for(var j = 0; j < dataset.length; j++) $ax.repeater.addItem(id, $ax.deepCopy(dataset[j]), eventInfo);
  3293. if(dataset.length) _addRefresh(id);
  3294. }
  3295. _dispatchAction(eventInfo, actions, index + 1);
  3296. };
  3297. _actionHandlers.deleteItemsFromDataSet = function(eventInfo, actions, index) {
  3298. var action = actions[index];
  3299. for(var i = 0; i < action.dataSetItemsToRemove.length; i++) {
  3300. // Grab the first one because repeaters must have only element id, as they cannot be inside repeaters
  3301. // or none if unplaced
  3302. var deleteInfo = action.dataSetItemsToRemove[i];
  3303. var id = $ax.getElementIdsFromPath(deleteInfo.path, eventInfo)[0];
  3304. if(!id || _ignoreAction(id)) continue;
  3305. $ax.repeater.deleteItems(id, eventInfo, deleteInfo.type, deleteInfo.rule);
  3306. _addRefresh(id);
  3307. }
  3308. _dispatchAction(eventInfo, actions, index + 1);
  3309. };
  3310. _actionHandlers.updateItemsInDataSet = function(eventInfo, actions, index) {
  3311. var action = actions[index];
  3312. for(var i = 0; i < action.dataSetsToUpdate.length; i++) {
  3313. var dataSet = action.dataSetsToUpdate[i];
  3314. // Grab the first one because repeaters must have only element id, as they cannot be inside repeaters
  3315. // or none if unplaced
  3316. var id = $ax.getElementIdsFromPath(dataSet.path, eventInfo)[0];
  3317. if(!id || _ignoreAction(id)) continue;
  3318. $ax.repeater.updateEditItems(id, dataSet.props, eventInfo, dataSet.type, dataSet.rule);
  3319. _addRefresh(id);
  3320. }
  3321. _dispatchAction(eventInfo, actions, index + 1);
  3322. };
  3323. _actionHandlers.setRepeaterToDataSet = function(eventInfo, actions, index) {
  3324. var action = actions[index];
  3325. for(var i = 0; i < action.repeatersToSet.length; i++) {
  3326. var setRepeaterInfo = action.repeatersToSet[i];
  3327. // Grab the first one because repeaters must have only element id, as they cannot be inside repeaters
  3328. // or none if unplaced
  3329. var id = $ax.getElementIdsFromPath(setRepeaterInfo.path, eventInfo)[0];
  3330. if(!id) continue;
  3331. $ax.repeater.setDataSet(id, setRepeaterInfo.localDataSetId);
  3332. }
  3333. _dispatchAction(eventInfo, actions, index + 1);
  3334. };
  3335. _actionHandlers.addFilterToRepeater = function(eventInfo, actions, index) {
  3336. var action = actions[index];
  3337. for(var i = 0; i < action.repeatersToAddFilter.length; i++) {
  3338. var addFilterInfo = action.repeatersToAddFilter[i];
  3339. // Grab the first one because repeaters must have only element id, as they cannot be inside repeaters
  3340. // or none if unplaced
  3341. var id = $ax.getElementIdsFromPath(addFilterInfo.path, eventInfo)[0];
  3342. if(!id || _ignoreAction(id)) continue;
  3343. $ax.repeater.addFilter(id, addFilterInfo.removeOtherFilters, addFilterInfo.label, addFilterInfo.filter, eventInfo.srcElement);
  3344. _addRefresh(id);
  3345. }
  3346. _dispatchAction(eventInfo, actions, index + 1);
  3347. };
  3348. _actionHandlers.removeFilterFromRepeater = function(eventInfo, actions, index) {
  3349. var action = actions[index];
  3350. for(var i = 0; i < action.repeatersToRemoveFilter.length; i++) {
  3351. var removeFilterInfo = action.repeatersToRemoveFilter[i];
  3352. // Grab the first one because repeaters must have only element id, as they cannot be inside repeaters
  3353. // or none if unplaced
  3354. var id = $ax.getElementIdsFromPath(removeFilterInfo.path, eventInfo)[0];
  3355. if(!id || _ignoreAction(id)) continue;
  3356. if(removeFilterInfo.removeAll) $ax.repeater.removeFilter(id);
  3357. else if(removeFilterInfo.filterName != '') {
  3358. $ax.repeater.removeFilter(id, removeFilterInfo.filterName);
  3359. }
  3360. _addRefresh(id);
  3361. }
  3362. _dispatchAction(eventInfo, actions, index + 1);
  3363. };
  3364. _actionHandlers.addSortToRepeater = function(eventInfo, actions, index) {
  3365. var action = actions[index];
  3366. for(var i = 0; i < action.repeatersToAddSort.length; i++) {
  3367. var addSortInfo = action.repeatersToAddSort[i];
  3368. // Grab the first one because repeaters must have only element id, as they cannot be inside repeaters
  3369. // or none if unplaced
  3370. var id = $ax.getElementIdsFromPath(addSortInfo.path, eventInfo)[0];
  3371. if(!id || _ignoreAction(id)) continue;
  3372. $ax.repeater.addSort(id, addSortInfo.label, addSortInfo.columnName, addSortInfo.ascending, addSortInfo.toggle, addSortInfo.sortType);
  3373. _addRefresh(id);
  3374. }
  3375. _dispatchAction(eventInfo, actions, index + 1);
  3376. };
  3377. _actionHandlers.removeSortFromRepeater = function(eventInfo, actions, index) {
  3378. var action = actions[index];
  3379. for(var i = 0; i < action.repeatersToRemoveSort.length; i++) {
  3380. var removeSortInfo = action.repeatersToRemoveSort[i];
  3381. // Grab the first one because repeaters must have only element id, as they cannot be inside repeaters
  3382. // or none if unplaced
  3383. var id = $ax.getElementIdsFromPath(removeSortInfo.path, eventInfo)[0];
  3384. if(!id || _ignoreAction(id)) continue;
  3385. if(removeSortInfo.removeAll) $ax.repeater.removeSort(id);
  3386. else if(removeSortInfo.sortName != '') $ax.repeater.removeSort(id, removeSortInfo.sortName);
  3387. _addRefresh(id);
  3388. }
  3389. _dispatchAction(eventInfo, actions, index + 1);
  3390. };
  3391. _actionHandlers.setRepeaterToPage = function(eventInfo, actions, index) {
  3392. var action = actions[index];
  3393. for(var i = 0; i < action.repeatersToSetPage.length; i++) {
  3394. var setPageInfo = action.repeatersToSetPage[i];
  3395. // Grab the first one because repeaters must have only element id, as they cannot be inside repeaters
  3396. // or none if unplaced
  3397. var id = $ax.getElementIdsFromPath(setPageInfo.path, eventInfo)[0];
  3398. if(!id || _ignoreAction(id)) continue;
  3399. var oldTarget = eventInfo.targetElement;
  3400. eventInfo.targetElement = id;
  3401. $ax.repeater.setRepeaterToPage(id, setPageInfo.pageType, setPageInfo.pageValue, eventInfo);
  3402. eventInfo.targetElement = oldTarget;
  3403. _addRefresh(id);
  3404. }
  3405. _dispatchAction(eventInfo, actions, index + 1);
  3406. };
  3407. _actionHandlers.setItemsPerRepeaterPage = function(eventInfo, actions, index) {
  3408. var action = actions[index];
  3409. for(var i = 0; i < action.repeatersToSetItemCount.length; i++) {
  3410. var setItemCountInfo = action.repeatersToSetItemCount[i];
  3411. // Grab the first one because repeaters must have only element id, as they cannot be inside repeaters
  3412. // or none if unplaced
  3413. var id = $ax.getElementIdsFromPath(setItemCountInfo.path, eventInfo)[0];
  3414. if(!id || _ignoreAction(id)) continue;
  3415. if(setItemCountInfo.noLimit) $ax.repeater.setNoItemLimit(id);
  3416. else $ax.repeater.setItemLimit(id, setItemCountInfo.itemCountValue, eventInfo);
  3417. _addRefresh(id);
  3418. }
  3419. _dispatchAction(eventInfo, actions, index + 1);
  3420. };
  3421. _actionHandlers.refreshRepeater = function(eventInfo, actions, index) {
  3422. // We use this as a psudo action now.
  3423. var action = actions[index];
  3424. for (var i = 0; i < action.repeatersToRefresh.length; i++) {
  3425. // Grab the first one because repeaters must have only element id, as they cannot be inside repeaters
  3426. // or none if unplaced
  3427. var id = $ax.getElementIdsFromPath(action.repeatersToRefresh[i], eventInfo)[0];
  3428. if(id) _tryRefreshRepeater(id, eventInfo);
  3429. }
  3430. _dispatchAction(eventInfo, actions, index + 1);
  3431. };
  3432. var _tryRefreshRepeater = function(id, eventInfo) {
  3433. var idIndex = _repeatersToRefresh.indexOf(id);
  3434. if(idIndex == -1) return;
  3435. $ax.splice(_repeatersToRefresh, idIndex, 1);
  3436. $ax.repeater.refreshRepeater(id, eventInfo);
  3437. };
  3438. _action.tryRefreshRepeaters = function(ids, eventInfo) {
  3439. for(var i = 0; i < ids.length; i++) _tryRefreshRepeater(ids[i], eventInfo);
  3440. };
  3441. _actionHandlers.scrollToWidget = function(eventInfo, actions, index) {
  3442. var action = actions[index];
  3443. var elementIds = $ax.getElementIdsFromPath(action.objectPath, eventInfo);
  3444. if(elementIds.length > 0) $ax('#' + elementIds[0]).scroll(action.options);
  3445. _dispatchAction(eventInfo, actions, index + 1);
  3446. };
  3447. _actionHandlers.enableDisableWidgets = function(eventInfo, actions, index) {
  3448. var action = actions[index];
  3449. for(var i = 0; i < action.pathToInfo.length; i++) {
  3450. var elementIds = $ax.getElementIdsFromPath(action.pathToInfo[i].objectPath, eventInfo);
  3451. var enable = action.pathToInfo[i].enableDisableInfo.enable;
  3452. for(var j = 0; j < elementIds.length; j++) $ax('#' + elementIds[j]).enabled(enable);
  3453. }
  3454. _dispatchAction(eventInfo, actions, index + 1);
  3455. };
  3456. _actionHandlers.setImage = function(eventInfo, actions, index) {
  3457. var oldTarget = eventInfo.targetElement;
  3458. var action = actions[index];
  3459. var view = $ax.adaptive.currentViewId;
  3460. eventInfo.image = true;
  3461. for(var i = 0; i < action.imagesToSet.length; i++) {
  3462. var imgInfo = action.imagesToSet[i];
  3463. imgInfo = view ? imgInfo.adaptive[view] : imgInfo.base;
  3464. var elementIds = $ax.getElementIdsFromPath(action.imagesToSet[i].objectPath, eventInfo);
  3465. for(var j = 0; j < elementIds.length; j++) {
  3466. var elementId = elementIds[j];
  3467. eventInfo.targetElement = elementId;
  3468. var evaluatedImgs = _evaluateImages(imgInfo, eventInfo);
  3469. var img = evaluatedImgs.normal;
  3470. if($ax.style.IsWidgetDisabled(elementId)) {
  3471. if(imgInfo.disabled) img = evaluatedImgs.disabled;
  3472. } else if($ax.style.IsWidgetSelected(elementId)) {
  3473. if(imgInfo.selected) img = evaluatedImgs.selected;
  3474. } else if($ax.event.mouseDownObjectId == elementId && imgInfo.mouseDown) img = evaluatedImgs.mouseDown;
  3475. else if($ax.event.mouseOverIds.indexOf(elementId) != -1 && imgInfo.mouseOver) {
  3476. img = evaluatedImgs.mouseOver;
  3477. //Update mouseOverObjectId
  3478. var currIndex = $ax.event.mouseOverIds.indexOf($ax.event.mouseOverObjectId);
  3479. var imgIndex = $ax.event.mouseOverIds.indexOf(elementId);
  3480. if(currIndex < imgIndex) $ax.event.mouseOverObjectId = elementId;
  3481. } else if(imgInfo.mouseOver && elementId == eventInfo.srcElement) {
  3482. img = evaluatedImgs.mouseOver;
  3483. }
  3484. // $('#' + $ax.repeater.applySuffixToElementId(elementId, '_img')).attr('src', img);
  3485. $jobj($ax.style.GetImageIdFromShape(elementId)).attr('src', img);
  3486. //Set up overrides
  3487. $ax.style.mapElementIdToImageOverrides(elementId, evaluatedImgs);
  3488. $ax.style.updateElementIdImageStyle(elementId);
  3489. if(evaluatedImgs.mouseOver || evaluatedImgs.mouseDown) $ax.event.updateIxStyleEvents(elementId);
  3490. }
  3491. }
  3492. eventInfo.targetElement = oldTarget;
  3493. eventInfo.image = false;
  3494. _dispatchAction(eventInfo, actions, index + 1);
  3495. };
  3496. var _evaluateImages = function(imgInfo, eventInfo) {
  3497. var retVal = {};
  3498. for(var state in imgInfo) {
  3499. if(!imgInfo.hasOwnProperty(state)) continue;
  3500. var img = imgInfo[state][$ax.adaptive.getSketchKey()] || $ax.expr.evaluateExpr(imgInfo[state].literal, eventInfo);
  3501. if(!img) img = $axure.utils.getTransparentGifPath();
  3502. retVal[state] = img;
  3503. }
  3504. return retVal;
  3505. };
  3506. $ax.clearRepeaterImageOverrides = function(repeaterId) {
  3507. var childIds = $ax.getChildElementIdsForRepeater(repeaterId);
  3508. for(var i = childIds; i < childIds.length; i++) $ax.style.deleteElementIdToImageOverride(childIds[i]);
  3509. };
  3510. _actionHandlers.setFocusOnWidget = function(eventInfo, actions, index) {
  3511. var action = actions[index];
  3512. if(action.objectPaths.length > 0) {
  3513. var elementIds = $ax.getElementIdsFromPath(action.objectPaths[0], eventInfo);
  3514. if(elementIds.length > 0) {
  3515. $ax('#' + elementIds[0]).focus();
  3516. //if select text and not in placeholder mode, then select all text
  3517. if(action.selectText && !$ax.placeholderManager.isActive(elementIds[0])) {
  3518. var elementChildren = document.getElementById(elementIds[0]).children;
  3519. //find the input or textarea element
  3520. for(var i = 0; i < elementChildren.length; i++) {
  3521. if (elementChildren[i].id.indexOf('_input') == -1) continue;
  3522. var elementTagName = elementChildren[i].tagName;
  3523. if(elementTagName && (elementTagName.toLowerCase() == "input" || elementTagName.toLowerCase() == "textarea")) {
  3524. elementChildren[i].select();
  3525. }
  3526. }
  3527. }
  3528. }
  3529. }
  3530. _dispatchAction(eventInfo, actions, index + 1);
  3531. };
  3532. _actionHandlers.expandCollapseTree = function(eventInfo, actions, index) {
  3533. var action = actions[index];
  3534. for(var i = 0; i < action.pathToInfo.length; i++) {
  3535. var pair = action.pathToInfo[i];
  3536. var elementIds = $ax.getElementIdsFromPath(pair.treeNodePath, eventInfo);
  3537. for(var j = 0; j < elementIds.length; j++) $ax('#' + elementIds[j]).expanded(pair.expandCollapseInfo.expand);
  3538. }
  3539. _dispatchAction(eventInfo, actions, index + 1);
  3540. };
  3541. _actionHandlers.other = function(eventInfo, actions, index) {
  3542. var action = actions[index];
  3543. $ax.navigate({
  3544. url: $axure.utils.getOtherPath() + "#other=" + encodeURI(action.otherDescription),
  3545. target: "popup",
  3546. includeVariables: false,
  3547. popupOptions: action.popup
  3548. });
  3549. _dispatchAction(eventInfo, actions, index + 1);
  3550. };
  3551. _actionHandlers.fireEvents = function(eventInfo, actions, index) {
  3552. var action = actions[index];
  3553. //look for the nearest element id
  3554. var objId = eventInfo.srcElement;
  3555. var thisWidget = eventInfo.thiswidget;
  3556. var obj = $ax.getObjectFromElementId(objId);
  3557. var rdoId = obj ? $ax.getRdoParentFromElementId(objId) : "";
  3558. var rdo = $ax.getObjectFromElementId(rdoId);
  3559. var page = rdo ? $ax.pageData.masters[rdo.masterId] : $ax.pageData.page;
  3560. // Check if rdo should be this
  3561. var oldIsMasterEvent = eventInfo.isMasterEvent;
  3562. if (obj && $ax.public.fn.IsReferenceDiagramObject(obj.type) && eventInfo.isMasterEvent) {
  3563. rdoId = objId;
  3564. rdo = obj;
  3565. page = $ax.pageData.masters[rdo.masterId];
  3566. }
  3567. for(var i = 0; i < action.firedEvents.length; i++) {
  3568. var firedEvent = action.firedEvents[i];
  3569. var isPage = firedEvent.objectPath.length == 0;
  3570. var targetObjIds = isPage ? [rdoId] : $ax.getElementIdsFromPath(firedEvent.objectPath, eventInfo);
  3571. for (var j = 0; j < targetObjIds.length; j++) {
  3572. var targetObjId = targetObjIds[j];
  3573. var targetObj = isPage ? rdo : $ax.getObjectFromElementId(targetObjId);
  3574. eventInfo.srcElement = targetObjId || '';
  3575. eventInfo.thiswidget = $ax.getWidgetInfo(eventInfo.srcElement);
  3576. eventInfo.isMasterEvent = false;
  3577. var raisedEvents = firedEvent.raisedEventIds;
  3578. if(raisedEvents) {
  3579. for(var k = 0; k < raisedEvents.length; k++) {
  3580. var event = targetObj.interactionMap && targetObj.interactionMap.raised && targetObj.interactionMap.raised[raisedEvents[k]];
  3581. if(event) $ax.event.handleEvent(targetObjId, eventInfo, event, false, true);
  3582. }
  3583. }
  3584. if(isPage) {
  3585. eventInfo.isMasterEvent = true;
  3586. eventInfo.label = $ax.pageData.page.name;
  3587. eventInfo.friendlyType = 'Page';
  3588. }
  3589. var firedTarget = isPage ? page : targetObj;
  3590. var firedEventNames = firedEvent.firedEventNames;
  3591. if(firedEventNames) {
  3592. for(k = 0; k < firedEventNames.length; k++) {
  3593. event = firedTarget.interactionMap && firedTarget.interactionMap[firedEventNames[k]];
  3594. if(event) $ax.event.handleEvent(isPage ? '' : targetObjId, eventInfo, event, false, true);
  3595. }
  3596. }
  3597. if(isPage) eventInfo.isMasterEvent = oldIsMasterEvent;
  3598. }
  3599. eventInfo.srcElement = objId;
  3600. eventInfo.thiswidget = thisWidget;
  3601. eventInfo.isMasterEvent = oldIsMasterEvent;
  3602. }
  3603. _dispatchAction(eventInfo, actions, index + 1);
  3604. };
  3605. });
  3606. //***** expr.js *****//
  3607. // ******* Expr MANAGER ******** //
  3608. $axure.internal(function($ax) {
  3609. var _expr = $ax.expr = {};
  3610. var _binOpHandlers = {
  3611. '&&': function(left, right) { return _binOpOverride(left, right, function(left) { return $ax.getBool(left) && $ax.getBool(right()); }); },
  3612. '||': function(left, right) { return _binOpOverride(left, right, function(left) { return $ax.getBool(left) || $ax.getBool(right()); }); },
  3613. '==': function(left, right) { return isEqual(left, right, true); },
  3614. '!=': function(left, right) { return !isEqual(left, right, true); },
  3615. '>': function(left, right) { return _binOpNum(left, right, function(left, right) { return left > right; }); },
  3616. '<': function(left, right) { return _binOpNum(left, right, function(left, right) { return left < right; }); },
  3617. '>=': function(left, right) { return _binOpNum(left, right, function(left, right) { return left >= right; }); },
  3618. '<=': function(left, right) { return _binOpNum(left, right, function(left, right) { return left <= right; }); }
  3619. };
  3620. var checkOps = function(left, right) {
  3621. return left == undefined || right == undefined;
  3622. };
  3623. var isEqual = function (left, right, isFunction) {
  3624. if (isFunction) {
  3625. //if left and right is function, then get the value
  3626. //otherwise left and right should be already the value we want
  3627. left = left();
  3628. right = right();
  3629. }
  3630. if(checkOps(left, right)) return false;
  3631. if(left instanceof Date && right instanceof Date) {
  3632. if(left.getMilliseconds() != right.getMilliseconds()) return false;
  3633. if(left.getSeconds() != right.getSeconds()) return false;
  3634. if(left.getMinutes() != right.getMinutes()) return false;
  3635. if(left.getHours() != right.getHours()) return false;
  3636. if(left.getDate() != right.getDate()) return false;
  3637. if(left.getMonth() != right.getMonth()) return false;
  3638. if(left.getYear() != right.getYear()) return false;
  3639. return true;
  3640. }
  3641. if(left instanceof Object && right instanceof Object) {
  3642. var prop;
  3643. // Go through all of lefts properties and compare them to rights.
  3644. for(prop in left) {
  3645. if(!left.hasOwnProperty(prop)) continue;
  3646. // If left has a property that the right doesn't they are not equal.
  3647. if(!right.hasOwnProperty(prop)) return false;
  3648. // If any of their properties are not equal, they are not equal.
  3649. if(!isEqual(left[prop], right[prop], false)) return false;
  3650. }
  3651. for(prop in right) {
  3652. // final check to make sure right doesn't have some extra properties that make them not equal.
  3653. if(left.hasOwnProperty(prop) != right.hasOwnProperty(prop)) return false;
  3654. }
  3655. return true;
  3656. }
  3657. return $ax.getBool(left) == $ax.getBool(right);
  3658. };
  3659. var _binOpOverride = function(left, right, func) {
  3660. left = left();
  3661. if(left == undefined) return false;
  3662. var res = func(left, right);
  3663. return res == undefined ? false : res;
  3664. };
  3665. var _binOpNum = function(left, right, func) {
  3666. var left = left();
  3667. var right = right();
  3668. if(checkOps(left, right)) return false;
  3669. return func(left, Number(right));
  3670. };
  3671. var _exprHandlers = {};
  3672. _exprHandlers.array = function(expr, eventInfo) {
  3673. var returnVal = [];
  3674. for(var i = 0; i < expr.items.length; i++) {
  3675. returnVal[returnVal.length] = _evaluateExpr(expr.items[i], eventInfo);
  3676. }
  3677. return returnVal;
  3678. };
  3679. _exprHandlers.binaryOp = function(expr, eventInfo) {
  3680. var left = function() { return expr.leftExpr && _evaluateExpr(expr.leftExpr, eventInfo); };
  3681. var right = function() { return expr.rightExpr && _evaluateExpr(expr.rightExpr, eventInfo); };
  3682. if(left == undefined || right == undefined) return false;
  3683. return _binOpHandlers[expr.op](left, right);
  3684. };
  3685. _exprHandlers.block = function(expr, eventInfo) {
  3686. var subExprs = expr.subExprs;
  3687. for(var i = 0; i < subExprs.length; i++) {
  3688. _evaluateExpr(subExprs[i], eventInfo); //ignore the result
  3689. }
  3690. };
  3691. _exprHandlers.booleanLiteral = function(expr) {
  3692. return expr.value;
  3693. };
  3694. _exprHandlers.nullLiteral = function() { return null; };
  3695. _exprHandlers.pathLiteral = function(expr, eventInfo) {
  3696. if(expr.isThis) return [eventInfo.srcElement];
  3697. if(expr.isFocused && window.lastFocusedControl) {
  3698. $ax('#' + window.lastFocusedControl).focus();
  3699. return [window.lastFocusedControl];
  3700. }
  3701. if(expr.isTarget) return [eventInfo.targetElement];
  3702. return $ax.getElementIdsFromPath(expr.value, eventInfo);
  3703. };
  3704. _exprHandlers.panelDiagramLiteral = function(expr, eventInfo) {
  3705. var elementIds = $ax.getElementIdsFromPath(expr.panelPath, eventInfo);
  3706. var elementIdsWithSuffix = [];
  3707. var suffix = '_state' + expr.panelIndex;
  3708. for(var i = 0; i < elementIds.length; i++) {
  3709. elementIdsWithSuffix[i] = $ax.repeater.applySuffixToElementId(elementIds[i], suffix);
  3710. }
  3711. return String($jobj(elementIdsWithSuffix).data('label'));
  3712. };
  3713. _exprHandlers.fcall = function(expr, eventInfo) {
  3714. var oldTarget = eventInfo.targetElement;
  3715. var targets = [];
  3716. var fcallArgs = [];
  3717. var exprArgs = expr.arguments;
  3718. for(var i = 0; i < expr.arguments.length; i++) {
  3719. var exprArg = exprArgs[i];
  3720. var fcallArg = '';
  3721. if(targets.length) {
  3722. for(var j = 0; j < targets.length; j++) {
  3723. if(exprArg == null) {
  3724. fcallArgs[j][i] = null;
  3725. continue;
  3726. }
  3727. eventInfo.targetElement = targets[j];
  3728. fcallArg = _evaluateExpr(exprArg, eventInfo);
  3729. if(typeof (fcallArg) == 'undefined') return '';
  3730. fcallArgs[j][i] = fcallArg;
  3731. }
  3732. } else {
  3733. if(exprArg == null) {
  3734. fcallArgs[i] = null;
  3735. continue;
  3736. }
  3737. fcallArg = _evaluateExpr(exprArg, eventInfo);
  3738. if(typeof (fcallArg) == 'undefined') return '';
  3739. fcallArgs[i] = fcallArg;
  3740. }
  3741. // We do support null exprArgs...
  3742. // 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
  3743. if(exprArg && exprArg.exprType == 'pathLiteral') {
  3744. targets = fcallArg;
  3745. // fcallArgs is now an array of an array of args
  3746. for(j = 0; j < targets.length; j++) fcallArgs[j] = [[fcallArg[j]]];
  3747. }
  3748. }
  3749. // we want to preserve the target element from outside this function.
  3750. eventInfo.targetElement = oldTarget;
  3751. var retval = '';
  3752. if(targets.length) {
  3753. // Go backwards so retval is the first item.
  3754. for(i = targets.length - 1; i >= 0; i--) {
  3755. var args = fcallArgs[i];
  3756. // Add event info to the end
  3757. args[args.length] = eventInfo;
  3758. retval = _exprFunctions[expr.functionName].apply(this, args);
  3759. }
  3760. } else fcallArgs[fcallArgs.length] = eventInfo;
  3761. return targets.length ? retval : _exprFunctions[expr.functionName].apply(this, fcallArgs);
  3762. };
  3763. _exprHandlers.globalVariableLiteral = function(expr) {
  3764. return expr.variableName;
  3765. };
  3766. _exprHandlers.keyPressLiteral = function(expr) {
  3767. var keyInfo = {};
  3768. keyInfo.keyCode = expr.keyCode;
  3769. keyInfo.ctrl = expr.ctrl;
  3770. keyInfo.alt = expr.alt;
  3771. keyInfo.shift = expr.shift;
  3772. return keyInfo;
  3773. };
  3774. _exprHandlers.adaptiveViewLiteral = function(expr) {
  3775. return expr.id;
  3776. };
  3777. _exprHandlers.optionLiteral = function(expr) {
  3778. return expr.value;
  3779. }
  3780. var _substituteSTOs = function(expr, eventInfo) {
  3781. //first evaluate the local variables
  3782. var scope = {};
  3783. for(var varName in expr.localVariables) {
  3784. scope[varName] = $ax.expr.evaluateExpr(expr.localVariables[varName], eventInfo);
  3785. }
  3786. // TODO: [ben] Date and data object (obj with info for url or image) both need to return non-strings.
  3787. var i = 0;
  3788. var retval;
  3789. var retvalString = expr.value.replace(/\[\[(?!\[)(.*?)\]\](?=\]*)/g, function(match) {
  3790. var sto = expr.stos[i++];
  3791. if(sto.sto == 'error') return match;
  3792. try {
  3793. var result = $ax.evaluateSTO(sto, scope, eventInfo);
  3794. } catch(e) {
  3795. return match;
  3796. }
  3797. if((result instanceof Object) && i == 1 && expr.value.substring(0, 2) == '[[' &&
  3798. expr.value.substring(expr.value.length - 2) == ']]') {
  3799. // If the result was an object, this was the first result, and the whole thing was this expresion.
  3800. retval = result;
  3801. }
  3802. return ((result instanceof Object) && (result.label || result.text)) || result;
  3803. });
  3804. // If more than one group returned, the object is not valid
  3805. if(i != 1) retval = false;
  3806. return retval || retvalString;
  3807. };
  3808. _exprHandlers.htmlLiteral = function (expr, eventInfo) {
  3809. eventInfo.htmlLiteral = true;
  3810. var html = _substituteSTOs(expr, eventInfo);
  3811. eventInfo.htmlLiteral = false
  3812. return html;
  3813. };
  3814. _exprHandlers.stringLiteral = function(expr, eventInfo) {
  3815. return _substituteSTOs(expr, eventInfo);
  3816. };
  3817. var _exprFunctions = {};
  3818. _exprFunctions.SetCheckState = function(elementIds, value) {
  3819. var toggle = value == 'toggle';
  3820. var boolValue = Boolean(value) && value != 'false';
  3821. for(var i = 0; i < elementIds.length; i++) {
  3822. var query = $ax('#' + elementIds[i]);
  3823. query.selected(toggle ? !query.selected() : boolValue);
  3824. }
  3825. };
  3826. _exprFunctions.SetSelectedOption = function(elementIds, value) {
  3827. for(var i = 0; i < elementIds.length; i++) {
  3828. var elementId = elementIds[i];
  3829. var obj = $jobj($ax.INPUT(elementId));
  3830. if(obj.val() == value) return;
  3831. obj.val(value);
  3832. if($ax.event.HasSelectionChanged($ax.getObjectFromElementId(elementId))) $ax.event.raiseSyntheticEvent(elementId, 'onSelectionChange');
  3833. }
  3834. };
  3835. _exprFunctions.SetGlobalVariableValue = function(varName, value) {
  3836. $ax.globalVariableProvider.setVariableValue(varName, value);
  3837. };
  3838. _exprFunctions.SetWidgetFormText = function(elementIds, value) {
  3839. for(var i = 0; i < elementIds.length; i++) {
  3840. var elementId = elementIds[i];
  3841. var inputId = $ax.repeater.applySuffixToElementId(elementId, '_input');
  3842. var obj = $jobj(inputId);
  3843. if(obj.val() == value || (value == '' && $ax.placeholderManager.isActive(elementId))) return;
  3844. obj.val(value);
  3845. $ax.placeholderManager.updatePlaceholder(elementId, !value);
  3846. if($ax.event.HasTextChanged($ax.getObjectFromElementId(elementId))) $ax.event.TryFireTextChanged(elementId);
  3847. }
  3848. };
  3849. _exprFunctions.SetFocusedWidgetText = function(elementId, value) {
  3850. if(window.lastFocusedControl) {
  3851. var elementId = window.lastFocusedControl;
  3852. var type = $obj(elementId).type;
  3853. if ($ax.public.fn.IsTextBox(type) || $ax.public.fn.IsTextArea(type)) _exprFunctions.SetWidgetFormText([elementId], value);
  3854. else _exprFunctions.SetWidgetRichText([elementId], value, true);
  3855. }
  3856. };
  3857. _exprFunctions.GetRtfElementHeight = function(rtfElement) {
  3858. if(rtfElement.innerHTML == '') rtfElement.innerHTML = '&nbsp;';
  3859. return rtfElement.offsetHeight;
  3860. };
  3861. _exprFunctions.SetWidgetRichText = function(ids, value, plain) {
  3862. // Converts dates, widgetinfo, and the like to strings.
  3863. value = _exprFunctions.ToString(value);
  3864. //Replace any newlines with line breaks
  3865. var finalValue = value.replace(/\r\n/g, '<br>').replace(/\n/g, '<br>');
  3866. for(var i = 0; i < ids.length; i++) {
  3867. var id = ids[i];
  3868. // If calling this on button shape, get the id of the rich text panel inside instead
  3869. var type = $obj(id).type;
  3870. if(type != 'richTextPanel' && type != 'hyperlink') {
  3871. id = $jobj(id).find('.text')[0].id;
  3872. }
  3873. var element = window.document.getElementById(id);
  3874. $ax.visibility.SetVisible(element, value != '');
  3875. $ax.style.transformTextWithVerticalAlignment(id, function() {
  3876. var spans = $jobj(id).find('span');
  3877. if(plain) {
  3878. // Wrap in span and p, style them accordingly.
  3879. var span = $('<span></span>');
  3880. if(spans.length > 0) {
  3881. span.attr('style', $(spans[0]).attr('style'));
  3882. span.attr('id', $(spans[0]).attr('id'));
  3883. }
  3884. // Can't set value as text because '<br/>' doesn't actually do a line break
  3885. // Can't set vaule as html because it doesn't like '<' and ignores all after it
  3886. // Create tags yourself
  3887. var lines = value.split(/\r\n|\n/);
  3888. if(lines.length == 1) span.text(value);
  3889. else {
  3890. for(var i = 0; i < lines.length; i++) {
  3891. if (i != 0) span.append($('<br />'));
  3892. var line = lines[i];
  3893. if(line.length == 0) continue;
  3894. var subSpan = $('<span />');
  3895. subSpan.text(line);
  3896. span.append(subSpan);
  3897. }
  3898. }
  3899. var p = $('<p></p>');
  3900. var ps = $jobj(id).find('p');
  3901. if(ps.length > 0) {
  3902. p.attr('style', $(ps[0]).attr('style'));
  3903. p.attr('id', $(ps[0]).attr('id'));
  3904. }
  3905. p.append(span);
  3906. finalValue = $('<div></div>').append(p).html();
  3907. }
  3908. element.innerHTML = finalValue;
  3909. });
  3910. if(!plain) $ax.style.CacheOriginalText(id, true);
  3911. }
  3912. };
  3913. _exprFunctions.GetCheckState = function(ids) {
  3914. return $ax('#' + ids[0]).selected();
  3915. };
  3916. _exprFunctions.GetSelectedOption = function (ids) {
  3917. var inputs = $jobj($ax.INPUT(ids[0]));
  3918. return inputs.length ? inputs[0].value : '';
  3919. };
  3920. _exprFunctions.GetNum = function(str) {
  3921. //Setting a GlobalVariable to some blank text then setting a widget to the value of that variable would result in 0 not ""
  3922. //I have fixed this another way so commenting this should be fine now
  3923. //if (!str) return "";
  3924. return isNaN(str) ? str : Number(str);
  3925. };
  3926. _exprFunctions.GetGlobalVariableValue = function(id) {
  3927. return $ax.globalVariableProvider.getVariableValue(id);
  3928. };
  3929. _exprFunctions.GetGlobalVariableLength = function(id) {
  3930. return _exprFunctions.GetGlobalVariableValue(id).length;
  3931. };
  3932. _exprFunctions.GetWidgetText = function(ids) {
  3933. if($ax.placeholderManager.isActive(ids[0])) return '';
  3934. var input = $ax.INPUT(ids[0]);
  3935. return $ax('#' + ($jobj(input).length ? input : ids[0])).text();
  3936. };
  3937. _exprFunctions.GetFocusedWidgetText = function() {
  3938. if(window.lastFocusedControl) {
  3939. return $ax('#' + window.lastFocusedControl).text();
  3940. } else {
  3941. return "";
  3942. }
  3943. };
  3944. _exprFunctions.GetWidgetValueLength = function(ids) {
  3945. var id = ids[0];
  3946. if(!id) return undefined;
  3947. if($ax.placeholderManager.isActive(id)) return 0;
  3948. var obj = $jobj($ax.INPUT(id));
  3949. if(!obj.length) obj = $jobj(id);
  3950. var val = obj[0].value || _exprFunctions.GetWidgetText([id]);
  3951. return val.length;
  3952. };
  3953. _exprFunctions.GetPanelState = function(ids) {
  3954. var id = ids[0];
  3955. if(!id) return undefined;
  3956. var stateId = $ax.visibility.GetPanelState(id);
  3957. return stateId && String($jobj(stateId).data('label'));
  3958. };
  3959. _exprFunctions.GetWidgetVisibility = function(ids) {
  3960. var id = ids[0];
  3961. if(!id) return undefined;
  3962. return $ax.visibility.IsIdVisible(id);
  3963. };
  3964. // ***************** Validation Functions ***************** //
  3965. _exprFunctions.IsValueAlpha = function(val) {
  3966. var isAlphaRegex = new RegExp("^[a-z\\s]+$", "gi");
  3967. return isAlphaRegex.test(val);
  3968. };
  3969. _exprFunctions.IsValueNumeric = function(val) {
  3970. var isNumericRegex = new RegExp("^[0-9,\\.\\s]+$", "gi");
  3971. return isNumericRegex.test(val);
  3972. };
  3973. _exprFunctions.IsValueAlphaNumeric = function(val) {
  3974. var isAlphaNumericRegex = new RegExp("^[0-9a-z\\s]+$", "gi");
  3975. return isAlphaNumericRegex.test(val);
  3976. };
  3977. _exprFunctions.IsValueOneOf = function(val, values) {
  3978. for(var i = 0; i < values.length; i++) {
  3979. var option = values[i];
  3980. if(val == option) return true;
  3981. }
  3982. //by default, return false
  3983. return false;
  3984. };
  3985. _exprFunctions.IsValueNotAlpha = function(val) {
  3986. return !_exprFunctions.IsValueAlpha(val);
  3987. };
  3988. _exprFunctions.IsValueNotNumeric = function(val) {
  3989. return !_exprFunctions.IsValueNumeric(val);
  3990. };
  3991. _exprFunctions.IsValueNotAlphaNumeric = function(val) {
  3992. return !_exprFunctions.IsValueAlphaNumeric(val);
  3993. };
  3994. _exprFunctions.IsValueNotOneOf = function(val, values) {
  3995. return !_exprFunctions.IsValueOneOf(val, values);
  3996. };
  3997. _exprFunctions.GetKeyPressed = function(eventInfo) {
  3998. return eventInfo.keyInfo;
  3999. };
  4000. _exprFunctions.GetCursorRectangles = function() {
  4001. var rects = new Object();
  4002. rects.lastRect = new $ax.drag.Rectangle($ax.lastMouseLocation.x, $ax.lastMouseLocation.y, 1, 1);
  4003. rects.currentRect = new $ax.drag.Rectangle($ax.mouseLocation.x, $ax.mouseLocation.y, 1, 1);
  4004. return rects;
  4005. };
  4006. _exprFunctions.GetWidgetRectangles = function (elementIds, eventInfo) {
  4007. var elementId = elementIds[0];
  4008. var rects = new Object();
  4009. var jObj = $jobj(elementId);
  4010. var invalid = jObj.length == 0;
  4011. var parent = jObj;
  4012. // Or are in valid if no obj can be found, or if it is not visible.
  4013. while(parent.length != 0 && !parent.is('body')) {
  4014. if(parent.css('display') == 'none') {
  4015. invalid = true;
  4016. break;
  4017. }
  4018. parent = parent.parent();
  4019. }
  4020. if(invalid) {
  4021. rects.lastRect = rects.currentRect = new $ax.drag.Rectangle(-1, -1, -1, -1);
  4022. return rects;
  4023. }
  4024. var axObj = $ax('#' + elementId);
  4025. rects.lastRect = new $ax.drag.Rectangle(
  4026. axObj.left(),
  4027. axObj.top(),
  4028. axObj.width(),
  4029. axObj.height());
  4030. rects.currentRect = rects.lastRect;
  4031. return rects;
  4032. };
  4033. _exprFunctions.GetWidget = function(elementId) {
  4034. return $ax.getWidgetInfo(elementId[0]);
  4035. };
  4036. _exprFunctions.GetAdaptiveView = function() {
  4037. return $ax.adaptive.currentViewId || '';
  4038. };
  4039. _exprFunctions.IsEntering = function(movingRects, targetRects) {
  4040. return !movingRects.lastRect.IntersectsWith(targetRects.currentRect) && movingRects.currentRect.IntersectsWith(targetRects.currentRect);
  4041. };
  4042. _exprFunctions.IsLeaving = function(movingRects, targetRects) {
  4043. return movingRects.lastRect.IntersectsWith(targetRects.currentRect) && !movingRects.currentRect.IntersectsWith(targetRects.currentRect);
  4044. };
  4045. var _IsOver = _exprFunctions.IsOver = function(movingRects, targetRects) {
  4046. return movingRects.currentRect.IntersectsWith(targetRects.currentRect);
  4047. };
  4048. _exprFunctions.IsNotOver = function(movingRects, targetRects) {
  4049. return !_IsOver(movingRects, targetRects);
  4050. };
  4051. _exprFunctions.ValueContains = function(inputString, value) {
  4052. return inputString.indexOf(value) > -1;
  4053. };
  4054. _exprFunctions.ValueNotContains = function(inputString, value) {
  4055. return !_exprFunctions.ValueContains(inputString, value);
  4056. };
  4057. _exprFunctions.ToString = function(value) {
  4058. if(value.isWidget) {
  4059. return value.text;
  4060. }
  4061. return String(value);
  4062. };
  4063. var _evaluateExpr = $ax.expr.evaluateExpr = function(expr, eventInfo, toString) {
  4064. if(expr === undefined || expr === null) return undefined;
  4065. var result = _exprHandlers[expr.exprType](expr, eventInfo);
  4066. return toString ? _exprFunctions.ToString(result) : result;
  4067. };
  4068. });
  4069. //***** geometry.js *****//
  4070. // ******* Region MANAGER ******** //
  4071. $axure.internal(function($ax) {
  4072. var _geometry = $ax.geometry = {};
  4073. var regionMap = {};
  4074. var regionList = [];
  4075. var _unregister = function(label) {
  4076. var regionIndex = regionList.indexOf(label);
  4077. if(regionIndex != -1) {
  4078. var end = $ax.splice(regionList, regionIndex + 1);
  4079. $ax.splice(regionList, regionIndex, regionList.length - regionIndex);
  4080. regionList = regionList.concat(end);
  4081. }
  4082. delete regionMap[label];
  4083. };
  4084. _geometry.unregister = _unregister;
  4085. var clear = function() {
  4086. regionMap = {};
  4087. regionList = [];
  4088. };
  4089. var _polygonRegistered = function(label) {
  4090. return Boolean(regionMap[label]);
  4091. };
  4092. _geometry.polygonRegistered = _polygonRegistered;
  4093. // Must be counterclockwise, or enter/exit will be wrong
  4094. var _registerPolygon = function(label, points, callback, info) {
  4095. var regionIndex = regionList.indexOf(label);
  4096. if(regionIndex == -1) regionList.push(label);
  4097. regionMap[label] = { points: points, callback: callback, info: info };
  4098. };
  4099. _geometry.registerPolygon = _registerPolygon;
  4100. var _getPolygonInfo = function(label) {
  4101. if(!_polygonRegistered(label)) return undefined;
  4102. return regionMap[label].info;
  4103. };
  4104. _geometry.getPolygonInfo = _getPolygonInfo;
  4105. var _genRect = function(info, roundHalfPixel) {
  4106. var x = info.pagex;
  4107. var y = info.pagey;
  4108. var w = info.width;
  4109. var h = info.height;
  4110. if(roundHalfPixel) {
  4111. if(x % 1 != 0) {
  4112. x = Math.floor(x);
  4113. w++;
  4114. }
  4115. if(y % 1 != 0) {
  4116. y = Math.floor(y);
  4117. h++;
  4118. }
  4119. }
  4120. var r = x + w;
  4121. var b = y + h;
  4122. var rect = {
  4123. X: function() { return x; },
  4124. Y: function() { return y; },
  4125. Wigth: function() { return w; },
  4126. Height: function() { return h; },
  4127. Left: function() { return x; },
  4128. Right: function() { return r; },
  4129. Top: function() { return y; },
  4130. Bottom: function() { return b; }
  4131. };
  4132. return rect;
  4133. };
  4134. _geometry.genRect = _genRect;
  4135. var _genPoint = function(x, y) {
  4136. return { x: x, y: y };
  4137. };
  4138. _geometry.genPoint = _genPoint;
  4139. var oldPoint = _genPoint(0, 0);
  4140. _geometry.tick = function(x, y, end) {
  4141. var lastPoint = oldPoint;
  4142. var nextPoint = oldPoint = _genPoint(x, y);
  4143. var line = { p1: lastPoint, p2: nextPoint };
  4144. if(!regionList.length) return;
  4145. for(var i = 0; i < regionList.length; i++) {
  4146. var region = regionMap[regionList[i]];
  4147. var points = region.points;
  4148. if(!region.checked) {
  4149. if(!_checkInside(points, $ax.mouseLocation)) {
  4150. region.callback({ outside: true });
  4151. continue;
  4152. }
  4153. region.checked = true;
  4154. }
  4155. for(var j = 0; j < points.length; j++) {
  4156. var startSegment = points[j];
  4157. var endSegment = points[(j + 1) % points.length];
  4158. var intersectInfo = linesIntersect(line, { p1: startSegment, p2: endSegment });
  4159. if(intersectInfo) {
  4160. region.callback(intersectInfo);
  4161. break;
  4162. }
  4163. }
  4164. }
  4165. if(end) clear();
  4166. };
  4167. // Info if the one line touches the other (even barely), false otherwise
  4168. // Info includes point, if l1 is entering or exiting l2, and any ties that happened, or parallel info
  4169. var linesIntersect = function(l1, l2) {
  4170. var retval = {};
  4171. var ties = {};
  4172. var l1p1 = l1.p1.x < l1.p2.x || (l1.p1.x == l1.p2.x && l1.p1.y < l1.p2.y) ? l1.p1 : l1.p2;
  4173. var l1p2 = l1.p1.x < l1.p2.x || (l1.p1.x == l1.p2.x && l1.p1.y < l1.p2.y) ? l1.p2 : l1.p1;
  4174. var m1 = (l1p2.y - l1p1.y) / (l1p2.x - l1p1.x);
  4175. var l2p1 = l2.p1.x < l2.p2.x || (l2.p1.x == l2.p2.x && l2.p1.y < l2.p2.y) ? l2.p1 : l2.p2;
  4176. var l2p2 = l2.p1.x < l2.p2.x || (l2.p1.x == l2.p2.x && l2.p1.y < l2.p2.y) ? l2.p2 : l2.p1;
  4177. var m2 = (l2p2.y - l2p1.y) / (l2p2.x - l2p1.x);
  4178. var l1Vert = l1.p1.x == l1.p2.x;
  4179. var l2Vert = l2.p1.x == l2.p2.x;
  4180. if(l1Vert || l2Vert) {
  4181. if(l1Vert && l2Vert) {
  4182. // If the lines don't follow the same path, return
  4183. if(l1p1.x != l2p1.x) return false;
  4184. // if they never meet, return
  4185. if(l1p2.y < l2p1.y || l1p1.y > l2p2.y) return false;
  4186. var firstVert = l1p1.y >= l2p1.y ? l1p1 : l2p1;
  4187. var secondVert = l1p2.y <= l2p2.y ? l1p2 : l2p2;
  4188. // First is from the perspective of l1
  4189. retval.parallel = {
  4190. first: l1p1 == l1.p1 ? firstVert : secondVert,
  4191. second: l1p2 == l1.p2 ? secondVert : firstVert,
  4192. sameDirection: (l1p1 == l1.p1) == (l2p1 == l2.p1)
  4193. };
  4194. return retval;
  4195. }
  4196. var x1 = l2Vert ? l1p1.x : l2p1.x;
  4197. var x2 = l2Vert ? l1p2.x : l2p2.x;
  4198. var xVert = l2Vert ? l2p1.x : l1p1.x;
  4199. var y = l2Vert ? l1p1.y + (xVert - x1) * m1 : l2p1.y + (xVert - x1) * m2;
  4200. var y1 = l2Vert ? l2p1.y : l1p1.y;
  4201. var y2 = l2Vert ? l2p2.y : l1p2.y;
  4202. if(xVert >= x1 && xVert <= x2 && y >= y1 && y <= y2) {
  4203. retval.point = { x: xVert, y: y };
  4204. retval.exiting = l2Vert == (y1 == (l2Vert ? l2.p1.y : l1.p1.y)) == (x1 == (l2Vert ? l1.p1.x : l2.p1.x));
  4205. retval.entering = !retval.exiting;
  4206. // Calculate ties
  4207. if(x1 == xVert) {
  4208. ties[l2Vert ? 'l1' : 'l2'] = (x1 == (l2Vert ? l1.p1.x : l2.p1.x)) ? 'start' : 'end';
  4209. retval.ties = ties;
  4210. } else if(x2 == xVert) {
  4211. ties[l2Vert ? 'l1' : 'l2'] = (x2 == (l2Vert ? l1.p2.x : l2.p2.x)) ? 'end' : 'start';
  4212. retval.ties = ties;
  4213. }
  4214. if(y1 == y) {
  4215. ties[l2Vert ? 'l2' : 'l1'] = (y1 == (l2Vert ? l2.p1.y : l1.p1.y)) ? 'start' : 'end';
  4216. retval.ties = ties;
  4217. } else if(y2 == y) {
  4218. ties[l2Vert ? 'l2' : 'l1'] = (y2 == (l2Vert ? l2.p2.y : l1.p2.y)) ? 'end' : 'start';
  4219. retval.ties = ties;
  4220. }
  4221. return retval;
  4222. }
  4223. return false;
  4224. }
  4225. // If here, no vertical lines
  4226. if(m1 == m2) {
  4227. // If the lines don't follow the same path, return
  4228. if(l1p1.y != (l2p1.y + (l1p1.x - l2p1.x) * m1)) return false;
  4229. // if they never meet, return
  4230. if(l1p2.x < l2p1.x || l1p1.x > l2p2.x) return false;
  4231. var first = l1p1.x >= l2p1.x ? l1p1 : l2p1;
  4232. var second = l1p2.x <= l2p2.x ? l1p2 : l2p2;
  4233. // First is from the perspective of l1
  4234. retval.parallel = {
  4235. first: l1p1 == l1.p1 ? first : second,
  4236. second: l1p2 == l1.p2 ? second : first,
  4237. sameDirection: (l1p1 == l1.p1) == (l2p1 == l2.p1)
  4238. };
  4239. return retval;
  4240. }
  4241. var x = (l2p1.y - l2p1.x * m2 - l1p1.y + l1p1.x * m1) / (m1 - m2);
  4242. // Check if x is out of bounds
  4243. if(x >= l1p1.x && x <= l1p2.x && x >= l2p1.x && x <= l2p2.x) {
  4244. var y = l1p1.y + (x - l1p1.x) * m1;
  4245. retval.point = { x: x, y: y };
  4246. retval.entering = m1 > m2 == (l1p1 == l1.p1) == (l2p1 == l2.p1);
  4247. retval.exiting = !retval.entering;
  4248. // Calculate ties
  4249. if(l1.p1.x == x) {
  4250. ties.l1 = 'start';
  4251. retval.ties = ties;
  4252. } else if(l1.p2.x == x) {
  4253. ties.l1 = 'end';
  4254. retval.ties = ties;
  4255. }
  4256. if(l2.p1.x == x) {
  4257. ties.l2 = 'start';
  4258. retval.ties = ties;
  4259. } else if(l2.p2.x == x) {
  4260. ties.l2 = 'end';
  4261. retval.ties = ties;
  4262. }
  4263. return retval;
  4264. }
  4265. return false;
  4266. };
  4267. var _checkInsideRegion = function(label, point) {
  4268. if(!_polygonRegistered(label)) return false;
  4269. return _checkInside(regionMap[label].points, point || $ax.mouseLocation);
  4270. };
  4271. _geometry.checkInsideRegion = _checkInsideRegion;
  4272. // Returns true if point is inside the polygon, including ties
  4273. var _checkInside = function(polygon, point) {
  4274. // Make horizontal line wider than the polygon, with the y of point to test location
  4275. var firstX = polygon[0].x;
  4276. var secondX = firstX;
  4277. var i;
  4278. for(i = 1; i < polygon.length; i++) {
  4279. var polyX = polygon[i].x;
  4280. firstX = Math.min(firstX, polyX);
  4281. secondX = Math.max(secondX, polyX);
  4282. }
  4283. var line = {
  4284. p1: _genPoint(--firstX, point.y),
  4285. p2: _genPoint(++secondX, point.y)
  4286. };
  4287. // If entered true, with closest intersection says you are inside the polygon.
  4288. var entered = false;
  4289. // Closest is the closest intersection to the left of the point
  4290. var closest = line.p1.x;
  4291. // This is for if intersections hit the same point, to find out which is correct
  4292. var cos = -2;
  4293. var getCos = function(line) {
  4294. var x = line.p2.x - line.p1.x;
  4295. var y = line.p2.y - line.p1.y;
  4296. return x / Math.sqrt(x * x + y * y);
  4297. };
  4298. for(i = 0; i < polygon.length; i++) {
  4299. var polyLine = { p1: polygon[i], p2: polygon[(i + 1) % polygon.length] };
  4300. var intersectInfo = linesIntersect(line, polyLine);
  4301. if(!intersectInfo) continue;
  4302. if(intersectInfo.parallel) {
  4303. // Only really care about this if it actually touches the point
  4304. if(intersectInfo.parallel.first.x <= point.x && intersectInfo.parallel.second.x >= point.x) return true;
  4305. continue;
  4306. }
  4307. var intersectionX = intersectInfo.point.x;
  4308. if(intersectionX > point.x || intersectionX < closest) continue;
  4309. if(intersectionX == point.x) return true;
  4310. // If closer than last time, reset cosine.
  4311. if(intersectionX != closest) cos = -2;
  4312. // For getting cosine, need to possibly reverse the direction of polyLine.
  4313. if(intersectInfo.ties) {
  4314. // 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.
  4315. if(intersectInfo.ties.l2 == 'end') polyLine = { p1: polyLine.p2, p2: polyLine.p1 };
  4316. } else {
  4317. // It is on both side, so you can take the larger one
  4318. if(polyLine.p1.x > polyLine.p2.x) polyLine = { p1: polyLine.p2, p2: polyLine.p1 };
  4319. }
  4320. var currCos = getCos(polyLine);
  4321. if(currCos > cos) {
  4322. cos = currCos;
  4323. closest = intersectionX;
  4324. entered = intersectInfo.entering;
  4325. }
  4326. }
  4327. return entered;
  4328. };
  4329. _geometry.checkInside = _checkInside;
  4330. });
  4331. //***** flyout.js *****//
  4332. // ******* Flyout MANAGER ******** //
  4333. $axure.internal(function($ax) {
  4334. var _flyoutManager = $ax.flyoutManager = {};
  4335. var getFlyoutLabel = function(panelId) {
  4336. return panelId + '_flyout';
  4337. };
  4338. var _unregisterPanel = function(panelId, keepShown) {
  4339. $ax.geometry.unregister(getFlyoutLabel(panelId));
  4340. if(panelToSrc[panelId]) {
  4341. $ax.style.RemoveRolloverOverride(panelToSrc[panelId]);
  4342. delete panelToSrc[panelId];
  4343. }
  4344. if(!keepShown) {
  4345. $ax.action.addAnimation(panelId, $ax.action.queueTypes.fade, function() {
  4346. $ax('#' + panelId).hide();
  4347. });
  4348. }
  4349. };
  4350. _flyoutManager.unregisterPanel = _unregisterPanel;
  4351. var genPoint = $ax.geometry.genPoint;
  4352. var _updateFlyout = function(panelId) {
  4353. var label = getFlyoutLabel(panelId);
  4354. if(!$ax.geometry.polygonRegistered(label)) return;
  4355. var info = $ax.geometry.getPolygonInfo(label);
  4356. var rects = info && info.rects;
  4357. var targetWidget = $ax.getWidgetInfo(panelId);
  4358. rects.target = $ax.geometry.genRect(targetWidget);
  4359. // Src will stay the same, just updating
  4360. $ax.flyoutManager.registerFlyout(rects, panelId, panelToSrc[panelId]);
  4361. if(!$ax.geometry.checkInsideRegion(label)) _unregisterPanel(panelId);
  4362. };
  4363. _flyoutManager.updateFlyout = _updateFlyout;
  4364. var panelToSrc = {};
  4365. var _registerFlyout = function(rects, panelId, srcId) {
  4366. var label = _getFlyoutLabel(panelId);
  4367. var callback = function(info) {
  4368. // If leaving object or already outside it, then unregister, otherwise just return
  4369. if(!info.exiting && !info.outside) return;
  4370. _unregisterPanel(panelId);
  4371. };
  4372. var points = [];
  4373. var lastSrcId = panelToSrc[panelId];
  4374. if(lastSrcId != srcId) {
  4375. if(lastSrcId) $ax.style.RemoveRolloverOverride(lastSrcId);
  4376. if(srcId) {
  4377. $ax.style.AddRolloverOverride(srcId);
  4378. panelToSrc[panelId] = srcId;
  4379. } else delete panelToSrc[panelId];
  4380. }
  4381. // rects should be one or two rectangles
  4382. if(!rects.src) {
  4383. var rect = rects.target;
  4384. points.push(genPoint(rect.Left(), rect.Top()));
  4385. points.push(genPoint(rect.Right(), rect.Top()));
  4386. points.push(genPoint(rect.Right(), rect.Bottom()));
  4387. points.push(genPoint(rect.Left(), rect.Bottom()));
  4388. } else {
  4389. var r0 = rects.src;
  4390. var r1 = rects.target;
  4391. // Right left of right, left right of left, top below top, bottom above bottom
  4392. var rlr = r0.Right() <= r1.Right();
  4393. var lrl = r0.Left() >= r1.Left();
  4394. var tbt = r0.Top() >= r1.Top();
  4395. var bab = r0.Bottom() <= r1.Bottom();
  4396. var info = { rlr: rlr, lrl: lrl, tbt: tbt, bab: bab };
  4397. if((rlr && lrl) || (tbt && bab)) {
  4398. points = getSmallPolygon(r0, r1, info);
  4399. } else {
  4400. points = getLargePolygon(r0, r1, info);
  4401. }
  4402. }
  4403. $ax.geometry.registerPolygon(label, points, callback, { rects: rects });
  4404. };
  4405. _flyoutManager.registerFlyout = _registerFlyout;
  4406. var _getFlyoutLabel = function(panelId) {
  4407. return panelId + '_flyout';
  4408. };
  4409. var _reregisterAllFlyouts = function() {
  4410. for(var panelId in panelToSrc) _reregisterFlyout(panelId);
  4411. };
  4412. _flyoutManager.reregisterAllFlyouts = _reregisterAllFlyouts;
  4413. var _reregisterFlyout = function(panelId) {
  4414. var rects = $ax.geometry.getPolygonInfo(getFlyoutLabel(panelId)).rects;
  4415. _registerFlyout(rects, panelId, panelToSrc[panelId]);
  4416. };
  4417. // This is the reduced size polygon connecting r0 to r1 by means of horizontal or vertical lines.
  4418. var getSmallPolygon = function(r0, r1, info) {
  4419. var points = [];
  4420. // NOTE: currently I make the assumption that if horizontal/vertical connecting lines from the src hit the target
  4421. // Meaning if horizontal, rlr and lrl are true, and if vertical, tbt and bab are true.
  4422. var r0Left = r0.Left();
  4423. var r0Right = r0.Right();
  4424. var r0Top = r0.Top();
  4425. var r0Bottom = r0.Bottom();
  4426. var r1Left = r1.Left();
  4427. var r1Right = r1.Right();
  4428. var r1Top = r1.Top();
  4429. var r1Bottom = r1.Bottom();
  4430. points.push(genPoint(r1Left, r1Top));
  4431. if(!info.tbt) {
  4432. points.push(genPoint(r0Left, r1Top));
  4433. points.push(genPoint(r0Left, r0Top));
  4434. points.push(genPoint(r0Right, r0Top));
  4435. points.push(genPoint(r0Right, r1Top));
  4436. }
  4437. points.push(genPoint(r1Right, r1Top));
  4438. if(!info.rlr) {
  4439. points.push(genPoint(r1Right, r0Top));
  4440. points.push(genPoint(r0Right, r0Top));
  4441. points.push(genPoint(r0Right, r0Bottom));
  4442. points.push(genPoint(r1Right, r0Bottom));
  4443. }
  4444. points.push(genPoint(r1Right, r1Bottom));
  4445. if(!info.bab) {
  4446. points.push(genPoint(r0Right, r1Bottom));
  4447. points.push(genPoint(r0Right, r0Bottom));
  4448. points.push(genPoint(r0Left, r0Bottom));
  4449. points.push(genPoint(r0Left, r1Bottom));
  4450. }
  4451. points.push(genPoint(r1Left, r1Bottom));
  4452. if(!info.lrl) {
  4453. points.push(genPoint(r1Left, r0Bottom));
  4454. points.push(genPoint(r0Left, r0Bottom));
  4455. points.push(genPoint(r0Left, r0Top));
  4456. points.push(genPoint(r1Left, r0Top));
  4457. }
  4458. return points;
  4459. };
  4460. // This is the original algorithm that connects the most extream corners to make polygon
  4461. var getLargePolygon = function(r0, r1, info) {
  4462. var points = [];
  4463. var r0Left = r0.Left();
  4464. var r0Right = r0.Right();
  4465. var r0Top = r0.Top();
  4466. var r0Bottom = r0.Bottom();
  4467. var r1Left = r1.Left();
  4468. var r1Right = r1.Right();
  4469. var r1Top = r1.Top();
  4470. var r1Bottom = r1.Bottom();
  4471. // Top lefts
  4472. if(info.tbt) {
  4473. if(!info.lrl) points.push(genPoint(r0Left, r0Top));
  4474. points.push(genPoint(r1Left, r1Top));
  4475. } else {
  4476. if(info.lrl) points.push(genPoint(r1Left, r1Top));
  4477. points.push(genPoint(r0Left, r0Top));
  4478. }
  4479. // Top rights
  4480. if(info.tbt) {
  4481. points.push(genPoint(r1Right, r1Top));
  4482. if(!info.rlr) points.push(genPoint(r0Right, r0Top));
  4483. } else {
  4484. points.push(genPoint(r0Right, r0Top));
  4485. if(info.rlr) points.push(genPoint(r1Right, r1Top));
  4486. }
  4487. // Bottom rights
  4488. if(info.bab) {
  4489. if(!info.rlr) points.push(genPoint(r0Right, r0Bottom));
  4490. points.push(genPoint(r1Right, r1Bottom));
  4491. } else {
  4492. if(info.rlr) points.push(genPoint(r1Right, r1Bottom));
  4493. points.push(genPoint(r0Right, r0Bottom));
  4494. }
  4495. // Bottom Lefts
  4496. if(info.bab) {
  4497. points.push(genPoint(r1Left, r1Bottom));
  4498. if(!info.lrl) points.push(genPoint(r0Left, r0Bottom));
  4499. } else {
  4500. points.push(genPoint(r0Left, r0Bottom));
  4501. if(info.lrl) points.push(genPoint(r1Left, r1Bottom));
  4502. }
  4503. return points;
  4504. };
  4505. });
  4506. // ******* Placeholder Manager ********* //
  4507. $axure.internal(function($ax) {
  4508. var _placeholderManager = $ax.placeholderManager = {};
  4509. var idToPlaceholderInfo = {};
  4510. var _registerPlaceholder = function(elementId, text, password) {
  4511. idToPlaceholderInfo[elementId] = { text: text, password: password, active: false };
  4512. };
  4513. _placeholderManager.registerPlaceholder = _registerPlaceholder;
  4514. _placeholderManager.refreshPlaceholder = function (elementId) {
  4515. var info = idToPlaceholderInfo[elementId];
  4516. if (!info || !info.active) return;
  4517. $ax.style.SetWidgetPlaceholder(elementId, true, info.text, info.password);
  4518. }
  4519. var _updatePlaceholder = function(elementId, active, clearText) {
  4520. var inputId = $ax.repeater.applySuffixToElementId(elementId, '_input');
  4521. var info = idToPlaceholderInfo[elementId];
  4522. if(!info || info.active == active) return;
  4523. info.active = active;
  4524. if(active) var value = info.text;
  4525. else if(!ANDROID) value = clearText ? '' : document.getElementById(inputId).value;
  4526. else {
  4527. var currentText = document.getElementById(inputId).value;
  4528. if(!clearText) value = currentText;
  4529. else if(currentText == info.text) value = "";
  4530. else {
  4531. var lastIndex = currentText.lastIndexOf(info.text);
  4532. //here i am assuming the text is always inserted in front
  4533. value = currentText.substring(0, lastIndex);
  4534. }
  4535. }
  4536. $ax.style.SetWidgetPlaceholder(elementId, active, value, info.password);
  4537. };
  4538. _placeholderManager.updatePlaceholder = _updatePlaceholder;
  4539. var _isActive = function(elementId) {
  4540. var info = idToPlaceholderInfo[elementId];
  4541. return Boolean(info && info.active);
  4542. };
  4543. _placeholderManager.isActive = _isActive;
  4544. var _selectRange = function(elementId, start, end) {
  4545. $jobj(elementId).each(function() {
  4546. if(this.setSelectionRange) {
  4547. var validTypes = ["text", "search", "url", "tel", "password"];
  4548. if(this.tagName.toLowerCase() != "input" || validTypes.indexOf(this.type) > -1) {
  4549. this.focus();
  4550. this.setSelectionRange(start, end);
  4551. }
  4552. } else if(this.createTextRange) {
  4553. var range = this.createTextRange();
  4554. range.collapse(true);
  4555. range.moveEnd('character', end);
  4556. range.moveStart('character', start);
  4557. range.select();
  4558. }
  4559. });
  4560. };
  4561. _placeholderManager.selectRange = _selectRange;
  4562. var _moveCaret = function(id, index) {
  4563. var inputIndex = id.indexOf('_input');
  4564. if(inputIndex == -1) return;
  4565. var inputId = id.substring(0, inputIndex);
  4566. if(!_isActive(inputId)) return;
  4567. _selectRange(id, index, index);
  4568. };
  4569. _placeholderManager.moveCaret = _moveCaret;
  4570. });
  4571. //***** ie.js *****//
  4572. // ******* Internet Explorer MANAGER ******** //
  4573. //this is to handle all the stupid IE Stuff
  4574. $axure.internal(function($ax) {
  4575. if(!IE_10_AND_BELOW) return;
  4576. var _ieColorManager = {};
  4577. if(Number(BROWSER_VERSION) < 9) $ax.ieColorManager = _ieColorManager;
  4578. var _applyIEFixedPosition = function() {
  4579. if(Number(BROWSER_VERSION) >= 7) return;
  4580. $axure(function(diagramObject) { return diagramObject.fixedVertical; }).$()
  4581. .appendTo($('body'))
  4582. .css('position', 'absolute').css('margin-left', 0 + 'px').css('margin-top', 0 + 'px');
  4583. var handleScroll = function() {
  4584. $axure(function(diagramObject) { return diagramObject.fixedVertical; })
  4585. .each(function(diagramObject, elementId) {
  4586. var win = $(window);
  4587. var windowWidth = win.width();
  4588. var windowHeight = win.height();
  4589. var windowScrollLeft = win.scrollLeft();
  4590. var windowScrollTop = win.scrollTop();
  4591. var newLeft = 0;
  4592. var newTop = 0;
  4593. var elementQuery = $('#' + elementId);
  4594. var elementAxQuery = $ax('#' + elementId);
  4595. var width = elementAxQuery.width();
  4596. var height = elementAxQuery.height();
  4597. var horz = diagramObject.fixedHorizontal;
  4598. if(horz == 'left') {
  4599. newLeft = windowScrollLeft + diagramObject.fixedMarginHorizontal;
  4600. } else if(horz == 'center') {
  4601. newLeft = windowScrollLeft + ((windowWidth - width) / 2) + diagramObject.fixedMarginHorizontal;
  4602. } else if(horz == 'right') {
  4603. newLeft = windowScrollLeft + windowWidth - width - diagramObject.fixedMarginHorizontal;
  4604. }
  4605. var vert = diagramObject.fixedVertical;
  4606. if(vert == 'top') {
  4607. newTop = windowScrollTop + diagramObject.fixedMarginVertical;
  4608. } else if(vert == 'middle') {
  4609. newTop = windowScrollTop + ((windowHeight - height) / 2) + diagramObject.fixedMarginVertical;
  4610. } else if(vert == 'bottom') {
  4611. newTop = windowScrollTop + windowHeight - height - diagramObject.fixedMarginVertical;
  4612. }
  4613. elementQuery.css('top', newTop + 'px').css('left', newLeft + 'px');
  4614. });
  4615. };
  4616. $(window).scroll(handleScroll);
  4617. $axure.resize(handleScroll);
  4618. handleScroll();
  4619. };
  4620. var _applyBackground = function() {
  4621. if(Number(BROWSER_VERSION) >= 9) return;
  4622. var styleChain = $ax.adaptive.getAdaptiveIdChain($ax.adaptive.currentViewId);
  4623. var argb = _getArgb($ax.pageData.page, styleChain);
  4624. var hexColor = _getHexColor(argb, false);
  4625. if(hexColor) $('body').css('background-color', hexColor);
  4626. _applyBackgroundToQuery($ax('*'));
  4627. };
  4628. var _applyBackgroundToQuery = function(query) {
  4629. if(Number(BROWSER_VERSION) >= 9) return;
  4630. var styleChain = $ax.adaptive.getAdaptiveIdChain($ax.adaptive.currentViewId);
  4631. query.each(function(obj, elementId) {
  4632. if ($ax.public.fn.IsDynamicPanel(obj.type)) {
  4633. var stateCount = obj.diagrams.length;
  4634. for(var j = 0; j < stateCount; j++) {
  4635. var stateId = $ax.repeater.applySuffixToElementId(elementId, '_state' + j);
  4636. var argb = _getArgb(obj.diagrams[j], styleChain);
  4637. var hexColor = _getHexColor(argb, true);
  4638. if(hexColor) $jobj(stateId).css('background-color', hexColor);
  4639. }
  4640. } else if ($ax.public.fn.IsRepeater(obj.type)) {
  4641. }
  4642. });
  4643. };
  4644. _ieColorManager.applyBackground = _applyBackgroundToQuery;
  4645. var _getArgb = function(diagram, styleChain) {
  4646. var argb = undefined;
  4647. for(var i = 0; i < styleChain.length && !argb; i++) {
  4648. var style = diagram.adaptiveStyles[styleChain[i]];
  4649. argb = style.fill && style.fill.color;
  4650. }
  4651. if(!argb) argb = diagram.style.fill.color;
  4652. return argb;
  4653. };
  4654. var gMult = 256;
  4655. var rMult = gMult * 256;
  4656. var aMult = rMult * 256;
  4657. var _getHexColor = function(argb, allowWhite) {
  4658. var a = Math.floor(argb / aMult);
  4659. argb -= a * aMult;
  4660. var r = Math.floor(argb / rMult);
  4661. argb -= r * rMult;
  4662. var g = Math.floor(argb / gMult);
  4663. var b = argb - g * gMult;
  4664. return _getColorFromArgb(a, r, g, b, allowWhite);
  4665. };
  4666. var _getColorFromArgb = function(a, r, g, b, allowWhite) {
  4667. if(Number(BROWSER_VERSION) >= 9) return undefined;
  4668. //convert the color with alpha to a color with no alpha (assuming white background)
  4669. r = Math.min((r * a) / 255 + 255 - a, 255);
  4670. g = Math.min((g * a) / 255 + 255 - a, 255);
  4671. b = Math.min((b * a) / 255 + 255 - a, 255);
  4672. if(a == 0) return undefined;
  4673. if(!allowWhite && (r == 255 && g == 255 && b == 255)) return undefined;
  4674. var color = '#';
  4675. color += Math.floor(r / 16).toString(16);
  4676. color += Math.floor(r % 16).toString(16);
  4677. color += Math.floor(g / 16).toString(16);
  4678. color += Math.floor(g % 16).toString(16);
  4679. color += Math.floor(b / 16).toString(16);
  4680. color += Math.floor(b % 16).toString(16);
  4681. return color;
  4682. };
  4683. _ieColorManager.getColorFromArgb = _getColorFromArgb;
  4684. var getIEOffset = function(transform, rect) {
  4685. var translatedVertexes = [
  4686. $axure.utils.Vector2D(0, 0), //we dont translate, so the orgin is fixed
  4687. transform.mul($axure.utils.Vector2D(0, rect.height)),
  4688. transform.mul($axure.utils.Vector2D(rect.width, 0)),
  4689. transform.mul($axure.utils.Vector2D(rect.width, rect.height))];
  4690. var minX = 0, minY = 0, maxX = 0, maxY = 0;
  4691. $.each(translatedVertexes, function(index, p) {
  4692. minX = Math.min(minX, p.x);
  4693. minY = Math.min(minY, p.y);
  4694. maxX = Math.max(maxX, p.x);
  4695. maxY = Math.max(maxY, p.y);
  4696. });
  4697. return $axure.utils.Vector2D(
  4698. (maxX - minX - rect.width) / 2,
  4699. (maxY - minY - rect.height) / 2);
  4700. };
  4701. var _filterFromTransform = function(transform) {
  4702. return "progid:DXImageTransform.Microsoft.Matrix(M11=" + transform.m11 +
  4703. ", M12=" + transform.m12 + ", M21=" + transform.m21 +
  4704. ", M22=" + transform.m22 + ", SizingMethod='auto expand')";
  4705. };
  4706. var _applyIERotation = function() {
  4707. if(Number(BROWSER_VERSION) >= 9) return;
  4708. $axure(function(diagramObject) {
  4709. return ((diagramObject.style.rotation && Math.abs(diagramObject.style.rotation) > 0.1)
  4710. || (diagramObject.style.textRotation && Math.abs(diagramObject.style.textRotation) > 0.1))
  4711. && !diagramObject.isContained;
  4712. }).each(function(diagramObject, elementId) {
  4713. var rotation = diagramObject.style.rotation || 0;
  4714. var $element = $('#' + elementId);
  4715. var axElement = $ax('#' + elementId);
  4716. var width = axElement.width();
  4717. var height = axElement.height();
  4718. var originX = width / 2;
  4719. var originY = height / 2;
  4720. var shapeIeOffset;
  4721. $element.children().each(function() {
  4722. var $child = $(this);
  4723. var axChild = $ax('#' + $child.attr('id'));
  4724. var childWidth = axChild.width();
  4725. var childHeight = axChild.height() + $child.position().top;
  4726. var centerX = $child.position().left + (childWidth / 2);
  4727. var centerY = $child.position().top + (childHeight / 2);
  4728. var deltaX = centerX - originX;
  4729. var deltaY = centerY - originY;
  4730. var effectiveRotation = rotation;
  4731. var textObject = $ax.getObjectFromElementId($child.attr('id'));
  4732. if(textObject) {
  4733. if(textObject.style.textRotation) effectiveRotation = textObject.style.textRotation;
  4734. else return;
  4735. }
  4736. var transform = $ax.utils.Matrix2D.identity().rotate(effectiveRotation);
  4737. var filter = _filterFromTransform(transform);
  4738. $child.css('filter', filter)
  4739. .width(childWidth + 1)
  4740. .height(childHeight + 1);
  4741. var p = transform.mul($ax.utils.Vector2D(deltaX, deltaY));
  4742. var ieOffset = getIEOffset(transform, { width: childWidth, height: childHeight });
  4743. if(!textObject) {
  4744. shapeIeOffset = ieOffset;
  4745. } else {
  4746. // This is a close approximation, but not exact
  4747. if(diagramObject.style.verticalAlignment != 'top') ieOffset.y -= shapeIeOffset.y + Math.abs(shapeIeOffset.x);
  4748. }
  4749. $child.css("margin-left", -ieOffset.x - deltaX + p.x).css("margin-top", -ieOffset.y - deltaY + p.y);
  4750. });
  4751. });
  4752. };
  4753. var _fixIEStretchBackground = function() {
  4754. if(Number(BROWSER_VERSION) >= 9) return;
  4755. var pageStyle = $ax.adaptive.getPageStyle();
  4756. if(!pageStyle.imageRepeat || pageStyle.imageRepeat == 'auto') return;
  4757. $('body').css('background-image', 'none');
  4758. var viewId = $ax.adaptive.currentViewId;
  4759. var imageInfo = viewId ? $ax.pageData.viewIdToBackgroundImageInfo && $ax.pageData.viewIdToBackgroundImageInfo[viewId] : $ax.pageData.defaultBackgroundImageInfo;
  4760. if(imageInfo && imageInfo.path) {
  4761. if($('#bg_img').length == 0) $('body').append('<img id="bg_img"/>');
  4762. $('#bg_img').attr('src', imageInfo.path).css('position', 'fixed').css('z-index', '-10000');
  4763. _resizeIEBackground();
  4764. } else $('#bg_img').remove();
  4765. };
  4766. var _resizeIEBackground = function() {
  4767. if(Number(BROWSER_VERSION) >= 9) return;
  4768. //var page = $ax.pageData.page;
  4769. var viewId = $ax.adaptive.currentViewId;
  4770. var pageStyle = $ax.adaptive.getPageStyle();
  4771. if(!$ax.pageData.defaultBackgroundImageInfo && !$ax.pageData.viewIdToBackgroundImageInfo) return;
  4772. var imageInfo = viewId ? $ax.pageData.viewIdToBackgroundImageInfo[viewId] : $ax.pageData.defaultBackgroundImageInfo;
  4773. if(!imageInfo) return;
  4774. var imageWidth = imageInfo.width;
  4775. var imageHeight = imageInfo.height;
  4776. var windowWidth = $(window).width();
  4777. var windowHeight = $(window).height();
  4778. var isCover = pageStyle.imageRepeat == 'cover';
  4779. var wRatio = windowWidth / imageWidth;
  4780. var hRatio = windowHeight / imageHeight;
  4781. var ratio = wRatio;
  4782. if(isCover) {
  4783. if(hRatio > wRatio) ratio = hRatio;
  4784. } else {
  4785. if(hRatio < wRatio) ratio = hRatio;
  4786. }
  4787. var width = imageWidth * ratio;
  4788. var height = imageHeight * ratio;
  4789. var left = '0px';
  4790. if((isCover && width > windowWidth) || (!isCover && width < windowWidth)) {
  4791. if(pageStyle.imageHorizontalAlignment == 'center') {
  4792. left = ((windowWidth - width) / 2) + 'px';
  4793. } else if(pageStyle.imageHorizontalAlignment == 'far') {
  4794. left = (windowWidth - width) + 'px';
  4795. }
  4796. }
  4797. var top = '0px';
  4798. if((isCover && height > windowHeight) || (!isCover && height < windowHeight)) {
  4799. if(pageStyle.imageVerticalAlignment == 'center') {
  4800. top = ((windowHeight - height) / 2) + 'px';
  4801. } else if(pageStyle.imageVerticalAlignment == 'far') {
  4802. top = (windowHeight - height) + 'px';
  4803. }
  4804. }
  4805. $('#bg_img').css('top', top).css('left', left).css('width', width).css('height', height);
  4806. };
  4807. var _fixAllPngs = function() {
  4808. if(!(/MSIE ((5\.5)|6)/.test(window.navigator.userAgent) && window.navigator.platform == "Win32")) return;
  4809. $('img[src$=".png"]').each(function() {
  4810. if(!this.complete) {
  4811. this.onload = function() { $axure.utils.fixPng(this); };
  4812. } else {
  4813. $axure.utils.fixPng(this);
  4814. }
  4815. });
  4816. };
  4817. var _fixInputSize = function() {
  4818. if(Number(BROWSER_VERSION) >= 8 || window.navigator.userAgent.indexOf("Trident/4.0") > -1) return;
  4819. var inputs = $('input').not(':input[type=button], :input[type=submit], :input[type=radio], :input[type=checkbox]');
  4820. inputs.each(function() {
  4821. var $input = $(this);
  4822. var axInput = $ax('#' + $input.attr('id'));
  4823. $input.css('height', (axInput.height() - 4 + 'px')).css('width', (axInput.width() - 2 + 'px'));
  4824. });
  4825. var textAreas = $($ax.constants.TEXT_AREA_TYPE);
  4826. textAreas.each(function() {
  4827. var $textArea = $(this);
  4828. var axText = $ax('#' + $textArea.attr('id'));
  4829. $textArea.css('height', (axText.height() - 6 + 'px')).css('width', (axText.width() - 6 + 'px'));
  4830. });
  4831. };
  4832. var _fixInputBackground = function() {
  4833. var inputs = $('input').not(':input[type=button], :input[type=submit], :input[type=radio], :input[type=checkbox]');
  4834. inputs = inputs.add($($ax.constants.TEXT_AREA_TYPE));
  4835. inputs.each(function() {
  4836. var $input = $(this);
  4837. if($input.css('background-color') == 'transparent') {
  4838. $input.css('background-image', 'url(../../transparent.gif)');
  4839. } else {
  4840. $input.css('background-image', '');
  4841. }
  4842. });
  4843. };
  4844. $(document).ready(function() {
  4845. _fixIEStretchBackground();
  4846. _applyIEFixedPosition();
  4847. $axure.resize(function() {
  4848. _resizeIEBackground();
  4849. });
  4850. $ax.adaptive.bind('viewChanged', function() {
  4851. _fixIEStretchBackground();
  4852. _applyBackground();
  4853. _fixInputBackground();
  4854. });
  4855. _fixAllPngs();
  4856. _applyIERotation();
  4857. _applyBackground();
  4858. _fixInputSize();
  4859. _fixInputBackground();
  4860. });
  4861. });
  4862. //***** model.js *****//
  4863. // ******* Object Model ******** //
  4864. $axure.internal(function($ax) {
  4865. var _implementations = {};
  4866. var _initializeObject = function(type, obj) {
  4867. $.extend(obj, _implementations[type]);
  4868. };
  4869. $ax.initializeObject = _initializeObject;
  4870. var _model = $ax.model = {};
  4871. _model.idsInRdoToHideOrLimbo = function(rdoId, scriptIds) {
  4872. var rdoScriptId = $ax.repeater.getScriptIdFromElementId(rdoId);
  4873. var path = $ax.getPathFromScriptId(rdoScriptId);
  4874. if(!scriptIds) scriptIds = [];
  4875. var rdo = $ax.getObjectFromElementId(rdoId);
  4876. var master = $ax.pageData.masters[rdo.masterId];
  4877. var masterChildren = master.diagram.objects;
  4878. for(var i = 0; i < masterChildren.length; i++) {
  4879. var obj = masterChildren[i];
  4880. var objScriptIds = obj.scriptIds;
  4881. for(var j = 0; j < objScriptIds.length; j++) {
  4882. var scriptId = objScriptIds[j];
  4883. // Anything in a layer is already handled by the layer
  4884. if($ax.getLayerParentFromElementId(scriptId)) continue;
  4885. // Make sure in same rdo
  4886. var elementPath = $ax.getPathFromScriptId(scriptId);
  4887. // This is because last part of path is for the obj itself.
  4888. elementPath.pop();
  4889. if(elementPath.length != path.length) continue;
  4890. var samePath = true;
  4891. for(var k = 0; k < path.length; k++) {
  4892. if(elementPath[k] != path[k]) {
  4893. samePath = false;
  4894. break;
  4895. }
  4896. }
  4897. if(!samePath) continue;
  4898. if($ax.public.fn.IsReferenceDiagramObject(obj.type)) _model.idsInRdoToHideOrLimbo(scriptId, scriptIds);
  4899. else if(scriptIds.indexOf(scriptId) == -1) scriptIds.push(scriptId);
  4900. break;
  4901. }
  4902. }
  4903. return scriptIds;
  4904. };
  4905. });
  4906. //***** repeater.js *****//
  4907. // ******* Repeater MANAGER ******** //
  4908. $axure.internal(function($ax) {
  4909. var _repeaterManager = {};
  4910. $ax.repeater = _repeaterManager;
  4911. //This is a mapping of current editItems
  4912. var repeaterToEditItems = {};
  4913. //This is a mapping of current filters
  4914. var repeaterToFilters = {};
  4915. // This is a mapping of current sorts
  4916. var repeaterToSorts = {};
  4917. // This is a mapping of repeater page info
  4918. var repeaterToPageInfo = {};
  4919. //Hopefully this can be simplified, but for now I think 3 are needed.
  4920. //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.
  4921. var repeaterToLocalDataSet = {};
  4922. //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).
  4923. var repeaterToCurrentDataSet = {};
  4924. //This is a copy of the current data set, that is replaced whenever a set or refresh is done.
  4925. var repeaterToActiveDataSet = {};
  4926. var _loadRepeaters = function() {
  4927. $ax(function(obj) {
  4928. return $ax.public.fn.IsRepeater(obj.type);
  4929. }).each(function(obj, repeaterId) {
  4930. repeaterToLocalDataSet[repeaterId] = $ax.deepCopy(obj.data);
  4931. repeaterToLocalDataSet[repeaterId].props = obj.dataProps;
  4932. repeaterToEditItems[repeaterId] = [];
  4933. _initPageInfo(obj, repeaterId);
  4934. _setRepeaterDataSet(repeaterId, repeaterId);
  4935. var initialItemIds = obj.repeaterPropMap.itemIds;
  4936. for (var i = 0; i < initialItemIds.length; i++) $ax.addItemIdToRepeater(initialItemIds[i], repeaterId);
  4937. $ax.visibility.initRepeater(repeaterId);
  4938. });
  4939. };
  4940. _repeaterManager.load = _loadRepeaters;
  4941. var _loaded = {};
  4942. var _initRepeaters = function() {
  4943. $ax(function(obj, repeaterId) {
  4944. return $ax.public.fn.IsRepeater(obj.type) && !_loaded[repeaterId];
  4945. }).each(function(obj, repeaterId) {
  4946. _refreshRepeater(repeaterId, undefined, true);
  4947. //// Fix selected and default if necessary
  4948. //var states = obj.evaluatedStates[repeaterId];
  4949. //if(!states) return; // If there are no evaluated states the repeater id key could not be mapped to an array of states.
  4950. //for(var i = 0; i < states.length; i++) {
  4951. // var state = states[i];
  4952. // $ax.style.SetWidgetEnabled(state.id, true); // So selected will take place. If disabled, selected wouldn't happen.
  4953. // $ax.style.SetWidgetSelected(state.id, state.selected);
  4954. // $ax.style.SetWidgetEnabled(state.id, !state.disabled);
  4955. //}
  4956. });
  4957. };
  4958. _repeaterManager.initRefresh = _initRepeaters;
  4959. var repeatersHaveNewDataSet = [];
  4960. var _setRepeaterDataSet = function(repeaterId, dataSetId) {
  4961. //TODO: No idea about how global data sets will be handled...
  4962. repeaterToCurrentDataSet[repeaterId] = repeaterToLocalDataSet[dataSetId];
  4963. repeaterToActiveDataSet[repeaterId] = getActiveDataSet(repeaterId);
  4964. repeaterToFilters[repeaterId] = [];
  4965. repeaterToSorts[repeaterId] = [];
  4966. // Not using this currently
  4967. // if(repeatersHaveNewDataSet.indexOf(repeaterId) == -1) repeatersHaveNewDataSet[repeatersHaveNewDataSet.length] = repeaterId;
  4968. };
  4969. _repeaterManager.setDataSet = _setRepeaterDataSet;
  4970. var _refreshRepeater = function(repeaterId, eventInfo, itemsPregen) {
  4971. // Don't show if you have a parent rdos thats limboed.
  4972. var rdoPath = $ax.getPathFromScriptId(repeaterId);
  4973. // Check each parent rdo through appropriate views to see if you are limboed
  4974. while (rdoPath.length > 0) {
  4975. if(!$ax.getScriptIdFromPath(rdoPath)) {
  4976. removeItems(repeaterId);
  4977. return;
  4978. }
  4979. $ax.splice(rdoPath, rdoPath.length - 1, 1);
  4980. }
  4981. _loaded[repeaterId] = true;
  4982. $ax.action.refreshStart(repeaterId);
  4983. $ax.style.ClearCacheForRepeater(repeaterId);
  4984. if($ax.visibility.limboIds[repeaterId]) {
  4985. removeItems(repeaterId);
  4986. $ax.dynamicPanelManager.fitParentPanel(repeaterId);
  4987. return;
  4988. }
  4989. // Remove delete map if there is one at this point
  4990. if(eventInfo && eventInfo.repeaterDeleteMap) delete eventInfo.repeaterDeleteMap[repeaterId];
  4991. var path = $ax.getPathFromScriptId(repeaterId);
  4992. path.pop();
  4993. if(eventInfo) {
  4994. eventInfo = $ax.eventCopy(eventInfo);
  4995. }
  4996. var obj = $ax.getObjectFromScriptId(repeaterId);
  4997. var propMap = obj.repeaterPropMap;
  4998. //If there is no wrap, then set it to be above the number of rows
  4999. var viewId = $ax.adaptive.currentViewId || '';
  5000. var wrap = _getAdaptiveProp(propMap, 'wrap', viewId);
  5001. var vertical = _getAdaptiveProp(propMap, 'vertical', viewId);
  5002. var offset = propMap[viewId];
  5003. // Right now pregen only works for default adaptive view
  5004. if(viewId) itemsPregen = false;
  5005. var orderedIds = [];
  5006. if(itemsPregen) {
  5007. var repeaterChildren = $jobj(repeaterId).children();
  5008. // Start at 1 to skip script div child
  5009. for(var i = 1; i < repeaterChildren.length; i++) {
  5010. orderedIds.push(_getItemIdFromElementId($(repeaterChildren[i]).attr('id')));
  5011. }
  5012. } else orderedIds = getOrderedIds(repeaterId, eventInfo);
  5013. var ids = [];
  5014. var background = _getAdaptiveProp(propMap, 'backColor', viewId);
  5015. var hasAltColor = _getAdaptiveProp(propMap, 'hasAltColor', viewId);
  5016. var altColor = hasAltColor ? _getAdaptiveProp(propMap, 'altColor', viewId) : undefined;
  5017. var useAlt = false;
  5018. if(itemsPregen) {
  5019. var start = 0;
  5020. var end = orderedIds.length;
  5021. } else {
  5022. var bounds = _getVisibleDataBounds(repeaterToPageInfo[repeaterId], itemsPregen ? obj.data.length : orderedIds.length);
  5023. start = bounds[0];
  5024. end = bounds[1];
  5025. }
  5026. var repeaterObj = $jobj(repeaterId);
  5027. var preevalMap = {};
  5028. if(itemsPregen) {
  5029. var templateIds = [repeaterId];
  5030. var processScriptIds = function (full, prop, id) {
  5031. if(id.indexOf('_') <= 0 && id.indexOf('p') == -1) templateIds.push('u' + id);
  5032. };
  5033. $('#' + repeaterId + '_script').html().replace(/(id|for)="?u([0-9]+(p([0-9]){3})?(_[_a-z0-9]*)?)"?/g, processScriptIds);
  5034. for(var i = 0; i < templateIds.length; i++) {
  5035. for(var j = 0; j < orderedIds.length; j++) {
  5036. ids.push(_createElementId(templateIds[i], orderedIds[j]));
  5037. }
  5038. }
  5039. for(var pos = start; pos < end; pos++) {
  5040. var itemId = orderedIds[pos];
  5041. itemElementId = _createElementId(repeaterId, itemId);
  5042. var jobj = $jobj(itemElementId);
  5043. var preeval = jobj.hasClass('preeval');
  5044. for(var i = 0; i < templateIds.length; i++) $ax.initializeObjectEvents($ax('#' + _createElementId(templateIds[i], itemId)), !preeval);
  5045. if(preeval) {
  5046. preevalMap[itemId] = true;
  5047. jobj.removeClass('preeval');
  5048. }
  5049. }
  5050. } else {
  5051. var html = $('#' + repeaterId + '_script').html();
  5052. // var container = $('<div></div>');
  5053. // container.html(html);
  5054. // container.attr('id', '' + repeaterId + '_container');
  5055. // container.css({ position: 'absolute' });
  5056. // container.offset({ left: -obj.x, top: -obj.y });
  5057. var div = $('<div></div>');
  5058. div.html(html);
  5059. div.find('.' + $ax.visibility.HIDDEN_CLASS).removeClass($ax.visibility.HIDDEN_CLASS);
  5060. div.find('.' + $ax.visibility.UNPLACED_CLASS).removeClass($ax.visibility.UNPLACED_CLASS);
  5061. var paddingTop = _getAdaptiveProp(propMap, 'paddingTop', viewId);
  5062. var paddingLeft = _getAdaptiveProp(propMap, 'paddingLeft', viewId);
  5063. var paddingY = paddingTop + _getAdaptiveProp(propMap, 'paddingBottom', viewId);
  5064. var paddingX = paddingLeft + _getAdaptiveProp(propMap, 'paddingRight', viewId);
  5065. var spacingX = _getAdaptiveProp(propMap, 'horizontalSpacing', viewId);
  5066. var xOffset = offset.width + spacingX;
  5067. var spacingY = _getAdaptiveProp(propMap, 'verticalSpacing', viewId);
  5068. var yOffset = offset.height + spacingY;
  5069. div.css({
  5070. width: offset.width,
  5071. height: offset.height
  5072. });
  5073. _applyColorCss(background, div);
  5074. var altDiv = div;
  5075. if(hasAltColor) altDiv = _applyColorCss(altColor, div.clone());
  5076. // Hide repeater, if shown, while updating.
  5077. var shown = $ax.visibility.IsIdVisible(repeaterId);
  5078. if(shown) document.getElementById(repeaterId).style.visibility = 'hidden';
  5079. //clean up old items as late as possible
  5080. removeItems(repeaterId);
  5081. resetItemSizes(repeaterId, offset, bounds, orderedIds, vertical, wrap);
  5082. var i = 0;
  5083. var startTop = paddingTop;
  5084. var startLeft = paddingLeft;
  5085. if(repeaterObj.css('box-sizing') == 'border-box') {
  5086. startTop -= $ax.getNumFromPx(repeaterObj.css('border-top-width')) || 0;
  5087. startLeft -= $ax.getNumFromPx(repeaterObj.css('border-left-width')) || 0;
  5088. }
  5089. var top = startTop;
  5090. var left = startLeft;
  5091. for(pos = start; pos < end; pos++) {
  5092. itemId = orderedIds[pos];
  5093. var itemElementId = _createElementId(repeaterId, itemId);
  5094. $ax.addItemIdToRepeater(itemId, repeaterId);
  5095. ids.push(itemElementId);
  5096. var processId = function(full, prop, id) {
  5097. var elementId = _createElementId('u' + id, itemId);
  5098. //If there is a suffix (ex. _img), then don't push the id.
  5099. if (id.indexOf('_') <= 0 && id.indexOf('p') == -1) ids.push(elementId);
  5100. return prop + '="' + elementId + '"';
  5101. };
  5102. var copy = (useAlt ? altDiv : div).clone();
  5103. useAlt = !useAlt;
  5104. copy.attr('id', itemElementId);
  5105. copy.html(div.html().replace(/(id|for)="?u([0-9]+(p([0-9]){3})?(_[_a-z0-9]*)?)"?/g, processId));
  5106. if(obj.repeaterPropMap.isolateRadio) {
  5107. var radioButtons = copy.find(':radio');
  5108. for(var radioIndex = 0; radioIndex < radioButtons.length; radioIndex++) {
  5109. var radio = $(radioButtons[radioIndex]);
  5110. var oldName = radio.attr('name') || '';
  5111. // Can't use create element id because there could be an underscore in name
  5112. if(oldName) radio.attr('name', oldName + '-' + itemId);
  5113. }
  5114. }
  5115. copy.css({
  5116. 'position': 'absolute',
  5117. 'top': top + 'px',
  5118. 'left': left + 'px',
  5119. 'width': obj.width + 'px',
  5120. 'height': obj.height + 'px'
  5121. });
  5122. $('#' + repeaterId).append(copy);
  5123. i++;
  5124. if(wrap != -1 && i % wrap == 0) {
  5125. if(vertical) {
  5126. top = startTop;
  5127. left += xOffset;
  5128. } else {
  5129. left = startLeft;
  5130. top += yOffset;
  5131. }
  5132. } else if (vertical) top += yOffset;
  5133. else left += xOffset;
  5134. }
  5135. var shownCount = end - start;
  5136. var repeaterSize = { width: paddingX, height: paddingY};
  5137. if(shownCount > 0) {
  5138. var primaryCount = wrap == -1 ? shownCount : Math.min(shownCount, wrap);
  5139. var secondaryCount = wrap == -1 ? 1 : Math.ceil(shownCount / wrap);
  5140. var widthCount = vertical ? secondaryCount : primaryCount;
  5141. var heightCount = vertical ? primaryCount : secondaryCount;
  5142. repeaterSize.width += offset.width + (widthCount - 1) * xOffset;
  5143. repeaterSize.height += offset.height + (heightCount - 1) * yOffset;
  5144. }
  5145. repeaterObj.css(repeaterSize);
  5146. // Had to move this here because it sets up cursor: pointer on inline links,
  5147. // but must be done before style cached when adaptive view is set.
  5148. // TODO: Should be able to combine this with initialization done in pregen items. Just need to have ids and template ids be the same.
  5149. for(var i = 0; i < ids.length; i++) $ax.initializeObjectEvents($ax('#' + ids[i]), true);
  5150. }
  5151. var query = _getItemQuery(repeaterId);
  5152. if(viewId) $ax.adaptive.applyView(viewId, query);
  5153. else $ax.visibility.resetLimboAndHiddenToDefaults(_getItemQuery(repeaterId, preevalMap));
  5154. $ax.annotation.InitializeAnnotations(query);
  5155. for(var index = 0; index < ids.length; index++) {
  5156. var id = ids[index];
  5157. var childObj = $obj(id);
  5158. var childJobj = $jobj(id);
  5159. var childItemId = _getItemIdFromElementId(id);
  5160. if(obj.repeaterPropMap.isolateSelection && childJobj.attr('selectiongroup')) {
  5161. childJobj.attr('selectiongroup', _createElementId(childJobj.attr('selectiongroup'), childItemId));
  5162. }
  5163. if ($ax.ieColorManager) $ax.ieColorManager.applyBackground($ax('#' + id));
  5164. $ax.style.initializeObjectTextAlignment($ax('#' + id));
  5165. $ax.applyHighlight($ax('#' + id), true);
  5166. }
  5167. $ax.messageCenter.startCombineEventMessages();
  5168. $ax.cacheRepeaterInfo(repeaterId, $ax.getWidgetInfo(repeaterId));
  5169. // Now load
  5170. for(pos = start; pos < end; pos++) {
  5171. itemId = orderedIds[pos];
  5172. itemElementId = _createElementId(repeaterId, itemId);
  5173. if(!preevalMap[orderedIds[pos]]) $ax.event.raiseSyntheticEvent(itemElementId, 'onItemLoad', true);
  5174. $ax.loadDynamicPanelsAndMasters(obj.objects, path, itemId);
  5175. }
  5176. $ax.removeCachedRepeaterInfo(repeaterId);
  5177. $ax.messageCenter.endCombineEventMessages();
  5178. // Reshow repeater if it was originally shown (load is complete by now)
  5179. if(shown && !itemsPregen) document.getElementById(repeaterId).style.visibility = 'inherit';
  5180. $ax.dynamicPanelManager.fitParentPanel(repeaterId);
  5181. // Right now we assume only one refresh at a time. If we can manually trigger refreshes, that may possibly change.
  5182. $ax.action.refreshEnd();
  5183. };
  5184. _repeaterManager.refreshRepeater = _refreshRepeater;
  5185. var _getItemQuery = function(repeaterId, preevalMap) {
  5186. var query = $ax(function (diagramObject, elementId) {
  5187. // Also need to check that this in not preeval
  5188. if(preevalMap) {
  5189. var itemId = _getItemIdFromElementId(elementId);
  5190. if(preevalMap[itemId]) return false;
  5191. }
  5192. // All objects with the repeater as their parent, except the repeater itself.
  5193. var scriptId = _getScriptIdFromElementId(elementId);
  5194. return $ax.getParentRepeaterFromScriptId(scriptId) == repeaterId && scriptId != repeaterId;
  5195. });
  5196. return query;
  5197. }
  5198. _repeaterManager.refreshAllRepeaters = function() {
  5199. $ax('*').each(function(diagramObject, elementId) {
  5200. if(!$ax.public.fn.IsRepeater(diagramObject.type)) return;
  5201. if($ax.visibility.isElementIdLimboOrInLimboContainer(elementId)) return;
  5202. _initPageInfo(diagramObject, elementId);
  5203. _refreshRepeater(elementId, $ax.getEventInfoFromEvent($ax.getjBrowserEvent()));
  5204. });
  5205. };
  5206. _repeaterManager.refreshRepeaters = function(ids, eventInfo) {
  5207. for(var i = 0; i < ids.length; i++) _refreshRepeater(ids[i], eventInfo);
  5208. };
  5209. var _initPageInfo = function(obj, elementId) {
  5210. var pageInfo = {};
  5211. var map = obj.repeaterPropMap;
  5212. var currentViewId = $ax.adaptive.currentViewId || '';
  5213. var itemsPerPage = _getAdaptiveProp(map, 'itemsPerPage', currentViewId);
  5214. if(itemsPerPage == -1) pageInfo.noLimit = true;
  5215. else {
  5216. pageInfo.itemsPerPage = itemsPerPage;
  5217. pageInfo.currPage = _getAdaptiveProp(map, 'currPage', currentViewId);
  5218. }
  5219. repeaterToPageInfo[elementId] = pageInfo;
  5220. };
  5221. _repeaterManager.initialize = function() {
  5222. $ax(function (obj) {
  5223. return $ax.public.fn.IsRepeater(obj.type);
  5224. }).each(function (obj, repeaterId) {
  5225. _initPregen(repeaterId);
  5226. });
  5227. }
  5228. var _initPregen = function(repeaterId) {
  5229. var obj = $ax.getObjectFromScriptId(repeaterId);
  5230. var propMap = obj.repeaterPropMap;
  5231. //If there is no wrap, then set it to be above the number of rows
  5232. var viewId = $ax.adaptive.currentViewId || '';
  5233. var wrap = _getAdaptiveProp(propMap, 'wrap', viewId);
  5234. var vertical = _getAdaptiveProp(propMap, 'vertical', viewId);
  5235. var orderedIds = [];
  5236. var ids = [];
  5237. var background = _getAdaptiveProp(propMap, 'backColor', viewId);
  5238. var hasAltColor = _getAdaptiveProp(propMap, 'hasAltColor', viewId);
  5239. var altColor = hasAltColor ? _getAdaptiveProp(propMap, 'altColor', viewId) : undefined;
  5240. var useAlt = false;
  5241. var bounds = _getVisibleDataBounds(repeaterToPageInfo[repeaterId], obj.data.length);
  5242. var start = bounds[0];
  5243. var end = bounds[1];
  5244. // Starts empty
  5245. if(start == end) {
  5246. $ax.action.refreshEnd(repeaterId);
  5247. return;
  5248. }
  5249. var unprocessedBaseIds = $jobj($ax.repeater.createElementId(repeaterId, start + 1)).html().match(/(id|for)="?u([0-9]+)/g);
  5250. var baseIds = [];
  5251. if(unprocessedBaseIds) {
  5252. for(var i = 0; i < unprocessedBaseIds.length; i++) {
  5253. var val = unprocessedBaseIds[i].split('=')[1].substr(1);
  5254. if(baseIds.indexOf(val) == -1) baseIds.push(val);
  5255. }
  5256. }
  5257. for(var itemNum = start; itemNum < end; itemNum++) {
  5258. ids.push($ax.repeater.createElementId(repeaterId, itemNum + 1));
  5259. for(i = 0; i < baseIds.length; i++) ids.push($ax.repeater.createElementId(baseIds[i], itemNum + 1));
  5260. var itemId = itemNum + 1;
  5261. orderedIds[itemNum] = itemId;
  5262. var itemDiv = $jobj($ax.repeater.createElementId(repeaterId, itemNum + 1));
  5263. _applyColorCss(useAlt ? altColor : background, itemDiv);
  5264. if(hasAltColor) useAlt = !useAlt;
  5265. }
  5266. resetItemSizes(repeaterId, undefined, bounds, orderedIds, vertical, wrap);
  5267. };
  5268. var _applyColorCss = function(json, div) {
  5269. var args = json.r + ', ' + json.g + ', ' + json.b;
  5270. var background = json.a == 0 ? '' : json.a == 1 ? 'rgb(' + args + ')' : 'rgba(' + args + ', ' + json.a + ')';
  5271. if($ax.ieColorManager && json.a != 0 && json.a != 1) {
  5272. var ieColor = $ax.ieColorManager.getColorFromArgb(json.a * 255, json.r, json.g, json.b, true);
  5273. if(ieColor) background = ieColor;
  5274. }
  5275. div.css('background-color', background);
  5276. return div;
  5277. };
  5278. var _getAdaptiveProp = _repeaterManager.getAdaptiveProp = function(map, prop, viewId) {
  5279. var viewChain = $ax.adaptive.getAdaptiveIdChain(viewId);
  5280. for(var i = viewChain.length - 1; i >= 0; i--) {
  5281. viewId = viewChain[i];
  5282. var viewProps = map[viewId];
  5283. if(viewProps.hasOwnProperty(prop)) return viewProps[prop];
  5284. }
  5285. var base = map[''];
  5286. if(base.hasOwnProperty(prop)) return base[prop];
  5287. return map['default'][prop];
  5288. };
  5289. _repeaterManager.getItemCount = function(repeaterId) {
  5290. var data = repeaterToActiveDataSet[repeaterId].length;
  5291. var info = repeaterToPageInfo[repeaterId];
  5292. if(!info.noLimit) {
  5293. var start = Math.min(data, info.itemsPerPage * info.currPage);
  5294. var end = Math.min(data, start + info.itemsPerPage);
  5295. data = end - start;
  5296. }
  5297. return data;
  5298. };
  5299. _repeaterManager.setDisplayProps = function(obj, repeaterId, itemIndex) {
  5300. var data = repeaterToActiveDataSet[repeaterId];
  5301. var info = repeaterToPageInfo[repeaterId];
  5302. var start = 0;
  5303. var end = data.length;
  5304. if(!info.noLimit) {
  5305. start = Math.min(end, info.itemsPerPage * (info.currPage - 1));
  5306. end = Math.min(end, start + info.itemsPerPage);
  5307. }
  5308. var count = end - start;
  5309. var index = -1;
  5310. for(var i = 0; i < count; i++) {
  5311. if(data[start + i].index == itemIndex) index = i + 1;
  5312. }
  5313. if(index == -1) return;
  5314. obj.index = index;
  5315. obj.isfirst = index == 1;
  5316. obj.islast = index == end - start;
  5317. obj.iseven = index % 2 == 0;
  5318. obj.isodd = index % 2 == 1;
  5319. };
  5320. var _getVisibleDataBounds = function(pageInfo, count) {
  5321. var retval = [0, count];
  5322. if(!pageInfo.noLimit) {
  5323. var end = pageInfo.itemsPerPage * pageInfo.currPage;
  5324. var start = end - pageInfo.itemsPerPage;
  5325. // If past the end, move to last page
  5326. if(start >= count) {
  5327. pageInfo.currPage = Math.floor((count - 1) / pageInfo.itemsPerPage) + 1;
  5328. if(pageInfo.currPage <= 0) pageInfo.currPage = 1;
  5329. end = pageInfo.itemsPerPage * pageInfo.currPage;
  5330. start = end - pageInfo.itemsPerPage;
  5331. }
  5332. end = Math.min(end, count);
  5333. retval[0] = start;
  5334. retval[1] = end;
  5335. }
  5336. return retval;
  5337. };
  5338. _repeaterManager.getVisibleDataCount = function(repeaterId) {
  5339. var bounds = _getVisibleDataBounds(repeaterToPageInfo[repeaterId], repeaterToActiveDataSet[repeaterId].length);
  5340. return bounds[1] - bounds[0];
  5341. };
  5342. _repeaterManager.getDataCount = function(repeaterId) {
  5343. return repeaterToCurrentDataSet[repeaterId].length;
  5344. };
  5345. var _getFilteredDataCount = _repeaterManager.getFilteredDataCount = function(repeaterId) {
  5346. return repeaterToActiveDataSet[repeaterId].length;
  5347. };
  5348. _repeaterManager.getPageCount = function(repeaterId) {
  5349. var info = repeaterToPageInfo[repeaterId];
  5350. return info.noLimit ? 1 : Math.ceil(_getFilteredDataCount(repeaterId) / info.itemsPerPage);
  5351. };
  5352. _repeaterManager.getPageIndex = function(repeaterId) {
  5353. var info = repeaterToPageInfo[repeaterId];
  5354. return info.noLimit ? 1 : info.currPage;
  5355. };
  5356. var getActiveDataSet = function(repeaterId) {
  5357. var active = $ax.deepCopy(repeaterToCurrentDataSet[repeaterId]);
  5358. // Set up 1 indexing each item.
  5359. for(var i = 0; i < active.length; i++) active[i].index = i + 1;
  5360. return active;
  5361. };
  5362. var getOrderedIds = function(repeaterId, eventInfo) {
  5363. var data = repeaterToActiveDataSet[repeaterId] = getActiveDataSet(repeaterId);
  5364. // Filter first so less to sort
  5365. applyFilter(repeaterId, data, eventInfo);
  5366. // Sort next
  5367. var sorts = repeaterToSorts[repeaterId] || [];
  5368. if(sorts.length != 0 && data.length > 1) {
  5369. // TODO: Make this generic and factor out if we want to use it elsewhere...
  5370. // Compare is a function that takes 2 arguments, and returns a number. A high number means the second should go first
  5371. // Otherwise the first stays first.
  5372. var mergesort = function(list, start, end, compare) {
  5373. var middle = Math.floor((start + end) / 2);
  5374. if(middle - start > 1) mergesort(list, start, middle, compare);
  5375. if(end - middle > 1) mergesort(list, middle, end, compare);
  5376. var index1 = start;
  5377. var index2 = middle;
  5378. var tempList = [];
  5379. while(index1 < middle && index2 < end) {
  5380. tempList[tempList.length] = list[compare(list[index1], list[index2]) > 0 ? index2++ : index1++];
  5381. }
  5382. while(index1 < middle) tempList[tempList.length] = list[index1++];
  5383. while(index2 < end) tempList[tempList.length] = list[index2++];
  5384. // transfer from temp list to the real list.
  5385. for(var i = 0; i < tempList.length; i++) list[start + i] = tempList[i];
  5386. };
  5387. // Compare is the tie breaking function to us if necessary.
  5388. var getComparator = function(columnName, ascending, type, compare) {
  5389. // If this needs to be sped up, break up into several smaller functions conditioned off of type
  5390. return function(row1, row2) {
  5391. // If column undefined, no way to measure this, so call it a tie.
  5392. if(row1[columnName] === undefined || row2[columnName] === undefined) return 0;
  5393. var text1 = row1[columnName].text;
  5394. var text2 = row2[columnName].text;
  5395. // This means we are case insensitive, so lowercase everything to kill casing
  5396. if(type == 'Text') {
  5397. text1 = text1.toLowerCase();
  5398. text2 = text2.toLowerCase();
  5399. }
  5400. //If tied, go to tie breaker
  5401. if(text1 == text2) {
  5402. if(compare) return compare(row1, row2);
  5403. // Actually a tie.
  5404. return 0;
  5405. }
  5406. if(type == 'Text' || type == 'Text (Case Sensitive)') {
  5407. if(text1 < text2 ^ ascending) return 1;
  5408. else return -1;
  5409. } else if(type == 'Number') {
  5410. var num1 = Number(text1);
  5411. var num2 = Number(text2);
  5412. if(isNaN(num1) && isNaN(num2)) return 0;
  5413. if(isNaN(num1) || isNaN(num2)) return isNaN(num1) ? 1 : -1;
  5414. if(num1 < num2 ^ ascending) return 1;
  5415. else return -1;
  5416. } else if(type == 'Date - YYYY-MM-DD' || type == 'Date - MM/DD/YYYY') {
  5417. var func = type == 'Date - YYYY-MM-DD' ? getDate1 : getDate2;
  5418. var date1 = func(text1);
  5419. var date2 = func(text2);
  5420. if(!date1.valid && !date2.valid) return 0;
  5421. if(!date1.valid || !date2.valid) return date1.valid ? -1 : 1;
  5422. var diff = date2.year - date1.year;
  5423. if(diff == 0) diff = date2.month - date1.month;
  5424. if(diff == 0) diff = date2.day - date1.day;
  5425. if(diff == 0) return 0;
  5426. return diff > 0 ^ ascending ? 1 : -1;
  5427. }
  5428. console.log('unhandled sort type');
  5429. return 0;
  5430. };
  5431. };
  5432. var compareFunc = null;
  5433. for(var i = 0; i < sorts.length; i++) compareFunc = getComparator(sorts[i].columnName, sorts[i].ascending, sorts[i].sortType, compareFunc);
  5434. mergesort(data, 0, data.length, compareFunc);
  5435. }
  5436. var ids = [];
  5437. for(i = 0; i < data.length; i++) ids[i] = data[i].index;
  5438. return ids;
  5439. };
  5440. var getDate1 = function(text) {
  5441. var date = { valid: false };
  5442. var sections = text.split('-');
  5443. if(sections.length == 1) sections = text.split('/');
  5444. if(sections.length != 3) return date;
  5445. date.year = Number(sections[0]);
  5446. date.month = Number(sections[1]);
  5447. date.day = Number(sections[2]);
  5448. date.valid = !isNaN(date.year);
  5449. date.valid &= !isNaN(date.month) && date.month > 0 && date.month <= 12;
  5450. date.valid &= !isNaN(date.day) && date.day > 0 && date.day <= daysPerMonth(date.month, date.year);
  5451. return date;
  5452. };
  5453. var getDate2 = function(text) {
  5454. var date = { valid: false };
  5455. var sections = text.split('-');
  5456. if(sections.length == 1) sections = text.split('/');
  5457. if(sections.length != 3) return date;
  5458. date.month = Number(sections[0]);
  5459. date.day = Number(sections[1]);
  5460. date.year = Number(sections[2]);
  5461. date.valid = !isNaN(date.year);
  5462. date.valid &= !isNaN(date.month) && date.month > 0 && date.month <= 12;
  5463. date.valid &= !isNaN(date.day) && date.day > 0 && date.day <= daysPerMonth(date.month, date.year);
  5464. return date;
  5465. };
  5466. var daysPerMonth = function(month, year) {
  5467. if(month == 9 || month == 4 || month == 6 || month == 11) return 30;
  5468. if(month != 2) return 31;
  5469. if(year % 4 != 0) return 28;
  5470. if(year % 100 != 0) return 29;
  5471. return year % 400 == 0 ? 29 : 28;
  5472. };
  5473. var applyFilter = function(repeaterId, data, eventInfo) {
  5474. var dataFiltered = [];
  5475. var filters = repeaterToFilters[repeaterId] || [];
  5476. if (filters.length != 0) {
  5477. var oldTarget = eventInfo.targetElement;
  5478. var oldSrc = eventInfo.srcElement;
  5479. var oldThis = eventInfo.thiswidget;
  5480. var oldItem = eventInfo.item;
  5481. var idToWidgetInfo = {};
  5482. outer:
  5483. for(var i = 1; i <= data.length; i++) {
  5484. for(var j = 0; j < filters.length; j++) {
  5485. eventInfo.targetElement = _createElementId(repeaterId, i);
  5486. eventInfo.srcElement = filters[j].thisId;
  5487. if(!idToWidgetInfo[eventInfo.srcElement]) idToWidgetInfo[eventInfo.srcElement] = $ax.getWidgetInfo(eventInfo.srcElement);
  5488. eventInfo.thiswidget = idToWidgetInfo[eventInfo.srcElement];
  5489. eventInfo.item = $ax.getItemInfo(eventInfo.srcElement);
  5490. if($ax.expr.evaluateExpr(filters[j].filter, eventInfo) != 'true') continue outer;
  5491. }
  5492. dataFiltered[dataFiltered.length] = data[i - 1];
  5493. }
  5494. for(i = 0; i < dataFiltered.length; i++) data[i] = dataFiltered[i];
  5495. while(data.length > dataFiltered.length) data.pop();
  5496. eventInfo.targetElement = oldTarget;
  5497. eventInfo.srcElement = oldSrc;
  5498. eventInfo.thiswidget = oldThis;
  5499. eventInfo.item = oldItem;
  5500. }
  5501. };
  5502. var _addFilter = function(repeaterId, removeOtherFilters, label, filter, thisId) {
  5503. if(removeOtherFilters) _removeFilter(repeaterId);
  5504. var filterList = repeaterToFilters[repeaterId];
  5505. if(!filterList) repeaterToFilters[repeaterId] = filterList = [];
  5506. var filterObj = { filter: filter, thisId: thisId };
  5507. if(label) filterObj.label = label;
  5508. filterList[filterList.length] = filterObj;
  5509. };
  5510. _repeaterManager.addFilter = _addFilter;
  5511. var _removeFilter = function(repeaterId, label) {
  5512. var filterList = repeaterToFilters[repeaterId];
  5513. // If no list, nothing to remove
  5514. if(!filterList) return;
  5515. // If no label, remove everything
  5516. if(!label) {
  5517. repeaterToFilters[repeaterId] = [];
  5518. return;
  5519. }
  5520. for(var i = filterList.length - 1; i >= 0; i--) {
  5521. var filterObj = filterList[i];
  5522. if(filterObj.label && filterObj.label == label) $ax.splice(filterList, i, 1);
  5523. }
  5524. };
  5525. _repeaterManager.removeFilter = _removeFilter;
  5526. var _addSort = function(repeaterId, label, columnName, ascending, toggle, sortType) {
  5527. var sortList = repeaterToSorts[repeaterId];
  5528. if(!sortList) repeaterToSorts[repeaterId] = sortList = [];
  5529. for(var i = 0; i < sortList.length; i++) {
  5530. if(columnName == sortList[i].columnName) {
  5531. var lastSortObj = $ax.splice(sortList, i, 1)[0];
  5532. if(toggle) ascending = !lastSortObj.ascending;
  5533. break;
  5534. }
  5535. }
  5536. var sortObj = { columnName: columnName, ascending: ascending, sortType: sortType };
  5537. if(label) sortObj.label = label;
  5538. sortList[sortList.length] = sortObj;
  5539. };
  5540. _repeaterManager.addSort = _addSort;
  5541. var _removeSort = function(repeaterId, label) {
  5542. var sortList = repeaterToSorts[repeaterId];
  5543. // If no list, nothing to remove
  5544. if(!sortList) return;
  5545. // If no label, remove everything
  5546. if(!label) {
  5547. repeaterToSorts[repeaterId] = [];
  5548. return;
  5549. }
  5550. for(var i = sortList.length - 1; i >= 0; i--) {
  5551. var sortObj = sortList[i];
  5552. if(sortObj.label && sortObj.label == label) $ax.splice(sortList, i, 1);
  5553. }
  5554. };
  5555. _repeaterManager.removeSort = _removeSort;
  5556. var _setRepeaterToPage = function(repeaterId, type, value, eventInfo) {
  5557. var pageInfo = repeaterToPageInfo[repeaterId];
  5558. // page doesn't matter if there is no limit.
  5559. if(pageInfo.noLimit) return;
  5560. var dataSet = repeaterToActiveDataSet[repeaterId];
  5561. if(!dataSet) dataSet = repeaterToCurrentDataSet[repeaterId];
  5562. var lastPage = Math.max(1, Math.ceil(dataSet.length / pageInfo.itemsPerPage));
  5563. if(type == 'Value') {
  5564. var val = Number($ax.expr.evaluateExpr(value, eventInfo));
  5565. // if invalid, default to 1, otherwise, clamp the value
  5566. if(isNaN(val)) val = 1;
  5567. else if(val < 1) val = 1;
  5568. else if(val > lastPage) val = lastPage;
  5569. pageInfo.currPage = val;
  5570. } else if(type == 'Previous') {
  5571. if(pageInfo.currPage > 1) pageInfo.currPage--;
  5572. } else if(type == 'Next') {
  5573. if(pageInfo.currPage < lastPage) pageInfo.currPage++;
  5574. } else if(type == 'Last') {
  5575. pageInfo.currPage = lastPage;
  5576. } else {
  5577. console.log('Unknown type');
  5578. }
  5579. };
  5580. _repeaterManager.setRepeaterToPage = _setRepeaterToPage;
  5581. var _setNoItemLimit = function(repeaterId) {
  5582. var pageInfo = repeaterToPageInfo[repeaterId];
  5583. delete pageInfo.currPage;
  5584. delete pageInfo.itemsPerPage;
  5585. pageInfo.noLimit = true;
  5586. };
  5587. _repeaterManager.setNoItemLimit = _setNoItemLimit;
  5588. var _setItemLimit = function(repeaterId, value, eventInfo) {
  5589. var pageInfo = repeaterToPageInfo[repeaterId];
  5590. if(pageInfo.noLimit) {
  5591. pageInfo.noLimit = false;
  5592. pageInfo.currPage = 1;
  5593. }
  5594. var oldTarget = eventInfo.targetElement;
  5595. eventInfo.targetElement = repeaterId;
  5596. var itemLimit = Number($ax.expr.evaluateExpr(value, eventInfo));
  5597. eventInfo.targetElement = oldTarget;
  5598. if(isNaN(itemLimit)) itemLimit = 20;
  5599. else if(itemLimit < 1) itemLimit = 1;
  5600. pageInfo.itemsPerPage = itemLimit;
  5601. };
  5602. _repeaterManager.setItemLimit = _setItemLimit;
  5603. var removeItems = function(repeaterId) {
  5604. var elementIds = $ax.getChildElementIdsForRepeater(repeaterId);
  5605. var itemId = $ax.getItemIdsForRepeater(repeaterId);
  5606. for(var i = 0; i < itemId.length; i++) $jobj(_createElementId(repeaterId, itemId[i])).remove();
  5607. $ax.visibility.clearLimboAndHiddenIds(elementIds);
  5608. $ax.clearItemsForRepeater(repeaterId);
  5609. };
  5610. var repeaterSizes = {};
  5611. var resetItemSizes = function (repeaterId, itemSize, bounds, ids, vertical, wrap) {
  5612. var calcItem = !itemSize;
  5613. if(calcItem) itemSize = {};
  5614. var repeaterMap = {};
  5615. repeaterMap.vert = vertical;
  5616. var sizesMap = {};
  5617. var sizes = [];
  5618. var currSizes = wrap == -1 ? sizes : [];
  5619. for(var i = 0; i + bounds[0] < bounds[1]; i++) {
  5620. var itemId = ids[i + bounds[0]];
  5621. if(calcItem) {
  5622. var itemJobj = $jobj(_createElementId(repeaterId, itemId));
  5623. itemSize.width = $ax.getNumFromPx(itemJobj.css('width'));
  5624. itemSize.height = $ax.getNumFromPx(itemJobj.css('height'));
  5625. }
  5626. var size = { itemId: itemId, width: itemSize.width, height: itemSize.height };
  5627. currSizes.push(size);
  5628. sizesMap[size.itemId] = size;
  5629. if(currSizes.length == wrap) {
  5630. sizes.push(currSizes);
  5631. currSizes = [];
  5632. }
  5633. }
  5634. if (wrap != -1 && currSizes.length > 0) sizes.push(currSizes);
  5635. repeaterMap.sizes = sizes;
  5636. repeaterMap.sizesMap = sizesMap;
  5637. repeaterSizes[repeaterId] = repeaterMap;
  5638. };
  5639. _repeaterManager.getItemSize = function(repeaterId, itemId) {
  5640. var repeaterSize = repeaterSizes[repeaterId];
  5641. if (!repeaterSize) return false;
  5642. return repeaterSize.sizesMap[itemId];
  5643. }
  5644. _repeaterManager.setItemSize = function (repeaterId, itemId, width, height) {
  5645. var repeaterSize = repeaterSizes[repeaterId];
  5646. if(!repeaterSize) return false;
  5647. var size = repeaterSize.sizesMap[itemId];
  5648. var deltaX = width - size.width;
  5649. var deltaY = height - size.height;
  5650. if(!deltaX && !deltaY) return false;
  5651. repeaterSize.resized = true;
  5652. if(deltaX) _pushItems(repeaterId, itemId, deltaX, false, true);
  5653. if(deltaY) _pushItems(repeaterId, itemId, deltaY, true, true);
  5654. if(deltaX || deltaY) $ax.event.raiseSyntheticEvent(_createElementId(repeaterId, itemId), 'onItemResize');
  5655. return true;
  5656. }
  5657. var _pushItems = _repeaterManager.pushItems = function (repeaterId, itemId, delta, vertical, suppressFire) {
  5658. if(delta == 0) return;
  5659. // Update repeater item size
  5660. var prop = vertical ? 'height' : 'width';
  5661. var itemObj = $jobj(_createElementId(repeaterId, itemId));
  5662. itemObj.css(prop, $ax.getNumFromPx(itemObj.css(prop)) + delta);
  5663. var repeaterObj = $jobj(repeaterId);
  5664. var repeaterMap = repeaterSizes[repeaterId];
  5665. var sizes = repeaterMap.sizes;
  5666. var wrap = sizes[0].length != undefined;
  5667. var vert = repeaterMap.vert;
  5668. // Not wrapping, has to push in primary direction
  5669. if (!wrap && vert != vertical) {
  5670. var before = 0;
  5671. var after = 0;
  5672. var limit = 0;
  5673. for(var i = 0; i < sizes.length; i++) {
  5674. var size = sizes[i];
  5675. if(size.itemId == itemId) {
  5676. before = size[prop];
  5677. size[prop] += delta;
  5678. after = size[prop];
  5679. } else {
  5680. limit = limit ? Math.max(limit, size[prop]) : size[prop];
  5681. }
  5682. }
  5683. // Repeater delta is because an item can increase secondary direction, but if another item is already larger, then repeater size isn't effected.
  5684. var repeaterDelta = delta;
  5685. if(sizes.length != 1) {
  5686. if(after >= limit) repeaterDelta = after - Math.max(limit, before);
  5687. else if(before > limit) repeaterDelta = limit - before;
  5688. else repeaterDelta = 0;
  5689. }
  5690. _updateRepeaterSize(prop, repeaterObj, repeaterDelta, vert);
  5691. if(!suppressFire) $ax.event.raiseSyntheticEvent(_createElementId(repeaterId, itemId), 'onItemResize');
  5692. return;
  5693. }
  5694. var index = 0;
  5695. var index2 = 0;
  5696. // Get the indices first
  5697. if(wrap) {
  5698. outer:
  5699. for(; index < sizes.length; index++) {
  5700. var innerSizes = sizes[index];
  5701. for(index2 = 0; index2 < innerSizes.length; index2++) if(innerSizes[index2].itemId == itemId) break outer;
  5702. }
  5703. } else {
  5704. for(; index < sizes.length; index++) if(sizes[index].itemId == itemId) break;
  5705. }
  5706. // Find out who is being pushed
  5707. var itemIdsEffected = [];
  5708. if (vert == vertical) {
  5709. // 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.
  5710. repeaterDelta = delta;
  5711. if(wrap && sizes.length > 1) {
  5712. var viewId = $ax.adaptive.currentViewId || '';
  5713. var spacing = _getAdaptiveProp($obj(repeaterId).repeaterPropMap, (vert ? 'vertical' : 'horizontal') + 'Spacing', viewId);
  5714. for(i = 0; i < sizes.length; i++) {
  5715. var rowColSize = 0;
  5716. var rowCol = sizes[i];
  5717. for(var j = 0; j < rowCol.length; j++) {
  5718. if(j != 0) rowColSize += spacing;
  5719. rowColSize += rowCol[j][prop];
  5720. }
  5721. if(i == index) {
  5722. before = rowColSize;
  5723. after = before + delta;
  5724. } else {
  5725. limit = limit ? Math.max(limit, rowColSize) : rowColSize;
  5726. }
  5727. }
  5728. if(after >= limit) repeaterDelta = after - Math.max(limit, before);
  5729. else if (before > limit) repeaterDelta = limit - before;
  5730. else repeaterDelta = 0;
  5731. }
  5732. if (repeaterDelta) {
  5733. _updateRepeaterSize(prop, repeaterObj, repeaterDelta, vert);
  5734. }
  5735. // Done the hard part, calculating/updating new repeater size. Now just resize items and find what to push.
  5736. var array = wrap ? sizes[index] : sizes;
  5737. i = wrap ? index2 : index;
  5738. array[i][prop] += delta;
  5739. for(i++; i < array.length; i++) itemIdsEffected.push(array[i].itemId);
  5740. } else {
  5741. // Secondary push is more interesting. See how much your primary row/column is already pushing, if that changes
  5742. // then effect all rows/columns after it
  5743. // Get the biggest one in the current row/column, ignoring the one we're changing
  5744. var biggest = 0;
  5745. var currSizes = sizes[index];
  5746. for(i = 0; i < currSizes.length; i++) {
  5747. if (i == index2) continue;
  5748. biggest = Math.max(biggest, currSizes[i][prop]);
  5749. }
  5750. var beforeSize = Math.max(biggest, currSizes[index2][prop]);
  5751. currSizes[index2][prop] += delta;
  5752. var afterSize = Math.max(biggest, currSizes[index2][prop]);
  5753. // Nothing pushed/pulled
  5754. if (afterSize == beforeSize) return;
  5755. for(i = index + 1; i < sizes.length; i++) {
  5756. currSizes = sizes[i];
  5757. for(j = 0; j < currSizes.length; j++) itemIdsEffected.push(currSizes[j].itemId);
  5758. }
  5759. // Delta is only how much the whole row/column changed
  5760. delta = afterSize - beforeSize;
  5761. // Repeater resize secondary is determined by the effective delta.
  5762. _updateRepeaterSize(prop, repeaterObj, delta, vert);
  5763. }
  5764. for(i = 0; i < itemIdsEffected.length; i++) {
  5765. var currItemId = itemIdsEffected[i];
  5766. var elementId = _createElementId(repeaterId, currItemId);
  5767. var loc = vertical ? 'top' : 'left';
  5768. var jobj = $jobj(elementId);
  5769. var currVal = Number(jobj.css(loc).replace('px', ''));
  5770. jobj.css(loc, currVal + delta);
  5771. }
  5772. if(!suppressFire) $ax.event.raiseSyntheticEvent(_createElementId(repeaterId, itemId), 'onItemResize');
  5773. }
  5774. var _updateRepeaterSize = function(prop, jobj, delta, vert) {
  5775. if (delta == 0) return;
  5776. var val = $ax.getNumFromPx(jobj.css(prop)) + delta;
  5777. var border = 0;
  5778. if(vert) border += $ax.getNumFromPx(jobj.css('border-top-width')) + $ax.getNumFromPx(jobj.css('border-bottom-width'));
  5779. else border += $ax.getNumFromPx(jobj.css('border-left-width')) + $ax.getNumFromPx(jobj.css('border-right-width'));
  5780. val += border;
  5781. jobj.css(prop, val);
  5782. $ax.dynamicPanelManager.fitParentPanel(jobj.attr('id'));
  5783. }
  5784. var _getDataFromDataSet = function (eventInfo, repeaterId, itemId, propName, type) {
  5785. var row = undefined;
  5786. var deleteMap = eventInfo && eventInfo.repeaterDeleteMap && eventInfo.repeaterDeleteMap[repeaterId];
  5787. if(deleteMap) row = deleteMap.idToRow[itemId];
  5788. if(!row) {
  5789. var itemNum = _getRealItemId(eventInfo, repeaterId, Number(itemId));
  5790. row = repeaterToCurrentDataSet[repeaterId][itemNum];
  5791. }
  5792. // Default to obj with text as empty string, as we don't generate the data for empty props
  5793. var data = row[propName] || { text: '' };
  5794. //For now text is always the default. May change this to depend on context.
  5795. switch(type) {
  5796. case 'data': return data.type == 'text' ? data.text : data
  5797. case 'img': return (data.img && data.img[$ax.adaptive.getSketchKey()]) || data.text;
  5798. default: return (type && data[type]) || data.text;
  5799. }
  5800. //return type == 'data' && data.type != 'text' ? data : (type && data[type]) || data['text'];
  5801. };
  5802. _repeaterManager.getData = _getDataFromDataSet;
  5803. _repeaterManager.hasData = function(id, propName) {
  5804. if(!_getItemIdFromElementId(id)) return false;
  5805. var repeaterId = $ax.getParentRepeaterFromScriptId(_getScriptIdFromElementId(id));
  5806. return Boolean(repeaterToCurrentDataSet[repeaterId] && repeaterToCurrentDataSet[repeaterId].props.indexOf(propName) != -1);
  5807. };
  5808. var _getEventDeleteData = function(eventInfo, repeaterId) {
  5809. var repeaterDeleteMap = eventInfo.repeaterDeleteMap;
  5810. if(!repeaterDeleteMap) repeaterDeleteMap = eventInfo.repeaterDeleteMap = {};
  5811. var myDeleteMap = repeaterDeleteMap[repeaterId];
  5812. if(!myDeleteMap) {
  5813. myDeleteMap = repeaterDeleteMap[repeaterId] = {};
  5814. myDeleteMap.deletedIds = [];
  5815. myDeleteMap.idToRow = {};
  5816. }
  5817. return myDeleteMap;
  5818. };
  5819. var _getRealItemId = function(eventInfo, repeaterId, itemId) {
  5820. var deletedBefore = 0;
  5821. var map = eventInfo.repeaterDeleteMap && eventInfo.repeaterDeleteMap[repeaterId];
  5822. var deletedIds = map && map.deletedIds;
  5823. if(!deletedIds) return itemId - 1;
  5824. for(var i = 0; i < deletedIds.length; i++) if (deletedIds[i] < itemId) deletedBefore++;
  5825. return itemId - deletedBefore - 1;
  5826. }
  5827. var _addItemToDataSet = function(repeaterId, row, itemEventInfo) {
  5828. itemEventInfo.data = true;
  5829. var oldTarget = itemEventInfo.targetElement;
  5830. itemEventInfo.targetElement = repeaterId;
  5831. var dataSet = repeaterToLocalDataSet[repeaterId];
  5832. for(var propName in row) {
  5833. if(!row.hasOwnProperty(propName)) continue;
  5834. var prop = row[propName];
  5835. if(prop.type == 'literal') {
  5836. var retval = $ax.expr.evaluateExpr(prop.literal, itemEventInfo);
  5837. if(typeof (retval) == 'string' || retval instanceof Date) retval = { type: 'text', text: retval };
  5838. row[propName] = retval;
  5839. }
  5840. }
  5841. itemEventInfo.targetElement = oldTarget;
  5842. dataSet[dataSet.length] = row;
  5843. itemEventInfo.data = false;
  5844. };
  5845. _repeaterManager.addItem = _addItemToDataSet;
  5846. var _deleteItemsFromDataSet = function(repeaterId, eventInfo, type, rule) {
  5847. var dataSet = repeaterToCurrentDataSet[repeaterId];
  5848. var deleteDataMap = _getEventDeleteData(eventInfo, repeaterId);
  5849. var items;
  5850. // Should always be this, marked, or rule.
  5851. if(type == 'this') items = [_getItemIdFromElementId(eventInfo.srcElement)];
  5852. else if(type == 'marked') items = $ax.deepCopy(repeaterToEditItems[repeaterId]);
  5853. else {
  5854. // This should be rule
  5855. var visibleData = repeaterToCurrentDataSet[repeaterId];
  5856. items = [];
  5857. var oldTarget = eventInfo.targetElement;
  5858. for(var i = 0; i < visibleData.length + deleteDataMap.deletedIds.length; i++) {
  5859. var index = i + 1;
  5860. if(deleteDataMap.deletedIds.indexOf(index) != -1) continue;
  5861. eventInfo.targetElement = _createElementId(repeaterId, index);
  5862. if($ax.expr.evaluateExpr(rule, eventInfo).toLowerCase() != 'true') continue;
  5863. items.push(index);
  5864. }
  5865. eventInfo.targetElement = oldTarget;
  5866. }
  5867. // Want them decending
  5868. items.sort(function(a, b) { return b - a; });
  5869. var editItems = repeaterToEditItems[repeaterId];
  5870. for(i = 0; i < items.length; i++) {
  5871. var itemId = items[i];
  5872. // Don't delete already deletedItem
  5873. if(deleteDataMap.deletedIds.indexOf(itemId) != -1) continue;
  5874. var deletedRow = $ax.splice(dataSet, _getRealItemId(eventInfo, repeaterId, itemId), 1)[0];
  5875. deleteDataMap.deletedIds.push(itemId);
  5876. deleteDataMap.idToRow[itemId] = deletedRow;
  5877. for(var j = editItems.length - 1; j >= 0; j--) {
  5878. var editItem = editItems[j];
  5879. if(editItem == itemId) $ax.splice(editItems, j, 1);
  5880. else if(editItem > itemId) editItems[j] = editItem - 1;
  5881. }
  5882. }
  5883. };
  5884. _repeaterManager.deleteItems = _deleteItemsFromDataSet;
  5885. var _updateEditItemsInDataSet = function(repeaterId, propMap, eventInfo, type, rule) {
  5886. var oldTarget = eventInfo.targetElement;
  5887. var dataSet = repeaterToCurrentDataSet[repeaterId];
  5888. var items;
  5889. // Should always be this, marked, or rule.
  5890. if(type == 'this') items = [_getItemIdFromElementId(eventInfo.srcElement)];
  5891. else if(type == 'marked') items = repeaterToEditItems[repeaterId];
  5892. else {
  5893. // This should be rule
  5894. var currData = repeaterToCurrentDataSet[repeaterId];
  5895. items = [];
  5896. oldTarget = eventInfo.targetElement;
  5897. for(var i = 0; i < currData.length; i++) {
  5898. var index = i + 1;
  5899. eventInfo.targetElement = _createElementId(repeaterId, index);
  5900. if($ax.expr.evaluateExpr(rule, eventInfo).toLowerCase() != 'true') continue;
  5901. items.push(index);
  5902. }
  5903. eventInfo.targetElement = oldTarget;
  5904. }
  5905. eventInfo.data = true;
  5906. for(var prop in propMap) {
  5907. if(!propMap.hasOwnProperty(prop)) continue;
  5908. for(i = 0; i < items.length; i++) {
  5909. var data = propMap[prop];
  5910. var item = items[i];
  5911. if(data.type == 'literal') {
  5912. eventInfo.targetElement = _createElementId(repeaterId, item);
  5913. data = $ax.expr.evaluateExpr(data.literal, eventInfo);
  5914. if(typeof (data) == 'object' && data.isWidget) data = data.text;
  5915. if(typeof (data) == 'string') data = { type: 'text', text: data };
  5916. }
  5917. dataSet[_getRealItemId(eventInfo, repeaterId, item)][prop] = data;
  5918. }
  5919. }
  5920. eventInfo.targetElement = oldTarget;
  5921. eventInfo.data = false;
  5922. };
  5923. _repeaterManager.updateEditItems = _updateEditItemsInDataSet;
  5924. var _getAllItemIds = function(repeaterId) {
  5925. var retval = [];
  5926. var currDataSet = repeaterToCurrentDataSet[repeaterId];
  5927. for(var i = 0; i < currDataSet.length; i++) retval.push(i + 1);
  5928. return retval;
  5929. };
  5930. _repeaterManager.getAllItemIds = _getAllItemIds;
  5931. var _addEditItemToRepeater = function(repeaterId, itemIds) {
  5932. for(var i = 0; i < itemIds.length; i++) {
  5933. var itemId = Number(itemIds[i]);
  5934. var items = repeaterToEditItems[repeaterId];
  5935. if(items.indexOf(itemId) == -1) items[items.length] = itemId;
  5936. }
  5937. };
  5938. _repeaterManager.addEditItems = _addEditItemToRepeater;
  5939. var _removeEditItemFromRepeater = function(repeaterId, itemIds) {
  5940. for(var i = 0; i < itemIds.length; i++) {
  5941. var itemId = itemIds[i];
  5942. var items = repeaterToEditItems[repeaterId];
  5943. var index = items.indexOf(Number(itemId));
  5944. if(index != -1) $ax.splice(items, index, 1);
  5945. }
  5946. };
  5947. _repeaterManager.removeEditItems = _removeEditItemFromRepeater;
  5948. _repeaterManager.isEditItem = function(repeaterId, itemId) {
  5949. var items = repeaterToEditItems[repeaterId];
  5950. return items.indexOf(Number(itemId)) != -1;
  5951. };
  5952. var _createElementId = function(scriptId, itemId) {
  5953. if(!itemId) return scriptId;
  5954. var i = scriptId.indexOf('_');
  5955. var sections = i > -1 ? [scriptId.substring(0, i), scriptId.substring(i + 1)] : [scriptId];
  5956. var retval = sections[0] + '-' + itemId;
  5957. return sections.length > 1 ? retval + '_' + sections[1] : retval;
  5958. };
  5959. _repeaterManager.createElementId = _createElementId;
  5960. var _getElementId = function(scriptId, childId) {
  5961. var elementId = scriptId;
  5962. if($ax.getParentRepeaterFromScriptId(scriptId)) {
  5963. // Must be in the same item as the child
  5964. var itemId = $ax.repeater.getItemIdFromElementId(childId);
  5965. elementId = $ax.repeater.createElementId(scriptId, itemId);
  5966. }
  5967. return elementId;
  5968. };
  5969. _repeaterManager.getElementId = _getElementId;
  5970. var _getScriptIdFromElementId = function(elementId) {
  5971. if(!elementId) return elementId;
  5972. var sections = elementId.split('-');
  5973. var retval = sections[0];
  5974. if(sections.length <= 1) return retval;
  5975. sections = sections[1].split('_');
  5976. return sections.length > 1 ? retval + '_' + sections[1] : retval;
  5977. };
  5978. _repeaterManager.getScriptIdFromElementId = _getScriptIdFromElementId;
  5979. var _getItemIdFromElementId = function(elementId) {
  5980. var sections = elementId.split('-');
  5981. if(sections.length < 2) return '';
  5982. sections = sections[1].split('_');
  5983. return sections[0];
  5984. };
  5985. _repeaterManager.getItemIdFromElementId = _getItemIdFromElementId;
  5986. // TODO: Just inline this if we keep it this way.
  5987. var _applySuffixToElementId = function(id, suffix) {
  5988. return id + suffix;
  5989. // return _createElementId(_getScriptIdFromElementId(id) + suffix, _getItemIdFromElementId(id));
  5990. };
  5991. _repeaterManager.applySuffixToElementId = _applySuffixToElementId;
  5992. var _removeSuffixFromElementId = function(id) {
  5993. if (id.indexOf('_') != -1) return id.split('_', 1)[0];
  5994. return id;
  5995. }
  5996. _repeaterManager.removeSuffixFromElementId = _removeSuffixFromElementId;
  5997. // var _getRepeaterSize = function(repeaterId) {
  5998. // var itemCount = ($ax.getItemIdsForRepeater(repeaterId) || []).length;
  5999. // if(itemCount == 0) return { width: 0, height: 0 };
  6000. // var repeater = $obj(repeaterId);
  6001. // // Width and height per item;
  6002. // var width = repeater.width;
  6003. // var height = repeater.height;
  6004. // var viewId = $ax.adaptive.currentViewId || '';
  6005. // var widthIncrement = width + _getAdaptiveProp(repeater.repeaterPropMap, 'horizontalSpacing', viewId);
  6006. // var heightIncrement = height + _getAdaptiveProp(repeater.repeaterPropMap, 'verticalSpacing', viewId);
  6007. // var wrap = _getAdaptiveProp(repeater.repeaterPropMap, 'wrap', viewId);
  6008. // var vertical = _getAdaptiveProp(repeater.repeaterPropMap, 'vertical', viewId);
  6009. // if(wrap == -1 || itemCount <= wrap) {
  6010. // if(vertical) height += heightIncrement * (itemCount - 1);
  6011. // else width += widthIncrement * (itemCount - 1);
  6012. // } else {
  6013. // var primaryDim = wrap;
  6014. // var secondaryDim = Math.ceil(itemCount / primaryDim);
  6015. // if(vertical) {
  6016. // height += heightIncrement * (primaryDim - 1);
  6017. // width += widthIncrement * (secondaryDim - 1);
  6018. // } else {
  6019. // width += widthIncrement * (primaryDim - 1);
  6020. // height += heightIncrement * (secondaryDim - 1);
  6021. // }
  6022. // }
  6023. // return { width: width, height: height };
  6024. // };
  6025. // _repeaterManager.getRepeaterSize = _getRepeaterSize;
  6026. });
  6027. // ******* Dynamic Panel Manager ******** //
  6028. $axure.internal(function($ax) {
  6029. // TODO: Probably a lot of the dynamic panel functions from pagescript should be moved here at some point...
  6030. var _dynamicPanelManager = $ax.dynamicPanelManager = {};
  6031. var _isIdFitToContent = _dynamicPanelManager.isIdFitToContent = function(id) {
  6032. var obj = $obj(id);
  6033. if (!obj || !$ax.public.fn.IsDynamicPanel(obj.type) || !obj.fitToContent) return false;
  6034. var jpanel = $jobj(id);
  6035. return !jpanel.attr('data-notfit');
  6036. };
  6037. //this function fit parent panel, also check for parent layer or repeaters
  6038. var _fitParentPanel = function (widgetId) {
  6039. var parentLayer = getParentLayer(widgetId);
  6040. if(parentLayer) {
  6041. if(_updateLayerRectCache(parentLayer)) _fitParentPanel(parentLayer);
  6042. return;
  6043. }
  6044. // Find parent panel if there is one.
  6045. var parentPanelInfo = getParentPanel(widgetId);
  6046. if(parentPanelInfo) {
  6047. var parentId = parentPanelInfo.parent;
  6048. if(_updateFitPanel(parentId, parentPanelInfo.state)) _fitParentPanel(parentId);
  6049. return;
  6050. }
  6051. // Otherwise, try to get parent repeater
  6052. var parentRepeaterId = $ax.getParentRepeaterFromElementId(widgetId);
  6053. var repeaterObj = $obj(parentRepeaterId);
  6054. if(!repeaterObj || widgetId == parentRepeaterId || !repeaterObj.repeaterPropMap.fitToContent) return;
  6055. var itemId = $ax.repeater.getItemIdFromElementId(widgetId);
  6056. var size = getContainerSize($ax.repeater.createElementId(parentRepeaterId, itemId));
  6057. $ax.repeater.setItemSize(parentRepeaterId, itemId, size.width, size.height);
  6058. };
  6059. _dynamicPanelManager.fitParentPanel = _fitParentPanel;
  6060. _dynamicPanelManager.initialize = function() {
  6061. $axure.resize(_handleResize);
  6062. };
  6063. var percentPanelToLeftCache = [];
  6064. var percentPanelsInitialized = false;
  6065. var _handleResize = function() {
  6066. if(percentPanelsInitialized) {
  6067. for(var key in percentPanelToLeftCache) {
  6068. //could optimize to only update non-contained panels
  6069. _updatePanelPercentWidth(key);
  6070. }
  6071. } else {
  6072. $ax('*').each(function(obj, elementId) {
  6073. if(_isPercentWidthPanel(obj)) _updatePanelPercentWidth(elementId);
  6074. });
  6075. percentPanelsInitialized = true;
  6076. }
  6077. };
  6078. var _isPercentWidthPanel = _dynamicPanelManager.isPercentWidthPanel = function(obj) {
  6079. return obj && $ax.public.fn.IsDynamicPanel(obj.type) && obj.percentWidth;
  6080. };
  6081. _dynamicPanelManager.updatePanelContentPercentWidth = function(elementId) {
  6082. // if(_isPercentWidthPanel($obj(elementId))) return;
  6083. var stateChildrenQuery = $jobj(elementId).children('.panel_state');
  6084. stateChildrenQuery.children('.panel_state_content').each(
  6085. function() {
  6086. $(this).children('.ax_dynamic_panel').each(
  6087. function() { _updatePanelPercentWidth(this.id); }
  6088. );
  6089. }
  6090. );
  6091. };
  6092. _dynamicPanelManager.updatePercentPanelCache = function(query) {
  6093. query.each(function(obj, elementId) {
  6094. if(_isPercentWidthPanel(obj)) {
  6095. if(_updatePercentPanelToLeftCache(obj, elementId, true)) {
  6096. _updatePanelPercentWidth(elementId);
  6097. }
  6098. }
  6099. });
  6100. };
  6101. _dynamicPanelManager.resetFixedPanel = function(obj, domElement) {
  6102. if(obj.fixedHorizontal == 'center') domElement.style.marginLeft = "";
  6103. if(obj.fixedVertical == 'middle') domElement.style.marginTop = "";
  6104. };
  6105. _dynamicPanelManager.resetAdaptivePercentPanel = function(obj, domElement) {
  6106. if(!_isPercentWidthPanel(obj)) return;
  6107. if(obj.fixedHorizontal == 'center') domElement.style.marginLeft = "";
  6108. else if(obj.fixedHorizontal == 'right') domElement.style.width = "";
  6109. };
  6110. var _updatePercentPanelToLeftCache = function(obj, elementId, overwrite) {
  6111. var wasUpdated = false;
  6112. var jObj = $jobj(elementId);
  6113. var axObj = $ax('#' + elementId);
  6114. if(percentPanelToLeftCache[elementId] == undefined || overwrite) {
  6115. if(obj.fixedHorizontal == 'center') percentPanelToLeftCache[elementId] = Number(jObj.css('margin-left').replace("px", ""));
  6116. else if(obj.fixedHorizontal == 'right') percentPanelToLeftCache[elementId] = axObj.width() + Number(jObj.css('right').replace("px", ""));
  6117. else percentPanelToLeftCache[elementId] = Number(jObj.css('left').replace("px", ""));
  6118. wasUpdated = true;
  6119. }
  6120. if(obj.fixedHorizontal == 'right' && _isIdFitToContent(elementId)) {
  6121. var fitWidth = getContainerSize($ax.visibility.GetPanelState(elementId) + '_content').width;
  6122. percentPanelToLeftCache[elementId] = fitWidth + Number(jObj.css('right').replace("px", ""));
  6123. wasUpdated = true;
  6124. }
  6125. return wasUpdated;
  6126. };
  6127. var _updatePanelPercentWidth = _dynamicPanelManager.updatePanelPercentWidth = function(elementId) {
  6128. var obj = $obj(elementId);
  6129. if(!_isPercentWidthPanel(obj)) return;
  6130. _updatePercentPanelToLeftCache(obj, elementId, false);
  6131. var width;
  6132. var x;
  6133. if(obj.fixedHorizontal) {
  6134. x = 0;
  6135. width = $(window).width();
  6136. } else {
  6137. var parentPanelInfo = getParentPanel(elementId);
  6138. if(parentPanelInfo) {
  6139. var parentId = parentPanelInfo.parent;
  6140. width = $ax('#' + parentId).width();
  6141. var parentObj = $obj(parentId);
  6142. if(parentObj.percentWidth) {
  6143. var stateId = $ax.repeater.applySuffixToElementId(parentId, '_state' + parentPanelInfo.state);
  6144. var stateContentId = stateId + '_content';
  6145. x = -Number($jobj(stateContentId).css('margin-left').replace("px", ""));
  6146. } else x = 0;
  6147. } else {
  6148. var parentRepeater = $ax.getParentRepeaterFromScriptId($ax.repeater.getScriptIdFromElementId(elementId));
  6149. if(parentRepeater) {
  6150. var itemId = $ax.repeater.getItemIdFromElementId(elementId);
  6151. var itemContainerId = $ax.repeater.createElementId(parentRepeater, itemId);
  6152. x = 0;
  6153. width = $ax('#' + itemContainerId).width();
  6154. } else {
  6155. var $window = $(window);
  6156. width = $window.width();
  6157. var bodyLeft = Number($('body').css('left').replace("px", ""));
  6158. var bodyWidth = Number($('body').css('width').replace("px", ""));
  6159. var isCenter = $ax.adaptive.getPageStyle().pageAlignment == 'center';
  6160. width = Math.max(width, bodyWidth);
  6161. x = isCenter ? -(width - bodyWidth) / 2 - bodyLeft : 0;
  6162. }
  6163. }
  6164. }
  6165. var jObj = $jobj(elementId);
  6166. if(obj.fixedHorizontal == 'left') jObj.css('left', x + 'px');
  6167. else if(obj.fixedHorizontal == 'center') {
  6168. jObj.css('left', x + 'px');
  6169. jObj.css('margin-left', 0 + 'px');
  6170. } else jObj.css('left', x + 'px');
  6171. jObj.css('width', width + 'px');
  6172. var panelLeft = percentPanelToLeftCache[elementId];
  6173. var stateParent = jObj;
  6174. while(stateParent.children()[0].id.indexOf($ax.visibility.CONTAINER_SUFFIX) != -1) stateParent = stateParent.children();
  6175. var stateChildrenQuery = stateParent.children('.panel_state');
  6176. stateChildrenQuery.css('width', width + 'px');
  6177. if(obj.fixedHorizontal == 'center')
  6178. stateChildrenQuery.children('.panel_state_content').css('left', '50%').css('margin-left', panelLeft + 'px');
  6179. else if(obj.fixedHorizontal == 'right')
  6180. stateChildrenQuery.children('.panel_state_content').css('left', width - panelLeft + 'px');
  6181. else stateChildrenQuery.children('.panel_state_content').css('margin-left', panelLeft - x + 'px');
  6182. };
  6183. _dynamicPanelManager.updateParentsOfNonDefaultFitPanels = function () {
  6184. $ax('*').each(function (diagramObject, elementId) {
  6185. if(!$ax.public.fn.IsDynamicPanel(diagramObject.type) || !diagramObject.fitToContent) return;
  6186. if($ax.visibility.isElementIdLimboOrInLimboContainer(elementId)) return;
  6187. var stateId = $ax.visibility.GetPanelState(elementId);
  6188. if(stateId != $ax.repeater.applySuffixToElementId(elementId, '_state0')) _fitParentPanel(elementId);
  6189. });
  6190. };
  6191. //_dynamicPanelManager.updateAllFitPanelsAndLayerSizeCaches = function() {
  6192. // var fitToContent = [];
  6193. // var layers = [];
  6194. // $ax('*').each(function (obj, elementId) {
  6195. // var isFitPanel = $ax.public.fn.IsDynamicPanel(obj.type) && obj.fitToContent;
  6196. // var isLayer = $ax.public.fn.IsLayer(obj.type);
  6197. // if(!isFitPanel && !isLayer) return;
  6198. // if($ax.visibility.isElementIdLimboOrInLimboContainer(elementId)) return;
  6199. // if(isFitPanel) {
  6200. // fitToContent[fitToContent.length] = elementId;
  6201. // } else if(isLayer) {
  6202. // layers[layers.length] = elementId;
  6203. // }
  6204. // });
  6205. // for(var i = fitToContent.length - 1; i >= 0; i--) {
  6206. // var panelId = fitToContent[i];
  6207. // var stateCount = $obj(panelId).diagrams.length;
  6208. // for(var j = 0; j < stateCount; j++) {
  6209. // $ax.dynamicPanelManager.setFitToContentCss(panelId, true);
  6210. // _updateFitPanel(panelId, j, true);
  6211. // }
  6212. // }
  6213. // for(var i = layers.length - 1; i >= 0; i--) {
  6214. // var layerId = layers[i];
  6215. // _updateLayerSizeCache(layerId);
  6216. // }
  6217. //};
  6218. var _getCachedLayerRect = function (elementId) {
  6219. var element = document.getElementById(elementId);
  6220. var rect = {};
  6221. rect.width = Number(element.getAttribute('data-width'));
  6222. rect.height = Number(element.getAttribute('data-height'));
  6223. rect.x = Number(element.getAttribute('data-left'));
  6224. rect.y = Number(element.getAttribute('data-top'));
  6225. return rect;
  6226. }
  6227. var _updateLayerRectCache = function (elementId) {
  6228. var oldRect = _getCachedLayerRect(elementId);
  6229. var axObj = $ax('#' + elementId);
  6230. var size = axObj.size();
  6231. var loc = {};
  6232. loc.x = axObj.locRelativeIgnoreLayer(false);
  6233. loc.y = axObj.locRelativeIgnoreLayer(true);
  6234. var sizeChange = oldRect.width != size.width || oldRect.height != size.height;
  6235. var locChange = oldRect.x != loc.x || oldRect.y != loc.y;
  6236. if(sizeChange || locChange) {
  6237. var element = document.getElementById(elementId);
  6238. if(sizeChange) {
  6239. element.setAttribute('data-width', size.width);
  6240. element.setAttribute('data-height', size.height);
  6241. $ax.event.raiseSyntheticEvent(elementId, 'onResize');
  6242. }
  6243. if(locChange) {
  6244. element.setAttribute('data-left', loc.x);
  6245. element.setAttribute('data-top', loc.y);
  6246. $ax.event.raiseSyntheticEvent(elementId, 'onMove');
  6247. }
  6248. return true;
  6249. }
  6250. return false;
  6251. }
  6252. _dynamicPanelManager.setFitToContentCss = function(elementId, fitToContent, oldWidth, oldHeight) {
  6253. if($ax.dynamicPanelManager.isIdFitToContent(elementId) == fitToContent) return;
  6254. var panel = $jobj(elementId);
  6255. var stateCss;
  6256. var scrollbars = $obj(elementId).scrollbars;
  6257. if(fitToContent) {
  6258. panel.attr('style', '');
  6259. panel.removeAttr('data-notfit');
  6260. stateCss = {};
  6261. stateCss.position = 'relative';
  6262. if(scrollbars != 'none') {
  6263. stateCss.overflow = 'visible';
  6264. stateCss['-webkit-overflow-scrolling'] = 'visible';
  6265. }
  6266. if(scrollbars == 'verticalAsNeeded') {
  6267. stateCss['overflow-x'] = 'visible';
  6268. stateCss['-ms-overflow-x'] = 'visible';
  6269. } else if(scrollbars == 'horizontalAsNeeded') {
  6270. stateCss['overflow-y'] = 'visible';
  6271. stateCss['-ms-overflow-y'] = 'visible';
  6272. }
  6273. panel.children().css(stateCss);
  6274. } else {
  6275. panel.attr('data-notfit', 'true');
  6276. var panelCss = { width: oldWidth, height: oldHeight };
  6277. stateCss = { width: oldWidth, height: oldHeight };
  6278. panelCss.overflow = 'hidden';
  6279. stateCss.position = 'absolute';
  6280. if(scrollbars != 'none') {
  6281. stateCss.overflow = 'auto';
  6282. stateCss['-webkit-overflow-scrolling'] = 'touch';
  6283. }
  6284. if(scrollbars == 'verticalAsNeeded') {
  6285. stateCss['overflow-x'] = 'hidden';
  6286. stateCss['-ms-overflow-x'] = 'hidden';
  6287. } else if(scrollbars == 'horizontalAsNeeded') {
  6288. stateCss['overflow-y'] = 'hidden';
  6289. stateCss['-ms-overflow-y'] = 'hidden';
  6290. }
  6291. panel.css(panelCss);
  6292. panel.children().css(stateCss);
  6293. }
  6294. };
  6295. var _getShownStateId = function (id) {
  6296. var obj = $obj(id);
  6297. if (!obj || !$ax.public.fn.IsDynamicPanel(obj.type)) return id;
  6298. var children = $ax.visibility.applyWidgetContainer(id, true).children();
  6299. for (var i = 0; i < children.length; i++) {
  6300. var child = children[i];
  6301. while ($ax.visibility.isContainer(child.id)) child = $(child).children()[0];
  6302. if (child && child.style && child.style.display != 'none') return child.id;
  6303. }
  6304. return id;
  6305. };
  6306. var _getShownStateObj = function(id) { return $ax('#' + _getShownStateId(id));}
  6307. _dynamicPanelManager.getShownState = function (id) { return $jobj(_getShownStateId(id)); };
  6308. var _getClamp = function(id) {
  6309. var obj = $obj(id);
  6310. if(!obj) return $ax('#' + id);
  6311. if ($ax.public.fn.IsDynamicPanel(obj.type)) return _getShownStateObj(id);
  6312. return $ax('#' + id);
  6313. };
  6314. var _updateFitPanel = function(panelId, stateIndex, initializingView) {
  6315. if(!panelId) return false;
  6316. // Only fit if fitToContent is true
  6317. if(!$ax.dynamicPanelManager.isIdFitToContent(panelId)) return false;
  6318. // Traverse through children to find what size it should be.
  6319. var stateId = $ax.repeater.applySuffixToElementId(panelId, '_state' + stateIndex);
  6320. var stateContentId = stateId + '_content';
  6321. var stateQuery = $jobj(stateId);
  6322. var size = getContainerSize(stateContentId);
  6323. // Skip if size hasn't changed
  6324. var oldWidth = stateQuery.width();
  6325. var oldHeight = stateQuery.height();
  6326. if(oldWidth == size.width && oldHeight == size.height) return false;
  6327. if(!$obj(panelId).percentWidth) stateQuery.width(size.width);
  6328. stateQuery.height(size.height);
  6329. //updatePercentWidth on all child panels
  6330. $jobj(stateContentId).children('.ax_dynamic_panel').each(
  6331. function() { _updatePanelPercentWidth(this.id); }
  6332. );
  6333. //do the following only if it is the current state
  6334. if(stateId != $ax.visibility.GetPanelState(panelId)) return false;
  6335. if(!initializingView) _adjustFixed(panelId, oldWidth, oldHeight, size.width, size.height);
  6336. else if(stateIndex != 0) {
  6337. var state0 = $jobj($ax.repeater.applySuffixToElementId(panelId, '_state0'));
  6338. _adjustFixed(panelId, state0.width(), state0.height(), size.width, size.height);
  6339. }
  6340. $ax.event.raiseSyntheticEvent(panelId, 'onResize');
  6341. $ax.flyoutManager.updateFlyout(panelId);
  6342. return true;
  6343. };
  6344. // widgetId is the one that crawls up masters until it finds a parent panel, targetId is the original widgetId (not the crawling master)
  6345. // finds the immediate parent panel and crawls up through masters but not repeaters
  6346. var getParentPanel = function(widgetId, path, targetId) {
  6347. path = path || $ax.getPathFromScriptId($ax.repeater.getScriptIdFromElementId(widgetId));
  6348. var obj = $obj(widgetId);
  6349. if(obj.parentDynamicPanel) {
  6350. path[path.length - 1] = obj.parentDynamicPanel;
  6351. var parentId = $ax.getScriptIdFromPath(path);
  6352. if(!parentId) return undefined;
  6353. parentId = $ax.repeater.getElementId(parentId, widgetId);
  6354. var parentObj = $obj(parentId);
  6355. var retVal = { parent: parentId };
  6356. for(var i = 0; i < parentObj.diagrams.length; i++) {
  6357. var stateId = $ax.repeater.applySuffixToElementId(parentId, '_state' + i);
  6358. var stateQuery = $jobj(stateId);
  6359. if(stateQuery.find('#' + (targetId || widgetId)).length != 0) {
  6360. retVal.state = i;
  6361. break;
  6362. }
  6363. }
  6364. return retVal;
  6365. }
  6366. if(path.length == 1) return undefined;
  6367. path.pop();
  6368. var parentMaster = $ax.getScriptIdFromPath(path);
  6369. if(!parentMaster) return undefined;
  6370. parentMaster = $ax.repeater.getElementId(parentMaster, widgetId);
  6371. //check if the master is in the same repeater as the widgetId widget
  6372. var parentMasterItemId = $ax.repeater.getItemIdFromElementId(parentMaster);
  6373. var widgetItemId = $ax.repeater.getItemIdFromElementId(widgetId);
  6374. if(parentMasterItemId != widgetItemId) return undefined;
  6375. return getParentPanel(parentMaster, path, targetId || widgetId);
  6376. };
  6377. // finds the immediate parent layer and crawls up through masters but not repeaters or panels
  6378. var getParentLayer = function (widgetId, path) {
  6379. path = path || $ax.getPathFromScriptId($ax.repeater.getScriptIdFromElementId(widgetId));
  6380. //gets immediate parent layer only
  6381. var layerId = $ax.getLayerParentFromElementId(widgetId);
  6382. if(layerId) return layerId;
  6383. if(path.length == 1) return undefined;
  6384. path.pop();
  6385. var parentMaster = $ax.getScriptIdFromPath(path);
  6386. if(!parentMaster) return undefined;
  6387. parentMaster = $ax.repeater.getElementId(parentMaster, widgetId);
  6388. //check if the master is in the same panel as the widgetId widget
  6389. var widgetParentPanel = getParentPanel(widgetId);
  6390. if(widgetParentPanel) {
  6391. var parentMasterParentPanel = getParentPanel(parentMaster);
  6392. if(!parentMasterParentPanel || widgetParentPanel.parent != parentMasterParentPanel.parent) return undefined;
  6393. }
  6394. //check if the master is in the same repeater as the widgetId widget
  6395. var parentMasterItemId = $ax.repeater.getItemIdFromElementId(parentMaster);
  6396. var widgetItemId = $ax.repeater.getItemIdFromElementId(widgetId);
  6397. if(parentMasterItemId != widgetItemId) return undefined;
  6398. return getParentLayer(parentMaster, path);
  6399. };
  6400. // TODO: May be a better location for this. Used currently for rdo and panel state containers
  6401. var getContainerSize = function(containerId) {
  6402. var containerQuery = containerId ? $jobj(containerId) : $('#base');
  6403. var children = containerQuery.children();
  6404. // Default size
  6405. var size = { width: 0, height: 0 };
  6406. for(var i = 0; i < children.length; i++) {
  6407. var child = $(children[i]);
  6408. var childId = child.attr('id');
  6409. //var axChild = $ax('#' + childId).width();
  6410. var childObj = $obj(childId);
  6411. if(!childObj) {
  6412. // On the body there are some children that should be ignored, as they are not objects.
  6413. if(!child.hasClass('basiclink') || child.get(0).tagName.toLowerCase() != 'a') continue;
  6414. // Otherwise it should be a basic link
  6415. var linkChildren = child.children();
  6416. if(!linkChildren.length) continue;
  6417. child = $(linkChildren[0]);
  6418. childId = child.attr('id');
  6419. childObj = $obj(childId);
  6420. }
  6421. // Ignore fixed
  6422. if(!childId || $ax.visibility.limboIds[childId] || !$ax.visibility.IsIdVisible(childId)
  6423. || $ax.public.fn.IsDynamicPanel(childObj.type) && childObj.fixedHorizontal) continue;
  6424. var boundingRect = $ax.public.fn.getWidgetBoundingRect(childId);
  6425. var position = { left: boundingRect.left, top: boundingRect.top };
  6426. var width = boundingRect.width;
  6427. var height = boundingRect.height;
  6428. if($ax.public.fn.IsMaster(childObj.type)) {
  6429. var masterSize = getContainerSize(childId);
  6430. width = masterSize.width;
  6431. height = masterSize.height;
  6432. // } else if($ax.public.fn.IsRepeater(childObj.type)) {
  6433. // var repeaterSize = $ax.repeater.getRepeaterSize(childId);
  6434. // width = repeaterSize.width;
  6435. // height = repeaterSize.height;
  6436. // if(width == 0 && height == 0) continue;
  6437. // position.left += childObj.x;
  6438. // position.top += childObj.y;
  6439. } else if ($ax.public.fn.IsDynamicPanel(childObj.type)) {
  6440. if($ax.dynamicPanelManager.isIdFitToContent(childId)) {
  6441. var stateQuery = $jobj($ax.visibility.GetPanelState(childId));
  6442. width = stateQuery.width();
  6443. height = stateQuery.height();
  6444. }
  6445. }
  6446. size.width = Math.max(size.width, position.left + width);
  6447. size.height = Math.max(size.height, position.top + height);
  6448. }
  6449. return size;
  6450. };
  6451. var _adjustFixed = _dynamicPanelManager.adjustFixed = function(panelId, oldWidth, oldHeight, width, height) {
  6452. var loc = _getFixedPosition(panelId, oldWidth, oldHeight, width, height);
  6453. if(loc) {
  6454. $ax.action.addAnimation(panelId, $ax.action.queueTypes.move, function() {
  6455. $ax.move.MoveWidget(panelId, loc[0], loc[1], { easing: 'none', duration: 0 }, false, null, true);
  6456. });
  6457. }
  6458. };
  6459. var _getFixedPosition = _dynamicPanelManager.getFixedPosition = function(panelId, oldWidth, oldHeight, width, height) {
  6460. var panelObj = $obj(panelId);
  6461. var x = 0;
  6462. var y = 0;
  6463. if(panelObj.fixedHorizontal == 'center') {
  6464. x = (oldWidth - width) / 2;
  6465. }
  6466. if(panelObj.fixedVertical == 'middle') {
  6467. y = (oldHeight - height) / 2;
  6468. }
  6469. return x == 0 && y == 0 ? undefined : [x, y];
  6470. };
  6471. _dynamicPanelManager.getFixedInfo = function(panelId) {
  6472. var panelObj = $obj(panelId);
  6473. if (!panelObj || !$ax.public.fn.IsDynamicPanel(panelObj.type)) return {};
  6474. var jobj = $jobj(panelId);
  6475. if(jobj.css('position') == 'absolute') return {};
  6476. var info = {};
  6477. var horizontal = panelObj.fixedHorizontal;
  6478. if(!horizontal) return info;
  6479. info.fixed = true;
  6480. info.horizontal = horizontal;
  6481. info.vertical = panelObj.fixedVertical;
  6482. if(info.horizontal == 'left') info.x = Number(jobj.css('left').replace('px', ''));
  6483. else if(info.horizontal == 'center') info.x = Number(jobj.css('margin-left').replace('px', ''));
  6484. else if(info.horizontal == 'right') info.x = Number(jobj.css('right').replace('px', ''));
  6485. if(info.vertical == 'top') info.y = Number(jobj.css('top').replace('px', ''));
  6486. else if(info.vertical == 'middle') info.y = Number(jobj.css('margin-top').replace('px', ''));
  6487. else if(info.vertical == 'bottom') info.y = Number(jobj.css('bottom').replace('px', ''));
  6488. return info;
  6489. };
  6490. // Show isn't necessary if this is always done before toggling (which is currently true), but I don't want that
  6491. // change (if it happened) to break this.
  6492. var _compressToggle = function (id, vert, show, easing, duration) {
  6493. var layer = $ax.getTypeFromElementId(id) == $ax.constants.LAYER_TYPE;
  6494. var locProp = vert ? 'top' : 'left';
  6495. var dimProp = vert ? 'height' : 'width';
  6496. var threshold;
  6497. var delta;
  6498. threshold = $ax('#' + id)[locProp](true);
  6499. delta = layer ? $ax('#' + id)[dimProp]() : _getShownStateObj(id)[dimProp]();
  6500. if(!show) {
  6501. // Need to make threshold bottom/right
  6502. threshold += delta;
  6503. // Delta is in the opposite direction
  6504. delta *= -1;
  6505. }
  6506. _compress(id, vert, threshold, delta, easing, duration);
  6507. };
  6508. _dynamicPanelManager.compressToggle = _compressToggle;
  6509. // Used when setting state of dynamic panel
  6510. var _compressDelta = function(id, oldState, newState, vert, easing, duration) {
  6511. var oldQuery = $jobj(oldState);
  6512. var newQuery = $jobj(newState);
  6513. var thresholdProp = vert ? 'top' : 'left';
  6514. var thresholdOffset = vert ? 'height' : 'width';
  6515. var threshold = $ax('#' + id)[thresholdProp](true);
  6516. threshold += oldQuery[thresholdOffset]();
  6517. var delta = newQuery[thresholdOffset]() - oldQuery[thresholdOffset]();
  6518. var clampOffset = vert ? 'width' : 'height';
  6519. var clampWidth = Math.max(oldQuery[clampOffset](), newQuery[clampOffset]());
  6520. _compress(id, vert, threshold, delta, easing, duration, clampWidth);
  6521. };
  6522. _dynamicPanelManager.compressDelta = _compressDelta;
  6523. var _compress = function (id, vert, threshold, delta, easing, duration, clampWidth) {
  6524. // If below, a horizantal clamp, otherwise a vertical clamp
  6525. var clamp = {
  6526. prop: vert ? 'left' : 'top',
  6527. offset: vert ? 'width' : 'height'
  6528. };
  6529. // Get clamp in coords relative to parent. Account for layers farther down
  6530. if($ax.getTypeFromElementId(id) == $ax.constants.LAYER_TYPE) {
  6531. clamp.start = $ax('#' + id)[clamp.prop](true);
  6532. clamp.end = clamp.start + $ax('#' + id)[clamp.offset]();
  6533. } else {
  6534. var clampLoc = $jobj(id);
  6535. if(typeof clampWidth == 'undefined') clampWidth = _getClamp(id)[clamp.offset]();
  6536. clamp.start = Number(clampLoc.css(clamp.prop).replace('px', ''));
  6537. clamp.end = clamp.start + clampWidth;
  6538. }
  6539. // If clamps, threshold, or delta is not a number, can't compress.
  6540. if (isNaN(clamp.start) || isNaN(clamp.end) || isNaN(threshold) || isNaN(delta)) return;
  6541. // Update clamp if fixed, to account for body position (only necessary when page centered)
  6542. if($jobj(id).css('position') == 'fixed') {
  6543. var clampDelta = $('#base').position().left;
  6544. clamp.start -= clampDelta;
  6545. clamp.end -= clampDelta;
  6546. }
  6547. if(!easing) {
  6548. easing = 'none';
  6549. duration = 0;
  6550. }
  6551. var parent = $ax('#' + id).getParents(false, ['item', 'state', 'layer'])[0];
  6552. var obj = parent && $ax.getObjectFromElementId($ax.repeater.removeSuffixFromElementId(parent));
  6553. // Go until you hit a parent item or state, or a layer that is hidden to use as parent.
  6554. // Account for layer container positions as you go.
  6555. while(obj && $ax.public.fn.IsLayer(obj.type) && $ax.visibility.IsIdVisible(parent)) {
  6556. var container = $ax.visibility.applyWidgetContainer(parent, true, true);
  6557. // If layer is using container, offset is going to be necessary
  6558. if(container.length) {
  6559. var offsetX = $ax.getNumFromPx(container.css('left'));
  6560. var offsetY = $ax.getNumFromPx(container.css('top'));
  6561. var clampProp = clamp.prop == 'left' ? offsetX : offsetY;
  6562. var threshProp = clamp.prop == 'left' ? offsetY : offsetX;
  6563. threshold += threshProp;
  6564. clamp.start += clampProp;
  6565. clamp.end += clampProp;
  6566. }
  6567. parent = $ax('#' + parent).getParents(false, ['item', 'state', 'layer'])[0];
  6568. obj = parent && $ax.getObjectFromElementId($ax.repeater.removeSuffixFromElementId(parent));
  6569. }
  6570. // Add container mid push causes strange behavior because we take container into account as we go down, but if after we accounted for it,
  6571. // a container is added, that container is not accounted for with threshold and clamp values.
  6572. var layer = obj && $ax.public.fn.IsLayer(obj.type) && parent;
  6573. if(layer) {
  6574. // If your parent layer is invisible, you want to be relative to it's container. That is true already if it has a container,
  6575. // but if you are just adding one now, then you need to offset your values
  6576. var needsOffset = !$jobj(layer + '_container').length && !$ax.visibility.IsIdVisible(layer);
  6577. $ax.visibility.pushContainer(layer, false);
  6578. if(needsOffset) {
  6579. container = $jobj(layer + '_container');
  6580. offsetX = $ax.getNumFromPx(container.css('left'));
  6581. offsetY = $ax.getNumFromPx(container.css('top'));
  6582. clampProp = clamp.prop == 'left' ? offsetX : offsetY;
  6583. threshProp = clamp.prop == 'left' ? offsetY : offsetX;
  6584. threshold -= threshProp;
  6585. clamp.start -= clampProp;
  6586. clamp.end -= clampProp;
  6587. }
  6588. }
  6589. // Note: If parent is body, some of these aren't widgets
  6590. if(parent && $jobj(parent + '_content').length > 0) parent = parent + '_content';
  6591. if(parent && $jobj(parent + '_container').length > 0) parent = parent + '_container';
  6592. _compressChildrenHelper(id, $(parent ? '#' + parent : '#base').children(), vert, threshold, delta, clamp, easing, duration);
  6593. if(layer) $ax.visibility.popContainer(layer, false);
  6594. // Do item push
  6595. var itemId = $ax.repeater.getItemIdFromElementId(id);
  6596. if(!itemId) return;
  6597. var repeaterId = $ax.getParentRepeaterFromElementId(id);
  6598. // Only need to push when parent is an item directly.
  6599. if(parent != $ax.repeater.createElementId(repeaterId, itemId)) return;
  6600. // If repeater is fit to content, then don't worry about it, it'll be handled elsewhere
  6601. if(!obj.repeaterPropMap.fitToContent) $ax.repeater.pushItems(repeaterId, itemId, delta, vert);
  6602. };
  6603. var _compressChildrenHelper = function (id, children, vert, threshold, delta, clamp, easing, duration, parentLayer) {
  6604. var toMove = [];
  6605. var allMove = true;
  6606. for (var i = 0; i < children.length; i++) {
  6607. var child = $(children[i]);
  6608. //don't move fixed
  6609. if(child.css('position') == 'fixed') continue;
  6610. // Check for basic links
  6611. if(child[0] && child[0].tagName == 'A' && child.hasClass('basiclink')) child = child.children();
  6612. var childId = child.attr('id');
  6613. // Don't move self, and check id to make sure it is a widget.
  6614. if(childId == id || !childId || childId[0] != 'u') {
  6615. allMove = false;
  6616. continue;
  6617. }
  6618. if ($ax.getTypeFromElementId(childId) == $ax.constants.LAYER_TYPE) {
  6619. $ax.visibility.pushContainer(childId, false);
  6620. var addSelf;
  6621. var container = $ax.visibility.applyWidgetContainer(childId, true, true);
  6622. var layerChildren = $ax.visibility.getRealChildren(child.children());
  6623. //if(container.length) {
  6624. var offsetX = -$ax.getNumFromPx(container.css('left'));
  6625. var offsetY = -$ax.getNumFromPx(container.css('top'));
  6626. var clampProp = clamp.prop == 'left' ? offsetX : offsetY;
  6627. var threshProp = clamp.prop == 'left' ? offsetY : offsetX;
  6628. var layerClamp = { prop: clamp.prop, offset: clamp.offset, start: clamp.start + clampProp, end: clamp.end + clampProp };
  6629. addSelf = _compressChildrenHelper(id, layerChildren, vert, threshold + threshProp, delta, layerClamp, easing, duration, childId);
  6630. //} else addSelf = _compressChildrenHelper(id, layerChildren, vert, threshold, delta, clamp, easing, duration, childId);
  6631. if(addSelf) toMove.push(childId);
  6632. else allMove = false;
  6633. $ax.visibility.popContainer(childId, false);
  6634. continue;
  6635. }
  6636. var numbers = childId.substring(1).split('-');
  6637. if(numbers.length < 1 || isNaN(Number(numbers[0])) || (numbers.length == 2 && isNaN(Number(numbers[1]))) || numbers.length > 2) continue;
  6638. var marker, childClamp;
  6639. var axChild = $ax('#' + childId);
  6640. var markerProp = vert ? 'top' : 'left';
  6641. marker = Number(axChild[markerProp](true));
  6642. childClamp = [Number(axChild[clamp.prop](true))];
  6643. // 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.
  6644. var sizeChild = _getShownStateObj(childId);
  6645. childClamp[1] = childClamp[0] + sizeChild[clamp.offset]();
  6646. if(isNaN(marker) || isNaN(childClamp[0]) || isNaN(childClamp[1]) ||
  6647. marker < threshold || childClamp[1] <= clamp.start || childClamp[0] >= clamp.end) {
  6648. allMove = false;
  6649. continue;
  6650. }
  6651. toMove.push(childId);
  6652. }
  6653. if (allMove && parentLayer) {
  6654. return true;
  6655. } else {
  6656. for(var i = 0; i < toMove.length; i++) {
  6657. $ax('#' + toMove[i]).moveBy(vert ? 0 : delta, vert ? delta : 0, easing == 'none' ? {} : { duration: duration, easing: easing });
  6658. }
  6659. }
  6660. return false;
  6661. };
  6662. var _parentHandlesStyles = function(id) {
  6663. var parents = $ax('#' + id).getParents(true, ['dynamicPanel', 'layer'])[0];
  6664. if(!parents) return false;
  6665. var directParent = true;
  6666. for(var i = 0; i < parents.length; i++) {
  6667. var parentId = parents[i];
  6668. var parentObj = $obj(parentId);
  6669. if(!parentObj.propagate) {
  6670. directParent = false;
  6671. continue;
  6672. }
  6673. return { id: parentId, direct: directParent };
  6674. }
  6675. return false;
  6676. };
  6677. _dynamicPanelManager.parentHandlesStyles = _parentHandlesStyles;
  6678. var _propagateMouseOver = function(id, value) {
  6679. propagate(id, true, value);
  6680. };
  6681. _dynamicPanelManager.propagateMouseOver = _propagateMouseOver;
  6682. var _propagateMouseDown = function(id, value) {
  6683. propagate(id, false, value);
  6684. };
  6685. _dynamicPanelManager.propagateMouseDown = _propagateMouseDown;
  6686. var propagate = function(id, hover, value) {
  6687. var hoverChildren = function(children) {
  6688. if(!children) return;
  6689. for(var i = 0; i < children.length; i++) {
  6690. var elementId = children[i].id;
  6691. var obj = $obj(elementId);
  6692. if(obj == null) {
  6693. elementId = elementId.split('_')[0];
  6694. obj = $obj(elementId);
  6695. }
  6696. if(obj == null) continue;
  6697. if (($ax.public.fn.IsDynamicPanel(obj.type) || $ax.public.fn.IsLayer(obj.type)) && !obj.propagate) continue;
  6698. if(hover) $ax.style.SetWidgetHover(elementId, value);
  6699. else $ax.style.SetWidgetMouseDown(elementId, value);
  6700. $ax.annotation.updateLinkLocations($ax.style.GetTextIdFromShape(elementId));
  6701. hoverChildren(children[i].children);
  6702. }
  6703. };
  6704. hoverChildren($ax('#' + id).getChildren(true)[0].children);
  6705. };
  6706. });
  6707. //***** sto.js *****//
  6708. $axure.internal(function($ax) {
  6709. var funcs = {};
  6710. var weekday = new Array(7);
  6711. weekday[0] = "Sunday";
  6712. weekday[1] = "Monday";
  6713. weekday[2] = "Tuesday";
  6714. weekday[3] = "Wednesday";
  6715. weekday[4] = "Thursday";
  6716. weekday[5] = "Friday";
  6717. weekday[6] = "Saturday";
  6718. funcs.getDayOfWeek = function() {
  6719. return _getDayOfWeek(this.getDay());
  6720. };
  6721. var _getDayOfWeek = $ax.getDayOfWeek = function(day) {
  6722. return weekday[day];
  6723. };
  6724. var month = new Array(12);
  6725. month[0] = "January";
  6726. month[1] = "February";
  6727. month[2] = "March";
  6728. month[3] = "April";
  6729. month[4] = "May";
  6730. month[5] = "June";
  6731. month[6] = "July";
  6732. month[7] = "August";
  6733. month[8] = "September";
  6734. month[9] = "October";
  6735. month[10] = "November";
  6736. month[11] = "December";
  6737. funcs.getMonthName = function() {
  6738. return _getMonthName(this.getMonth());
  6739. };
  6740. var _getMonthName = $ax.getMonthName = function(monthNum) {
  6741. return month[monthNum];
  6742. };
  6743. funcs.getMonth = function() {
  6744. return this.getMonth() + 1;
  6745. };
  6746. funcs.addYears = function(years) {
  6747. var retVal = new Date(this.valueOf());
  6748. retVal.setFullYear(this.getFullYear() + Number(years));
  6749. return retVal;
  6750. };
  6751. funcs.addMonths = function(months) {
  6752. var retVal = new Date(this.valueOf());
  6753. retVal.setMonth(this.getMonth() + Number(months));
  6754. return retVal;
  6755. };
  6756. funcs.addDays = function(days) {
  6757. var retVal = new Date(this.valueOf());
  6758. retVal.setDate(this.getDate() + Number(days));
  6759. return retVal;
  6760. };
  6761. funcs.addHours = function(hours) {
  6762. var retVal = new Date(this.valueOf());
  6763. retVal.setHours(this.getHours() + Number(hours));
  6764. return retVal;
  6765. };
  6766. funcs.addMinutes = function(minutes) {
  6767. var retVal = new Date(this.valueOf());
  6768. retVal.setMinutes(this.getMinutes() + Number(minutes));
  6769. return retVal;
  6770. };
  6771. funcs.addSeconds = function(seconds) {
  6772. var retVal = new Date(this.valueOf());
  6773. retVal.setSeconds(this.getSeconds() + Number(seconds));
  6774. return retVal;
  6775. };
  6776. funcs.addMilliseconds = function(milliseconds) {
  6777. var retVal = new Date(this.valueOf());
  6778. retVal.setMilliseconds(this.getMilliseconds() + Number(milliseconds));
  6779. return retVal;
  6780. };
  6781. var _stoHandlers = {};
  6782. _stoHandlers.literal = function(sto, scope, eventInfo) {
  6783. return sto.value;
  6784. };
  6785. //need angle bracket syntax because var is a reserved word
  6786. _stoHandlers['var'] = function(sto, scope, eventInfo) {
  6787. // Can't us 'A || B' here, because the first value can be false, true, or empty string and still be valid.
  6788. var retVal = scope.hasOwnProperty(sto.name) ? scope[sto.name] : $ax.globalVariableProvider.getVariableValue(sto.name, eventInfo);
  6789. // Handle desired type here?
  6790. if(retVal && retVal.exprType) {
  6791. retVal = $ax.expr.evaluateExpr(retVal, eventInfo);
  6792. }
  6793. if((sto.desiredType == 'int' || sto.desiredType == 'float')) {
  6794. var num = new Number(retVal);
  6795. retVal = isNaN(num.valueOf()) ? retVal : num;
  6796. }
  6797. return retVal;
  6798. };
  6799. //TODO: Perhaps repeaterId can be detirmined at generation, and stored in the sto info.
  6800. _stoHandlers.item = function(sto, scope, eventInfo, prop) {
  6801. prop = prop || (eventInfo.data ? 'data' : eventInfo.link ? 'url' : eventInfo.image ? 'img' : 'text');
  6802. var id = sto.isTarget || !$ax.repeater.hasData(eventInfo.srcElement, sto.name) ? eventInfo.targetElement : eventInfo.srcElement;
  6803. return getData(eventInfo, id, sto.name, prop);
  6804. };
  6805. var getData = function(eventInfo, id, name, prop) {
  6806. var repeaterId = $ax.getParentRepeaterFromScriptId($ax.repeater.getScriptIdFromElementId(id));
  6807. var itemId = $ax.repeater.getItemIdFromElementId(id);
  6808. return $ax.repeater.getData(eventInfo, repeaterId, itemId, name, prop);
  6809. };
  6810. _stoHandlers.paren = function(sto, scope, eventInfo) {
  6811. return _evaluateSTO(sto.innerSTO, scope, eventInfo);
  6812. };
  6813. _stoHandlers.fCall = function(sto, scope, eventInfo) {
  6814. //TODO: [mas] handle required type
  6815. var thisObj = _evaluateSTO(sto.thisSTO, scope, eventInfo);
  6816. if(sto.thisSTO.desiredType == 'string' && sto.thisSTO.computedType != 'string') thisObj = thisObj.toString();
  6817. var args = [];
  6818. for(var i = 0; i < sto.arguments.length; i++) {
  6819. args[i] = _evaluateSTO(sto.arguments[i], scope, eventInfo);
  6820. }
  6821. var fn = (funcs.hasOwnProperty(sto.func) && funcs[sto.func]) || thisObj[sto.func];
  6822. return fn.apply(thisObj, args);
  6823. };
  6824. _stoHandlers.propCall = function(sto, scope, eventInfo) {
  6825. //TODO: [mas] handle required type
  6826. if((sto.prop == 'url' || sto.prop == 'img') && sto.thisSTO.sto == 'item') return _stoHandlers.item(sto.thisSTO, scope, eventInfo, sto.prop);
  6827. var thisObj = _evaluateSTO(sto.thisSTO, scope, eventInfo);
  6828. return thisObj[sto.prop];
  6829. };
  6830. var _binOps = {};
  6831. _binOps['+'] = function(left, right) {
  6832. if(left instanceof Date) return addDayToDate(left, right);
  6833. if(right instanceof Date) return addDayToDate(right, left);
  6834. var num = Number(left) + Number(right);
  6835. return isNaN(num) ? (String(left) + String(right)) : num;
  6836. };
  6837. _binOps['-'] = function(left, right) {
  6838. if(left instanceof Date) return addDayToDate(left, -right);
  6839. return left - right;
  6840. };
  6841. _binOps['*'] = function(left, right) { return Number(left) * Number(right); };
  6842. _binOps['/'] = function(left, right) { return Number(left) / Number(right); };
  6843. _binOps['%'] = function(left, right) { return Number(left) % Number(right); };
  6844. _binOps['=='] = function(left, right) { return _getBool(left) == _getBool(right); };
  6845. _binOps['!='] = function(left, right) { return _getBool(left) != _getBool(right); };
  6846. _binOps['<'] = function(left, right) { return Number(left) < Number(right); };
  6847. _binOps['<='] = function(left, right) { return Number(left) <= Number(right); };
  6848. _binOps['>'] = function(left, right) { return Number(left) > Number(right); };
  6849. _binOps['>='] = function(left, right) { return Number(left) >= Number(right); };
  6850. _binOps['&&'] = function(left, right) { return _getBool(left) && _getBool(right); };
  6851. _binOps['||'] = function(left, right) { return _getBool(left) || _getBool(right); };
  6852. // TODO: Move this to generic place to be used.
  6853. var addDayToDate = function(date, days) {
  6854. var retVal = new Date(date.valueOf());
  6855. retVal.setDate(date.getDate() + days);
  6856. return retVal;
  6857. };
  6858. var _unOps = {};
  6859. _unOps['+'] = function(arg) { return +arg; };
  6860. _unOps['-'] = function(arg) { return -arg; };
  6861. _unOps['!'] = function(arg) { return !_getBool(arg); };
  6862. _stoHandlers.binOp = function(sto, scope, eventInfo) {
  6863. var left = _evaluateSTO(sto.leftSTO, scope, eventInfo);
  6864. var right = _evaluateSTO(sto.rightSTO, scope, eventInfo);
  6865. return _binOps[sto.op](left, right);
  6866. };
  6867. _stoHandlers.unOp = function(sto, scope, eventInfo) {
  6868. var input = _evaluateSTO(sto.inputSTO, scope, eventInfo);
  6869. return _unOps[sto.op](input);
  6870. };
  6871. var _getBool = function(val) {
  6872. var lowerVal = val.toLowerCase ? val.toLowerCase() : val;
  6873. return lowerVal == "false" ? false : lowerVal == "true" ? true : val;
  6874. };
  6875. $ax.getBool = _getBool;
  6876. var _evaluateSTO = function(sto, scope, eventInfo) {
  6877. if(sto.sto == 'error') return undefined;
  6878. return _tryEscapeRichText(castSto(_stoHandlers[sto.sto](sto, scope, eventInfo), sto), eventInfo);
  6879. };
  6880. $ax.evaluateSTO = _evaluateSTO;
  6881. var castSto = function(val, sto) {
  6882. var type = sto.computedType || sto.desiredType;
  6883. if(type == 'string') val = String(val);
  6884. else if(type == 'date' && !(val instanceof Date)) val = new Date(val);
  6885. else if(type == 'int' || type == 'float') val = Number(val);
  6886. else if(type == 'bool') val = Boolean(val);
  6887. return val;
  6888. };
  6889. var _tryEscapeRichText = function(text, eventInfo) {
  6890. return eventInfo.htmlLiteral ? _escapeRichText(text) : text;
  6891. };
  6892. var _escapeRichText = function(text) {
  6893. if(typeof (text) != 'string') return text;
  6894. return text.replace('<', '&lt;');
  6895. };
  6896. });
  6897. //***** utils.temp.js *****//
  6898. // ******* Deep Copy ******** //
  6899. $axure.internal(function($ax) {
  6900. // 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).
  6901. var _deepCopy = function(original, trackCopies) {
  6902. if(trackCopies) {
  6903. var index = _getCopyIndex(original);
  6904. if(index != -1) return _originalToCopy[index][1];
  6905. }
  6906. var isArray = original instanceof Array;
  6907. var isObject = !(original instanceof Function) && !(original instanceof Date) && (original instanceof Object);
  6908. if(!isArray && !isObject) return original;
  6909. var copy = isArray ? [] : { };
  6910. if(trackCopies) _originalToCopy.push([original, copy]);
  6911. isArray ? deepCopyArray(original, trackCopies, copy) : deepCopyObject(original, trackCopies, copy);
  6912. return copy;
  6913. };
  6914. $ax.deepCopy = _deepCopy;
  6915. // Hacky way to copy event info. Copying dragInfo causes major issues due to infinite loops
  6916. // Hashmap doesn't map objects well. It just toStrings them, making them all the same key. This has to be slow...
  6917. var _originalToCopy = [];
  6918. var _getCopyIndex = function(original) {
  6919. for(var i = 0; i < _originalToCopy.length; i++) if(original === _originalToCopy[i][0]) return i;
  6920. return -1;
  6921. };
  6922. $ax.eventCopy = function(eventInfo) {
  6923. var dragInfo = eventInfo.dragInfo;
  6924. delete eventInfo.dragInfo;
  6925. var copy = _deepCopy(eventInfo, true);
  6926. copy.dragInfo = dragInfo;
  6927. eventInfo.dragInfo = dragInfo;
  6928. // reset the map.
  6929. _originalToCopy = [];
  6930. return copy;
  6931. };
  6932. var deepCopyArray = function(original, trackCopies, copy) {
  6933. for(var i = 0; i < original.length; i++) {
  6934. copy[i] = _deepCopy(original[i], trackCopies);
  6935. }
  6936. };
  6937. var deepCopyObject = function(original, trackCopies, copy) {
  6938. for(var key in original) {
  6939. if(!original.hasOwnProperty(key)) continue;
  6940. copy[key] = _deepCopy(original[key], trackCopies);
  6941. }
  6942. };
  6943. // Our implementation of splice because it is broken in IE8...
  6944. $ax.splice = function(array, startIndex, count) {
  6945. var retval = [];
  6946. if(startIndex >= array.length || startIndex < 0 || count == 0) return retval;
  6947. if(!count || startIndex + count > array.length) count = array.length - startIndex;
  6948. for(var i = 0; i < count; i++) retval[i] = array[startIndex + i];
  6949. for(i = startIndex + count; i < array.length; i++) array[i - count] = array[i];
  6950. for(i = 0; i < count; i++) array.pop();
  6951. return retval;
  6952. };
  6953. });
  6954. // ******* Flow Shape Links ******** //
  6955. $axure.internal(function($ax) {
  6956. if(!$ax.document.configuration.linkFlowsToPages && !$ax.document.configuration.linkFlowsToPagesNewWindow) return;
  6957. $(window.document).ready(function() {
  6958. $ax(function (dObj) { return ($ax.public.fn.IsVector(dObj.type) || $ax.public.fn.IsSnapshot(dObj.type)) && dObj.referencePageUrl; }).each(function (dObj, elementId) {
  6959. var elementIdQuery = $('#' + elementId);
  6960. if($ax.document.configuration.linkFlowsToPages && !$ax.event.HasClick(dObj)) {
  6961. elementIdQuery.css("cursor", "pointer");
  6962. elementIdQuery.click(function() {
  6963. $ax.navigate({
  6964. url: dObj.referencePageUrl,
  6965. target: "current",
  6966. includeVariables: true
  6967. });
  6968. });
  6969. }
  6970. if($ax.document.configuration.linkFlowsToPagesNewWindow) {
  6971. $('#' + elementId + "_ref").append("<div id='" + elementId + "PagePopup' class='refpageimage'></div>");
  6972. $('#' + elementId + "PagePopup").click(function() {
  6973. $ax.navigate({
  6974. url: dObj.referencePageUrl,
  6975. target: "new",
  6976. includeVariables: true
  6977. });
  6978. });
  6979. }
  6980. });
  6981. });
  6982. });
  6983. //***** variables.js *****//
  6984. // ******* GLOBAL VARIABLE PROVIDER ******** //
  6985. $axure.internal(function($ax) {
  6986. var _globalVariableValues = {};
  6987. var _globalVariableProvider = {};
  6988. $ax.globalVariableProvider = _globalVariableProvider;
  6989. var setVariableValue = function(variable, value, suppressBroadcast) {
  6990. if(!(value instanceof Object)) value = value.toString();
  6991. variable = variable.toLowerCase();
  6992. _globalVariableValues[variable] = value;
  6993. if(suppressBroadcast !== true) {
  6994. var varData = {
  6995. globalVarName: variable,
  6996. globalVarValue: value.toString()
  6997. };
  6998. $axure.messageCenter.postMessage('setGlobalVar', varData);
  6999. }
  7000. //Post global var values only if pageData is loaded (suppresses exception which occurs when page loads)
  7001. if($ax.pageData) {
  7002. _postGlobalVarVals();
  7003. }
  7004. };
  7005. _globalVariableProvider.setVariableValue = setVariableValue;
  7006. var getVariableValue = function(variable, eventInfo, ignoreDefaultsForLinkUrl) {
  7007. variable = variable.toLowerCase();
  7008. if(_globalVariableValues[variable] !== undefined) {
  7009. //If this is for the GetLinkUrl function and
  7010. //the current value of the global variable is the same as the default defined in the document, don't return it
  7011. if(ignoreDefaultsForLinkUrl == true && $ax.document.globalVariables[variable] == _globalVariableValues[variable]) {
  7012. return null;
  7013. }
  7014. return _globalVariableValues[variable];
  7015. }
  7016. if($ax.document.globalVariables[variable] !== undefined) return ignoreDefaultsForLinkUrl == true ? null : $ax.document.globalVariables[variable];
  7017. switch(variable) {
  7018. case "pagename": return $ax.pageData.page.name;
  7019. case "now": return eventInfo.now;
  7020. case "gendate": return $ax.pageData.generationDate;
  7021. case "dragx": return $ax.drag.GetDragX();
  7022. case "dragy": return $ax.drag.GetDragY();
  7023. case "totaldragx": return $ax.drag.GetTotalDragX();
  7024. case "totaldragy": return $ax.drag.GetTotalDragY();
  7025. case "dragtime": return $ax.drag.GetDragTime();
  7026. case "math": return Math;
  7027. case "date": return Date;
  7028. case "window": return eventInfo && eventInfo.window;
  7029. case "this": return eventInfo && eventInfo.thiswidget && $ax.getWidgetInfo(eventInfo.thiswidget.elementId);
  7030. case "item": return (eventInfo && eventInfo.item && eventInfo.item.valid && eventInfo.item) || getVariableValue('targetitem', eventInfo, ignoreDefaultsForLinkUrl);
  7031. case "targetitem": return eventInfo && eventInfo.targetElement && $ax.getItemInfo(eventInfo.targetElement);
  7032. case "repeater": return eventInfo && eventInfo.repeater;
  7033. case "target": return eventInfo && eventInfo.targetElement && $ax.getWidgetInfo(eventInfo.targetElement);
  7034. case "cursor": return eventInfo && eventInfo.cursor;
  7035. default:
  7036. var gen = variable.substr(0, 3) == "gen";
  7037. var date = gen ? $ax.pageData.generationDate : new Date();
  7038. var prop = gen ? variable.substr(3) : variable;
  7039. switch(prop) {
  7040. case "day": return date.getDate();
  7041. case "month": return date.getMonth() + 1;
  7042. case "monthname": return $ax.getMonthName(date.getMonth());
  7043. case "dayofweek": return $ax.getDayOfWeek(date.getDay());
  7044. case "year": return date.getFullYear();
  7045. case "time": return date.toLocaleTimeString();
  7046. case "hours": return date.getHours();
  7047. case "minutes": return date.getMinutes();
  7048. case "seconds": return date.getSeconds();
  7049. default: return '';
  7050. }
  7051. }
  7052. };
  7053. _globalVariableProvider.getVariableValue = getVariableValue;
  7054. var load = function() {
  7055. var csum = false;
  7056. var query = (window.location.href.split("#")[1] || ''); //hash.substring(1); Firefox decodes this so & in variables breaks
  7057. if(query.length > 0) {
  7058. var vars = query.split("&");
  7059. for(var i = 0; i < vars.length; i++) {
  7060. var pair = vars[i].split("=");
  7061. var varName = pair[0];
  7062. var varValue = pair[1];
  7063. if(varName) {
  7064. if(varName == 'CSUM') {
  7065. csum = true;
  7066. } else setVariableValue(varName, decodeURIComponent(varValue), true);
  7067. }
  7068. }
  7069. if(!csum && query.length > 250) {
  7070. 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.');
  7071. }
  7072. }
  7073. };
  7074. var getLinkUrl = function(baseUrl) {
  7075. var toAdd = '';
  7076. var definedVariables = _getDefinedVariables();
  7077. for(var i = 0; i < definedVariables.length; i++) {
  7078. var key = definedVariables[i];
  7079. var val = getVariableValue(key, undefined, true);
  7080. if(val != null) {
  7081. if(toAdd.length > 0) toAdd += '&';
  7082. toAdd += key + '=' + encodeURIComponent(val);
  7083. }
  7084. }
  7085. return toAdd.length > 0 ? baseUrl + ($axure.shouldSendVarsToServer() ? '?' : '#') + toAdd + "&CSUM=1" : baseUrl;
  7086. };
  7087. _globalVariableProvider.getLinkUrl = getLinkUrl;
  7088. var _getDefinedVariables = function() {
  7089. return $ax.pageData.variables;
  7090. };
  7091. _globalVariableProvider.getDefinedVariables = _getDefinedVariables;
  7092. var _postGlobalVarVals = function() {
  7093. var retVal = {};
  7094. var definedVariables = _getDefinedVariables();
  7095. for(var i = 0; i < definedVariables.length; i++) {
  7096. var key = definedVariables[i];
  7097. var val = getVariableValue(key);
  7098. if(val != null) {
  7099. retVal[key] = val;
  7100. }
  7101. }
  7102. $ax.messageCenter.postMessage('globalVariableValues', retVal);
  7103. };
  7104. $ax.messageCenter.addMessageListener(function(message, data) {
  7105. if(message == 'getGlobalVariables') {
  7106. _postGlobalVarVals();
  7107. } else if(message == 'resetGlobalVariables') {
  7108. _globalVariableValues = {};
  7109. _postGlobalVarVals();
  7110. }
  7111. });
  7112. load();
  7113. });
  7114. //***** drag.js *****//
  7115. $axure.internal(function($ax) {
  7116. var widgetDragInfo = new Object();
  7117. var _drag = {};
  7118. $ax.drag = _drag;
  7119. $ax.drag.GetWidgetDragInfo = function() {
  7120. return $.extend({}, widgetDragInfo);
  7121. };
  7122. $ax.drag.StartDragWidget = function(event, id) {
  7123. $ax.setjBrowserEvent(jQuery.Event(event));
  7124. if(event.donotdrag) return;
  7125. var x, y;
  7126. var tg;
  7127. if(IE_10_AND_BELOW) {
  7128. x = window.event.clientX + window.document.documentElement.scrollLeft + window.document.body.scrollLeft;
  7129. y = window.event.clientY + window.document.documentElement.scrollTop + window.document.body.scrollTop;
  7130. tg = window.event.srcElement;
  7131. } else {
  7132. if(event.changedTouches) {
  7133. x = event.changedTouches[0].pageX;
  7134. y = event.changedTouches[0].pageY;
  7135. } else {
  7136. x = event.pageX;
  7137. y = event.pageY;
  7138. event.preventDefault();
  7139. }
  7140. tg = event.target;
  7141. }
  7142. widgetDragInfo.hasStarted = false;
  7143. widgetDragInfo.widgetId = id;
  7144. widgetDragInfo.cursorStartX = x;
  7145. widgetDragInfo.cursorStartY = y;
  7146. widgetDragInfo.lastX = x;
  7147. widgetDragInfo.lastY = y;
  7148. widgetDragInfo.currentX = x;
  7149. widgetDragInfo.currentY = y;
  7150. widgetDragInfo.movedWidgets = new Object();
  7151. widgetDragInfo.startTime = (new Date()).getTime();
  7152. widgetDragInfo.targetWidget = tg;
  7153. var movedownName = IE_10_AND_BELOW && $ax.features.supports.windowsMobile ?
  7154. $ax.features.eventNames.mouseDownName : $ax.features.eventNames.mouseMoveName;
  7155. $ax.event.addEvent(document, movedownName, _dragWidget, true);
  7156. $ax.event.addEvent(document, $ax.features.eventNames.mouseUpName, _stopDragWidget, true);
  7157. // if(IE && BROWSER_VERSION < 9) {
  7158. // if($ax.features.supports.windowsMobile) {
  7159. // window.document.attachEvent($ax.features.eventNames.mouseDownName, _dragWidget);
  7160. // window.document.attachEvent($ax.features.eventNames.mouseUpName, _stopDragWidget);
  7161. // } else {
  7162. // window.document.attachEvent('on' + $ax.features.eventNames.mouseMoveName, _dragWidget);
  7163. // window.document.attachEvent('on' + $ax.features.eventNames.mouseUpName, _stopDragWidget);
  7164. // }
  7165. // } else {
  7166. // window.document.addEventListener($ax.features.eventNames.mouseMoveName, _dragWidget, true);
  7167. // window.document.addEventListener($ax.features.eventNames.mouseUpName, _stopDragWidget, true);
  7168. // }
  7169. $ax.legacy.SuppressBubble(event);
  7170. };
  7171. var _dragWidget = function(event) {
  7172. $ax.setjBrowserEvent(jQuery.Event(event));
  7173. var x, y;
  7174. if(IE_10_AND_BELOW) {
  7175. x = window.event.clientX + window.document.documentElement.scrollLeft + window.document.body.scrollLeft;
  7176. y = window.event.clientY + window.document.documentElement.scrollTop + window.document.body.scrollTop;
  7177. } else {
  7178. if(event.changedTouches) {
  7179. x = event.changedTouches[0].pageX;
  7180. y = event.changedTouches[0].pageY;
  7181. //allow scroll (defaults) if only swipe events have cases and delta x is less than 5px and not blocking scrolling
  7182. var deltaX = x - widgetDragInfo.currentX;
  7183. var target = window.document.getElementById(widgetDragInfo.widgetId);
  7184. if($ax.event.hasSyntheticEvent(widgetDragInfo.widgetId, "onDrag") || $ax.event.hasSyntheticEvent(widgetDragInfo.widgetId, "onSwipeUp") ||
  7185. $ax.event.hasSyntheticEvent(widgetDragInfo.widgetId, "onSwipeDown") || (deltaX * deltaX) > 25
  7186. || ($ax.document.configuration.preventScroll && $ax.legacy.GetScrollable(target) == window.document.body)) {
  7187. event.preventDefault();
  7188. }
  7189. } else {
  7190. x = event.pageX;
  7191. y = event.pageY;
  7192. }
  7193. }
  7194. widgetDragInfo.xDelta = x - widgetDragInfo.currentX;
  7195. widgetDragInfo.yDelta = y - widgetDragInfo.currentY;
  7196. widgetDragInfo.lastX = widgetDragInfo.currentX;
  7197. widgetDragInfo.lastY = widgetDragInfo.currentY;
  7198. widgetDragInfo.currentX = x;
  7199. widgetDragInfo.currentY = y;
  7200. widgetDragInfo.currentTime = (new Date()).getTime();
  7201. $ax.legacy.SuppressBubble(event);
  7202. if(!widgetDragInfo.hasStarted) {
  7203. widgetDragInfo.hasStarted = true;
  7204. $ax.event.raiseSyntheticEvent(widgetDragInfo.widgetId, "onDragStart");
  7205. widgetDragInfo.oldBodyCursor = window.document.body.style.cursor;
  7206. window.document.body.style.cursor = 'move';
  7207. var widget = window.document.getElementById(widgetDragInfo.widgetId);
  7208. widgetDragInfo.oldCursor = widget.style.cursor;
  7209. widget.style.cursor = 'move';
  7210. }
  7211. $ax.event.raiseSyntheticEvent(widgetDragInfo.widgetId, "onDrag");
  7212. };
  7213. var _suppressClickAfterDrag = function(event) {
  7214. _removeSuppressEvents();
  7215. $ax.legacy.SuppressBubble(event);
  7216. };
  7217. var _removeSuppressEvents = function () {
  7218. if(IE_10_AND_BELOW) {
  7219. $ax.event.removeEvent(event.srcElement, 'click', _suppressClickAfterDrag, undefined, true);
  7220. $ax.event.removeEvent(widgetDragInfo.targetWidget, 'mousemove', _removeSuppressEvents, undefined, true);
  7221. } else {
  7222. $ax.event.removeEvent(document, "click", _suppressClickAfterDrag, true);
  7223. $ax.event.removeEvent(document, 'mousemove', _removeSuppressEvents, true);
  7224. }
  7225. };
  7226. var _stopDragWidget = function(event) {
  7227. $ax.setjBrowserEvent(jQuery.Event(event));
  7228. var tg;
  7229. var movedownName = IE_10_AND_BELOW && $ax.features.supports.windowsMobile ?
  7230. $ax.features.eventNames.mouseDownName : $ax.features.eventNames.mouseMoveName;
  7231. $ax.event.removeEvent(document, movedownName, _dragWidget, true);
  7232. $ax.event.removeEvent(document, $ax.features.eventNames.mouseUpName, _stopDragWidget, true);
  7233. tg = IE_10_AND_BELOW ? window.event.srcElement : event.target;
  7234. //
  7235. //
  7236. // if(OLD_IE && BROWSER_VERSION < 9) {
  7237. // if($ax.features.supports.windowsMobile) {
  7238. // window.document.detachEvent($ax.features.eventNames.mouseDownName, _dragWidget);
  7239. // window.document.detachEvent($ax.features.eventNames.mouseUpName, _stopDragWidget);
  7240. //
  7241. // } else {
  7242. // window.document.detachEvent('on' + $ax.features.eventNames.mouseMoveName, _dragWidget);
  7243. // window.document.detachEvent('on' + $ax.features.eventNames.mouseUpName, _stopDragWidget);
  7244. // }
  7245. // tg = window.event.srcElement;
  7246. // } else {
  7247. // window.document.removeEventListener($ax.features.eventNames.mouseMoveName, _dragWidget, true);
  7248. // window.document.removeEventListener($ax.features.eventNames.mouseUpName, _stopDragWidget, true);
  7249. // tg = event.target;
  7250. // }
  7251. if(widgetDragInfo.hasStarted) {
  7252. widgetDragInfo.currentTime = (new Date()).getTime();
  7253. $ax.event.raiseSyntheticEvent(widgetDragInfo.widgetId, "onDragDrop");
  7254. if($ax.globalVariableProvider.getVariableValue('totaldragx') < -30 && $ax.globalVariableProvider.getVariableValue('dragtime') < 1000) {
  7255. $ax.event.raiseSyntheticEvent(widgetDragInfo.widgetId, "onSwipeLeft");
  7256. }
  7257. if($ax.globalVariableProvider.getVariableValue('totaldragx') > 30 && $ax.globalVariableProvider.getVariableValue('dragtime') < 1000) {
  7258. $ax.event.raiseSyntheticEvent(widgetDragInfo.widgetId, "onSwipeRight");
  7259. }
  7260. var totalDragY = $ax.globalVariableProvider.getVariableValue('totaldragy');
  7261. if(totalDragY < -30 && $ax.globalVariableProvider.getVariableValue('dragtime') < 1000) {
  7262. $ax.event.raiseSyntheticEvent(widgetDragInfo.widgetId, "onSwipeUp");
  7263. }
  7264. if(totalDragY > 30 && $ax.globalVariableProvider.getVariableValue('dragtime') < 1000) {
  7265. $ax.event.raiseSyntheticEvent(widgetDragInfo.widgetId, "onSwipeDown");
  7266. }
  7267. window.document.body.style.cursor = widgetDragInfo.oldBodyCursor;
  7268. var widget = window.document.getElementById(widgetDragInfo.widgetId);
  7269. // It may be null if OnDragDrop filtered out the widget
  7270. if(widget != null) widget.style.cursor = widgetDragInfo.oldCursor;
  7271. if(widgetDragInfo.targetWidget == tg && !event.changedTouches) {
  7272. // suppress the click after the drag on desktop browsers
  7273. if(IE_10_AND_BELOW && widgetDragInfo.targetWidget) {
  7274. $ax.event.addEvent(widgetDragInfo.targetWidget, 'click', _suppressClickAfterDrag, true, true);
  7275. $ax.event.addEvent(widgetDragInfo.targetWidget, "onmousemove", _removeSuppressEvents, true, true);
  7276. } else {
  7277. $ax.event.addEvent(document, "click", _suppressClickAfterDrag, true);
  7278. $ax.event.addEvent(document, "mousemove", _removeSuppressEvents, true);
  7279. }
  7280. //
  7281. //
  7282. // if(IE && BROWSER_VERSION < 9 && widgetDragInfo.targetWidget) {
  7283. // widgetDragInfo.targetWidget.attachEvent("onclick", _suppressClickAfterDrag);
  7284. // widgetDragInfo.targetWidget.attachEvent("onmousemove", _removeSuppressEvents);
  7285. // } else {
  7286. // window.document.addEventListener("click", _suppressClickAfterDrag, true);
  7287. // window.document.addEventListener("mousemove", _removeSuppressEvents, true);
  7288. // }
  7289. }
  7290. }
  7291. widgetDragInfo.hasStarted = false;
  7292. widgetDragInfo.movedWidgets = new Object();
  7293. return false;
  7294. };
  7295. $ax.drag.GetDragX = function() {
  7296. if(widgetDragInfo.hasStarted) return widgetDragInfo.xDelta;
  7297. return 0;
  7298. };
  7299. $ax.drag.GetDragY = function() {
  7300. if(widgetDragInfo.hasStarted) return widgetDragInfo.yDelta;
  7301. return 0;
  7302. };
  7303. $ax.drag.GetTotalDragX = function() {
  7304. if(widgetDragInfo.hasStarted) return widgetDragInfo.currentX - widgetDragInfo.cursorStartX;
  7305. return 0;
  7306. };
  7307. $ax.drag.GetTotalDragY = function() {
  7308. if(widgetDragInfo.hasStarted) return widgetDragInfo.currentY - widgetDragInfo.cursorStartY;
  7309. return 0;
  7310. };
  7311. $ax.drag.GetDragTime = function() {
  7312. if(widgetDragInfo.hasStarted) return widgetDragInfo.currentTime - widgetDragInfo.startTime;
  7313. return 600000;
  7314. };
  7315. // $ax.drag.GetCursorRectangles = function() {
  7316. // var rects = new Object();
  7317. // rects.lastRect = new rect($ax.lastMouseLocation.x, $ax.lastMouseLocation.y, 1, 1);
  7318. // rects.currentRect = new rect($ax.mouseLocation.x, $ax.mouseLocation.y, 1, 1);
  7319. // return rects;
  7320. // };
  7321. // $ax.drag.GetWidgetRectangles = function(id) {
  7322. // var widget = window.document.getElementById(id);
  7323. // var rects = new Object();
  7324. // rects.lastRect = new rect($ax.legacy.getAbsoluteLeft(widget), $ax.legacy.getAbsoluteTop(widget), Number($('#' + id).css('width').replace("px", "")), Number($('#' + id).css('height').replace("px", "")));
  7325. // rects.currentRect = rects.lastRect;
  7326. // return rects;
  7327. // };
  7328. // $ax.drag.IsEntering = function(movingRects, targetRects) {
  7329. // return !movingRects.lastRect.IntersectsWith(targetRects.currentRect) && movingRects.currentRect.IntersectsWith(targetRects.currentRect);
  7330. // };
  7331. // $ax.drag.IsLeaving = function(movingRects, targetRects) {
  7332. // return movingRects.lastRect.IntersectsWith(targetRects.currentRect) && !movingRects.currentRect.IntersectsWith(targetRects.currentRect);
  7333. // };
  7334. // function IsOver(movingRects, targetRects) {
  7335. // return movingRects.currentRect.IntersectsWith(targetRects.currentRect);
  7336. // }
  7337. // function IsNotOver(movingRects, targetRects) {
  7338. // return !IsOver(movingRects, targetRects);
  7339. // }
  7340. $ax.drag.LogMovedWidgetForDrag = function (id, dragInfo) {
  7341. dragInfo = dragInfo || widgetDragInfo;
  7342. if(dragInfo.hasStarted) {
  7343. var containerIndex = id.indexOf('_container');
  7344. if(containerIndex != -1) id = id.substring(0, containerIndex);
  7345. // If state or other non-widget id, this should not be dragged, and should exit out to avoid exceptions.
  7346. if(!$obj(id)) return;
  7347. var query = $ax('#' + id);
  7348. var x = query.left();
  7349. var y = query.top();
  7350. var movedWidgets = dragInfo.movedWidgets;
  7351. if(!movedWidgets[id]) {
  7352. movedWidgets[id] = new Location(x, y);
  7353. }
  7354. }
  7355. };
  7356. var Location = function(x, y) {
  7357. this.x = x;
  7358. this.y = y;
  7359. };
  7360. $ax.drag.location = Location;
  7361. var Rectangle = $ax.drag.Rectangle = function(x, y, width, height) {
  7362. this.x = x;
  7363. this.y = y;
  7364. this.width = width;
  7365. this.height = height;
  7366. this.right = x + width;
  7367. this.bottom = y + height;
  7368. };
  7369. Rectangle.prototype.IntersectsWith = function(rect) {
  7370. if(this.Invalid()) return false;
  7371. if(rect.length) {
  7372. for(var i = 0; i < rect.length; i++) if(!rect[i].Invalid && this.IntersectsWith(rect[i])) return true;
  7373. return false;
  7374. }
  7375. if(rect.Invalid()) return false;
  7376. return this.x < rect.right && this.right > rect.x && this.y < rect.bottom && this.bottom > rect.y;
  7377. };
  7378. Rectangle.prototype.Invalid = function() {
  7379. return this.x == -1 && this.y == -1 && this.width == -1 && this.height == -1;
  7380. };
  7381. Rectangle.prototype.Move = function(x, y) {
  7382. return new Rectangle(x, y, this.width, this.height);
  7383. };
  7384. });
  7385. //***** move.js *****//
  7386. $axure.internal(function($ax) {
  7387. var _move = {};
  7388. $ax.move = _move;
  7389. var widgetMoveInfo = {};
  7390. //register and return move info, also create container for rootlayer if needed
  7391. $ax.move.PrepareForMove = function (id, x, y, to, options, jobj, rootLayer, skipContainerForRootLayer) {
  7392. var fixedInfo = jobj ? {} : $ax.dynamicPanelManager.getFixedInfo(id);
  7393. var widget = $jobj(id);
  7394. var query = $ax('#' + id);
  7395. var isLayer = $ax.getTypeFromElementId(id) == $ax.constants.LAYER_TYPE;
  7396. if(!rootLayer) {
  7397. rootLayer = _move.getRootLayer(id);
  7398. if (rootLayer && !skipContainerForRootLayer) {
  7399. $ax.visibility.pushContainer(rootLayer, false);
  7400. if (isLayer) widget = $ax.visibility.applyWidgetContainer(id, true);
  7401. }
  7402. }
  7403. if (!jobj) jobj = widget;
  7404. var horzProp = 'left';
  7405. var vertProp = 'top';
  7406. var horzX = to ? x - query.locRelativeIgnoreLayer(false) : x;
  7407. var vertY = to ? y - query.locRelativeIgnoreLayer(true) : y;
  7408. if (fixedInfo.horizontal == 'right') {
  7409. horzProp = 'right';
  7410. horzX = to ? $(window).width() - x - Number(jobj.css('right').replace('px', '')) - query.width() : -x;
  7411. } else if(fixedInfo.horizontal == 'center') {
  7412. horzProp = 'margin-left';
  7413. if (to) horzX = x - $(window).width() / 2;
  7414. }
  7415. if (fixedInfo.vertical == 'bottom') {
  7416. vertProp = 'bottom';
  7417. vertY = to ? $(window).height() - y - Number(jobj.css('bottom').replace('px', '')) - query.height() : -y;
  7418. } else if (fixedInfo.vertical == 'middle') {
  7419. vertProp = 'margin-top';
  7420. if (to) vertY = y - $(window).height() / 2;
  7421. }
  7422. //todo currently this always save the info, which is not needed for compound vector children and maybe some other cases
  7423. //let's optimize it later, only register if registerid is valid..
  7424. widgetMoveInfo[id] = {
  7425. x: horzX,
  7426. y: vertY,
  7427. options: options
  7428. };
  7429. return {
  7430. horzX: horzX,
  7431. vertY: vertY,
  7432. horzProp: horzProp,
  7433. vertProp: vertProp,
  7434. rootLayer: rootLayer,
  7435. jobj: jobj
  7436. };
  7437. };
  7438. $ax.move.GetWidgetMoveInfo = function() {
  7439. return $.extend({}, widgetMoveInfo);
  7440. };
  7441. _move.getRootLayer = function (id) {
  7442. var isLayer = $ax.getTypeFromElementId(id) == $ax.constants.LAYER_TYPE;
  7443. var rootLayer = isLayer ? id : '';
  7444. var parentIds = $ax('#' + id).getParents(true, '*')[0];
  7445. for(var i = 0; i < parentIds.length; i++) {
  7446. var parentId = parentIds[i];
  7447. // Keep climbing up layers until you hit a non-layer. At that point you have your root layer
  7448. if($ax.public.fn.IsLayer($ax.getTypeFromElementId(parentId))) rootLayer = parentId;
  7449. else break;
  7450. }
  7451. return rootLayer;
  7452. };
  7453. $ax.move.MoveWidget = function (id, x, y, options, to, animationCompleteCallback, shouldFire, jobj, skipOnMoveEvent) {
  7454. var moveInfo = $ax.move.PrepareForMove(id, x, y, to, options, jobj);
  7455. $ax.drag.LogMovedWidgetForDrag(id, options.dragInfo);
  7456. var object = $obj(id);
  7457. if(object && $ax.public.fn.IsLayer(object.type)) {
  7458. var childrenIds = $ax.public.fn.getLayerChildrenDeep(id, true);
  7459. //don't push container when register moveinfo for child
  7460. if(!skipOnMoveEvent) {
  7461. for(var i = 0; i < childrenIds.length; i++) $ax.move.PrepareForMove(childrenIds[i], x, y, to, options, null, moveInfo.rootLayer, true);
  7462. }
  7463. }
  7464. //if(!moveInfo) moveInfo = _getMoveInfo(id, x, y, to, options, jobj);
  7465. jobj = moveInfo.jobj;
  7466. _moveElement(id, options, animationCompleteCallback, shouldFire, jobj, moveInfo);
  7467. if(skipOnMoveEvent) return;
  7468. $ax.event.raiseSyntheticEvent(id, "onMove");
  7469. if(childrenIds) {
  7470. for(var i = 0; i < childrenIds.length; i++) $ax.event.raiseSyntheticEvent(childrenIds[i], 'onMove');
  7471. }
  7472. };
  7473. var _moveElement = function (id, options, animationCompleteCallback, shouldFire, jobj, moveInfo){
  7474. var cssStyles = {};
  7475. if(!$ax.dynamicPanelManager.isPercentWidthPanel($obj(id))) cssStyles[moveInfo.horzProp] = '+=' + moveInfo.horzX;
  7476. cssStyles[moveInfo.vertProp] = '+=' + moveInfo.vertY;
  7477. // I don't think root layer is necessary anymore after changes to layer container structure.
  7478. // Wait to try removing it until more stable.
  7479. var rootLayer = moveInfo.rootLayer;
  7480. var query = $addAll(jobj, id);
  7481. if(options.easing == 'none') {
  7482. query.animate(cssStyles, { duration: 0, queue: false });
  7483. if(rootLayer) $ax.visibility.popContainer(rootLayer, false);
  7484. if(animationCompleteCallback) animationCompleteCallback();
  7485. //if this widget is inside a layer, we should just remove the layer from the queue
  7486. if(shouldFire) $ax.action.fireAnimationFromQueue(id, $ax.action.queueTypes.move);
  7487. } else {
  7488. var completeCount = query.length;
  7489. query.animate(cssStyles, {
  7490. duration: options.duration, easing: options.easing, queue: false, complete: function () {
  7491. if (animationCompleteCallback) animationCompleteCallback();
  7492. completeCount--;
  7493. if(completeCount == 0 && rootLayer) $ax.visibility.popContainer(rootLayer, false);
  7494. if(shouldFire) $ax.action.fireAnimationFromQueue(id, $ax.action.queueTypes.move);
  7495. }});
  7496. }
  7497. // //moveinfo is used for moving 'with this'
  7498. // var moveInfo = new Object();
  7499. // moveInfo.x = horzX;
  7500. // moveInfo.y = vertY;
  7501. // moveInfo.options = options;
  7502. // widgetMoveInfo[id] = moveInfo;
  7503. };
  7504. _move.nopMove = function(id, options) {
  7505. var moveInfo = new Object();
  7506. moveInfo.x = 0;
  7507. moveInfo.y = 0;
  7508. moveInfo.options = {};
  7509. moveInfo.options.easing = 'none';
  7510. moveInfo.options.duration = 0;
  7511. widgetMoveInfo[id] = moveInfo;
  7512. // Layer move using container now.
  7513. var obj = $obj(id);
  7514. if($ax.public.fn.IsLayer(obj.type)) if(options.onComplete) options.onComplete();
  7515. $ax.event.raiseSyntheticEvent(id, "onMove");
  7516. };
  7517. //rotationDegree: total degree to rotate
  7518. //centerPoint: the center of the circular path
  7519. var _noRotateOnlyMove = function (id, moveDelta, rotatableMove, fireAnimationQueue, easing, duration, completionCallback) {
  7520. moveDelta.x += rotatableMove.x;
  7521. moveDelta.y += rotatableMove.y;
  7522. if (moveDelta.x == 0 && moveDelta.y == 0) {
  7523. if(fireAnimationQueue) {
  7524. $ax.action.fireAnimationFromQueue(id, $ax.action.queueTypes.rotate);
  7525. $ax.action.fireAnimationFromQueue(id, $ax.action.queueTypes.move);
  7526. }
  7527. } else {
  7528. $jobj(id).animate({ top: '+=' + moveDelta.y, left: '+=' + moveDelta.x }, {
  7529. duration: duration,
  7530. easing: easing,
  7531. queue: false,
  7532. complete: function () {
  7533. if(fireAnimationQueue) {
  7534. $ax.action.fireAnimationFromQueue(id, $ax.action.queueTypes.move);
  7535. $ax.action.fireAnimationFromQueue(id, $ax.action.queueTypes.rotate);
  7536. }
  7537. if (completionCallback) completionCallback();
  7538. }
  7539. });
  7540. }
  7541. }
  7542. _move.circularMove = function (id, degreeDelta, centerPoint, moveDelta, rotatableMove, resizeOffset, options, fireAnimationQueue, completionCallback) {
  7543. var elem = $jobj(id);
  7544. var moveInfo = $ax.move.PrepareForMove(id, moveDelta.x, moveDelta.y, false, options);
  7545. // If not rotating, still need to check moveDelta and may need to handle that.
  7546. if (degreeDelta === 0) {
  7547. _noRotateOnlyMove(id, moveDelta, rotatableMove, fireAnimationQueue, options.easing, options.duration, completionCallback);
  7548. return;
  7549. }
  7550. var stepFunc = function(newDegree) {
  7551. var deg = newDegree - rotation.degree;
  7552. var widgetCenter = $ax.public.fn.getWidgetBoundingRect(id).centerPoint;
  7553. //console.log("widget center of " + id + " x " + widgetCenter.x + " y " + widgetCenter.y);
  7554. var widgetNewCenter = $axure.fn.getPointAfterRotate(deg, widgetCenter, centerPoint);
  7555. // Start by getting the move not related to rotation, and make sure to update center point to move with it.
  7556. var ratio = deg / degreeDelta;
  7557. var xdelta = (moveDelta.x + rotatableMove.x) * ratio;
  7558. var ydelta = (moveDelta.y + rotatableMove.y) * ratio;
  7559. if(resizeOffset) {
  7560. var resizeShift = {};
  7561. resizeShift.x = resizeOffset.x * ratio;
  7562. resizeShift.y = resizeOffset.y * ratio;
  7563. $axure.fn.getPointAfterRotate(rotation.degree, resizeShift, { x: 0, y: 0 });
  7564. xdelta += resizeShift.x;
  7565. ydelta += resizeShift.y;
  7566. }
  7567. centerPoint.x += xdelta;
  7568. centerPoint.y += ydelta;
  7569. // Now for the move that is rotatable, it must be rotated
  7570. rotatableMove = $axure.fn.getPointAfterRotate(deg, rotatableMove, { x: 0, y: 0 });
  7571. // Now add in circular move to the mix.
  7572. xdelta += widgetNewCenter.x - widgetCenter.x;
  7573. ydelta += widgetNewCenter.y - widgetCenter.y;
  7574. if(xdelta < 0) elem.css('left', '-=' + -xdelta);
  7575. else if(xdelta > 0) elem.css('left', '+=' + xdelta);
  7576. if(ydelta < 0) elem.css('top', '-=' + -ydelta);
  7577. else if(ydelta > 0) elem.css('top', '+=' + ydelta);
  7578. };
  7579. var onComplete = function() {
  7580. if(fireAnimationQueue) $ax.action.fireAnimationFromQueue(id, $ax.action.queueTypes.move);
  7581. if(completionCallback) completionCallback();
  7582. if(moveInfo.rootLayer) $ax.visibility.popContainer(moveInfo.rootLayer, false);
  7583. var isPercentWidthPanel = $ax.dynamicPanelManager.isPercentWidthPanel($obj(id));
  7584. if(isPercentWidthPanel) {
  7585. $ax.dynamicPanelManager.updatePanelPercentWidth(id);
  7586. $ax.dynamicPanelManager.updatePanelContentPercentWidth(id);
  7587. }
  7588. if(elem.css('position') == 'fixed') {
  7589. if(!isPercentWidthPanel) elem.css('left', '');
  7590. elem.css('top', '');
  7591. }
  7592. };
  7593. var rotation = { degree: 0 };
  7594. if(!options.easing || options.easing === 'none' || options.duration <= 0) {
  7595. stepFunc(degreeDelta);
  7596. onComplete();
  7597. } else {
  7598. $(rotation).animate({ degree: degreeDelta }, {
  7599. duration: options.duration,
  7600. easing: options.easing,
  7601. queue: false,
  7602. step: stepFunc,
  7603. complete: onComplete
  7604. });
  7605. }
  7606. };
  7607. //rotate a widget by degree, center is 50% 50%
  7608. _move.rotate = function (id, degree, easing, duration, to, shouldFire, completionCallback) {
  7609. var currentDegree = _getRotationDegree(id);
  7610. if(to) degree = degree - currentDegree;
  7611. if(degree === 0) {
  7612. if (shouldFire) $ax.action.fireAnimationFromQueue(id, $ax.action.queueTypes.rotate);
  7613. return;
  7614. }
  7615. var query = $jobj(id).add($jobj(id + '_ann')).add($jobj(id + '_ref'));
  7616. var stepFunc = function(now) {
  7617. var degreeDelta = now - rotation.degree;
  7618. var newDegree = currentDegree + degreeDelta;
  7619. query.css($ax.public.fn.setTransformHowever("rotate(" + newDegree + "deg)"));
  7620. currentDegree = newDegree;
  7621. };
  7622. var onComplete = function() {
  7623. if(shouldFire) {
  7624. $ax.action.fireAnimationFromQueue($ax.public.fn.compoundIdFromComponent(id), $ax.action.queueTypes.rotate);
  7625. }
  7626. if(completionCallback) completionCallback();
  7627. };
  7628. var rotation = { degree: 0 };
  7629. //if no animation, setting duration to 1, to prevent RangeError in rotation loops without animation
  7630. if(!easing || easing === 'none' || duration <= 0) {
  7631. stepFunc(degree);
  7632. onComplete();
  7633. } else {
  7634. $(rotation).animate({ degree: degree }, {
  7635. duration: duration,
  7636. easing: easing,
  7637. queue: false,
  7638. step: stepFunc,
  7639. complete: onComplete
  7640. });
  7641. }
  7642. };
  7643. _move.compoundRotateAround = function (id, degreeDelta, centerPoint, moveDelta, rotatableMove, resizeOffset, easing, duration, fireAnimationQueue, completionCallback) {
  7644. if (degreeDelta === 0) {
  7645. _noRotateOnlyMove($ax.public.fn.compoundIdFromComponent(id), moveDelta, rotatableMove, fireAnimationQueue, easing, duration, completionCallback, $ax.action.queueTypes.rotate);
  7646. return;
  7647. }
  7648. var elem = $jobj(id);
  7649. var rotation = { degree: 0 };
  7650. if (!easing || easing === 'none' || duration <= 0) {
  7651. duration = 1;
  7652. easing = 'linear'; //it doesn't matter anymore here...
  7653. }
  7654. var originalWidth = Number(elem.css('width').replace('px', ''));
  7655. var originalHeight = Number(elem.css('height').replace('px', ''));
  7656. var originalLeft = Number(elem.css('left').replace('px', ''));
  7657. var originalTop = Number(elem.css('top').replace('px', ''));
  7658. $(rotation).animate({ degree: degreeDelta }, {
  7659. duration: duration,
  7660. easing: easing,
  7661. queue: false,
  7662. step: function (newDegree) {
  7663. var transform = $ax.public.fn.transformFromElement(elem[0]);
  7664. var originalCenter = { x: originalLeft + 0.5 * originalWidth, y: originalTop + 0.5 * originalHeight};
  7665. var componentCenter = { x: originalCenter.x + transform[4], y: originalCenter.y + transform[5] };
  7666. var deg = newDegree - rotation.degree;
  7667. var ratio = deg / degreeDelta;
  7668. var xdelta = (moveDelta.x + rotatableMove.x) * ratio;
  7669. var ydelta = (moveDelta.y + rotatableMove.y) * ratio;
  7670. if (resizeOffset) {
  7671. var resizeShift = {};
  7672. resizeShift.x = resizeOffset.x * ratio;
  7673. resizeShift.y = resizeOffset.y * ratio;
  7674. $axure.fn.getPointAfterRotate(rotation.degree, resizeShift, { x: 0, y: 0 });
  7675. xdelta += resizeShift.x;
  7676. ydelta += resizeShift.y;
  7677. }
  7678. var rotationMatrix = $ax.public.fn.rotationMatrix(deg);
  7679. var compositionTransform = $ax.public.fn.matrixMultiplyMatrix(rotationMatrix,
  7680. { m11: transform[0], m21: transform[1], m12: transform[2], m22: transform[3] });
  7681. //console.log("widget center of " + id + " x " + widgetCenter.x + " y " + widgetCenter.y);
  7682. var widgetNewCenter = $axure.fn.getPointAfterRotate(deg, componentCenter, centerPoint);
  7683. var newMatrix = $ax.public.fn.matrixString(compositionTransform.m11, compositionTransform.m21, compositionTransform.m12, compositionTransform.m22,
  7684. widgetNewCenter.x - originalCenter.x + xdelta, widgetNewCenter.y - originalCenter.y + ydelta);
  7685. elem.css($ax.public.fn.setTransformHowever(newMatrix));
  7686. },
  7687. complete: function () {
  7688. if (fireAnimationQueue) {
  7689. $ax.action.fireAnimationFromQueue(elem.parent()[0].id, $ax.action.queueTypes.rotate);
  7690. }
  7691. if(completionCallback) completionCallback();
  7692. }
  7693. });
  7694. };
  7695. var _getRotationDegree = _move.getRotationDegree = function(elementId) {
  7696. if($ax.public.fn.IsLayer($obj(elementId).type)) {
  7697. return $jobj(elementId).data('layerDegree');
  7698. }
  7699. var element = document.getElementById(elementId);
  7700. if(element == null) return NaN;
  7701. //var transformString = element.style.transform ||
  7702. // element.style.OTransform ||
  7703. // element.style.msTransform ||
  7704. // element.style.MozTransform ||
  7705. // element.style.webkitTransform;
  7706. var transformString = element.style['transform'] ||
  7707. element.style['-o-transform'] ||
  7708. element.style['-ms-transform'] ||
  7709. element.style['-moz-transform'] ||
  7710. element.style['-webkit-transform'];
  7711. if(transformString) {
  7712. var rotateRegex = /rotate\(([-?0-9]+)deg\)/;
  7713. var degreeMatch = rotateRegex.exec(transformString);
  7714. if(degreeMatch && degreeMatch[1]) return parseFloat(degreeMatch[1]);
  7715. }
  7716. if(window.getComputedStyle) {
  7717. var st = window.getComputedStyle(element, null);
  7718. } else {
  7719. console.log('rotation is not supported for ie 8 and below in this version of axure rp');
  7720. return 0;
  7721. }
  7722. var tr = st.getPropertyValue("transform") ||
  7723. st.getPropertyValue("-o-transform") ||
  7724. st.getPropertyValue("-ms-transform") ||
  7725. st.getPropertyValue("-moz-transform") ||
  7726. st.getPropertyValue("-webkit-transform");
  7727. if(!tr || tr === 'none') return 0;
  7728. var values = tr.split('(')[1];
  7729. values = values.split(')')[0],
  7730. values = values.split(',');
  7731. var a = values[0];
  7732. var b = values[1];
  7733. var radians = Math.atan2(b, a);
  7734. if(radians < 0) {
  7735. radians += (2 * Math.PI);
  7736. }
  7737. var angle = Math.round(radians * (180 / Math.PI));
  7738. return angle;
  7739. };
  7740. // var generateFilter = function(deg) {
  7741. // var rot, cos, sin, matrix;
  7742. //
  7743. // rot=deg>=0 ? Math.PI*deg/180 : Math.PI*(360+deg)/180;
  7744. // cos=Math.cos(rot);
  7745. // sin=Math.sin(rot);
  7746. // matrix='M11='+cos+',M12='+(-sin)+',M21='+sin+',M22='+cos+',SizingMethod="auto expand"';
  7747. // return 'progid:DXImageTransform.Microsoft.Matrix('+matrix+')';
  7748. // }
  7749. });
  7750. //***** visibility.js *****//
  7751. $axure.internal(function($ax) {
  7752. var document = window.document;
  7753. var _visibility = {};
  7754. $ax.visibility = _visibility;
  7755. var _defaultHidden = {};
  7756. var _defaultLimbo = {};
  7757. // ****************** Visibility and State Functions ****************** //
  7758. var _isIdVisible = $ax.visibility.IsIdVisible = function(id) {
  7759. return $ax.visibility.IsVisible(window.document.getElementById(id));
  7760. };
  7761. $ax.visibility.IsVisible = function(element) {
  7762. //cannot use css('visibility') because that gets the effective visiblity
  7763. //e.g. won't be able to set visibility on panels inside hidden panels
  7764. return element.style.visibility != 'hidden';
  7765. };
  7766. $ax.visibility.SetIdVisible = function(id, visible) {
  7767. $ax.visibility.SetVisible(window.document.getElementById(id), visible);
  7768. // Hide lightbox if necessary
  7769. if(!visible) {
  7770. $jobj($ax.repeater.applySuffixToElementId(id, '_lightbox')).remove();
  7771. $ax.flyoutManager.unregisterPanel(id, true);
  7772. }
  7773. };
  7774. var _setAllVisible = function(query, visible) {
  7775. for(var i = 0; i < query.length; i++) {
  7776. _visibility.SetVisible(query[i], visible);
  7777. }
  7778. }
  7779. $ax.visibility.SetVisible = function (element, visible) {
  7780. //not setting display to none to optimize measuring
  7781. if(visible) {
  7782. if($(element).hasClass(HIDDEN_CLASS)) $(element).removeClass(HIDDEN_CLASS);
  7783. if($(element).hasClass(UNPLACED_CLASS)) $(element).removeClass(UNPLACED_CLASS);
  7784. element.style.display = '';
  7785. element.style.visibility = 'inherit';
  7786. } else {
  7787. element.style.display = 'none';
  7788. element.style.visibility = 'hidden';
  7789. }
  7790. };
  7791. var _setWidgetVisibility = $ax.visibility.SetWidgetVisibility = function (elementId, options) {
  7792. var visible = $ax.visibility.IsIdVisible(elementId);
  7793. // If limboed, just fire the next action then leave.
  7794. if(visible == options.value || _limboIds[elementId]) {
  7795. if(!_limboIds[elementId]) options.onComplete && options.onComplete();
  7796. $ax.action.fireAnimationFromQueue(elementId, $ax.action.queueTypes.fade);
  7797. return;
  7798. }
  7799. options.containInner = true;
  7800. var query = $jobj(elementId);
  7801. var parentId = query.parent().attr('id');
  7802. var axObj = $obj(elementId);
  7803. var preserveScroll = false;
  7804. var isPanel = $ax.public.fn.IsDynamicPanel(axObj.type);
  7805. var isLayer = $ax.public.fn.IsLayer(axObj.type);
  7806. if(!options.noContainer && (isPanel || isLayer)) {
  7807. //if dp has scrollbar, save its scroll position
  7808. if(isPanel && axObj.scrollbars != 'none') {
  7809. var shownState = $ax.dynamicPanelManager.getShownState(elementId);
  7810. preserveScroll = true;
  7811. //before hiding, try to save scroll location
  7812. if(!options.value && shownState) {
  7813. DPStateAndScroll[elementId] = {
  7814. shownId: shownState.attr('id'),
  7815. left: shownState.scrollLeft(),
  7816. top: shownState.scrollTop()
  7817. }
  7818. }
  7819. }
  7820. _pushContainer(elementId, isPanel);
  7821. if(isPanel && !options.value) _tryResumeScrollForDP(elementId);
  7822. var complete = options.onComplete;
  7823. options.onComplete = function () {
  7824. if(complete) complete();
  7825. _popContainer(elementId, isPanel);
  7826. //after showing dp, restore the scoll position
  7827. if(isPanel && options.value) _tryResumeScrollForDP(elementId, true);
  7828. }
  7829. options.containerExists = true;
  7830. }
  7831. _setVisibility(parentId, elementId, options, preserveScroll);
  7832. //set the visibility of the annotation box as well if it exists
  7833. var ann = document.getElementById(elementId + "_ann");
  7834. if(ann) _visibility.SetVisible(ann, options.value);
  7835. //set ref visibility for ref of flow shape, if that exists
  7836. var ref = document.getElementById(elementId + '_ref');
  7837. if(ref) _visibility.SetVisible(ref, options.value);
  7838. };
  7839. var _setVisibility = function(parentId, childId, options, preserveScroll) {
  7840. var wrapped = $jobj(childId);
  7841. var completeTotal = 1;
  7842. var visible = $ax.visibility.IsIdVisible(childId);
  7843. if(visible == options.value) {
  7844. options.onComplete && options.onComplete();
  7845. $ax.action.fireAnimationFromQueue(childId, $ax.action.queueTypes.fade);
  7846. return;
  7847. }
  7848. var child = $jobj(childId);
  7849. var size = options.size || (options.containerExists ? $(child.children()[0]) : child);
  7850. var isIdFitToContent = $ax.dynamicPanelManager.isIdFitToContent(parentId);
  7851. //fade and resize won't work together when there is a container... but we still needs the container for fit to content DPs
  7852. var needContainer = options.easing && options.easing != 'none' && (options.easing != 'fade' || isIdFitToContent);
  7853. var cullPosition = options.cull ? options.cull.css('position') : '';
  7854. var containerExists = options.containerExists;
  7855. var isFullWidth = $ax.dynamicPanelManager.isPercentWidthPanel($obj(childId));
  7856. // 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.
  7857. var needSetSize = false;
  7858. var sizeObj = {};
  7859. if(needContainer) {
  7860. var sizeId = '';
  7861. if($ax.dynamicPanelManager.isIdFitToContent(childId)) sizeId = childId;
  7862. else {
  7863. var panelId = $ax.repeater.removeSuffixFromElementId(childId);
  7864. if($ax.dynamicPanelManager.isIdFitToContent(panelId)) sizeId = panelId;
  7865. }
  7866. if(sizeId) {
  7867. needSetSize = true;
  7868. sizeObj = $jobj(sizeId);
  7869. var newSize = options.cull || sizeObj;
  7870. var newAxSize = $ax('#' + newSize.attr('id'));
  7871. sizeObj.width(newAxSize.width());
  7872. sizeObj.height(newAxSize.height());
  7873. }
  7874. }
  7875. var wrappedOffset = { left: 0, top: 0 };
  7876. var visibleWrapped = wrapped;
  7877. if(needContainer) {
  7878. var childObj = $obj(childId);
  7879. if (options.cull) {
  7880. var axCull = $ax('#' + options.cull.attr('id'));
  7881. var containerWidth = axCull.width();
  7882. var containerHeight = axCull.height();
  7883. } else {
  7884. if(childObj && ($ax.public.fn.IsLayer(childObj.type))) {// || childObj.generateCompound)) {
  7885. var boundingRectangle = $ax.public.fn.getWidgetBoundingRect(childId);
  7886. wrappedOffset.left = boundingRectangle.left;
  7887. wrappedOffset.top = boundingRectangle.top;
  7888. containerWidth = boundingRectangle.width;
  7889. containerHeight = boundingRectangle.height;
  7890. } else if (childObj && childObj.generateCompound) {
  7891. var image = $jobj(childId + '_img');
  7892. containerWidth = $ax.getNumFromPx(image.css('width'));
  7893. containerHeight = $ax.getNumFromPx(image.css('height'));
  7894. wrappedOffset.left = $ax.getNumFromPx(image.css('left'));
  7895. wrappedOffset.top = $ax.getNumFromPx(image.css('top'));
  7896. } else {
  7897. containerWidth = $ax('#' + childId).width();
  7898. containerHeight = $ax('#' + childId).height();
  7899. }
  7900. }
  7901. var containerId = $ax.visibility.applyWidgetContainer(childId);
  7902. // var container = _makeContainer(containerId, options.cull || boundingRectangle, isFullWidth, options.easing == 'flip', wrappedOffset, options.containerExists);
  7903. var container = _makeContainer(containerId, containerWidth, containerHeight, isFullWidth, options.easing == 'flip', wrappedOffset, options.containerExists);
  7904. if(options.containInner) {
  7905. wrapped = _wrappedChildren(containerExists ? $(child.children()[0]) : child);
  7906. // Filter for visibile wrapped children
  7907. visibleWrapped = [];
  7908. for (var i = 0; i < wrapped.length; i++) if($ax.visibility.IsVisible(wrapped[i])) visibleWrapped.push(wrapped[i]);
  7909. visibleWrapped = $(visibleWrapped);
  7910. completeTotal = visibleWrapped.length;
  7911. if(!containerExists) container.prependTo(child);
  7912. // Offset items if necessary
  7913. if(!containerExists && (wrappedOffset.left != 0 || wrappedOffset.top != 0)) {
  7914. for(var i = 0; i < wrapped.length; i++) {
  7915. var inner = $(wrapped[i]);
  7916. inner.css('left', $ax.getNumFromPx(inner.css('left')) - wrappedOffset.left);
  7917. inner.css('top', $ax.getNumFromPx(inner.css('top')) - wrappedOffset.top);
  7918. // Parent layer is now size 0, so have to have to use conatiner since it's the real size.
  7919. // Should we use container all the time? This may make things easier for fit panels too.
  7920. size = container;
  7921. }
  7922. }
  7923. } else if(!containerExists) container.insertBefore(child);
  7924. if(!containerExists) wrapped.appendTo(container);
  7925. if (options.value && options.containInner) {
  7926. //has to set children first because flip to show needs children invisible
  7927. _setAllVisible(visibleWrapped, false);
  7928. _updateChildAlignment(childId);
  7929. _setAllVisible(child, true);
  7930. }
  7931. }
  7932. var completeCount = 0;
  7933. var onComplete = function () {
  7934. completeCount++;
  7935. if (needContainer && completeCount == completeTotal) {
  7936. if ($ax.public.fn.isCompoundVectorHtml(container.parent()[0])) {
  7937. wrappedOffset.left = $ax.getNumFromPx(container.css('left'));
  7938. wrappedOffset.top = $ax.getNumFromPx(container.css('top'));
  7939. }
  7940. if (options.containInner && !containerExists && (wrappedOffset.left != 0 || wrappedOffset.top != 0)) {
  7941. for (i = 0; i < wrapped.length; i++) {
  7942. inner = $(wrapped[i]);
  7943. //if ($ax.public.fn.isCompoundVectorComponentHtml(inner[0])) break;
  7944. inner.css('left', $ax.getNumFromPx(inner.css('left')) + wrappedOffset.left);
  7945. inner.css('top', $ax.getNumFromPx(inner.css('top')) + wrappedOffset.top);
  7946. }
  7947. }
  7948. if(options.containInner && !options.value) {
  7949. _setAllVisible(child, false);
  7950. _setAllVisible(visibleWrapped, true);
  7951. }
  7952. if(containerExists) {
  7953. if(!options.settingChild) container.css('position', 'relative;');
  7954. } else {
  7955. wrapped.insertBefore(container);
  7956. container.remove();
  7957. }
  7958. if(childObj && $ax.public.fn.IsDynamicPanel(childObj.type) && window.modifiedDynamicPanleParentOverflowProp) {
  7959. child.css('overflow', 'hidden');
  7960. window.modifiedDynamicPanleParentOverflowProp = false;
  7961. }
  7962. }
  7963. if(options.value) _updateChildAlignment(childId);
  7964. if(!needContainer || completeTotal == completeCount) {
  7965. if(options.cull) options.cull.css('position', cullPosition);
  7966. if(needSetSize) {
  7967. sizeObj.css('width', 'auto');
  7968. sizeObj.css('height', 'auto');
  7969. }
  7970. options.onComplete && options.onComplete();
  7971. if(options.fire) {
  7972. $ax.event.raiseSyntheticEvent(childId, options.value ? 'onShow' : 'onHide');
  7973. $ax.action.fireAnimationFromQueue(childId, $ax.action.queueTypes.fade);
  7974. }
  7975. }
  7976. };
  7977. // Nothing actually being animated, all wrapped elements invisible
  7978. if(!visibleWrapped.length) {
  7979. if(!options.easing || options.easing == 'none') {
  7980. $ax.visibility.SetIdVisible(childId, options.value);
  7981. completeTotal = 1;
  7982. onComplete();
  7983. } else {
  7984. window.setTimeout(function() {
  7985. completeCount = completeTotal - 1;
  7986. onComplete();
  7987. },options.duration);
  7988. }
  7989. return;
  7990. }
  7991. if(!options.easing || options.easing == 'none') {
  7992. $ax.visibility.SetIdVisible(childId, options.value);
  7993. completeTotal = 1;
  7994. onComplete();
  7995. } else if(options.easing == 'fade') {
  7996. if(options.value) {
  7997. if(preserveScroll) {
  7998. visibleWrapped.css('opacity', 0);
  7999. visibleWrapped.css('visibility', 'inherit');
  8000. visibleWrapped.css('display', 'block');
  8001. //was hoping we could just use fadein here, but need to set display before set scroll position
  8002. _tryResumeScrollForDP(childId);
  8003. visibleWrapped.animate({ opacity: 1 }, {
  8004. duration: options.duration,
  8005. easing: 'swing',
  8006. queue: false,
  8007. complete: function() {
  8008. $ax.visibility.SetIdVisible(childId, true);
  8009. visibleWrapped.css('opacity', '');
  8010. onComplete();
  8011. }
  8012. });
  8013. } else {
  8014. // Can't use $ax.visibility.SetIdVisible, because we only want to set visible, we don't want to set display, fadeIn will handle that.
  8015. visibleWrapped.css('visibility', 'inherit');
  8016. visibleWrapped.fadeIn({
  8017. queue: false,
  8018. duration: options.duration,
  8019. complete: onComplete
  8020. });
  8021. }
  8022. } else {
  8023. // Fading here is being strange...
  8024. visibleWrapped.animate({ opacity: 0 }, { duration: options.duration, easing: 'swing', queue: false, complete: function() {
  8025. $ax.visibility.SetIdVisible(childId, false);
  8026. visibleWrapped.css('opacity', '');
  8027. onComplete();
  8028. }});
  8029. }
  8030. } else if (options.easing == 'flip') {
  8031. //this container will hold
  8032. var innerContainer = $('<div></div>');
  8033. innerContainer.attr('id', containerId + "_inner");
  8034. innerContainer.data('flip', options.direction == 'left' || options.direction == 'right' ? 'y' : 'x');
  8035. innerContainer.css({
  8036. position: 'relative',
  8037. 'width': containerWidth,
  8038. 'height': containerHeight
  8039. });
  8040. innerContainer.appendTo(container);
  8041. wrapped.appendTo(innerContainer);
  8042. if(childObj && $ax.public.fn.IsDynamicPanel(childObj.type)) var containerDiv = child;
  8043. else containerDiv = parentId ? $jobj(parentId) : child.parent();
  8044. completeTotal = 1;
  8045. var flipdegree;
  8046. var requestAnimFrame = window.requestAnimationFrame ||
  8047. window.webkitRequestAnimationFrame ||
  8048. window.mozRequestAnimationFrame || window.msRequestAnimationFrame ||
  8049. function (callback) {
  8050. window.setTimeout(callback, 1000 / 60);
  8051. };
  8052. var originForUpOrDown = '100% ' + containerHeight / 2 + 'px';
  8053. if(options.value) {
  8054. //options.value == true means in or show, note to get here, the element must be currently hidden
  8055. //to show, we need to first flip it 180deg without animation
  8056. switch(options.direction) {
  8057. case 'right':
  8058. case 'left':
  8059. _setRotateTransformation(innerContainer, 'rotateY(180deg)');
  8060. flipdegree = options.direction === 'right' ? 'rotateY(360deg)' : 'rotateY(0deg)';
  8061. break;
  8062. case 'up':
  8063. case 'down':
  8064. innerContainer.css({
  8065. '-webkit-transform-origin': originForUpOrDown,
  8066. '-ms-transform-origin': originForUpOrDown,
  8067. 'transform-origin': originForUpOrDown,
  8068. });
  8069. _setRotateTransformation(innerContainer, 'rotateX(180deg)');
  8070. flipdegree = options.direction === 'up' ? 'rotateX(360deg)' : 'rotateX(0deg)';
  8071. break;
  8072. }
  8073. var onFlipShowComplete = function() {
  8074. $ax.visibility.SetIdVisible(childId, true);
  8075. wrapped.insertBefore(innerContainer);
  8076. innerContainer.remove();
  8077. onComplete();
  8078. };
  8079. innerContainer.css({
  8080. '-webkit-backface-visibility': 'hidden',
  8081. 'backface-visibility': 'hidden'
  8082. });
  8083. child.css({
  8084. 'display': '',
  8085. 'visibility': 'inherit'
  8086. });
  8087. visibleWrapped.css({
  8088. 'display': '',
  8089. 'visibility': 'inherit'
  8090. });
  8091. innerContainer.css({
  8092. '-webkit-transition-duration': options.duration + 'ms',
  8093. 'transition-duration': options.duration + 'ms'
  8094. });
  8095. if(preserveScroll) _tryResumeScrollForDP(childId);
  8096. requestAnimFrame(function () {
  8097. _setRotateTransformation(innerContainer, flipdegree, containerDiv, onFlipShowComplete, options.duration);
  8098. });
  8099. } else { //hide or out
  8100. switch(options.direction) {
  8101. case 'right':
  8102. case 'left':
  8103. flipdegree = options.direction === 'right' ? 'rotateY(180deg)' : 'rotateY(-180deg)';
  8104. break;
  8105. case 'up':
  8106. case 'down':
  8107. //_setRotateTransformation(wrapped, 'rotateX(0deg)');
  8108. innerContainer.css({
  8109. '-webkit-transform-origin': originForUpOrDown,
  8110. '-ms-transform-origin': originForUpOrDown,
  8111. 'transform-origin': originForUpOrDown,
  8112. });
  8113. flipdegree = options.direction === 'up' ? 'rotateX(180deg)' : 'rotateX(-180deg)';
  8114. break;
  8115. }
  8116. var onFlipHideComplete = function() {
  8117. wrapped.insertBefore(innerContainer);
  8118. $ax.visibility.SetIdVisible(childId, false);
  8119. innerContainer.remove();
  8120. onComplete();
  8121. };
  8122. innerContainer.css({
  8123. '-webkit-backface-visibility': 'hidden',
  8124. 'backface-visibility': 'hidden',
  8125. '-webkit-transition-duration': options.duration + 'ms',
  8126. 'transition-duration': options.duration + 'ms'
  8127. });
  8128. if(preserveScroll) _tryResumeScrollForDP(childId);
  8129. requestAnimFrame(function () {
  8130. _setRotateTransformation(innerContainer, flipdegree, containerDiv, onFlipHideComplete, options.duration);
  8131. });
  8132. }
  8133. } else {
  8134. // Because the move is gonna fire on annotation and ref too, need to update complete total
  8135. completeTotal = $addAll(visibleWrapped, childId).length;
  8136. if(options.value) {
  8137. _slideStateIn(childId, childId, options, size, false, onComplete, visibleWrapped, preserveScroll);
  8138. } else {
  8139. var tops = [];
  8140. var lefts = [];
  8141. for(var i = 0; i < visibleWrapped.length; i++) {
  8142. var currWrapped = $(visibleWrapped[i]);
  8143. tops.push(currWrapped.css('top'));
  8144. lefts.push(currWrapped.css('left'));
  8145. }
  8146. var onOutComplete = function () {
  8147. //bring back SetIdVisible on childId for hiding lightbox
  8148. $ax.visibility.SetIdVisible(childId, false);
  8149. for(i = 0; i < visibleWrapped.length; i++) {
  8150. currWrapped = $(visibleWrapped[i]);
  8151. $ax.visibility.SetIdVisible(currWrapped.attr('id'), false);
  8152. currWrapped.css('top', tops[i]);
  8153. currWrapped.css('left', lefts[i]);
  8154. }
  8155. onComplete();
  8156. };
  8157. _slideStateOut(size, childId, options, onOutComplete, visibleWrapped);
  8158. }
  8159. }
  8160. // If showing, go through all rich text objects inside you, and try to redo alignment of them
  8161. if(options.value && !options.containInner) {
  8162. _updateChildAlignment(childId);
  8163. }
  8164. };
  8165. var _updateChildAlignment = function(childId) {
  8166. var descendants = $jobj(childId).find('*');
  8167. for(var i = 0; i < descendants.length; i++) {
  8168. var decendantId = descendants[i].id;
  8169. // This check is probably redundant? UpdateTextAlignment should ignore any text objects that haven't set the vAlign yet.
  8170. if($ax.getTypeFromElementId(decendantId) != 'richTextPanel') continue;
  8171. $ax.style.updateTextAlignmentForVisibility(decendantId);
  8172. }
  8173. };
  8174. var _wrappedChildren = function (child) {
  8175. return child.children();
  8176. //var children = child.children();
  8177. //var valid = [];
  8178. //for(var i = 0; i < children.length; i++) if($ax.visibility.IsVisible(children[i])) valid.push(children[i]);
  8179. //return $(valid);
  8180. };
  8181. var _setRotateTransformation = function(elementsToSet, transformValue, elementParent, flipCompleteCallback, flipDurationMs) {
  8182. if(flipCompleteCallback) {
  8183. //here we didn't use 'transitionend' event to fire callback
  8184. //when show/hide on one element, changing transition property will stop the event from firing
  8185. window.setTimeout(flipCompleteCallback, flipDurationMs);
  8186. }
  8187. elementsToSet.css({
  8188. '-webkit-transform': transformValue,
  8189. '-moz-transform': transformValue,
  8190. '-ms-transform': transformValue,
  8191. '-o-transform': transformValue,
  8192. 'transform': transformValue
  8193. });
  8194. //when deal with dynamic panel, we need to set it's parent's overflow to visible to have the 3d effect
  8195. //NOTE: we need to set this back when both flips finishes in DP, to prevents one animation finished first and set this back
  8196. if(elementParent && elementParent.css('overflow') === 'hidden') {
  8197. elementParent.css('overflow', 'visible');
  8198. window.modifiedDynamicPanleParentOverflowProp = true;
  8199. }
  8200. };
  8201. $ax.visibility.GetPanelState = function(id) {
  8202. var children = $ax.visibility.getRealChildren($jobj(id).children());
  8203. for(var i = 0; i < children.length; i++) {
  8204. if(children[i].style && $ax.visibility.IsVisible(children[i])) return children[i].id;
  8205. }
  8206. return '';
  8207. };
  8208. var containerCount = {};
  8209. $ax.visibility.SetPanelState = function(id, stateId, easingOut, directionOut, durationOut, easingIn, directionIn, durationIn, showWhenSet) {
  8210. var show = !$ax.visibility.IsIdVisible(id) && showWhenSet;
  8211. if(show) $ax.visibility.SetIdVisible(id, true);
  8212. // Exit here if already at desired state.
  8213. if($ax.visibility.IsIdVisible(stateId)) {
  8214. if(show) {
  8215. $ax.event.raiseSyntheticEvent(id, 'onShow');
  8216. // If showing size changes and need to update parent panels
  8217. $ax.dynamicPanelManager.fitParentPanel(id);
  8218. }
  8219. $ax.action.fireAnimationFromQueue(id, $ax.action.queueTypes.setState);
  8220. return;
  8221. }
  8222. _pushContainer(id, true);
  8223. var state = $jobj(stateId);
  8224. var oldStateId = $ax.visibility.GetPanelState(id);
  8225. var oldState = $jobj(oldStateId);
  8226. //pin to browser
  8227. $ax.dynamicPanelManager.adjustFixed(id, oldState.width(), oldState.height(), state.width(), state.height());
  8228. _bringPanelStateToFront(id, stateId, oldStateId);
  8229. var fitToContent = $ax.dynamicPanelManager.isIdFitToContent(id);
  8230. var resized = false;
  8231. if(fitToContent) {
  8232. // Set resized
  8233. resized = state.width() != oldState.width() || state.height() != oldState.height();
  8234. }
  8235. //edge case for sliding
  8236. var movement = (directionOut == 'left' || directionOut == 'up' || state.children().length == 0) && oldState.children().length != 0 ? oldState : state;
  8237. var onCompleteCount = 0;
  8238. var onComplete = function () {
  8239. //move this call from _setVisibility() for animate out.
  8240. //Because this will make the order of dp divs consistence: the showing panel is always in front after both animation finished
  8241. //tested in the cases where one panel is out/show slower/faster/same time/instantly.
  8242. _bringPanelStateToFront(id, stateId, oldStateId);
  8243. if (window.modifiedDynamicPanleParentOverflowProp) {
  8244. var parent = id ? $jobj(id) : child.parent();
  8245. parent.css('overflow', 'hidden');
  8246. window.modifiedDynamicPanleParentOverflowProp = false;
  8247. }
  8248. $ax.dynamicPanelManager.fitParentPanel(id);
  8249. $ax.dynamicPanelManager.updatePanelPercentWidth(id);
  8250. $ax.dynamicPanelManager.updatePanelContentPercentWidth(id);
  8251. $ax.action.fireAnimationFromQueue(id, $ax.action.queueTypes.setState);
  8252. $ax.event.raiseSyntheticEvent(id, "onPanelStateChange");
  8253. $ax.event.leavingState(oldStateId);
  8254. _popContainer(id, true);
  8255. };
  8256. // Must do state out first, so if we cull by new state, location is correct
  8257. _setVisibility(id, oldStateId, {
  8258. value: false,
  8259. easing: easingOut,
  8260. direction: directionOut,
  8261. duration: durationOut,
  8262. containerExists: true,
  8263. onComplete: function() {
  8264. // if(easingIn !== 'flip') _bringPanelStateToFront(id, stateId);
  8265. if (++onCompleteCount == 2) onComplete();
  8266. },
  8267. settingChild: true,
  8268. size: movement,
  8269. //cull for
  8270. cull: easingOut == 'none' || state.children().length == 0 ? oldState : state
  8271. });
  8272. _setVisibility(id, stateId, {
  8273. value: true,
  8274. easing: easingIn,
  8275. direction: directionIn,
  8276. duration: durationIn,
  8277. containerExists: true,
  8278. onComplete: function () {
  8279. // if (easingIn === 'flip') _bringPanelStateToFront(id, stateId);
  8280. if (++onCompleteCount == 2) onComplete();
  8281. },
  8282. settingChild: true,
  8283. //size for offset
  8284. size: movement
  8285. });
  8286. if(show) $ax.event.raiseSyntheticEvent(id, 'onShow');
  8287. if(resized) $ax.event.raiseSyntheticEvent(id, 'onResize');
  8288. };
  8289. var containedFixed = {};
  8290. var _pushContainer = _visibility.pushContainer = function(id, panel) {
  8291. var count = containerCount[id];
  8292. if(count) containerCount[id] = count + 1;
  8293. else {
  8294. var trapScroll = _trapScrollLoc(id);
  8295. var jobj = $jobj(id);
  8296. var children = jobj.children();
  8297. var css = {
  8298. position: 'relative',
  8299. top: 0,
  8300. left: 0
  8301. };
  8302. if(!panel) {
  8303. var boundingRect = $axure.fn.getWidgetBoundingRect(id);
  8304. css.top = boundingRect.top;
  8305. css.left = boundingRect.left;
  8306. }
  8307. var container = $('<div></div>');
  8308. container.attr('id', $ax.visibility.applyWidgetContainer(id));
  8309. container.css(css);
  8310. //container.append(jobj.children());
  8311. jobj.append(container);
  8312. containerCount[id] = 1;
  8313. // Panel needs to wrap children
  8314. if(panel) {
  8315. for(var i = 0; i < children.length; i++) {
  8316. var child = $(children[i]);
  8317. var childContainer = $('<div></div>');
  8318. childContainer.attr('id', $ax.visibility.applyWidgetContainer(child.attr('id')));
  8319. childContainer.css(css);
  8320. child.after(childContainer);
  8321. childContainer.append(child);
  8322. container.append(childContainer);
  8323. }
  8324. } else {
  8325. var focus = _getCurrFocus();
  8326. if(focus) $ax.event.addSuppressedEvent($ax.repeater.removeSuffixFromElementId(focus), 'OnLostFocus');
  8327. // Layer needs to fix top left
  8328. var childIds = $ax('#' + id).getChildren()[0].children;
  8329. for(var i = 0; i < childIds.length; i++) {
  8330. var childId = childIds[i];
  8331. var childObj = $jobj(childId);
  8332. var fixedInfo = $ax.dynamicPanelManager.getFixedInfo(childId);
  8333. if(fixedInfo.fixed) {
  8334. var axObj = $ax('#' + childId);
  8335. var left = axObj.left();
  8336. var top = axObj.top();
  8337. containedFixed[childId] = { left: left, top: top, fixed: fixedInfo };
  8338. childObj.css('left', left);
  8339. childObj.css('top', top);
  8340. childObj.css('margin-left', 0);
  8341. childObj.css('margin-top', 0);
  8342. childObj.css('right', 'auto');
  8343. childObj.css('bottom', 'auto');
  8344. childObj.css('position', 'absolute');
  8345. }
  8346. var cssChange = {
  8347. left: '-=' + css.left,
  8348. top: '-=' + css.top
  8349. };
  8350. if($ax.getTypeFromElementId(childId) == $ax.constants.LAYER_TYPE) {
  8351. _pushContainer(childId, false);
  8352. $ax.visibility.applyWidgetContainer(childId, true).css(cssChange);
  8353. } else {
  8354. //if ($ax.public.fn.isCompoundVectorHtml(jobj[0])) {
  8355. // var grandChildren = jobj[0].children;
  8356. // //while (grandChildren.length > 0 && grandChildren[0].id.indexOf('container') >= 0) grandChildren = grandChildren[0].children;
  8357. // for (var j = 0; j < grandChildren.length; j++) {
  8358. // var grandChildId = grandChildren[j].id;
  8359. // if (grandChildId.indexOf(childId + 'p') >= 0 || grandChildId.indexOf('_container') >= 0) $jobj(grandChildId).css(cssChange);
  8360. // }
  8361. //} else
  8362. // Need to include ann and ref in move.
  8363. childObj = $addAll(childObj, childId);
  8364. childObj.css(cssChange);
  8365. }
  8366. container.append(childObj);
  8367. }
  8368. _setCurrFocus(focus);
  8369. }
  8370. trapScroll();
  8371. }
  8372. };
  8373. var _popContainer = _visibility.popContainer = function (id, panel) {
  8374. var count = containerCount[id];
  8375. if(!count) return;
  8376. count--;
  8377. containerCount[id] = count;
  8378. if(count != 0) return;
  8379. var trapScroll = _trapScrollLoc(id);
  8380. var jobj = $jobj(id);
  8381. var container = $ax.visibility.applyWidgetContainer(id, true);
  8382. // If layer is at bottom or right of page, unwrapping could change scroll by temporarily reducting page size.
  8383. // To avoid this, we let container persist on page, with the size it is at this point, and don't remove container completely
  8384. // until the children are back to their proper locations.
  8385. var size = $ax('#' + id).size();
  8386. container.css('width', size.width);
  8387. container.css('height', size.height);
  8388. var focus = _getCurrFocus();
  8389. if(focus) $ax.event.addSuppressedEvent($ax.repeater.removeSuffixFromElementId(focus), 'OnLostFocus');
  8390. jobj.append(container.children());
  8391. _setCurrFocus(focus);
  8392. $('body').append(container);
  8393. // Layer doesn't have children containers to clean up
  8394. if(panel) {
  8395. var children = jobj.children();
  8396. for(var i = 0; i < children.length; i++) {
  8397. var childContainer = $(children[i]);
  8398. var child = $(childContainer.children()[0]);
  8399. childContainer.after(child);
  8400. childContainer.remove();
  8401. }
  8402. } else {
  8403. var left = container.css('left');
  8404. var top = container.css('top');
  8405. var childIds = $ax('#' + id).getChildren()[0].children;
  8406. for (var i = 0; i < childIds.length; i++) {
  8407. var childId = childIds[i];
  8408. var cssChange = {
  8409. left: '+=' + left,
  8410. top: '+=' + top
  8411. };
  8412. if($ax.getTypeFromElementId(childId) == $ax.constants.LAYER_TYPE) {
  8413. $ax.visibility.applyWidgetContainer(childId, true).css(cssChange);
  8414. _popContainer(childId, false);
  8415. } else {
  8416. var childObj = $jobj(childId);
  8417. // if ($ax.public.fn.isCompoundVectorHtml(jobj[0])) {
  8418. // var grandChildren = jobj[0].children;
  8419. // //while (grandChildren.length > 0 && grandChildren[0].id.indexOf('container') >= 0) grandChildren = grandChildren[0].children;
  8420. // for (var j = 0; j < grandChildren.length; j++) {
  8421. // var grandChildId = grandChildren[j].id;
  8422. // if (grandChildId.indexOf(childId + 'p') >= 0 || grandChildId.indexOf('_container') >= 0) $jobj(grandChildId).css(cssChange);
  8423. // }
  8424. //} else
  8425. var allObjs = $addAll(childObj, childId); // Just include other objects for initial css. Fixed panels need to be dealt with separately.
  8426. allObjs.css(cssChange);
  8427. var fixedInfo = containedFixed[childId];
  8428. if(fixedInfo) {
  8429. delete containedFixed[childId];
  8430. childObj.css('position', 'fixed');
  8431. var deltaX = $ax.getNumFromPx(childObj.css('left')) - fixedInfo.left;
  8432. var deltaY = $ax.getNumFromPx(childObj.css('top')) - fixedInfo.top;
  8433. fixedInfo = fixedInfo.fixed;
  8434. if(fixedInfo.horizontal == 'left') childObj.css('left', fixedInfo.x + deltaX);
  8435. else if(fixedInfo.horizontal == 'center') {
  8436. childObj.css('left', '50%');
  8437. childObj.css('margin-left', fixedInfo.x + deltaX);
  8438. } else {
  8439. childObj.css('left', 'auto');
  8440. childObj.css('right', fixedInfo.x - deltaX);
  8441. }
  8442. if(fixedInfo.vertical == 'top') childObj.css('top', fixedInfo.y + deltaY);
  8443. else if(fixedInfo.vertical == 'middle') {
  8444. childObj.css('top', '50%');
  8445. childObj.css('margin-top', fixedInfo.y + deltaY);
  8446. } else {
  8447. childObj.css('top', 'auto');
  8448. childObj.css('bottom', fixedInfo.y - deltaY);
  8449. }
  8450. $ax.dynamicPanelManager.updatePanelPercentWidth(childId);
  8451. $ax.dynamicPanelManager.updatePanelContentPercentWidth(childId);
  8452. }
  8453. }
  8454. }
  8455. }
  8456. container.remove();
  8457. trapScroll();
  8458. };
  8459. var _trapScrollLoc = function(id) {
  8460. var locs = {};
  8461. var states = $jobj(id).find('.panel_state');
  8462. for(var i = 0; i < states.length; i++) {
  8463. var state = $(states[i]);
  8464. locs[state.attr('id')] = { x: state.scrollLeft(), y: state.scrollTop() };
  8465. }
  8466. return function() {
  8467. for(var key in locs) {
  8468. var state = $jobj(key);
  8469. state.scrollLeft(locs[key].x);
  8470. state.scrollTop(locs[key].y);
  8471. }
  8472. };
  8473. }
  8474. var _getCurrFocus = function () {
  8475. // Only care about focused a tags and inputs
  8476. var id = window.lastFocusedClickable && window.lastFocusedClickable.id;
  8477. if(!id) return id;
  8478. var jobj = $(window.lastFocusedClickable);
  8479. return jobj.is('a') || jobj.is('input') ? id : '';
  8480. }
  8481. var _setCurrFocus = function(id) {
  8482. if(id) {
  8483. // This is really just needed for IE, so if this causes issues on other browsers, try adding that check here
  8484. var trap = $ax.event.blockEvent($ax.repeater.removeSuffixFromElementId(id), 'OnFocus');
  8485. window.setTimeout(function () {
  8486. $jobj(id).focus();
  8487. trap();
  8488. }, 0);
  8489. }
  8490. }
  8491. //use this to save & restore DP's scroll position when show/hide
  8492. //key => dp's id (not state's id, because it seems we can change state while hiding)
  8493. //value => first state's id & scroll position
  8494. //we only need to store one scroll position for one DP, and remove the key after shown.
  8495. var DPStateAndScroll = {}
  8496. var _tryResumeScrollForDP = function (dpId, deleteId) {
  8497. var scrollObj = DPStateAndScroll[dpId];
  8498. if(scrollObj) {
  8499. var shownState = document.getElementById(scrollObj.shownId);
  8500. if(scrollObj.left) shownState.scrollLeft = scrollObj.left;
  8501. if(scrollObj.top) shownState.scrollTop = scrollObj.top;
  8502. if(deleteId) delete DPStateAndScroll[dpId];
  8503. }
  8504. };
  8505. // var _makeContainer = function (containerId, rect, isFullWidth, isFlip, offset, containerExists) {
  8506. var _makeContainer = function (containerId, width, height, isFullWidth, isFlip, offset, containerExists) {
  8507. if(containerExists) var container = $jobj(containerId);
  8508. else {
  8509. container = $('<div></div>');
  8510. container.attr('id', containerId);
  8511. }
  8512. var css = {
  8513. position: 'absolute',
  8514. width: width,
  8515. height: height,
  8516. };
  8517. if(!containerExists) {
  8518. // If container exists, may be busy updating location. Will init and update it correctly.
  8519. css.top = offset.top;
  8520. css.left = offset.left;
  8521. }
  8522. if(isFlip) {
  8523. css.perspective = '800px';
  8524. css.webkitPerspective = "800px";
  8525. css.mozPerspective = "800px";
  8526. } else css.overflow = 'hidden';
  8527. //perspective on container will give us 3d effect when flip
  8528. //if(!isFlip) css.overflow = 'hidden';
  8529. // Rect should be a jquery not axquery obj
  8530. //_getFixedCss(css, rect.$ ? rect.$() : rect, fixedInfo, isFullWidth);
  8531. container.css(css);
  8532. return container;
  8533. };
  8534. var CONTAINER_SUFFIX = _visibility.CONTAINER_SUFFIX = '_container';
  8535. var CONTAINER_INNER = CONTAINER_SUFFIX + '_inner';
  8536. _visibility.getWidgetFromContainer = function(id) {
  8537. var containerIndex = id.indexOf(CONTAINER_SUFFIX);
  8538. if(containerIndex == -1) return id;
  8539. return id.substr(0, containerIndex) + id.substr(containerIndex + CONTAINER_SUFFIX.length);
  8540. };
  8541. // Apply container to widget id if necessary.
  8542. // returnJobj: True if you want the jquery object rather than id returned
  8543. // skipCheck: True if you want the query returned reguardless of container existing
  8544. // checkInner: True if inner container should be checked
  8545. _visibility.applyWidgetContainer = function (id, returnJobj, skipCheck, checkInner) {
  8546. // If container exists, just return (return query if requested)
  8547. if(id.indexOf(CONTAINER_SUFFIX) != -1) return returnJobj ? $jobj(id) : id;
  8548. // Get desired id, and return it if query is not desired
  8549. var containerId = $ax.repeater.applySuffixToElementId(id, checkInner ? CONTAINER_INNER : CONTAINER_SUFFIX);
  8550. if(!returnJobj) return containerId;
  8551. // If skipping check or container exists, just return innermost container requested
  8552. var container = $jobj(containerId);
  8553. if(skipCheck || container.length) return container;
  8554. // If inner container was not checked, then no more to check, return query for widget
  8555. if(!checkInner) return $jobj(id);
  8556. // If inner container was checked, check for regular container still
  8557. container = $jobj($ax.repeater.applySuffixToElementId(id, CONTAINER_SUFFIX));
  8558. return container.length ? container : $jobj(id);
  8559. };
  8560. _visibility.isContainer = function(id) {
  8561. return id.indexOf(CONTAINER_SUFFIX) != -1;
  8562. };
  8563. _visibility.getRealChildren = function(query) {
  8564. while(query.length && $(query[0]).attr('id').indexOf(CONTAINER_SUFFIX) != -1) query = query.children();
  8565. return query;
  8566. };
  8567. var _getFixedCss = function(css, rect, fixedInfo, isFullWidth) {
  8568. // todo: **mas** make sure this is ok
  8569. if(fixedInfo.fixed) {
  8570. css.position = 'fixed';
  8571. if(fixedInfo.horizontal == 'left') css.left = fixedInfo.x;
  8572. else if(fixedInfo.horizontal == 'center') {
  8573. css.left = isFullWidth ? '0px' : '50%';
  8574. css['margin-left'] = fixedInfo.x;
  8575. } else if(fixedInfo.horizontal == 'right') {
  8576. css.left = 'auto';
  8577. css.right = fixedInfo.x;
  8578. }
  8579. if(fixedInfo.vertical == 'top') css.top = fixedInfo.y;
  8580. else if(fixedInfo.vertical == 'middle') {
  8581. css.top = '50%';
  8582. css['margin-top'] = fixedInfo.y;
  8583. } else if(fixedInfo.vertical == 'bottom') {
  8584. css.top = 'auto';
  8585. css.bottom = fixedInfo.y;
  8586. }
  8587. } else {
  8588. css.left = Number(rect.css('left').replace('px', '')) || 0;
  8589. css.top = Number(rect.css('top').replace('px', '')) || 0;
  8590. }
  8591. };
  8592. var _slideStateOut = function (container, stateId, options, onComplete, jobj) {
  8593. var directionOut = options.direction;
  8594. var axObject = $ax('#' + container.attr('id'));
  8595. var width = axObject.width();
  8596. var height = axObject.height();
  8597. if(directionOut == "right") {
  8598. $ax.move.MoveWidget(stateId, width, 0, options, false, onComplete, false, jobj, true);
  8599. } else if(directionOut == "left") {
  8600. $ax.move.MoveWidget(stateId, -width, 0, options, false, onComplete, false, jobj, true);
  8601. } else if(directionOut == "up") {
  8602. $ax.move.MoveWidget(stateId, 0, -height, options, false, onComplete, false, jobj, true);
  8603. } else if(directionOut == "down") {
  8604. $ax.move.MoveWidget(stateId, 0, height, options, false, onComplete, false, jobj, true);
  8605. }
  8606. };
  8607. var _slideStateIn = function (id, stateId, options, container, makePanelVisible, onComplete, jobj, preserveScroll) {
  8608. var directionIn = options.direction;
  8609. var axObject = $ax('#' +container.attr('id'));
  8610. var width = axObject.width();
  8611. var height = axObject.height();
  8612. for(var i = 0; i < jobj.length; i++) {
  8613. var child = $(jobj[i]);
  8614. var oldTop = $ax.getNumFromPx(child.css('top'));
  8615. var oldLeft = $ax.getNumFromPx(child.css('left'));
  8616. if (directionIn == "right") {
  8617. child.css('left', oldLeft - width + 'px');
  8618. } else if(directionIn == "left") {
  8619. child.css('left', oldLeft + width + 'px');
  8620. } else if(directionIn == "up") {
  8621. child.css('top', oldTop + height + 'px');
  8622. } else if(directionIn == "down") {
  8623. child.css('top', oldTop - height + 'px');
  8624. }
  8625. }
  8626. if (makePanelVisible) $ax.visibility.SetIdVisible(id, true);
  8627. for(i = 0; i < jobj.length; i++) $ax.visibility.SetIdVisible($(jobj[i]).attr('id'), true);
  8628. if(preserveScroll) _tryResumeScrollForDP(id);
  8629. if(directionIn == "right") {
  8630. $ax.move.MoveWidget(stateId, width, 0, options, false, onComplete, false, jobj, true);
  8631. } else if(directionIn == "left") {
  8632. $ax.move.MoveWidget(stateId, -width, 0, options, false, onComplete, false, jobj, true);
  8633. } else if(directionIn == "up") {
  8634. $ax.move.MoveWidget(stateId, 0, -height, options, false, onComplete, false, jobj, true);
  8635. } else if(directionIn == "down") {
  8636. $ax.move.MoveWidget(stateId, 0, height, options, false, onComplete, false, jobj, true);
  8637. }
  8638. };
  8639. $ax.visibility.GetPanelStateId = function(dpId, index) {
  8640. var itemNum = $ax.repeater.getItemIdFromElementId(dpId);
  8641. var panelStateId = $ax.repeater.getScriptIdFromElementId(dpId) + '_state' + index;
  8642. return $ax.repeater.createElementId(panelStateId, itemNum);
  8643. };
  8644. $ax.visibility.GetPanelStateCount = function(id) {
  8645. return $ax.visibility.getRealChildren($jobj(id).children()).length;
  8646. };
  8647. var _bringPanelStateToFront = function (dpId, stateid, oldStateId) {
  8648. var panel = $jobj(dpId);
  8649. if(containerCount[dpId]) {
  8650. stateid = $ax.visibility.applyWidgetContainer(stateid);
  8651. panel = $ax.visibility.applyWidgetContainer(dpId, true, false, true);
  8652. }
  8653. $jobj(stateid).appendTo(panel);
  8654. //when bring a panel to front, it will be focused, and the previous front panel should fire blur event if it's lastFocusedClickableSelector
  8655. //ie(currently 11) and firefox(currently 34) doesn't fire blur event, this is the hack to fire it manually
  8656. if((IE || FIREFOX) && window.lastFocusedClickable && $ax.event.getFocusableWidgetOrChildId(window.lastFocusedControl) == window.lastFocusedClickable.id) {
  8657. // Only need to do this if the currently focused widget is in the panel state that is being hidden.
  8658. if($jobj(oldStateId).find('#' + window.lastFocusedClickable.id.split('_')[0]).length) $(window.lastFocusedClickable).triggerHandler('blur');
  8659. }
  8660. };
  8661. var _limboIds = _visibility.limboIds = {};
  8662. // limboId's is a dictionary of id->true, essentially a set.
  8663. var _addLimboAndHiddenIds = $ax.visibility.addLimboAndHiddenIds = function(newLimboIds, newHiddenIds, query, skipRepeater) {
  8664. var limboedByMaster = {};
  8665. for(var key in newLimboIds) {
  8666. if (!$ax.public.fn.IsReferenceDiagramObject($ax.getObjectFromElementId(key).type)) continue;
  8667. var ids = $ax.model.idsInRdoToHideOrLimbo(key);
  8668. for(var i = 0; i < ids.length; i++) limboedByMaster[ids[i]] = true;
  8669. }
  8670. var hiddenByMaster = {};
  8671. for(key in newHiddenIds) {
  8672. if (!$ax.public.fn.IsReferenceDiagramObject($ax.getObjectFromElementId(key).type)) continue;
  8673. ids = $ax.model.idsInRdoToHideOrLimbo(key);
  8674. for(i = 0; i < ids.length; i++) hiddenByMaster[ids[i]] = true;
  8675. }
  8676. // Extend with children of rdos
  8677. newLimboIds = $.extend(newLimboIds, limboedByMaster);
  8678. newHiddenIds = $.extend(newHiddenIds, hiddenByMaster);
  8679. // something is only visible if it's not hidden and limboed
  8680. query.each(function(diagramObject, elementId) {
  8681. // Rdos already handled, contained widgets are limboed by the parent, and sub menus should be ignored
  8682. if(diagramObject.isContained || $ax.public.fn.IsReferenceDiagramObject(diagramObject.type) || $ax.public.fn.IsTableCell(diagramObject.type) || $jobj(elementId).hasClass('sub_menu')) return;
  8683. if(diagramObject.type == 'table' && $jobj(elementId).parent().hasClass('ax_menu')) return;
  8684. if(skipRepeater) {
  8685. // Any item in a repeater should return
  8686. if($ax.getParentRepeaterFromElementIdExcludeSelf(elementId)) return;
  8687. }
  8688. var scriptId = $ax.repeater.getScriptIdFromElementId(elementId);
  8689. var shouldBeVisible = Boolean(!newLimboIds[scriptId] && !newHiddenIds[scriptId]);
  8690. var isVisible = Boolean(_isIdVisible(elementId));
  8691. if(shouldBeVisible != isVisible) {
  8692. _setWidgetVisibility(elementId, { value: shouldBeVisible, noContainer: true });
  8693. }
  8694. });
  8695. _limboIds = _visibility.limboIds = $.extend(_limboIds, newLimboIds);
  8696. };
  8697. var _clearLimboAndHidden = $ax.visibility.clearLimboAndHidden = function(ids) {
  8698. _limboIds = _visibility.limboIds = {};
  8699. };
  8700. $ax.visibility.clearLimboAndHiddenIds = function(ids) {
  8701. for(var i = 0; i < ids.length; i++) {
  8702. var scriptId = $ax.repeater.getScriptIdFromElementId(ids[i]);
  8703. delete _limboIds[scriptId];
  8704. }
  8705. };
  8706. $ax.visibility.resetLimboAndHiddenToDefaults = function (query) {
  8707. if(!query) query = $ax('*');
  8708. _clearLimboAndHidden();
  8709. _addLimboAndHiddenIds(_defaultLimbo, _defaultHidden, query);
  8710. };
  8711. $ax.visibility.isScriptIdLimbo = function(scriptId) {
  8712. if(_limboIds[scriptId]) return true;
  8713. var repeater = $ax.getParentRepeaterFromScriptId(scriptId);
  8714. if(!repeater) return false;
  8715. var itemId = $ax.getItemIdsForRepeater(repeater)[0];
  8716. return _limboIds[$ax.repeater.createElementId(scriptId, itemId)];
  8717. }
  8718. $ax.visibility.isElementIdLimboOrInLimboContainer = function (elementId) {
  8719. var parent = document.getElementById(elementId);
  8720. while(parent) {
  8721. var scriptId = $ax.repeater.getScriptIdFromElementId($(parent).attr('id'));
  8722. if(_limboIds[scriptId]) return true;
  8723. parent = parent.parentElement;
  8724. }
  8725. return false;
  8726. }
  8727. $ax.visibility.initialize = function() {
  8728. // initialize initial visible states
  8729. $('.' + HIDDEN_CLASS).each(function (index, diagramObject) {
  8730. _defaultHidden[$ax.repeater.getScriptIdFromElementId(diagramObject.id)] = true;
  8731. });
  8732. $('.' + UNPLACED_CLASS).each(function (index, diagramObject) {
  8733. _defaultLimbo[$ax.repeater.getScriptIdFromElementId(diagramObject.id)] = true;
  8734. });
  8735. _addLimboAndHiddenIds(_defaultLimbo, _defaultHidden, $ax('*'), true);
  8736. };
  8737. _visibility.initRepeater = function(repeaterId) {
  8738. var html = $('<div></div>');
  8739. html.append($jobj(repeaterId + '_script').html());
  8740. html.find('.' + HIDDEN_CLASS).each(function (index, element) {
  8741. _defaultHidden[$ax.repeater.getScriptIdFromElementId(element.id)] = true;
  8742. });
  8743. html.find('.' + UNPLACED_CLASS).each(function (index, element) {
  8744. _defaultLimbo[$ax.repeater.getScriptIdFromElementId(element.id)] = true;
  8745. });
  8746. }
  8747. var HIDDEN_CLASS = _visibility.HIDDEN_CLASS = 'ax_default_hidden';
  8748. var UNPLACED_CLASS = _visibility.UNPLACED_CLASS = 'ax_default_unplaced';
  8749. });
  8750. //***** style.js *****//
  8751. $axure.internal(function($ax) {
  8752. var _style = {};
  8753. $ax.style = _style;
  8754. var _disabledWidgets = {};
  8755. var _selectedWidgets = {};
  8756. // A table to cache the outerHTML of the _rtf elements before the rollover state is applied.
  8757. var _originalTextCache = {};
  8758. // A table to exclude the normal style from adaptive overrides
  8759. var _shapesWithSetRichText = {};
  8760. // just a listing of shape ids
  8761. var _adaptiveStyledWidgets = {};
  8762. var _setLinkStyle = function(id, styleName) {
  8763. var textId = $ax.style.GetTextIdFromLink(id);
  8764. var style = _computeAllOverrides(id, textId, styleName, $ax.adaptive.currentViewId);
  8765. if(!_originalTextCache[textId]) {
  8766. $ax.style.CacheOriginalText(textId);
  8767. }
  8768. if($.isEmptyObject(style)) return;
  8769. var parentObjectCache = _originalTextCache[textId].styleCache;
  8770. _transformTextWithVerticalAlignment(textId, function() {
  8771. var cssProps = _getCssStyleProperties(style);
  8772. $('#' + id).find('*').andSelf().each(function(index, element) {
  8773. element.setAttribute('style', parentObjectCache[element.id]);
  8774. _applyCssProps(element, cssProps);
  8775. });
  8776. });
  8777. };
  8778. var _resetLinkStyle = function(id) {
  8779. var textId = $ax.style.GetTextIdFromLink(id);
  8780. var parentObjectCache = _originalTextCache[textId].styleCache;
  8781. _transformTextWithVerticalAlignment(textId, function() {
  8782. $('#' + id).find('*').andSelf().each(function(index, element) {
  8783. element.style.cssText = parentObjectCache[element.id];
  8784. });
  8785. });
  8786. if($ax.event.mouseDownObjectId) {
  8787. $ax.style.SetWidgetMouseDown($ax.event.mouseDownObjectId, true);
  8788. } else if($ax.event.mouseOverObjectId) {
  8789. $ax.style.SetWidgetHover($ax.event.mouseOverObjectId, true);
  8790. }
  8791. };
  8792. $ax.style.SetLinkHover = function(id) {
  8793. _setLinkStyle(id, MOUSE_OVER);
  8794. };
  8795. $ax.style.SetLinkNotHover = function(id) {
  8796. _resetLinkStyle(id);
  8797. };
  8798. $ax.style.SetLinkMouseDown = function(id) {
  8799. _setLinkStyle(id, MOUSE_DOWN);
  8800. };
  8801. $ax.style.SetLinkNotMouseDown = function(id) {
  8802. _resetLinkStyle(id);
  8803. var style = _computeAllOverrides(id, $ax.event.mouseOverObjectId, MOUSE_OVER, $ax.adaptive.currentViewId);
  8804. if(!$.isEmptyObject(style)) $ax.style.SetLinkHover(id);
  8805. //we dont do anything here because the widget not mouse down has taken over here
  8806. };
  8807. var _widgetHasState = function(id, state) {
  8808. if($ax.style.getElementImageOverride(id, state)) return true;
  8809. var diagramObject = $ax.getObjectFromElementId(id);
  8810. var adaptiveIdChain = $ax.adaptive.getAdaptiveIdChain($ax.adaptive.currentViewId);
  8811. for(var i = 0; i < adaptiveIdChain.length; i++) {
  8812. var viewId = adaptiveIdChain[i];
  8813. var adaptiveStyle = diagramObject.adaptiveStyles[viewId];
  8814. if(adaptiveStyle && adaptiveStyle.stateStyles && adaptiveStyle.stateStyles[state]) return true;
  8815. }
  8816. if(diagramObject.style.stateStyles) return diagramObject.style.stateStyles[state];
  8817. return false;
  8818. };
  8819. // Returns what overrides the hover, or false if nothing.
  8820. var _hoverOverride = function(id) {
  8821. if($ax.style.IsWidgetDisabled(id)) return DISABLED;
  8822. if($ax.style.IsWidgetSelected(id)) return SELECTED;
  8823. var obj = $ax.getObjectFromElementId(id);
  8824. if(!obj.isContained) return false;
  8825. var path = $ax.getPathFromScriptId($ax.repeater.getScriptIdFromElementId(id));
  8826. path[path.length - 1] = obj.parent.id;
  8827. var itemId = $ax.repeater.getItemIdFromElementId(id);
  8828. return _hoverOverride($ax.getElementIdFromPath(path, { itemNum: itemId }));
  8829. };
  8830. $ax.style.SetWidgetHover = function(id, value) {
  8831. var override = _hoverOverride(id);
  8832. if(override == DISABLED) return;
  8833. if(!_widgetHasState(id, MOUSE_OVER)) return;
  8834. var valToSet = value || _isRolloverOverride(id);
  8835. var state = _generateMouseState(id, valToSet ? MOUSE_OVER : NORMAL, override == SELECTED);
  8836. _applyImageAndTextJson(id, state);
  8837. _updateElementIdImageStyle(id, state);
  8838. };
  8839. var _rolloverOverrides = [];
  8840. var _isRolloverOverride = function(id) {
  8841. return _rolloverOverrides.indexOf(id) != -1;
  8842. };
  8843. $ax.style.AddRolloverOverride = function(id) {
  8844. if(_isRolloverOverride(id)) return;
  8845. _rolloverOverrides[_rolloverOverrides.length] = id;
  8846. if($ax.event.mouseOverIds.indexOf(id) == -1) $ax.style.SetWidgetHover(id, true);
  8847. };
  8848. $ax.style.RemoveRolloverOverride = function(id) {
  8849. var index = _rolloverOverrides.indexOf(id);
  8850. if(index == -1) return;
  8851. $ax.splice(_rolloverOverrides, index, 1);
  8852. if($ax.event.mouseOverIds.indexOf(id) == -1) $ax.style.SetWidgetHover(id, false);
  8853. };
  8854. // function GetWidgetCurrentState(id) {
  8855. // if($ax.style.IsWidgetDisabled(id)) return "disabled";
  8856. // if($ax.style.IsWidgetSelected(id)) return "selected";
  8857. // if($ax.event.mouseOverObjectId == id) return "mouseOver";
  8858. // if($ax.event.mouseDownObjectId == id) return "mouseDown";
  8859. // return "normal";
  8860. // }
  8861. $ax.style.ObjHasMouseDown = function(id) {
  8862. var obj = $obj(id);
  8863. if($ax.style.getElementImageOverride(id, 'mouseDown') || obj.style && obj.style.stateStyles && obj.style.stateStyles.mouseDown) return true;
  8864. var chain = $ax.adaptive.getAdaptiveIdChain($ax.adaptive.currentViewId);
  8865. for(var i = 0; i < chain.length; i++) {
  8866. var style = obj.adaptiveStyles[chain[i]];
  8867. if(style && style.stateStyles && style.stateStyles.mouseDown) return true;
  8868. }
  8869. return false;
  8870. };
  8871. $ax.style.SetWidgetMouseDown = function(id, value) {
  8872. if($ax.style.IsWidgetDisabled(id)) return;
  8873. if(!_widgetHasState(id, MOUSE_DOWN)) return;
  8874. // ApplyImageAndTextJson(id, value ? 'mouseDown' : !$.isEmptyObject(GetStyleForState(id, null, 'mouseOver')) ? 'mouseOver' : 'normal');
  8875. var state = _generateMouseState(id, value ? MOUSE_DOWN : MOUSE_OVER, $ax.style.IsWidgetSelected(id));
  8876. _applyImageAndTextJson(id, state);
  8877. _updateElementIdImageStyle(id, state);
  8878. };
  8879. var _generateMouseState = function(id, mouseState, selected) {
  8880. if (selected) {
  8881. if (_style.getElementImageOverride(id, SELECTED)) return SELECTED;
  8882. var viewChain = $ax.adaptive.getAdaptiveIdChain($ax.adaptive.currentViewId);
  8883. viewChain[viewChain.length] = '';
  8884. var obj = $obj(id);
  8885. if(obj.type == "dynamicPanel") return SELECTED;
  8886. var any = function(dict) {
  8887. for(var key in dict) return true;
  8888. return false;
  8889. };
  8890. for(var i = 0; i < viewChain.length; i++) {
  8891. var viewId = viewChain[i];
  8892. // Need to check seperately for images.
  8893. if(obj.adaptiveStyles && obj.adaptiveStyles[viewId] && any(obj.adaptiveStyles[viewId])
  8894. || obj.images && obj.images['selected~' + viewId]) return SELECTED;
  8895. }
  8896. var selectedStyle = obj.style && obj.style.stateStyles && obj.style.stateStyles.selected;
  8897. if(selectedStyle && any(selectedStyle)) return SELECTED;
  8898. }
  8899. // Not using selected
  8900. return mouseState;
  8901. };
  8902. $ax.style.SetWidgetSelected = function(id, value, alwaysApply) {
  8903. if(_isWidgetDisabled(id)) return;
  8904. //NOTE: not firing select events if state didn't change
  8905. var raiseSelectedEvents = $ax.style.IsWidgetSelected(id) != value;
  8906. if(value) {
  8907. var group = $('#' + id).attr('selectiongroup');
  8908. if(group) {
  8909. $("[selectiongroup='" + group + "']").each(function() {
  8910. var otherId = this.id;
  8911. if(otherId == id) return;
  8912. if ($ax.visibility.isScriptIdLimbo($ax.repeater.getScriptIdFromElementId(otherId))) return;
  8913. $ax.style.SetWidgetSelected(otherId, false);
  8914. });
  8915. }
  8916. }
  8917. var obj = $obj(id);
  8918. if(obj) {
  8919. var actionId = id;
  8920. if ($ax.public.fn.IsDynamicPanel(obj.type) || $ax.public.fn.IsLayer(obj.type)) {
  8921. if(!value) $jobj(id).removeClass('selected');
  8922. var children = $axure('#' + id).getChildren()[0].children;
  8923. for(var i = 0; i < children.length; i++) {
  8924. var childId = children[i];
  8925. // Special case for trees
  8926. var childObj = $jobj(childId);
  8927. if(childObj.hasClass('treeroot')) {
  8928. var treenodes = childObj.find('.treenode');
  8929. for(var j = 0; j < treenodes.length; j++) {
  8930. $axure('#' + treenodes[j].id).selected(value);
  8931. }
  8932. } else $axure('#' + childId).selected(value);
  8933. }
  8934. } else {
  8935. var widgetHasSelectedState = _widgetHasState(id, SELECTED);
  8936. while(obj.isContained && !widgetHasSelectedState) obj = obj.parent;
  8937. var itemId = $ax.repeater.getItemIdFromElementId(id);
  8938. var path = $ax.getPathFromScriptId($ax.repeater.getScriptIdFromElementId(id));
  8939. path[path.length - 1] = obj.id;
  8940. actionId = $ax.getElementIdFromPath(path, { itemNum: itemId });
  8941. if(alwaysApply || widgetHasSelectedState) {
  8942. var state = _generateSelectedState(actionId, value);
  8943. _applyImageAndTextJson(actionId, state);
  8944. _updateElementIdImageStyle(actionId, state);
  8945. }
  8946. //added actionId and this hacky logic because we set style state on child, but interaction on parent
  8947. //then the id saved in _selectedWidgets would be depended on widgetHasSelectedState... more see case 1818143
  8948. while(obj.isContained && !$ax.getObjectFromElementId(id).interactionMap) obj = obj.parent;
  8949. path = $ax.getPathFromScriptId($ax.repeater.getScriptIdFromElementId(id));
  8950. path[path.length - 1] = obj.id;
  8951. actionId = $ax.getElementIdFromPath(path, { itemNum: itemId });
  8952. }
  8953. }
  8954. // ApplyImageAndTextJson(id, value ? 'selected' : 'normal');
  8955. _selectedWidgets[id] = value;
  8956. if(raiseSelectedEvents) $ax.event.raiseSelectedEvents(actionId, value);
  8957. };
  8958. var _generateSelectedState = function(id, selected) {
  8959. var mouseState = $ax.event.mouseDownObjectId == id ? MOUSE_DOWN : $.inArray(id, $ax.event.mouseOverIds) != -1 ? MOUSE_OVER : NORMAL;
  8960. //var mouseState = $ax.event.mouseDownObjectId == id ? MOUSE_DOWN : $ax.event.mouseOverIds.indexOf(id) != -1 ? MOUSE_OVER : NORMAL;
  8961. return _generateMouseState(id, mouseState, selected);
  8962. };
  8963. $ax.style.IsWidgetSelected = function(id) {
  8964. return Boolean(_selectedWidgets[id]) || $('#'+id).hasClass('selected');
  8965. };
  8966. $ax.style.SetWidgetEnabled = function(id, value) {
  8967. _disabledWidgets[id] = !value;
  8968. $('#' + id).find('a').css('cursor', value ? 'pointer' : 'default');
  8969. if(!_widgetHasState(id, DISABLED)) return;
  8970. if(!value) {
  8971. _applyImageAndTextJson(id, DISABLED);
  8972. _updateElementIdImageStyle(id, DISABLED);
  8973. } else $ax.style.SetWidgetSelected(id, $ax.style.IsWidgetSelected(id), true);
  8974. };
  8975. $ax.style.SetWidgetPlaceholder = function(id, value, text, password) {
  8976. var inputId = $ax.repeater.applySuffixToElementId(id, '_input');
  8977. // Right now this is the only style on the widget. If other styles (ex. Rollover), are allowed
  8978. // on TextBox/TextArea, or Placeholder is applied to more widgets, this may need to do more.
  8979. var obj = $jobj(inputId);
  8980. var height = document.getElementById(inputId).style['height'];
  8981. var width = document.getElementById(inputId).style['width'];
  8982. obj.attr('style', '');
  8983. //removing all styles, but now we can change the size, so we should add them back
  8984. //this is more like a quick hack
  8985. if (height) obj.css('height', height);
  8986. if (width) obj.css('width', width);
  8987. if(!value) {
  8988. try { //ie8 and below error
  8989. if(password) document.getElementById(inputId).type = 'password';
  8990. } catch(e) { }
  8991. } else {
  8992. var element = $('#' + inputId)[0];
  8993. var style = _computeAllOverrides(id, undefined, HINT, $ax.adaptive.currentViewId);
  8994. var styleProperties = _getCssStyleProperties(style);
  8995. //moved this out of GetCssStyleProperties for now because it was breaking un/rollovers with gradient fills
  8996. if(style.fill) styleProperties.allProps.backgroundColor = _getColorFromFill(style.fill);
  8997. _applyCssProps(element, styleProperties, true);
  8998. try { //ie8 and below error
  8999. if(password) document.getElementById(inputId).type = 'text';
  9000. } catch(e) { }
  9001. }
  9002. obj.val(text);
  9003. };
  9004. var _isWidgetDisabled = $ax.style.IsWidgetDisabled = function(id) {
  9005. return Boolean(_disabledWidgets[id]);
  9006. };
  9007. var _elementIdsToImageOverrides = {};
  9008. $ax.style.mapElementIdToImageOverrides = function (elementId, override) {
  9009. for(var key in override) _addImageOverride(elementId, key, override[key]);
  9010. };
  9011. var _addImageOverride = function (elementId, state, val) {
  9012. if (!_elementIdsToImageOverrides[elementId]) _elementIdsToImageOverrides[elementId] = {};
  9013. _elementIdsToImageOverrides[elementId][state] = val;
  9014. }
  9015. $ax.style.deleteElementIdToImageOverride = function(elementId) {
  9016. delete _elementIdsToImageOverrides[elementId];
  9017. };
  9018. $ax.style.getElementImageOverride = function(elementId, state) {
  9019. var url = _elementIdsToImageOverrides[elementId] && _elementIdsToImageOverrides[elementId][state];
  9020. return url;
  9021. };
  9022. $ax.style.elementHasAnyImageOverride = function(elementId) {
  9023. return Boolean(_elementIdsToImageOverrides[elementId]);
  9024. };
  9025. var NORMAL = 'normal';
  9026. var MOUSE_OVER = 'mouseOver';
  9027. var MOUSE_DOWN = 'mouseDown';
  9028. var SELECTED = 'selected';
  9029. var DISABLED = 'disabled';
  9030. var HINT = 'hint';
  9031. var _generateState = _style.generateState = function(id) {
  9032. return $ax.placeholderManager.isActive(id) ? HINT : _style.IsWidgetDisabled(id) ? DISABLED : _generateSelectedState(id, _style.IsWidgetSelected(id));
  9033. };
  9034. var _progressState = _style.progessState = function(state) {
  9035. if(state == NORMAL) return false;
  9036. if(state == MOUSE_DOWN) return MOUSE_OVER;
  9037. return NORMAL;
  9038. };
  9039. var _unprogressState = function(state, goal) {
  9040. state = state || NORMAL;
  9041. if(state == goal) return undefined;
  9042. if(state == NORMAL && goal == MOUSE_DOWN) return MOUSE_OVER;
  9043. return goal;
  9044. };
  9045. var _updateElementIdImageStyle = _style.updateElementIdImageStyle = function(elementId, state) {
  9046. if(!_style.elementHasAnyImageOverride(elementId)) return;
  9047. if(!state) state = _generateState(elementId);
  9048. var style = _computeFullStyle(elementId, state, $ax.adaptive.currentViewId);
  9049. var query = $jobj($ax.repeater.applySuffixToElementId(elementId, '_img'));
  9050. style.size.width = query.width();
  9051. style.size.height = query.height();
  9052. var borderId = $ax.repeater.applySuffixToElementId(elementId, '_border');
  9053. var borderQuery = $jobj(borderId);
  9054. if(!borderQuery.length) {
  9055. borderQuery = $('<div></div>');
  9056. borderQuery.attr('id', borderId);
  9057. query.after(borderQuery);
  9058. }
  9059. borderQuery.attr('style', '');
  9060. borderQuery.css('position', 'absolute');
  9061. query.attr('style', '');
  9062. var borderWidth = Number(style.borderWidth);
  9063. var hasBorderWidth = borderWidth > 0;
  9064. if(hasBorderWidth) {
  9065. borderQuery.css('border-style', 'solid');
  9066. borderQuery.css('border-width', borderWidth + 'px'); // If images start being able to turn off borders on specific sides, need to update this.
  9067. borderQuery.css('width', style.size.width - borderWidth * 2);
  9068. borderQuery.css('height', style.size.height - borderWidth * 2);
  9069. }
  9070. var linePattern = style.linePattern;
  9071. if(hasBorderWidth && linePattern) borderQuery.css('border-style', linePattern);
  9072. var borderFill = style.borderFill;
  9073. if(hasBorderWidth && borderFill) {
  9074. var color = borderFill.fillType == 'solid' ? borderFill.color :
  9075. borderFill.fillType == 'linearGradient' ? borderFill.colors[0].color : 0;
  9076. var alpha = Math.floor(color / 256 / 256 / 256);
  9077. color -= alpha * 256 * 256 * 256;
  9078. alpha = alpha / 255;
  9079. var red = Math.floor(color / 256 / 256);
  9080. color -= red * 256 * 256;
  9081. var green = Math.floor(color / 256);
  9082. var blue = color - green * 256;
  9083. borderQuery.css('border-color', _rgbaToFunc(red, green, blue, alpha));
  9084. }
  9085. var cornerRadiusTopLeft = style.cornerRadius;
  9086. if(cornerRadiusTopLeft) {
  9087. query.css('border-radius', cornerRadiusTopLeft + 'px');
  9088. borderQuery.css('border-radius', cornerRadiusTopLeft + 'px');
  9089. }
  9090. var outerShadow = style.outerShadow;
  9091. if(outerShadow && outerShadow.on) {
  9092. var arg = '';
  9093. arg += outerShadow.offsetX + 'px' + ' ' + outerShadow.offsetY + 'px' + ' ';
  9094. var rgba = outerShadow.color;
  9095. arg += outerShadow.blurRadius + 'px' + ' 0px ' + _rgbaToFunc(rgba.r, rgba.g, rgba.b, rgba.a);
  9096. query.css('-moz-box-shadow', arg);
  9097. query.css('-wibkit-box-shadow', arg);
  9098. query.css('box-shadow', arg);
  9099. query.css('left', '0px');
  9100. query.css('top', '0px');
  9101. }
  9102. query.css({ width: style.size.width, height: style.size.height });
  9103. };
  9104. var _rgbaToFunc = function(red, green, blue, alpha) {
  9105. return 'rgba(' + red + ',' + green + ',' + blue + ',' + alpha + ')';
  9106. };
  9107. //function $ax.style.GetTextIdFromShape(id) {
  9108. // return $.grep(
  9109. // $('#' + id).children().map(function (i, obj) { return obj.id; }), // all the child ids
  9110. // function (item) { return item.indexOf(id) < 0; })[0]; // that are not similar to the parent
  9111. //}
  9112. var _getButtonShapeId = function(id) {
  9113. var obj = $obj(id);
  9114. return $ax.public.fn.IsTreeNodeObject(obj.type) ? $ax.getElementIdFromPath([obj.buttonShapeId], { relativeTo: id }) : id;
  9115. };
  9116. var _getButtonShape = function(id) {
  9117. var obj = $obj(id);
  9118. // some treeNodeObjects don't have button shapes
  9119. return $jobj($ax.public.fn.IsTreeNodeObject(obj.type) && obj.buttonShapeId ? $ax.getElementIdFromPath([obj.buttonShapeId], { relativeTo: id }) : id);
  9120. };
  9121. var _getTextIdFromShape = $ax.style.GetTextIdFromShape = function(id) {
  9122. return _getButtonShape(id).find('.text').attr('id');
  9123. };
  9124. $ax.style.GetTextIdFromLink = function(id) {
  9125. return $jobj(id).parentsUntil('.text').parent().attr('id');
  9126. };
  9127. var _getShapeIdFromText = $ax.style.GetShapeIdFromText = function(id) {
  9128. if(!id) return undefined; // this is to prevent an infinite loop.
  9129. var current = document.getElementById(id);
  9130. if(!current) return undefined;
  9131. current = current.parentElement;
  9132. while(current && current.tagName != 'BODY') {
  9133. var currentId = current.id;
  9134. if(currentId && currentId != 'base') return $ax.visibility.getWidgetFromContainer(currentId);
  9135. current = current.parentElement;
  9136. }
  9137. return undefined;
  9138. };
  9139. $ax.style.GetImageIdFromShape = function(id) {
  9140. var image = _getButtonShape(id).find('img[id$=img]');
  9141. if(!image.length) image = $jobj(id).find('img[id$=image_sketch]');
  9142. return image.attr('id');
  9143. };
  9144. var _applyImageAndTextJson = function(id, event) {
  9145. var textId = $ax.style.GetTextIdFromShape(id);
  9146. _resetTextJson(id, textId);
  9147. // This should never be the case
  9148. //if(event != '') {
  9149. var imgQuery = $jobj($ax.style.GetImageIdFromShape(id));
  9150. var e = imgQuery.data('events');
  9151. if(e && e[event]) imgQuery.trigger(event);
  9152. var imageUrl = $ax.adaptive.getImageForStateAndView(id, event);
  9153. if(imageUrl) _applyImage(id, imageUrl, event);
  9154. var style = _computeAllOverrides(id, undefined, event, $ax.adaptive.currentViewId);
  9155. if(!$.isEmptyObject(style)) _applyTextStyle(textId, style);
  9156. _updateStateClasses(id, event);
  9157. _updateStateClasses($ax.repeater.applySuffixToElementId(id, '_div'), event);
  9158. };
  9159. var _updateStateClasses = function(id, event) {
  9160. var jobj = $jobj(id);
  9161. //if(jobj[0] && jobj[0].hasAttribute('widgetwidth')) {
  9162. // for (var x = 0; x < jobj[0].children.length; x++) {
  9163. // var childId = jobj[0].children[x].id;
  9164. // if (childId.indexOf('p') < 0) continue;
  9165. // _updateStateClasses(childId, event) ;
  9166. // }
  9167. //} else {
  9168. for (var i = 0; i < ALL_STATES.length; i++) jobj.removeClass(ALL_STATES[i]);
  9169. if (event == 'mouseDown') jobj.addClass('mouseOver');
  9170. if(event != 'normal') jobj.addClass(event);
  9171. //}
  9172. }
  9173. /* -------------------
  9174. here's the algorithm in a nutshell:
  9175. [DOWN] -- refers to navigation down the view inheritance heirarchy (default to most specific)
  9176. [UP] -- navigate up the heirarchy
  9177. ComputeAllOverrides (object):
  9178. All view styles [DOWN]
  9179. If hyperlink
  9180. - DO ComputeStateStyle for parent object
  9181. - if (MouseOver || MouseDown)
  9182. - linkMouseOver Style
  9183. - if (MouseDown)
  9184. - linkMouseDown style
  9185. - ComputeStateStyleForViewChain (parent, STATE)
  9186. if (MouseDown) DO ComputeStateStyleForViewChain for object, mouseOver
  9187. DO ComputeStateStyleForViewChain for object, style
  9188. ComputeStateStyleForViewChain (object, STATE)
  9189. FIRST STATE state style [UP] the chain OR default object STATE style
  9190. ------------------- */
  9191. var FONT_PROPS = {
  9192. 'typeface': true,
  9193. 'fontName': true,
  9194. 'fontWeight': true,
  9195. 'fontStyle': true,
  9196. 'fontStretch': true,
  9197. 'fontSize': true,
  9198. 'underline': true,
  9199. 'foreGroundFill': true,
  9200. 'horizontalAlignment': true
  9201. };
  9202. var _computeAllOverrides = $ax.style.computeAllOverrides = function(id, parentId, state, currentViewId) {
  9203. var computedStyle = {};
  9204. if(parentId) computedStyle = _computeAllOverrides(parentId, null, state, currentViewId);
  9205. var diagramObject = $ax.getObjectFromElementId(id);
  9206. var viewIdChain = $ax.adaptive.getAdaptiveIdChain(currentViewId);
  9207. var excludeFont = _shapesWithSetRichText[id];
  9208. for(var i = 0; i < viewIdChain.length; i++) {
  9209. var viewId = viewIdChain[i];
  9210. var style = diagramObject.adaptiveStyles[viewId];
  9211. if(style) {
  9212. // we want to exclude the normal font style for shapes where the rich text has been set with an interaction
  9213. // so we copy the style so we don't modify the original, then delete all the font props.
  9214. if(excludeFont) {
  9215. style = $ax.deepCopy(style);
  9216. for(var prop in FONT_PROPS) delete style[prop];
  9217. }
  9218. if(style) {
  9219. var customStyle = style.baseStyle && $ax.document.stylesheet.stylesById[style.baseStyle];
  9220. //make sure not to extend the customStyle this can mutate it for future use
  9221. $.extend(computedStyle, customStyle);
  9222. }
  9223. $.extend(computedStyle, style);
  9224. }
  9225. }
  9226. var currState = NORMAL;
  9227. while(currState) {
  9228. $.extend(computedStyle, _computeStateStyleForViewChain(diagramObject, currState, viewIdChain, true));
  9229. currState = _unprogressState(currState, state);
  9230. }
  9231. return _removeUnsupportedProperties(computedStyle, diagramObject.type);
  9232. };
  9233. var _computeStateStyleForViewChain = function(diagramObject, state, viewIdChain, excludeNormal) {
  9234. var styleObject = diagramObject;
  9235. while(styleObject.isContained) styleObject = styleObject.parent;
  9236. var adaptiveStyles = styleObject.adaptiveStyles;
  9237. for(var i = viewIdChain.length - 1; i >= 0; i--) {
  9238. var viewId = viewIdChain[i];
  9239. var viewStyle = adaptiveStyles[viewId];
  9240. var stateStyle = viewStyle && _getFullStateStyle(viewStyle, state, excludeNormal);
  9241. if(stateStyle) return $.extend({}, stateStyle);
  9242. }
  9243. // 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
  9244. var stateStyleFromDefault = _getFullStateStyle(styleObject.style, state, true);
  9245. return $.extend({}, stateStyleFromDefault);
  9246. };
  9247. // returns the full effective style for an object in a state state and view
  9248. var _computeFullStyle = function(id, state, currentViewId) {
  9249. var obj = $obj(id);
  9250. var overrides = _computeAllOverrides(id, undefined, state, currentViewId);
  9251. // todo: account for image box
  9252. var objStyle = obj.style;
  9253. var customStyle = objStyle.baseStyle && $ax.document.stylesheet.stylesById[objStyle.baseStyle];
  9254. var returnVal = $.extend({}, $ax.document.stylesheet.defaultStyle, customStyle, objStyle, overrides);
  9255. return _removeUnsupportedProperties(returnVal, obj.type);
  9256. };
  9257. var _removeUnsupportedProperties = function(style, objectType) {
  9258. // for now all we need to do is remove padding from checkboxes and radio buttons
  9259. if ($ax.public.fn.IsRadioButton(objectType) || $ax.public.fn.IsCheckBox(objectType)) {
  9260. style.paddingTop = 0;
  9261. style.paddingLeft = 0;
  9262. style.paddingRight = 0;
  9263. style.paddingBottom = 0;
  9264. }
  9265. return style;
  9266. };
  9267. var _getFullStateStyle = function(style, state, excludeNormal) {
  9268. //'normal' is needed because now DiagramObjects get their image from the Style and unapplying a rollover needs the image
  9269. var stateStyle = state == 'normal' && !excludeNormal ? style : style && style.stateStyles && style.stateStyles[state];
  9270. if(stateStyle) {
  9271. var customStyle = stateStyle.baseStyle && $ax.document.stylesheet.stylesById[stateStyle.baseStyle];
  9272. //make sure not to extend the customStyle this can mutate it for future use
  9273. return $.extend({}, customStyle, stateStyle);
  9274. }
  9275. return undefined;
  9276. };
  9277. // commented this out for now... we actually will probably need it for ie
  9278. var _applyOpacityFromStyle = $ax.style.applyOpacityFromStyle = function(id, style) {
  9279. return;
  9280. var opacity = style.opacity || '';
  9281. $jobj(id).children().css('opacity', opacity);
  9282. };
  9283. var _initialize = function() {
  9284. //being handled at on window.load
  9285. //$ax.style.initializeObjectTextAlignment($ax('*'));
  9286. };
  9287. $ax.style.initialize = _initialize;
  9288. var _initTextAlignment = function(elementId) {
  9289. var textId = _getTextIdFromShape(elementId);
  9290. _storeIdToAlignProps(textId);
  9291. // now handle vertical alignment
  9292. if(_getObjVisible(textId)) {
  9293. _setTextAlignment(textId, _idToAlignProps[textId], false);
  9294. }
  9295. };
  9296. $ax.style.initializeObjectTextAlignment = function(query) {
  9297. query.filter(function(diagramObject) {
  9298. return $ax.public.fn.IsVector(diagramObject.type) || $ax.public.fn.IsImageBox(diagramObject.type);
  9299. }).each(function(diagramObject, elementId) {
  9300. if($jobj(elementId).length == 0) return;
  9301. _initTextAlignment(elementId);
  9302. });
  9303. };
  9304. var _storeIdToAlignProps = function(textId) {
  9305. var shapeId = _getShapeIdFromText(textId);
  9306. var shapeObj = $obj(shapeId);
  9307. var state = _generateState(shapeId);
  9308. var style = _computeFullStyle(shapeId, state, $ax.adaptive.currentViewId);
  9309. var vAlign = style.verticalAlignment || 'middle';
  9310. var paddingLeft = Number(style.paddingLeft) || 0;
  9311. paddingLeft += (Number(shapeObj && shapeObj.extraLeft) || 0);
  9312. var paddingTop = style.paddingTop || 0;
  9313. var paddingRight = style.paddingRight || 0;
  9314. var paddingBottom = style.paddingBottom || 0;
  9315. _idToAlignProps[textId] = { vAlign: vAlign, paddingLeft: paddingLeft, paddingTop: paddingTop, paddingRight: paddingRight, paddingBottom: paddingBottom };
  9316. };
  9317. var ALL_STATES = ['mouseOver', 'mouseDown', 'selected', 'disabled'];
  9318. var _applyImage = $ax.style.applyImage = function (id, imgUrl, state) {
  9319. var object = $obj(id);
  9320. if (object.generateCompound) {
  9321. for (var i = 0; i < object.compoundChildren.length; i++) {
  9322. var componentId = object.compoundChildren[i];
  9323. var childId = $ax.public.fn.getComponentId(id, componentId);
  9324. var childImgQuery = $jobj(childId + '_img');
  9325. var childQuery = $jobj(childId);
  9326. childImgQuery.attr('src', imgUrl[componentId]);
  9327. for (var j = 0; j < ALL_STATES.length; j++) {
  9328. childImgQuery.removeClass(ALL_STATES[j]);
  9329. childQuery.removeClass(ALL_STATES[j]);
  9330. }
  9331. if (state != 'normal') {
  9332. childImgQuery.addClass(state);
  9333. childQuery.addClass(state);
  9334. }
  9335. }
  9336. } else {
  9337. var imgQuery = $jobj($ax.style.GetImageIdFromShape(id));
  9338. var idQuery = $jobj(id);
  9339. //it is hard to tell if setting the image or the class first causing less flashing when adding shadows.
  9340. imgQuery.attr('src', imgUrl);
  9341. for (var i = 0; i < ALL_STATES.length; i++) {
  9342. idQuery.removeClass(ALL_STATES[i]);
  9343. imgQuery.removeClass(ALL_STATES[i]);
  9344. }
  9345. if (state != 'normal') {
  9346. idQuery.addClass(state);
  9347. imgQuery.addClass(state);
  9348. }
  9349. if (imgQuery.parents('a.basiclink').length > 0) imgQuery.css('border', 'none');
  9350. if (imgUrl.indexOf(".png") > -1) $ax.utils.fixPng(imgQuery[0]);
  9351. }
  9352. };
  9353. $ax.public.fn.getComponentId = function (id, componentId) {
  9354. var idParts = id.split('-');
  9355. idParts[0] = idParts[0] + componentId;
  9356. return idParts.join('-');
  9357. }
  9358. var _resetTextJson = function(id, textid) {
  9359. // reset the opacity
  9360. $jobj(id).children().css('opacity', '');
  9361. var cacheObject = _originalTextCache[textid];
  9362. if(cacheObject) {
  9363. _transformTextWithVerticalAlignment(textid, function() {
  9364. var styleCache = cacheObject.styleCache;
  9365. var textQuery = $('#' + textid);
  9366. textQuery.find('*').each(function(index, element) {
  9367. element.style.cssText = styleCache[element.id];
  9368. });
  9369. });
  9370. }
  9371. };
  9372. // Preserves the alingment for the element textid after executing transformFn
  9373. var _getRtfElementHeight = function(rtfElement) {
  9374. if(rtfElement.innerHTML == '') rtfElement.innerHTML = '&nbsp;';
  9375. // To handle render text as image
  9376. var images = $(rtfElement).children('img');
  9377. if(images.length) return images.height();
  9378. return rtfElement.offsetHeight;
  9379. };
  9380. // why microsoft decided to default to round to even is beyond me...
  9381. var _roundToEven = function(number) {
  9382. var numString = number.toString();
  9383. var parts = numString.split('.');
  9384. if(parts.length == 1) return number;
  9385. if(parts[1].length == 1 && parts[1] == '5') {
  9386. var wholePart = Number(parts[0]);
  9387. return wholePart % 2 == 0 ? wholePart : wholePart + 1;
  9388. } else return Math.round(number);
  9389. };
  9390. var _transformTextWithVerticalAlignment = $ax.style.transformTextWithVerticalAlignment = function(textId, transformFn) {
  9391. if(!_originalTextCache[textId]) {
  9392. $ax.style.CacheOriginalText(textId);
  9393. }
  9394. var rtfElement = window.document.getElementById(textId);
  9395. if(!rtfElement) return;
  9396. transformFn();
  9397. _storeIdToAlignProps(textId);
  9398. $ax.style.updateTextAlignmentForVisibility(textId);
  9399. };
  9400. // this is for vertical alignments set on hidden objects
  9401. var _idToAlignProps = {};
  9402. $ax.style.updateTextAlignmentForVisibility = function (textId) {
  9403. var textObj = $jobj(textId);
  9404. // must check if parent id exists. Doesn't exist for text objs in check boxes, and potentially elsewhere.
  9405. var parentId = textObj.parent().attr('id');
  9406. if (parentId && $ax.visibility.isContainer(parentId)) return;
  9407. var alignProps = _idToAlignProps[textId];
  9408. if(!alignProps || !_getObjVisible(textId)) return;
  9409. _setTextAlignment(textId, alignProps);
  9410. };
  9411. var _getObjVisible = _style.getObjVisible = function (id) {
  9412. var element = document.getElementById(id);
  9413. return element && (element.offsetWidth || element.offsetHeight);
  9414. };
  9415. var _setTextAlignment = function (textId, alignProps, updateProps) {
  9416. if(updateProps) {
  9417. _storeIdToAlignProps(textId);
  9418. }
  9419. if(!alignProps) return;
  9420. var vAlign = alignProps.vAlign;
  9421. var paddingTop = Number(alignProps.paddingTop);
  9422. var paddingBottom = Number(alignProps.paddingBottom);
  9423. var paddingLeft = Number(alignProps.paddingLeft);
  9424. var paddingRight = Number(alignProps.paddingRight);
  9425. var topParam = 0.0;
  9426. var bottomParam = 1.0;
  9427. var leftParam = 0.0;
  9428. var rightParam = 1.0;
  9429. var textObj = $jobj(textId);
  9430. var textHeight = _getRtfElementHeight(textObj[0]);
  9431. var textObjParent = textObj.offsetParent();
  9432. var parentId = textObjParent.attr('id');
  9433. var isConnector = false;
  9434. if(parentId) {
  9435. parentId = $ax.visibility.getWidgetFromContainer(textObjParent.attr('id'));
  9436. textObjParent = $jobj(parentId);
  9437. var parentObj = $obj(parentId);
  9438. if (parentObj['bottomTextPadding']) bottomParam = parentObj['bottomTextPadding'];
  9439. if (parentObj['topTextPadding']) topParam = parentObj['topTextPadding'];
  9440. if (parentObj['leftTextPadding']) leftParam = parentObj['leftTextPadding'];
  9441. if (parentObj['rightTextPadding']) rightParam = parentObj['rightTextPadding'];
  9442. // smart shapes are mutually exclusive from compound vectors.
  9443. isConnector = parentObj.type == $ax.constants.CONNECTOR_TYPE;
  9444. }
  9445. if (isConnector) return;
  9446. var axTextObjectParent = $ax('#' + textObjParent.attr('id'));
  9447. var oldWidth = $ax.getNumFromPx(textObj.css('width'));
  9448. var oldLeft = $ax.getNumFromPx(textObj.css('left'));
  9449. var oldTop = $ax.getNumFromPx(textObj.css('top'));
  9450. var newTop = 0;
  9451. var newLeft = 0.0;
  9452. var width = axTextObjectParent.width();
  9453. var height = axTextObjectParent.height();
  9454. // If text rotated need to handle getting the correct width for text based on bounding rect of rotated parent.
  9455. var boundingRotation = -$ax.move.getRotationDegree(textId);
  9456. var boundingParent = $axure.fn.getBoundingSizeForRotate(width, height, boundingRotation);
  9457. var extraLeftPadding = (width - boundingParent.width) / 2;
  9458. width = boundingParent.width;
  9459. var relativeTop = 0.0;
  9460. relativeTop = height * topParam;
  9461. var containerHeight = height * bottomParam - relativeTop;
  9462. if (vAlign == "middle") newTop = _roundToEven(relativeTop + (containerHeight - textHeight + paddingTop - paddingBottom) / 2);
  9463. else if (vAlign == "bottom") newTop = _roundToEven(relativeTop + containerHeight - textHeight - paddingBottom);
  9464. else newTop = _roundToEven(paddingTop + relativeTop);
  9465. newLeft = paddingLeft + extraLeftPadding + width * leftParam;
  9466. var newWidth = width * (rightParam - leftParam) - paddingLeft - paddingRight;
  9467. var vertChange = oldTop != newTop;
  9468. if (vertChange) textObj.css('top', newTop + 'px');
  9469. var horizChange = newWidth != oldWidth || newLeft != oldLeft;
  9470. if (horizChange) {
  9471. textObj.css('left', newLeft);
  9472. textObj.width(newWidth);
  9473. }
  9474. if ((vertChange || horizChange)) _updateTransformOrigin(textId);
  9475. };
  9476. var _updateTransformOrigin = function(textId) {
  9477. var textObj = $jobj(textId);
  9478. var transformOrigin = textObj.css('-webkit-transform-origin') ||
  9479. textObj.css('-moz-transform-origin') ||
  9480. textObj.css('-ms-transform-origin') ||
  9481. textObj.css('transform-origin');
  9482. if(transformOrigin) {
  9483. var textObjParent = $ax('#' + textObj.parent().attr('id'));
  9484. var newX = (textObjParent.width() / 2 - textObj.css('left').replace('px', ''));
  9485. var newY = (textObjParent.height() / 2 - textObj.css('top').replace('px', ''));
  9486. var newOrigin = newX + 'px ' + newY + 'px';
  9487. textObj.css('-webkit-transform-origin', newOrigin);
  9488. textObj.css('-moz-transform-origin', newOrigin);
  9489. textObj.css('-ms-transform-origin', newOrigin);
  9490. textObj.css('transform-origin', newOrigin);
  9491. }
  9492. };
  9493. $ax.style.reselectElements = function() {
  9494. for(var id in _selectedWidgets) {
  9495. // Only looking for the selected widgets that don't have their class set
  9496. if(!_selectedWidgets[id] || $jobj(id).hasClass('selected')) continue;
  9497. $jobj(id).addClass('selected');
  9498. _applyImageAndTextJson(id, $ax.style.generateState(id));
  9499. }
  9500. for(id in _disabledWidgets) {
  9501. // Only looking for the disabled widgets that don't have their class yet
  9502. if (!_disabledWidgets[id] || $jobj(id).hasClass('disabled')) continue;
  9503. $jobj(id).addClass('disabled');
  9504. _applyImageAndTextJson(id, $ax.style.generateState(id));
  9505. }
  9506. }
  9507. $ax.style.clearAdaptiveStyles = function() {
  9508. for(var shapeId in _adaptiveStyledWidgets) {
  9509. var repeaterId = $ax.getParentRepeaterFromScriptId(shapeId);
  9510. if(repeaterId) continue;
  9511. var elementId = _getButtonShapeId(shapeId);
  9512. if(elementId) {
  9513. _applyImageAndTextJson(elementId, $ax.style.generateState(elementId));
  9514. }
  9515. }
  9516. _adaptiveStyledWidgets = {};
  9517. };
  9518. $ax.style.setAdaptiveStyle = function(shapeId, style) {
  9519. _adaptiveStyledWidgets[$ax.repeater.getScriptIdFromElementId(shapeId)] = style;
  9520. var textId = $ax.style.GetTextIdFromShape(shapeId);
  9521. if(textId) _applyTextStyle(textId, style);
  9522. $ax.placeholderManager.refreshPlaceholder(shapeId);
  9523. // removing this for now
  9524. // if(style.location) {
  9525. // $jobj(shapeId).css('top', style.location.x + "px")
  9526. // .css('left', style.location.y + "px");
  9527. // }
  9528. };
  9529. //-------------------------------------------------------------------------
  9530. // _applyTextStyle
  9531. //
  9532. // Applies a rollover style to a text element.
  9533. // id : the id of the text object to set.
  9534. // styleProperties : an object mapping style properties to values. eg:
  9535. // { 'fontWeight' : 'bold',
  9536. // 'fontStyle' : 'italic' }
  9537. //-------------------------------------------------------------------------
  9538. var _applyTextStyle = function(id, style) {
  9539. _transformTextWithVerticalAlignment(id, function() {
  9540. var styleProperties = _getCssStyleProperties(style);
  9541. $('#' + id).find('*').each(function(index, element) {
  9542. _applyCssProps(element, styleProperties);
  9543. });
  9544. });
  9545. };
  9546. var _applyCssProps = function(element, styleProperties, applyAllStyle) {
  9547. if(applyAllStyle) {
  9548. var allProps = styleProperties.allProps;
  9549. for(var prop in allProps) element.style[prop] = allProps[prop];
  9550. } else {
  9551. var nodeName = element.nodeName.toLowerCase();
  9552. if(nodeName == 'p') {
  9553. var parProps = styleProperties.parProps;
  9554. for(prop in parProps) element.style[prop] = parProps[prop];
  9555. } else if(nodeName != 'a') {
  9556. var runProps = styleProperties.runProps;
  9557. for(prop in runProps) element.style[prop] = runProps[prop];
  9558. }
  9559. }
  9560. };
  9561. var _getCssShadow = function(shadow) {
  9562. return !shadow.on ? "none"
  9563. : shadow.offsetX + "px " + shadow.offsetY + "px " + shadow.blurRadius + "px " + _getCssColor(shadow.color);
  9564. };
  9565. var _getCssStyleProperties = function(style) {
  9566. var toApply = {};
  9567. toApply.runProps = {};
  9568. toApply.parProps = {};
  9569. toApply.allProps = {};
  9570. if(style.fontName) toApply.allProps.fontFamily = toApply.runProps.fontFamily = style.fontName;
  9571. // we need to set font size on both runs and pars because otherwise it well mess up the measure and thereby vertical alignment
  9572. if(style.fontSize) toApply.allProps.fontSize = toApply.runProps.fontSize = toApply.parProps.fontSize = style.fontSize;
  9573. if(style.fontWeight !== undefined) toApply.allProps.fontWeight = toApply.runProps.fontWeight = style.fontWeight;
  9574. if(style.fontStyle !== undefined) toApply.allProps.fontStyle = toApply.runProps.fontStyle = style.fontStyle;
  9575. if(style.underline !== undefined) toApply.allProps.textDecoration = toApply.runProps.textDecoration = style.underline ? 'underline' : 'none';
  9576. if(style.foreGroundFill) {
  9577. toApply.allProps.color = toApply.runProps.color = _getColorFromFill(style.foreGroundFill);
  9578. //if(style.foreGroundFill.opacity) toApply.allProps.opacity = toApply.runProps.opacity = style.foreGroundFill.opacity;
  9579. }
  9580. if(style.horizontalAlignment) toApply.allProps.textAlign = toApply.parProps.textAlign = toApply.runProps.textAlign = style.horizontalAlignment;
  9581. if(style.lineSpacing) toApply.allProps.lineHeight = toApply.parProps.lineHeight = style.lineSpacing;
  9582. if(style.textShadow) toApply.allProps.textShadow = toApply.parProps.textShadow = _getCssShadow(style.textShadow);
  9583. return toApply;
  9584. };
  9585. var _getColorFromFill = function(fill) {
  9586. //var fillString = '00000' + fill.color.toString(16);
  9587. //return '#' + fillString.substring(fillString.length - 6);
  9588. var val = fill.color;
  9589. var color = {};
  9590. color.b = val % 256;
  9591. val = Math.floor(val / 256);
  9592. color.g = val % 256;
  9593. val = Math.floor(val / 256);
  9594. color.r = val % 256;
  9595. color.a = typeof (fill.opacity) == 'number' ? fill.opacity : 1;
  9596. return _getCssColor(color);
  9597. };
  9598. var _getCssColor = function(rgbaObj) {
  9599. return "rgba(" + rgbaObj.r + ", " + rgbaObj.g + ", " + rgbaObj.b + ", " + rgbaObj.a + ")";
  9600. };
  9601. // //--------------------------------------------------------------------------
  9602. // // ApplyStyleRecursive
  9603. // //
  9604. // // Applies a style recursively to all span and div tags including elementNode
  9605. // // and all of its children.
  9606. // //
  9607. // // element : the element to apply the style to
  9608. // // styleName : the name of the style property to set (eg. 'font-weight')
  9609. // // styleValue : the value of the style to set (eg. 'bold')
  9610. // //--------------------------------------------------------------------------
  9611. // function ApplyStyleRecursive(element, styleName, styleValue) {
  9612. // var nodeName = element.nodeName.toLowerCase();
  9613. // if (nodeName == 'div' || nodeName == 'span' || nodeName == 'p') {
  9614. // element.style[styleName] = styleValue;
  9615. // }
  9616. // for (var i = 0; i < element.childNodes.length; i++) {
  9617. // ApplyStyleRecursive(element.childNodes[i], styleName, styleValue);
  9618. // }
  9619. // }
  9620. // //---------------------------------------------------------------------------
  9621. // // ApplyTextProperty
  9622. // //
  9623. // // Applies a text property to rtfElement.
  9624. // //
  9625. // // rtfElement : the the root text element of the rtf object (this is the
  9626. // // element named <id>_rtf
  9627. // // prop : the style property to set.
  9628. // // value : the style value to set.
  9629. // //---------------------------------------------------------------------------
  9630. // function ApplyTextProperty(rtfElement, prop, value) {
  9631. // /*
  9632. // var oldHtml = rtfElement.innerHTML;
  9633. // if (prop == 'fontWeight') {
  9634. // rtfElement.innerHTML = oldHtml.replace(/< *b *\/?>/gi, "");
  9635. // } else if (prop == 'fontStyle') {
  9636. // rtfElement.innerHTML = oldHtml.replace(/< *i *\/?>/gi, "");
  9637. // } else if (prop == 'textDecoration') {
  9638. // rtfElement.innerHTML = oldHtml.replace(/< *u *\/?>/gi, "");
  9639. // }
  9640. // */
  9641. // for (var i = 0; i < rtfElement.childNodes.length; i++) {
  9642. // ApplyStyleRecursive(rtfElement.childNodes[i], prop, value);
  9643. // }
  9644. // }
  9645. //}
  9646. //---------------------------------------------------------------------------
  9647. // GetAndCacheOriginalText
  9648. //
  9649. // Gets the html for the pre-rollover state and returns the Html representing
  9650. // the Rich text.
  9651. //---------------------------------------------------------------------------
  9652. var CACHE_COUNTER = 0;
  9653. $ax.style.CacheOriginalText = function(textId, hasRichTextBeenSet) {
  9654. var rtfQuery = $('#' + textId);
  9655. if(rtfQuery.length > 0) {
  9656. var styleCache = {};
  9657. rtfQuery.find('*').each(function(index, element) {
  9658. var elementId = element.id;
  9659. if(!elementId) element.id = elementId = 'cache' + CACHE_COUNTER++;
  9660. styleCache[elementId] = element.style.cssText;
  9661. });
  9662. _originalTextCache[textId] = {
  9663. styleCache: styleCache
  9664. };
  9665. if(hasRichTextBeenSet) {
  9666. var shapeId = _getShapeIdFromText(textId);
  9667. _shapesWithSetRichText[shapeId] = true;
  9668. }
  9669. }
  9670. };
  9671. $ax.style.ClearCacheForRepeater = function(repeaterId) {
  9672. for(var elementId in _originalTextCache) {
  9673. var scriptId = $ax.repeater.getScriptIdFromElementId(elementId);
  9674. if($ax.getParentRepeaterFromScriptId(scriptId) == repeaterId) delete _originalTextCache[elementId];
  9675. }
  9676. };
  9677. $ax.style.prefetch = function() {
  9678. var scriptIds = $ax.getAllScriptIds();
  9679. var image = new Image();
  9680. for(var i = 0; i < scriptIds.length; i++) {
  9681. var obj = $obj(scriptIds[i]);
  9682. if (!$ax.public.fn.IsImageBox(obj.type)) continue;
  9683. var images = obj.images;
  9684. for (var key in images) image.src = images[key];
  9685. var imageOverrides = obj.imageOverrides;
  9686. for(var elementId in imageOverrides) {
  9687. var override = imageOverrides[elementId];
  9688. for (var state in override) {
  9689. _addImageOverride(elementId, state, override[state]);
  9690. image.src = override[state];
  9691. }
  9692. }
  9693. }
  9694. };
  9695. });
  9696. //***** adaptive.js *****//
  9697. $axure.internal(function($ax) {
  9698. $ax.adaptive = {};
  9699. $axure.utils.makeBindable($ax.adaptive, ["viewChanged"]);
  9700. var _auto = true;
  9701. var _autoIsHandledBySidebar = false;
  9702. var _views;
  9703. var _idToView;
  9704. var _enabledViews = [];
  9705. var _initialViewToLoad;
  9706. var _initialViewSizeToLoad;
  9707. var _loadFinished = false;
  9708. $ax.adaptive.loadFinished = function() {
  9709. if(_loadFinished) return;
  9710. _loadFinished = true;
  9711. if($ax.adaptive.currentViewId) $ax.viewChangePageAndMasters();
  9712. else $ax.postAdaptiveViewChanged();
  9713. };
  9714. var _handleResize = function(forceSwitchTo) {
  9715. if(!_auto) return;
  9716. if(_auto && _autoIsHandledBySidebar && !forceSwitchTo) return;
  9717. var $window = $(window);
  9718. var height = $window.height();
  9719. var width = $window.width();
  9720. var toView = _getAdaptiveView(width, height);
  9721. var toViewId = toView && toView.id;
  9722. _switchView(toViewId, forceSwitchTo);
  9723. };
  9724. var _setAuto = $ax.adaptive.setAuto = function(val) {
  9725. if(_auto != val) {
  9726. _auto = Boolean(val);
  9727. }
  9728. };
  9729. var _setLineImage = function(id, imageUrl) {
  9730. var imageQuery = $jobj(id).attr('src', imageUrl);
  9731. if(imageUrl.indexOf(".png") > -1) $ax.utils.fixPng(imageQuery[0]);
  9732. };
  9733. var _switchView = function (viewId, forceSwitchTo) {
  9734. if(!$ax.pageData.isAdaptiveEnabled) return;
  9735. var previousViewId = $ax.adaptive.currentViewId;
  9736. if(typeof previousViewId == 'undefined') previousViewId = '';
  9737. if(typeof viewId == 'undefined') viewId = '';
  9738. if (viewId == previousViewId) {
  9739. if(forceSwitchTo) $ax.postAdaptiveViewChanged(forceSwitchTo);
  9740. return;
  9741. }
  9742. $ax('*').each(function(obj, elementId) {
  9743. if (!$ax.public.fn.IsTreeNodeObject(obj.type)) return;
  9744. if(!obj.hasOwnProperty('isExpanded')) return;
  9745. var query = $ax('#' + elementId);
  9746. var defaultExpanded = obj.isExpanded;
  9747. query.expanded(defaultExpanded);
  9748. });
  9749. // reset all the inline positioning from move and rotate actions including size and transformation
  9750. $axure('*').each(function (diagramObject, elementId) {
  9751. if(diagramObject.isContained) return;
  9752. if($ax.getParentRepeaterFromElementIdExcludeSelf(elementId)) return;
  9753. var element = document.getElementById(elementId);
  9754. if(element) {
  9755. var resetCss = {
  9756. top: "", left: "", width: "", height: "", opacity: "",
  9757. transform: "", webkitTransform: "", MozTransform: "", msTransform: "", OTransform: ""
  9758. };
  9759. var query = $(element);
  9760. query.css(resetCss);
  9761. var isPanel = $ax.public.fn.IsDynamicPanel(diagramObject.type);
  9762. if(!isPanel || diagramObject.fitToContent) { //keeps size on the panel states when switching adaptive views to optimize fit to panel
  9763. if(diagramObject.fitToContent) $ax.dynamicPanelManager.setFitToContentCss(elementId, true);
  9764. var children = query.children();
  9765. if(children.length) children.css(resetCss);
  9766. }
  9767. $ax.dynamicPanelManager.resetFixedPanel(diagramObject, element);
  9768. $ax.dynamicPanelManager.resetAdaptivePercentPanel(diagramObject, element);
  9769. }
  9770. });
  9771. $ax.adaptive.currentViewId = viewId; // we need to set this so the enabled and selected styles will apply properly
  9772. if(previousViewId) {
  9773. $ax.style.clearAdaptiveStyles();
  9774. $('*').removeClass(previousViewId);
  9775. } else {
  9776. $ax.style.reselectElements();
  9777. }
  9778. $axure('*').each(function (obj, elementId) {
  9779. if($ax.getParentRepeaterFromElementIdExcludeSelf(elementId)) return;
  9780. $ax.style.updateElementIdImageStyle(elementId); // When image override exists, fix styling/borders
  9781. });
  9782. // reset all the images only if we're going back to the default view
  9783. if(!viewId) {
  9784. _updateInputVisibility('', $axure('*'));
  9785. $axure('*').each(function (diagramObject, elementId) {
  9786. if($ax.getParentRepeaterFromElementIdExcludeSelf(elementId)) return;
  9787. $ax.placeholderManager.refreshPlaceholder(elementId);
  9788. var images = diagramObject.images;
  9789. if(diagramObject.type == 'horizontalLine' || diagramObject.type == 'verticalLine') {
  9790. var startImg = images['start~'];
  9791. _setLineImage(elementId + "_start", startImg);
  9792. var endImg = images['end~'];
  9793. _setLineImage(elementId + "_end", endImg);
  9794. var lineImg = images['line~'];
  9795. _setLineImage(elementId + "_line", lineImg);
  9796. } else if(diagramObject.type == $ax.constants.CONNECTOR_TYPE) {
  9797. _setAdaptiveConnectorImages(elementId, images, '');
  9798. } else if(images) {
  9799. if (diagramObject.generateCompound) {
  9800. if($ax.style.IsWidgetDisabled(elementId)) {
  9801. disabledImage = _getImageWithTag(images, 'disabled~');
  9802. if(disabledImage) $ax.style.applyImage(elementId, disabledImage, 'disabled');
  9803. return;
  9804. }
  9805. if($ax.style.IsWidgetSelected(elementId)) {
  9806. selectedImage = _getImageWithTag(images, 'selected~');
  9807. if(selectedImage) $ax.style.applyImage(elementId, selectedImage, 'selected');
  9808. return;
  9809. }
  9810. $ax.style.applyImage(elementId, _getImageWithTag(images, 'normal~'));
  9811. } else {
  9812. if ($ax.style.IsWidgetDisabled(elementId)) {
  9813. var disabledImage = $ax.style.getElementImageOverride(elementId, 'disabled') || images['disabled~'];
  9814. if (disabledImage) $ax.style.applyImage(elementId, disabledImage, 'disabled');
  9815. return;
  9816. }
  9817. if ($ax.style.IsWidgetSelected(elementId)) {
  9818. var selectedImage = $ax.style.getElementImageOverride(elementId, 'selected') || images['selected~'];
  9819. if (selectedImage) $ax.style.applyImage(elementId, selectedImage, 'selected');
  9820. return;
  9821. }
  9822. $ax.style.applyImage(elementId, $ax.style.getElementImageOverride(elementId, 'normal') || images['normal~']);
  9823. }
  9824. }
  9825. //align all text
  9826. var child = $jobj(elementId).children('.text');
  9827. if(child.length) $ax.style.transformTextWithVerticalAlignment(child[0].id, function() { });
  9828. });
  9829. // we have to reset visibility if we aren't applying a new view
  9830. $ax.visibility.resetLimboAndHiddenToDefaults();
  9831. $ax.repeater.refreshAllRepeaters();
  9832. $ax.dynamicPanelManager.updateParentsOfNonDefaultFitPanels();
  9833. $ax.dynamicPanelManager.updatePercentPanelCache($ax('*'));
  9834. } else {
  9835. $ax.visibility.clearLimboAndHidden();
  9836. _applyView(viewId);
  9837. $ax.repeater.refreshAllRepeaters();
  9838. $ax.dynamicPanelManager.updateParentsOfNonDefaultFitPanels();
  9839. }
  9840. $ax.adaptive.triggerEvent('viewChanged', {});
  9841. if(_loadFinished) $ax.viewChangePageAndMasters(forceSwitchTo);
  9842. };
  9843. var _getImageWithTag = function(image, tag) {
  9844. var flattened = {};
  9845. for (var component in image) {
  9846. var componentImage = image[component][tag];
  9847. if(componentImage) flattened[component] = componentImage;
  9848. }
  9849. return flattened;
  9850. }
  9851. // gets if input is hidden due to sketch
  9852. var BORDER_WIDTH = "borderWidth";
  9853. var COLOR_STYLE = "colorStyle";
  9854. var SKETCH_FACTOR = "sketchFactor";
  9855. var _areInputsHidden = function(viewId) {
  9856. var chain = _getAdaptiveIdChain(viewId);
  9857. var page = $ax.pageData.page;
  9858. var adaptiveStyles = page.adaptiveStyles;
  9859. // keep track of props that are not sketchy, as you continue to climb up your parents;
  9860. var notSketch = [];
  9861. for(var i = chain.length - 1; i >= -1; i--) {
  9862. var style = i == -1 ? page.style : adaptiveStyles[chain[i]];
  9863. if(notSketch.indexOf(BORDER_WIDTH) == -1 && style.hasOwnProperty(BORDER_WIDTH)) {
  9864. if(style[BORDER_WIDTH] != 0) return true;
  9865. notSketch.push(BORDER_WIDTH);
  9866. }
  9867. if(notSketch.indexOf(COLOR_STYLE) == -1 && style.hasOwnProperty(COLOR_STYLE)) {
  9868. if(style[COLOR_STYLE] != 'appliedColor') return true;
  9869. notSketch.push(COLOR_STYLE);
  9870. }
  9871. if(notSketch.indexOf(SKETCH_FACTOR) == -1 && style.hasOwnProperty(SKETCH_FACTOR)) {
  9872. if(style[SKETCH_FACTOR] != 0) return true;
  9873. notSketch.push(SKETCH_FACTOR);
  9874. }
  9875. }
  9876. return false;
  9877. };
  9878. var _updateInputVisibility = function(viewId, query) {
  9879. var func = _areInputsHidden(viewId) ? 'addClass' : 'removeClass';
  9880. query.each(function(obj, elementId) {
  9881. var input = $jobj($ax.repeater.applySuffixToElementId(elementId, '_input'));
  9882. if(input.length == 0) return;
  9883. input[func]('form_sketch');
  9884. });
  9885. };
  9886. // gets the inheritance chain of a particular view.
  9887. var _getAdaptiveIdChain = $ax.adaptive.getAdaptiveIdChain = function(viewId) {
  9888. if(!viewId) return [];
  9889. var view = _idToView[viewId];
  9890. var chain = [];
  9891. var current = view;
  9892. while(current) {
  9893. chain[chain.length] = current.id;
  9894. current = _idToView[current.baseViewId];
  9895. }
  9896. return chain.reverse();
  9897. };
  9898. var _getPageStyle = $ax.adaptive.getPageStyle = function() {
  9899. var currentViewId = $ax.adaptive.currentViewId;
  9900. var adaptiveChain = _getAdaptiveIdChain(currentViewId);
  9901. var currentStyle = $.extend({}, $ax.pageData.page.style);
  9902. for(var i = 0; i < adaptiveChain.length; i++) {
  9903. var viewId = adaptiveChain[i];
  9904. $.extend(currentStyle, $ax.pageData.page.adaptiveStyles[viewId]);
  9905. }
  9906. return currentStyle;
  9907. };
  9908. var _setAdaptiveLineImages = function(elementId, images, viewIdChain) {
  9909. for(var i = viewIdChain.length - 1; i >= 0; i--) {
  9910. var viewId = viewIdChain[i];
  9911. var startImg = images['start~' + viewId];
  9912. if(startImg) {
  9913. _setLineImage(elementId + "_start", startImg);
  9914. var endImg = images['end~' + viewId];
  9915. _setLineImage(elementId + "_end", endImg);
  9916. var lineImg = images['line~' + viewId];
  9917. _setLineImage(elementId + "_line", lineImg);
  9918. break;
  9919. }
  9920. }
  9921. };
  9922. var _setAdaptiveConnectorImages = function (elementId, images, view) {
  9923. var conn = $jobj(elementId);
  9924. var count = conn.children().length-1; // -1 for rich text panel
  9925. for(var i = 0; i < count; i++) {
  9926. var img = images['' + i + '~' + view];
  9927. $jobj(elementId + '_seg' + i).attr('src', img);
  9928. }
  9929. };
  9930. var _applyView = $ax.adaptive.applyView = function(viewId, query) {
  9931. var limboIds = {};
  9932. var hiddenIds = {};
  9933. var jquery;
  9934. if(query) {
  9935. jquery = query.jQuery();
  9936. jquery = jquery.add(jquery.find('*'));
  9937. var jqueryAnn = $ax.annotation.jQueryAnn(query);
  9938. jquery = jquery.add(jqueryAnn);
  9939. } else {
  9940. jquery = $('*');
  9941. query = $ax('*');
  9942. }
  9943. jquery.addClass(viewId);
  9944. _updateInputVisibility(viewId, query);
  9945. var viewIdChain = _getAdaptiveIdChain(viewId);
  9946. // this could be made more efficient by computing it only once per object
  9947. query.each(function(diagramObject, elementId) {
  9948. _applyAdaptiveViewOnObject(diagramObject, elementId, viewIdChain, viewId, limboIds, hiddenIds);
  9949. });
  9950. $ax.visibility.addLimboAndHiddenIds(limboIds, hiddenIds, query);
  9951. //$ax.dynamicPanelManager.updateAllFitPanelsAndLayerSizeCaches();
  9952. $ax.dynamicPanelManager.updatePercentPanelCache(query);
  9953. };
  9954. var _applyAdaptiveViewOnObject = function(diagramObject, elementId, viewIdChain, viewId, limboIds, hiddenIds) {
  9955. var adaptiveChain = [];
  9956. for(var i = 0; i < viewIdChain.length; i++) {
  9957. var viewId = viewIdChain[i];
  9958. var viewStyle = diagramObject.adaptiveStyles[viewId];
  9959. if(viewStyle) {
  9960. adaptiveChain[adaptiveChain.length] = viewStyle;
  9961. if (viewStyle.size) $ax.public.fn.convertToSingleImage($jobj(elementId));
  9962. }
  9963. }
  9964. var state = $ax.style.generateState(elementId);
  9965. // set the image
  9966. var images = diagramObject.images;
  9967. if(images) {
  9968. if(diagramObject.type == 'horizontalLine' || diagramObject.type == 'verticalLine') {
  9969. _setAdaptiveLineImages(elementId, images, viewIdChain);
  9970. } else if (diagramObject.type == $ax.constants.CONNECTOR_TYPE) {
  9971. _setAdaptiveConnectorImages(elementId, images, viewId);
  9972. } else if (diagramObject.generateCompound) {
  9973. var compoundUrl = _matchImageCompound(diagramObject, elementId, viewIdChain, state);
  9974. if (compoundUrl) $ax.style.applyImage(elementId, compoundUrl, state);
  9975. }else {
  9976. var imgUrl = _matchImage(elementId, images, viewIdChain, state);
  9977. if(imgUrl) $ax.style.applyImage(elementId, imgUrl, state);
  9978. }
  9979. // for(var i = viewIdChain.length - 1; i >= 0; i--) {
  9980. // var viewId = viewIdChain[i];
  9981. // var imgUrl = $ax.style.getElementImageOverride(elementId, state) || images[state + '~' + viewId] || images['normal~' + viewId];
  9982. // if(imgUrl) {
  9983. // $ax.style.applyImage(elementId, imgUrl, state);
  9984. // break;
  9985. // }
  9986. // }
  9987. // }
  9988. }
  9989. // addaptive override style (not including default style props)
  9990. var adaptiveStyle = $ax.style.computeAllOverrides(elementId, undefined, state, viewId);
  9991. // this style INCLUDES the object's my style
  9992. var compoundStyle = $.extend({}, diagramObject.style, adaptiveStyle);
  9993. //$ax.style.setAdaptiveStyle(elementId, adaptiveStyle);
  9994. if(!diagramObject.isContained) {
  9995. $ax.style.setAdaptiveStyle(elementId, adaptiveStyle);
  9996. }
  9997. var scriptId = $ax.repeater.getScriptIdFromElementId(elementId);
  9998. if(compoundStyle.limbo && !diagramObject.isContained) limboIds[scriptId] = true;
  9999. // sigh, javascript. we need the === here because undefined means not overriden
  10000. if(compoundStyle.visible === false) hiddenIds[scriptId] = true;
  10001. };
  10002. var _matchImage = function(id, images, viewIdChain, state) {
  10003. var override = $ax.style.getElementImageOverride(id, state);
  10004. if(override) return override;
  10005. if(!images) return undefined;
  10006. // first check all the images for this state
  10007. for(var i = viewIdChain.length - 1; i >= 0; i--) {
  10008. var viewId = viewIdChain[i];
  10009. var img = images[state + "~" + viewId];
  10010. if(img) return img;
  10011. }
  10012. // check for the default state style
  10013. var defaultStateImage = images[state + '~'];
  10014. if(defaultStateImage) return defaultStateImage;
  10015. state = $ax.style.progessState(state);
  10016. if(state) return _matchImage(id, images, viewIdChain, state);
  10017. // SHOULD NOT REACH HERE! NORMAL SHOULD ALWAYS CATCH AT THE DEFAULT!
  10018. return images['normal~']; // this is the default
  10019. };
  10020. var _matchImageCompound = function(diagramObject, id, viewIdChain, state) {
  10021. var images = [];
  10022. for(var i = 0; i < diagramObject.compoundChildren.length; i++) {
  10023. var component = diagramObject.compoundChildren[i];
  10024. images[component] = _matchImage(id, diagramObject.images[component], viewIdChain, state);
  10025. }
  10026. return images;
  10027. };
  10028. $ax.adaptive.getImageForStateAndView = function(id, state) {
  10029. var viewIdChain = _getAdaptiveIdChain($ax.adaptive.currentViewId);
  10030. var diagramObject = $ax.getObjectFromElementId(id);
  10031. if (diagramObject.generateCompound) return _matchImageCompound(diagramObject, id, viewIdChain, state);
  10032. else return _matchImage(id, diagramObject.images, viewIdChain, state);
  10033. };
  10034. var _getAdaptiveView = function(winWidth, winHeight) {
  10035. var _isViewOneGreaterThanTwo = function(view1, view2) {
  10036. return view1.size.width > view2.size.width || (view1.size.width == view2.size.width && view1.size.height > view2.size.height);
  10037. };
  10038. var _isViewOneLessThanTwo = function(view1, view2) {
  10039. var width2 = view2.size.width || 1000000; // artificially large number
  10040. var height2 = view2.size.height || 1000000;
  10041. var width1 = view1.size.width || 1000000;
  10042. var height1 = view1.size.height || 1000000;
  10043. return width1 < width2 || (width1 == width2 && height1 < height2);
  10044. };
  10045. var _isWindowGreaterThanView = function(view, width, height) {
  10046. return width >= view.size.width && height >= view.size.height;
  10047. };
  10048. var _isWindowLessThanView = function(view1, width, height) {
  10049. var viewWidth = view1.size.width || 1000000;
  10050. var viewHeight = view1.size.height || 1000000;
  10051. return width <= viewWidth && height <= viewHeight;
  10052. };
  10053. var greater = undefined;
  10054. var less = undefined;
  10055. for(var i = 0; i < _enabledViews.length; i++) {
  10056. var view = _enabledViews[i];
  10057. if(view.condition == ">=") {
  10058. if(_isWindowGreaterThanView(view, winWidth, winHeight)) {
  10059. if(!greater || _isViewOneGreaterThanTwo(view, greater)) greater = view;
  10060. }
  10061. } else {
  10062. if(_isWindowLessThanView(view, winWidth, winHeight)) {
  10063. if(!less || _isViewOneLessThanTwo(view, less)) less = view;
  10064. }
  10065. }
  10066. }
  10067. return less || greater;
  10068. };
  10069. var _isAdaptiveInitialized = function() {
  10070. return typeof _idToView != 'undefined';
  10071. };
  10072. $ax.messageCenter.addMessageListener(function(message, data) {
  10073. //If the adaptive plugin hasn't been initialized yet then
  10074. //save the view to load so that it can get set when initialize occurs
  10075. if(message == 'switchAdaptiveView') {
  10076. var href = window.location.href.split('#')[0];
  10077. var lastSlash = href.lastIndexOf('/');
  10078. href = href.substring(lastSlash + 1);
  10079. if(href != data.src) return;
  10080. var view = data.view == 'auto' ? undefined : (data.view == 'default' ? '' : data.view);
  10081. if(!_isAdaptiveInitialized()) {
  10082. _initialViewToLoad = view;
  10083. } else _handleLoadViewId(view);
  10084. } else if(message == 'setAdaptiveViewForSize') {
  10085. _autoIsHandledBySidebar = true;
  10086. if(!_isAdaptiveInitialized()) {
  10087. _initialViewSizeToLoad = data;
  10088. } else _handleSetViewForSize(data.width, data.height);
  10089. }
  10090. });
  10091. $ax.adaptive.setAdaptiveView = function(view) {
  10092. var viewIdForSitemapToUnderstand = view == 'auto' ? undefined : (view == 'default' ? '' : view);
  10093. if(!_isAdaptiveInitialized()) {
  10094. _initialViewToLoad = viewIdForSitemapToUnderstand;
  10095. } else _handleLoadViewId(viewIdForSitemapToUnderstand);
  10096. };
  10097. $ax.adaptive.initialize = function() {
  10098. _views = $ax.document.adaptiveViews;
  10099. _idToView = {};
  10100. if(_views && _views.length > 0) {
  10101. for(var i = 0; i < _views.length; i++) {
  10102. var view = _views[i];
  10103. _idToView[view.id] = view;
  10104. }
  10105. var enabledViewIds = $ax.document.configuration.enabledViewIds;
  10106. for(var i = 0; i < enabledViewIds.length; i++) {
  10107. _enabledViews[_enabledViews.length] = _idToView[enabledViewIds[i]];
  10108. }
  10109. if(_autoIsHandledBySidebar && _initialViewSizeToLoad) _handleSetViewForSize(_initialViewSizeToLoad.width, _initialViewSizeToLoad.height);
  10110. else _handleLoadViewId(_initialViewToLoad);
  10111. }
  10112. $axure.resize(function(e) {
  10113. _handleResize();
  10114. $ax.postResize(e); //window resize fires after view changed
  10115. });
  10116. };
  10117. var _handleLoadViewId = function (loadViewId, forceSwitchTo) {
  10118. if(typeof loadViewId != 'undefined') {
  10119. _setAuto(false);
  10120. _switchView(loadViewId != 'default' ? loadViewId : '', forceSwitchTo);
  10121. } else {
  10122. _setAuto(true);
  10123. _handleResize(forceSwitchTo);
  10124. }
  10125. };
  10126. var _handleSetViewForSize = function (width, height) {
  10127. if(!_auto) return;
  10128. var toView = _getAdaptiveView(width, height);
  10129. var toViewId = toView && toView.id;
  10130. _switchView(toViewId);
  10131. };
  10132. $ax.adaptive.getSketchKey = function() {
  10133. return $ax.pageData.sketchKeys[$ax.adaptive.currentViewId || ''];
  10134. }
  10135. });
  10136. //***** tree.js *****//
  10137. // This is actually for BOTH trees and menus
  10138. $axure.internal(function($ax) {
  10139. var _tree = $ax.tree = {};
  10140. var _menu = $ax.menu = {};
  10141. $ax.menu.InitializeSubmenu = function(subMenuId, cellId) {
  10142. var $submenudiv = $('#' + subMenuId);
  10143. //mouseenter and leave for parent table cell
  10144. $('#' + cellId).mouseenter(function(e) {
  10145. //show current submenu
  10146. // var submenuElement = document.getElementById(subMenuId);
  10147. // if($ax.visibility.IsVisible(submenuElement) && submenuElement.style.display !== 'none') return;
  10148. $ax.visibility.SetIdVisible(subMenuId, true);
  10149. $ax.legacy.BringToFront(subMenuId);
  10150. _fireEventForSubmenu(subMenuId, "onShow");
  10151. }).mouseleave(function (e) {
  10152. var offset = $submenudiv.offset();
  10153. var subcontwidth = $submenudiv.width();
  10154. var subcontheight = $submenudiv.height();
  10155. //If mouse is not within the submenu (added 3 pixel margin to top and left calculations), then close the submenu...
  10156. if(e.pageX + 3 < offset.left || e.pageX > offset.left + subcontwidth || e.pageY + 3 < offset.top || e.pageY > offset.top + subcontheight) {
  10157. $submenudiv.find('.sub_menu').andSelf().each(function () {
  10158. // if(!$ax.visibility.IsVisible(this)) return;
  10159. $ax.visibility.SetVisible(this, false);
  10160. _fireEventForSubmenu(subMenuId, "onHide");
  10161. });
  10162. $ax.style.SetWidgetHover(cellId, false);
  10163. }
  10164. });
  10165. $submenudiv.css('display', 'none');
  10166. //mouseleave for submenu
  10167. $submenudiv.mouseleave(function(e) {
  10168. //close this menu and all menus below it
  10169. $(this).find('.sub_menu').andSelf().css({ 'visibility': 'hidden', 'display': 'none' }).each(function () {
  10170. // if(!$ax.visibility.IsVisible(this)) return;
  10171. _fireEventForSubmenu(this.id, "onHide");
  10172. });
  10173. $ax.style.SetWidgetHover(cellId, false);
  10174. });
  10175. };
  10176. var _fireEventForSubmenu = function(targetId, eventName) {
  10177. var diagramObject = $ax.getObjectFromElementId(targetId);
  10178. var event = diagramObject.interactionMap && diagramObject.interactionMap[eventName];
  10179. if(event) {
  10180. var eventInfo = $ax.getEventInfoFromEvent($ax.getjBrowserEvent(), false, targetId);
  10181. $ax.event.handleEvent(targetId, eventInfo, event, false, true);
  10182. }
  10183. }
  10184. function IsNodeVisible(nodeId) {
  10185. var current = window.document.getElementById(nodeId);
  10186. var parent = current.parentNode;
  10187. //move all the parent's children that are below the node and their annotations
  10188. while(!$(current).hasClass("treeroot")) {
  10189. if(!$ax.visibility.IsVisible(parent)) return false;
  10190. current = parent;
  10191. parent = parent.parentNode;
  10192. }
  10193. return true;
  10194. }
  10195. $ax.tree.ExpandNode = function(nodeId, childContainerId, plusMinusId) {
  10196. var container = window.document.getElementById(childContainerId);
  10197. if(!container || $ax.visibility.IsVisible(container)) return;
  10198. $ax.visibility.SetVisible(container, true);
  10199. if(plusMinusId != '') $ax.style.SetWidgetSelected(plusMinusId, true);
  10200. var delta = _getExpandCollapseDelta(nodeId, childContainerId);
  10201. var isVisible = IsNodeVisible(nodeId);
  10202. var current = window.document.getElementById(nodeId);
  10203. var parent = current.parentNode;
  10204. //move all the parent's children that are below the node and their annotations
  10205. while(!$(current).hasClass("treeroot")) {
  10206. var after = false;
  10207. var i = 0;
  10208. for(i = 0; i < parent.childNodes.length; i++) {
  10209. var child = parent.childNodes[i];
  10210. if(after && child.id && $(child).hasClass("treenode")) {
  10211. var elementId = child.id;
  10212. child.style.top = Number($(child).css('top').replace("px", "")) + delta + 'px';
  10213. var ann = window.document.getElementById(elementId + "_ann");
  10214. if(ann) ann.style.top = Number($(ann).css('top').replace("px", "")) + delta + 'px';
  10215. }
  10216. if(child == current) after = true;
  10217. }
  10218. current = parent;
  10219. parent = parent.parentNode;
  10220. if(!isVisible && $ax.visibility.IsVisible(parent)) break;
  10221. }
  10222. };
  10223. $ax.tree.CollapseNode = function(nodeId, childContainerId, plusMinusId) {
  10224. var container = window.document.getElementById(childContainerId);
  10225. if(!container || !$ax.visibility.IsVisible(container)) return;
  10226. if(plusMinusId != '') $ax.style.SetWidgetSelected(plusMinusId, false);
  10227. var delta = _getExpandCollapseDelta(nodeId, childContainerId);
  10228. //hide it after getting the delta, otherwise the delta can't be calculated (offsetParent is null)
  10229. $ax.visibility.SetVisible(container, false);
  10230. var isVisible = IsNodeVisible(nodeId);
  10231. var current = window.document.getElementById(nodeId);
  10232. var parent = current.parentNode;
  10233. //move all the parent's children that are below the node and their annotations
  10234. while(!$(current).hasClass("treeroot")) {
  10235. var after = false;
  10236. var i = 0;
  10237. for(i = 0; i < parent.childNodes.length; i++) {
  10238. var child = parent.childNodes[i];
  10239. if(after && child.id && $(child).hasClass("treenode")) {
  10240. var elementId = child.id;
  10241. child.style.top = Number($(child).css('top').replace("px", "")) - delta + 'px';
  10242. var ann = window.document.getElementById(elementId + "_ann");
  10243. if(ann) ann.style.top = Number($(ann).css('top').replace("px", "")) - delta + 'px';
  10244. }
  10245. if(child == current) after = true;
  10246. }
  10247. current = parent;
  10248. parent = current.parentNode;
  10249. if(!isVisible && $ax.visibility.IsVisible(parent)) break;
  10250. }
  10251. };
  10252. var _getExpandCollapseDelta = function(nodeId, childContainerId) {
  10253. return _getChildContainerHeightHelper(childContainerId);
  10254. };
  10255. var _getChildContainerHeightHelper = function(childContainerId) {
  10256. var height = 0;
  10257. $('#' + childContainerId).children().each(function() {
  10258. if($(this).hasClass("treenode")) {
  10259. height += $(this).height();
  10260. var subContainer = window.document.getElementById(this.id + '_children');
  10261. if(subContainer && $ax.visibility.IsVisible(subContainer)) {
  10262. height += _getChildContainerHeightHelper(subContainer.id);
  10263. }
  10264. }
  10265. });
  10266. return height;
  10267. };
  10268. $ax.tree.InitializeTreeNode = function(nodeId, plusminusid, childContainerId, selectText) {
  10269. var childContainer = window.document.getElementById(childContainerId);
  10270. if(childContainer) {
  10271. //relying on the html generator to put this inline so we know to collapse by default
  10272. var isCollapsed = childContainer.style.visibility == "hidden";
  10273. if(isCollapsed) $ax.visibility.SetVisible(childContainer, false);
  10274. if(!isCollapsed && plusminusid != '') $ax.style.SetWidgetSelected(plusminusid, true);
  10275. }
  10276. if(plusminusid != '') {
  10277. $jobj(plusminusid).click(function() {
  10278. var visibleSet = $ax.visibility.IsIdVisible(childContainerId);
  10279. if(visibleSet) $ax.tree.CollapseNode(nodeId, childContainerId, plusminusid);
  10280. else $ax.tree.ExpandNode(nodeId, childContainerId, plusminusid);
  10281. $ax.tree.SelectTreeNode(nodeId, true);
  10282. return false;
  10283. }).css('cursor', 'default');
  10284. }
  10285. };
  10286. var _getButtonShapeId = function(id) {
  10287. var obj = $obj(id);
  10288. return $ax.public.fn.IsTreeNodeObject(obj.type) ? $ax.getElementIdFromPath([obj.buttonShapeId], { relativeTo: id }) : id;
  10289. };
  10290. $ax.tree.SelectTreeNode = function(id, selected) {
  10291. $ax.style.SetWidgetSelected(_getButtonShapeId(id), selected);
  10292. };
  10293. });
  10294. //***** init.temp.js *****//
  10295. $axure.internal(function($ax) {
  10296. $(window.document).ready(function() {
  10297. var readyStart = (new Date()).getTime();
  10298. //this is because the page id is not formatted as a guid
  10299. var pageId = $ax.pageData.page.packageId;
  10300. var pageData = {
  10301. id: pageId,
  10302. pageName: $ax.pageData.page.name,
  10303. location: window.location.toString(),
  10304. notes: $ax.pageData.page.notes
  10305. };
  10306. var anns = [];
  10307. $ax('*').each(function (dObj, elementId) {
  10308. pushAnnotation(dObj, elementId);
  10309. });
  10310. function pushAnnotation(dObj, elementId) {
  10311. var ann = dObj.annotation;
  10312. if(ann) {
  10313. ann["id"] = elementId;
  10314. ann["label"] = dObj.label + " (" + dObj.friendlyType + ")";
  10315. anns.push(ann);
  10316. }
  10317. if(dObj.type == 'repeater') {
  10318. if(dObj.objects) {
  10319. for(var i = 0, len = dObj.objects.length; i < len; i++) {
  10320. pushAnnotation(dObj.objects[i]);
  10321. }
  10322. }
  10323. }
  10324. }
  10325. pageData.widgetNotes = anns;
  10326. //only trigger the page.data setting if the window is on the mainframe
  10327. var isMainFrame = false;
  10328. try {
  10329. if(window.name == 'mainFrame' ||
  10330. (!CHROME_5_LOCAL && window.parent.$ && window.parent.$('#mainFrame').length > 0)) {
  10331. isMainFrame = true;
  10332. $ax.messageCenter.addMessageListener(function(message, data) {
  10333. if(message == 'finishInit') {
  10334. _processTempInit();
  10335. }
  10336. });
  10337. $axure.messageCenter.setState('page.data', pageData);
  10338. window.focus();
  10339. }
  10340. } catch(e) { }
  10341. //attach here for chrome local
  10342. $(window).load(function() {
  10343. $ax.style.initializeObjectTextAlignment($ax('*'));
  10344. });
  10345. if(!isMainFrame) _processTempInit();
  10346. });
  10347. var _processTempInit = function() {
  10348. //var start = (new Date()).getTime();
  10349. //var end = (new Date()).getTime();
  10350. //window.alert('elapsed ' + (end - start));
  10351. $('iframe').each(function() {
  10352. var origSrc = $(this).attr('basesrc');
  10353. var $this = $(this);
  10354. if(origSrc) {
  10355. var newSrcUrl = origSrc.toLowerCase().indexOf('http://') == -1 ? $ax.globalVariableProvider.getLinkUrl(origSrc) : origSrc;
  10356. $this.attr('src', newSrcUrl);
  10357. }
  10358. if(IOS) {
  10359. $this.parent().css('overflow', 'auto').css('-webkit-overflow-scrolling', 'touch').css('-ms-overflow-x', 'hidden').css('overflow-x', 'hidden');
  10360. }
  10361. });
  10362. $axure.messageCenter.addMessageListener(function(message, data) {
  10363. if(message == 'setGlobalVar') {
  10364. $ax.globalVariableProvider.setVariableValue(data.globalVarName, data.globalVarValue, true);
  10365. }
  10366. });
  10367. window.lastFocusedClickable = null;
  10368. var _lastFocusedClickableSelector = 'input, a';
  10369. var shouldOutline = true;
  10370. $ax(function (dObj) { return dObj.tabbable; }).each(function (dObj, elementId) {
  10371. if ($ax.public.fn.IsLayer(dObj.type)) $ax.event.layerMapFocus(dObj, elementId);
  10372. var focusableId = $ax.event.getFocusableWidgetOrChildId(elementId);
  10373. var $focusable = $('#' + focusableId);
  10374. $focusable.attr("tabIndex", 0);
  10375. if($focusable.is('div') || $focusable.is('img')) {
  10376. $focusable.bind($ax.features.eventNames.mouseDownName, function() {
  10377. shouldOutline = false;
  10378. });
  10379. attachFocusAndBlur($focusable);
  10380. }
  10381. });
  10382. $(window.document).bind($ax.features.eventNames.mouseUpName, function() {
  10383. shouldOutline = true;
  10384. });
  10385. attachFocusAndBlur($(_lastFocusedClickableSelector));
  10386. function attachFocusAndBlur($query) {
  10387. $query.focus(function () {
  10388. if(shouldOutline) {
  10389. $(this).css('outline', '');
  10390. } else {
  10391. $(this).css('outline', 'none');
  10392. }
  10393. window.lastFocusedClickable = this;
  10394. }).blur(function () {
  10395. if(window.lastFocusedClickable == this) window.lastFocusedClickable = null;
  10396. });
  10397. }
  10398. $(window.document).bind('keyup', function(e) {
  10399. if(e.keyCode == '13' || e.keyCode == '32') {
  10400. if(window.lastFocusedClickable) $(window.lastFocusedClickable).click();
  10401. }
  10402. });
  10403. if($ax.document.configuration.hideAddress) {
  10404. $(window).load(function() {
  10405. window.setTimeout(function() {
  10406. window.scrollTo(0, 0.9);
  10407. }, 0);
  10408. });
  10409. }
  10410. if($ax.document.configuration.preventScroll) {
  10411. $(window.document).bind('touchmove', function(e) {
  10412. var inScrollable = $ax.legacy.GetScrollable(e.target) != window.document.body;
  10413. if(!inScrollable) {
  10414. e.preventDefault();
  10415. }
  10416. });
  10417. $ax(function(diagramObject) {
  10418. return $ax.public.fn.IsDynamicPanel(diagramObject.type) && diagramObject.scrollbars != 'none';
  10419. }).$().children().bind('touchstart', function() {
  10420. var target = this;
  10421. var top = target.scrollTop;
  10422. if(top <= 0) target.scrollTop = 1;
  10423. if(top + target.offsetHeight >= target.scrollHeight) target.scrollTop = target.scrollHeight - target.offsetHeight - 1;
  10424. });
  10425. }
  10426. if(OS_MAC && WEBKIT) {
  10427. $ax(function(diagramObject) {
  10428. return $ax.public.fn.IsComboBox(diagramObject.type);
  10429. }).each(function(obj, id) {
  10430. $jobj($ax.INPUT(id)).css('-webkit-appearance', 'menulist-button');
  10431. });
  10432. }
  10433. $ax.legacy.BringFixedToFront();
  10434. $ax.event.initialize();
  10435. $ax.style.initialize();
  10436. $ax.visibility.initialize();
  10437. $ax.repeater.initialize();
  10438. $ax.dynamicPanelManager.initialize(); //needs to be called after visibility is initialized
  10439. $ax.adaptive.initialize();
  10440. $ax.loadDynamicPanelsAndMasters();
  10441. $ax.adaptive.loadFinished();
  10442. var start = (new Date()).getTime();
  10443. $ax.repeater.initRefresh();
  10444. var end = (new Date()).getTime();
  10445. console.log('loadTime: ' + (end - start) / 1000);
  10446. $ax.style.prefetch();
  10447. $(window).resize();
  10448. //var readyEnd = (new Date()).getTime();
  10449. //window.alert('elapsed ' + (readyEnd - readyStart));
  10450. };
  10451. });
  10452. /* extend canvas */
  10453. var gv_hasCanvas = false;
  10454. (function() {
  10455. var _canvas = document.createElement('canvas'), proto, abbrev;
  10456. if(gv_hasCanvas = !!(_canvas.getContext && _canvas.getContext('2d')) && typeof (CanvasGradient) !== 'undefined') {
  10457. function chain(func) {
  10458. return function() {
  10459. return func.apply(this, arguments) || this;
  10460. };
  10461. }
  10462. with(proto = CanvasRenderingContext2D.prototype) for(var func in abbrev = {
  10463. a: arc,
  10464. b: beginPath,
  10465. n: clearRect,
  10466. c: clip,
  10467. p: closePath,
  10468. g: createLinearGradient,
  10469. f: fill,
  10470. j: fillRect,
  10471. z: function(s) { this.fillStyle = s; },
  10472. l: lineTo,
  10473. w: function(w) { this.lineWidth = w; },
  10474. m: moveTo,
  10475. q: quadraticCurveTo,
  10476. h: rect,
  10477. r: restore,
  10478. o: rotate,
  10479. s: save,
  10480. x: scale,
  10481. y: function(s) { this.strokeStyle = s; },
  10482. u: setTransform,
  10483. k: stroke,
  10484. i: strokeRect,
  10485. t: translate
  10486. }) proto[func] = chain(abbrev[func]);
  10487. CanvasGradient.prototype.a = chain(CanvasGradient.prototype.addColorStop);
  10488. }
  10489. })();
  10490. //***** legacy.js *****//
  10491. //stored on each browser event
  10492. var windowEvent;
  10493. $axure.internal(function($ax) {
  10494. var _legacy = {};
  10495. $ax.legacy = _legacy;
  10496. // ************************** GLOBAL VARS *********************************//
  10497. // ************************************************************************//
  10498. //Check if IE
  10499. //var bIE = false;
  10500. //if ((index = navigator.userAgent.indexOf("MSIE")) >= 0) {
  10501. // bIE = true;
  10502. //}
  10503. var Forms = window.document.getElementsByTagName("FORM");
  10504. for(var i = 0; i < Forms.length; i++) {
  10505. var Form = Forms[i];
  10506. Form.onclick = $ax.legacy.SuppressBubble;
  10507. }
  10508. $ax.legacy.SuppressBubble = function(event) {
  10509. if(IE_10_AND_BELOW) {
  10510. window.event.cancelBubble = true;
  10511. window.event.returnValue = false;
  10512. } else {
  10513. if(event) {
  10514. event.stopPropagation();
  10515. }
  10516. }
  10517. };
  10518. // function InsertAfterBegin(dom, html) {
  10519. // if(!IE) {
  10520. // var phtml;
  10521. // var range = dom.ownerDocument.createRange();
  10522. // range.selectNodeContents(dom);
  10523. // range.collapse(true);
  10524. // phtml = range.createContextualFragment(html);
  10525. // dom.insertBefore(phtml, dom.firstChild);
  10526. // } else {
  10527. // dom.insertAdjacentHTML("afterBegin", html);
  10528. // }
  10529. // }
  10530. // function InsertBeforeEnd(dom, html) {
  10531. // if(!IE) {
  10532. // var phtml;
  10533. // var range = dom.ownerDocument.createRange();
  10534. // range.selectNodeContents(dom);
  10535. // range.collapse(dom);
  10536. // phtml = range.createContextualFragment(html);
  10537. // dom.appendChild(phtml);
  10538. // } else {
  10539. // dom.insertAdjacentHTML("beforeEnd", html);
  10540. // }
  10541. // }
  10542. //Get the id of the Workflow Dialog belonging to element with id = id
  10543. // function Workflow(id) {
  10544. // return id + 'WF';
  10545. // }
  10546. $ax.legacy.BringToFront = function(id, skipFixed) {
  10547. _bringToFrontHelper(id);
  10548. if(!skipFixed) $ax.legacy.BringFixedToFront();
  10549. };
  10550. var _bringToFrontHelper = function(id) {
  10551. var target = window.document.getElementById(id);
  10552. if(target == null) return;
  10553. $ax.globals.MaxZIndex = $ax.globals.MaxZIndex + 1;
  10554. target.style.zIndex = $ax.globals.MaxZIndex;
  10555. };
  10556. $ax.legacy.BringFixedToFront = function() {
  10557. $ax(function(diagramObject) { return diagramObject.fixedKeepInFront; }).each(function(diagramObject, scriptId) {
  10558. _bringToFrontHelper(scriptId);
  10559. });
  10560. };
  10561. $ax.legacy.SendToBack = function(id) {
  10562. var target = window.document.getElementById(id);
  10563. if(target == null) return;
  10564. target.style.zIndex = $ax.globals.MinZIndex = $ax.globals.MinZIndex - 1;
  10565. };
  10566. $ax.legacy.RefreshScreen = function() {
  10567. var oldColor = window.document.body.style.backgroundColor;
  10568. var setColor = (oldColor == "rgb(0,0,0)") ? "#FFFFFF" : "#000000";
  10569. window.document.body.style.backgroundColor = setColor;
  10570. window.document.body.style.backgroundColor = oldColor;
  10571. };
  10572. $ax.legacy.getAbsoluteLeft = function(currentNode, elementId) {
  10573. var oldDisplay = currentNode.css('display');
  10574. var displaySet = false;
  10575. if(oldDisplay == 'none') {
  10576. currentNode.css('display', '');
  10577. displaySet = true;
  10578. }
  10579. var left = currentNode.offset().left;
  10580. // Special Layer code
  10581. if($ax.getTypeFromElementId(elementId) == 'layer') {
  10582. var first = true;
  10583. var children = currentNode.children();
  10584. for(var i = 0; i < children.length; i++) {
  10585. var child = $(children[i]);
  10586. var subDisplaySet = false;
  10587. if(child.css('display') == 'none') {
  10588. child.css('display', '');
  10589. subDisplaySet = true;
  10590. }
  10591. if(first) left = child.offset().left;
  10592. else left = Math.min(child.offset().left, left);
  10593. first = false;
  10594. if(subDisplaySet) child.css('display', 'none');
  10595. }
  10596. }
  10597. if (displaySet) currentNode.css('display', oldDisplay);
  10598. return $axure.fn.bodyToWorld(left, true);
  10599. };
  10600. $ax.legacy.getAbsoluteTop = function(currentNode, elementId) {
  10601. var oldDisplay = currentNode.css('display');
  10602. var displaySet = false;
  10603. if(oldDisplay == 'none') {
  10604. currentNode.css('display', '');
  10605. displaySet = true;
  10606. }
  10607. var top = currentNode.offset().top;
  10608. // Special Layer code
  10609. if ($ax.getTypeFromElementId(elementId) == 'layer') {
  10610. var first = true;
  10611. var children = currentNode.children();
  10612. for (var i = 0; i < children.length; i++) {
  10613. var child = $(children[i]);
  10614. var subDisplaySet = false;
  10615. if (child.css('display') == 'none') {
  10616. child.css('display', '');
  10617. subDisplaySet = true;
  10618. }
  10619. if (first) top = child.offset().top;
  10620. else top = Math.min(child.offset().top, top);
  10621. first = false;
  10622. if (subDisplaySet) child.css('display', 'none');
  10623. }
  10624. }
  10625. if(displaySet) currentNode.css('display', oldDisplay);
  10626. return top;
  10627. };
  10628. // ****************** Annotation and Link Functions ****************** //
  10629. $ax.legacy.GetAnnotationHtml = function(annJson) {
  10630. var retVal = "";
  10631. for(var noteName in annJson) {
  10632. if(noteName != "label" && noteName != "id") {
  10633. retVal += "<div class='annotationName'>" + noteName + "</div>";
  10634. retVal += "<div class='annotationValue'>" + linkify(annJson[noteName]) + "</div>";
  10635. }
  10636. }
  10637. return retVal;
  10638. function linkify(text) {
  10639. var urlRegex = /(\b(((https?|ftp|file):\/\/)|(www\.))[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;
  10640. return text.replace(urlRegex, function (url, b, c) {
  10641. var url2 = (c == 'www.') ? 'http://' + url : url;
  10642. return '<a href="' + url2 + '" target="_blank" class="noteLink">' + url + '</a>';
  10643. });
  10644. }
  10645. };
  10646. $ax.legacy.GetScrollable = function(target) {
  10647. var $target = $(target);
  10648. var last = $target;
  10649. // Start past inital target. Can't scroll to target in itself, must be some ancestor.
  10650. var current = last.parent();
  10651. while(!current.is('body') && !current.is('html')) {
  10652. var elementId = current.attr('id');
  10653. var diagramObject = elementId && $ax.getObjectFromElementId(elementId);
  10654. if(diagramObject && $ax.public.fn.IsDynamicPanel(diagramObject.type) && diagramObject.scrollbars != 'none') {
  10655. //returns the panel diagram div which handles scrolling
  10656. return $ax.dynamicPanelManager.getShownState(current.attr('id'))[0];
  10657. }
  10658. last = current;
  10659. current = current.parent();
  10660. }
  10661. // Need to do this because of ie
  10662. if(IE_10_AND_BELOW) return window.document.documentElement;
  10663. else return window.document.body;
  10664. };
  10665. });
  10666. //***** viewer.js *****//
  10667. // ******* SITEMAP TOOLBAR VIEWER ACTIONS ******** //
  10668. $axure.internal(function ($ax) {
  10669. var userTriggeredEventNames = ['onClick', 'onDoubleClick', 'onMouseOver', 'onMouseMove', 'onMouseOut', 'onMouseDown', 'onMouseUp',
  10670. 'onKeyDown', 'onKeyUp', 'onFocus', 'onLostFocus', 'onTextChange', 'onSelectionChange', 'onSelectedChange', 'onSelect', 'onUnselect',
  10671. 'onSwipeLeft', 'onSwipeRight', 'onSwipeUp', 'onSwipeDown', 'onDragStart', 'onDrag', 'onDragDrop', 'onScroll', 'onContextMenu', 'onMouseHover', 'onLongClick'];
  10672. $ax.messageCenter.addMessageListener(function(message, data) {
  10673. //If annotation toggle message received from sitemap, toggle footnotes
  10674. if(message == 'annotationToggle') {
  10675. if(data == true) {
  10676. $('div.annotation').show();
  10677. $('div.annnotelabel').show();
  10678. $('div.annnoteimage').show();
  10679. } else {
  10680. $('div.annotation').hide();
  10681. $('div.annnotelabel').hide();
  10682. $('div.annnoteimage').hide();
  10683. }
  10684. }
  10685. });
  10686. var lastSelectedWidgetNote;
  10687. $ax.messageCenter.addMessageListener(function (message, data) {
  10688. //If annotation toggle message received from sitemap, toggle footnotes
  10689. if(message == 'toggleSelectWidgetNote') {
  10690. if(lastSelectedWidgetNote == data) {
  10691. $('#' + lastSelectedWidgetNote).removeClass('widgetNoteSelected');
  10692. lastSelectedWidgetNote = null;
  10693. return;
  10694. }
  10695. if(lastSelectedWidgetNote) $('#' + lastSelectedWidgetNote).removeClass('widgetNoteSelected');
  10696. $('#' + data).addClass('widgetNoteSelected');
  10697. lastSelectedWidgetNote = data;
  10698. }
  10699. });
  10700. var highlightEnabled = false;
  10701. $ax.messageCenter.addMessageListener(function(message, data) {
  10702. if(message == 'highlightInteractive') {
  10703. highlightEnabled = data == true;
  10704. _applyHighlight($ax('*'));
  10705. }
  10706. });
  10707. var _applyHighlight = $ax.applyHighlight = function(query, ignoreUnset) {
  10708. if(ignoreUnset && !highlightEnabled) return;
  10709. var pulsateClassName = 'legacyPulsateBorder';
  10710. //Find all widgets with a defined userTriggeredEventName specified in the array above
  10711. var $matchingElements = query.filter(function(obj) {
  10712. if(obj.interactionMap) {
  10713. for(var index in userTriggeredEventNames) {
  10714. if(obj.interactionMap[userTriggeredEventNames[index]]) return true;
  10715. }
  10716. } else if ($ax.public.fn.IsVector(obj.type) && obj.referencePageUrl) {
  10717. return true;
  10718. }
  10719. return false;
  10720. }).$();
  10721. var isHighlighted = $matchingElements.is('.' + pulsateClassName);
  10722. //Toggle the pulsate class on the matched elements
  10723. if(highlightEnabled && !isHighlighted) {
  10724. $matchingElements.addClass(pulsateClassName);
  10725. } else if(!highlightEnabled && isHighlighted) {
  10726. $matchingElements.removeClass(pulsateClassName);
  10727. }
  10728. };
  10729. });
  10730. //***** math.js *****//
  10731. $axure.internal(function($ax) {
  10732. $ax.public.fn.matrixMultiply = function(matrix, vector) {
  10733. if(!matrix.tx) matrix.tx = 0;
  10734. if(!matrix.ty) matrix.ty = 0;
  10735. var outX = matrix.m11 * vector.x + matrix.m12 * vector.y + matrix.tx;
  10736. var outY = matrix.m21 * vector.x + matrix.m22 * vector.y + matrix.ty;
  10737. return { x: outX, y: outY };
  10738. }
  10739. $ax.public.fn.matrixInverse = function(matrix) {
  10740. if(!matrix.tx) matrix.tx = 0;
  10741. if(!matrix.ty) matrix.ty = 0;
  10742. var determinant = matrix.m11*matrix.m22 - matrix.m12*matrix.m21;
  10743. //var threshold = (M11 * M11 + M22 *M22 + M12 *M12+ M21 *M21) / 100000;
  10744. //if(determinant.DeltaEquals(0, threshold) && determinant < 0.01) {
  10745. // return Invalid;
  10746. //}
  10747. return {
  10748. m11 : matrix.m22/determinant,
  10749. m12 : -matrix.m12/determinant,
  10750. tx : (matrix.ty*matrix.m12 - matrix.tx*matrix.m22)/determinant,
  10751. m21: -matrix.m21 / determinant,
  10752. m22: matrix.m11 / determinant,
  10753. ty: (matrix.tx * matrix.m21 - matrix.ty * matrix.m11) / determinant
  10754. };
  10755. }
  10756. $ax.public.fn.matrixMultiplyMatrix = function (matrix1, matrix2) {
  10757. if (!matrix1.tx) matrix1.tx = 0;
  10758. if (!matrix1.ty) matrix1.ty = 0;
  10759. if (!matrix2.tx) matrix2.tx = 0;
  10760. if (!matrix2.ty) matrix2.ty = 0;
  10761. return {
  10762. m11: matrix1.m12*matrix2.m21 + matrix1.m11*matrix2.m11,
  10763. m12: matrix1.m12*matrix2.m22 + matrix1.m11*matrix2.m12,
  10764. tx: matrix1.m12 * matrix2.ty + matrix1.m11 * matrix2.tx + matrix1.tx,
  10765. m21: matrix1.m22 * matrix2.m21 + matrix1.m21 * matrix2.m11,
  10766. m22: matrix1.m22 * matrix2.m22 + matrix1.m21 * matrix2.m12,
  10767. ty: matrix1.m22 * matrix2.ty + matrix1.m21 * matrix2.tx + matrix1.ty,
  10768. };
  10769. }
  10770. $ax.public.fn.transformFromElement = function (element) {
  10771. var st = window.getComputedStyle(element, null);
  10772. var tr = st.getPropertyValue("-webkit-transform") ||
  10773. st.getPropertyValue("-moz-transform") ||
  10774. st.getPropertyValue("-ms-transform") ||
  10775. st.getPropertyValue("-o-transform") ||
  10776. st.getPropertyValue("transform");
  10777. if (tr.indexOf('none') < 0) {
  10778. var matrix = tr.split('(')[1];
  10779. matrix = matrix.split(')')[0];
  10780. matrix = matrix.split(',');
  10781. for (var l = 0; l < matrix.length; l++) {
  10782. matrix[l] = Number(matrix[l]);
  10783. }
  10784. } else { matrix = [1.0, 0.0, 0.0, 1.0, 0.0, 0.0]; }
  10785. return matrix;
  10786. // matrix[0] = cosine, matrix[1] = sine.
  10787. // Assuming the element is still orthogonal.
  10788. }
  10789. $ax.public.fn.vectorMinus = function(vector1, vector2) { return { x: vector1.x - vector2.x, y: vector1.y - vector2.y }; }
  10790. $ax.public.fn.vectorPlus = function (vector1, vector2) { return { x: vector1.x + vector2.x, y: vector1.y + vector2.y }; }
  10791. $ax.public.fn.vectorMidpoint = function (vector1, vector2) { return { x: (vector1.x + vector2.x) / 2.0, y: (vector1.y + vector2.y) / 2.0 }; }
  10792. $ax.public.fn.fourCornersToBasis = function (fourCorners) {
  10793. return {
  10794. widthVector: $ax.public.fn.vectorMinus(fourCorners.widgetTopRight, fourCorners.widgetTopLeft),
  10795. heightVector: $ax.public.fn.vectorMinus(fourCorners.widgetBottomLeft, fourCorners.widgetTopLeft)
  10796. };
  10797. }
  10798. $ax.public.fn.matrixString = function(m11, m21, m12, m22, tx, ty) {
  10799. return "Matrix(" + m11 + "," + m21 + "," + m12 + "," + m22 + ", " + tx + ", " + ty + ")";
  10800. }
  10801. $ax.public.fn.getWidgetBoundingRect = function (widgetId) {
  10802. var emptyRect = { left: 0, top: 0, centerPoint: { x: 0, y: 0 }, width: 0, height: 0 };
  10803. var element = document.getElementById(widgetId);
  10804. if (!element) return emptyRect;
  10805. var object = $obj(widgetId);
  10806. if (object && object.type && $ax.public.fn.IsLayer(object.type)) {
  10807. var layerChildren = _getLayerChildrenDeep(widgetId);
  10808. if (!layerChildren) return emptyRect;
  10809. else return _getBoundingRectForMultipleWidgets(layerChildren);
  10810. }
  10811. return _getBoundingRectForSingleWidget(widgetId);
  10812. };
  10813. var _getLayerChildrenDeep = $ax.public.fn.getLayerChildrenDeep = function (layerId, includeLayers, includeHidden) {
  10814. var deep = [];
  10815. var children = $ax('#' + layerId).getChildren()[0].children;
  10816. for (var index = 0; index < children.length; index++) {
  10817. var childId = children[index];
  10818. if(!includeHidden && !$ax.visibility.IsIdVisible(childId)) continue;
  10819. if ($ax.public.fn.IsLayer($obj(childId).type)) {
  10820. if (includeLayers) deep.push(childId);
  10821. var recursiveChildren = _getLayerChildrenDeep(childId, includeLayers, includeHidden);
  10822. for (var j = 0; j < recursiveChildren.length; j++) deep.push(recursiveChildren[j]);
  10823. } else deep.push(childId);
  10824. }
  10825. return deep;
  10826. };
  10827. var _getBoundingRectForMultipleWidgets = function (widgetsIdArray, relativeToPage) {
  10828. if (!widgetsIdArray || widgetsIdArray.constructor !== Array) return undefined;
  10829. if (widgetsIdArray.length == 0) return { left: 0, top: 0, centerPoint: { x: 0, y: 0 }, width: 0, height: 0 };
  10830. var widgetRect = _getBoundingRectForSingleWidget(widgetsIdArray[0], relativeToPage, true);
  10831. var boundingRect = { left: widgetRect.left, right: widgetRect.right, top: widgetRect.top, bottom: widgetRect.bottom };
  10832. for (var index = 1; index < widgetsIdArray.length; index++) {
  10833. widgetRect = _getBoundingRectForSingleWidget(widgetsIdArray[index], relativeToPage);
  10834. boundingRect.left = Math.min(boundingRect.left, widgetRect.left);
  10835. boundingRect.top = Math.min(boundingRect.top, widgetRect.top);
  10836. boundingRect.right = Math.max(boundingRect.right, widgetRect.right);
  10837. boundingRect.bottom = Math.max(boundingRect.bottom, widgetRect.bottom);
  10838. }
  10839. boundingRect.centerPoint = { x: (boundingRect.right + boundingRect.left) / 2.0, y: (boundingRect.bottom + boundingRect.top) / 2.0 };
  10840. boundingRect.width = boundingRect.right - boundingRect.left;
  10841. boundingRect.height = boundingRect.bottom - boundingRect.top;
  10842. return boundingRect;
  10843. };
  10844. var _getBoundingRectForSingleWidget = function (widgetId, relativeToPage, justSides) {
  10845. var element = document.getElementById(widgetId);
  10846. var boundingRect, tempBoundingRect, position;
  10847. var displayChanged = _displayHackStart(element);
  10848. if (_isCompoundVectorHtml(element)) {
  10849. //tempBoundingRect = _getCompoundImageBoundingClientSize(widgetId);
  10850. //position = { left: tempBoundingRect.left, top: tempBoundingRect.top };
  10851. position = $(element).position();
  10852. tempBoundingRect = {};
  10853. tempBoundingRect.left = position.left; //= _getCompoundImageBoundingClientSize(widgetId);
  10854. tempBoundingRect.top = position.top;
  10855. tempBoundingRect.width = Number(element.getAttribute('WidgetWidth'));
  10856. tempBoundingRect.height = Number(element.getAttribute('WidgetHeight'));
  10857. } else {
  10858. tempBoundingRect = element.getBoundingClientRect();
  10859. var jElement = $(element);
  10860. position = jElement.position();
  10861. if(jElement.css('position') == 'fixed') {
  10862. position.left += Number(jElement.css('margin-left').replace("px", ""));
  10863. position.top += Number(jElement.css('margin-top').replace("px", ""));
  10864. }
  10865. }
  10866. var layers = $ax('#' + widgetId).getParents(true, ['layer'])[0];
  10867. var flip = '';
  10868. var mirrorWidth = 0;
  10869. var mirrorHeight = 0;
  10870. for (var i = 0; i < layers.length; i++) {
  10871. //should always be 0,0
  10872. var layerPos = $jobj(layers[i]).position();
  10873. position.left += layerPos.left;
  10874. position.top += layerPos.top;
  10875. var outer = $ax.visibility.applyWidgetContainer(layers[i], true, true);
  10876. if (outer.length) {
  10877. var outerPos = outer.position();
  10878. position.left += outerPos.left;
  10879. position.top += outerPos.top;
  10880. }
  10881. //when a group is flipped we find the unflipped position
  10882. var inner = $jobj(layers[i] + '_container_inner');
  10883. var taggedFlip = inner.data('flip');
  10884. if (inner.length && taggedFlip) {
  10885. //only account for flip if transform is applied
  10886. var matrix = taggedFlip && (inner.css("-webkit-transform") || inner.css("-moz-transform") ||
  10887. inner.css("-ms-transform") || inner.css("-o-transform") || inner.css("transform"));
  10888. if (matrix !== 'none') {
  10889. flip = taggedFlip;
  10890. mirrorWidth = $ax.getNumFromPx(inner.css('width'));
  10891. mirrorHeight = $ax.getNumFromPx(inner.css('height'));
  10892. }
  10893. }
  10894. }
  10895. //Now account for flip
  10896. if (flip == 'x') position.top = mirrorHeight - position.top - element.getBoundingClientRect().height;
  10897. else if (flip == 'y') position.left = mirrorWidth - position.left - element.getBoundingClientRect().width;
  10898. boundingRect = {
  10899. left: position.left,
  10900. right: position.left + tempBoundingRect.width,
  10901. top: position.top,
  10902. bottom: position.top + tempBoundingRect.height
  10903. };
  10904. _displayHackEnd(displayChanged);
  10905. if (justSides) return boundingRect;
  10906. boundingRect.width = boundingRect.right - boundingRect.left;
  10907. boundingRect.height = boundingRect.bottom - boundingRect.top;
  10908. boundingRect.centerPoint = {
  10909. x: boundingRect.width / 2 + boundingRect.left,
  10910. y: boundingRect.height / 2 + boundingRect.top
  10911. };
  10912. return boundingRect;
  10913. };
  10914. var _getPointAfterRotate = $ax.public.fn.getPointAfterRotate = function (angleInDegrees, pointToRotate, centerPoint) {
  10915. var displacement = $ax.public.fn.vectorMinus(pointToRotate, centerPoint);
  10916. var rotationMatrix = $ax.public.fn.rotationMatrix(angleInDegrees);
  10917. rotationMatrix.tx = centerPoint.x;
  10918. rotationMatrix.ty = centerPoint.y;
  10919. return $ax.public.fn.matrixMultiply(rotationMatrix, displacement);
  10920. };
  10921. $ax.public.fn.getBoundingSizeForRotate = function(width, height, rotation) {
  10922. // point to rotate around doesn't matter since we just care about size, if location matter we need more args and location matters.
  10923. var origin = { x: 0, y: 0 };
  10924. var corner1 = { x: width, y: 0 };
  10925. var corner2 = { x: 0, y: height };
  10926. var corner3 = { x: width, y: height };
  10927. corner1 = _getPointAfterRotate(rotation, corner1, origin);
  10928. corner2 = _getPointAfterRotate(rotation, corner2, origin);
  10929. corner3 = _getPointAfterRotate(rotation, corner3, origin);
  10930. var left = Math.min(0, corner1.x, corner2.x, corner3.x);
  10931. var right = Math.max(0, corner1.x, corner2.x, corner3.x);
  10932. var top = Math.min(0, corner1.y, corner2.y, corner3.y);
  10933. var bottom = Math.max(0, corner1.y, corner2.y, corner3.y);
  10934. return { width: right - left, height: bottom - top };
  10935. }
  10936. $ax.public.fn.getPositionRelativeToParent = function (elementId) {
  10937. var element = document.getElementById(elementId);
  10938. var list = _displayHackStart(element);
  10939. var position = $(element).position();
  10940. _displayHackEnd(list);
  10941. return position;
  10942. };
  10943. var _displayHackStart = $ax.public.fn.displayHackStart = function (element) {
  10944. // TODO: Options: 1) stop setting display none. Big change for this late in the game. 2) Implement our own bounding.
  10945. // 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.
  10946. var parent = element;
  10947. var displays = [];
  10948. while (parent) {
  10949. if (parent.style.display == 'none') {
  10950. displays.push(parent);
  10951. //use block to overwrites default hidden objects' display
  10952. parent.style.display = 'block';
  10953. }
  10954. parent = parent.parentElement;
  10955. }
  10956. return displays;
  10957. };
  10958. var _displayHackEnd = $ax.public.fn.displayHackEnd = function (displayChangedList) {
  10959. for (var i = 0; i < displayChangedList.length; i++) displayChangedList[i].style.display = 'none';
  10960. };
  10961. var _isCompoundVectorHtml = $ax.public.fn.isCompoundVectorHtml = function(hElement) {
  10962. return hElement.hasAttribute('compoundmode') && hElement.getAttribute('compoundmode') == "true";
  10963. }
  10964. $ax.public.fn.removeCompound = function (jobj) { if(_isCompoundVectorHtml(jobj[0])) jobj.removeClass('compound'); }
  10965. $ax.public.fn.restoreCompound = function (jobj) { if (_isCompoundVectorHtml(jobj[0])) jobj.addClass('compound'); }
  10966. $ax.public.fn.compoundIdFromComponent = function(id) {
  10967. var pPos = id.indexOf('p');
  10968. var dashPos = id.indexOf('-');
  10969. if (pPos < 1) return id;
  10970. else if (dashPos < 0) return id.substring(0, pPos);
  10971. else return id.substring(0, pPos) + id.substring(dashPos);
  10972. }
  10973. $ax.public.fn.l2 = function (x, y) { return Math.sqrt(x * x + y * y); }
  10974. $ax.public.fn.convertToSingleImage = function (jobj) {
  10975. if(!jobj[0]) return;
  10976. var widgetId = jobj[0].id;
  10977. var object = $obj(widgetId);
  10978. if ($ax.public.fn.IsLayer(object.type)) {
  10979. var recursiveChildren = _getLayerChildrenDeep(widgetId, true);
  10980. for (var j = 0; j < recursiveChildren.length; j++)
  10981. $ax.public.fn.convertToSingleImage($jobj(recursiveChildren[j]));
  10982. return;
  10983. }
  10984. //var layer =
  10985. if(!_isCompoundVectorHtml(jobj[0])) return;
  10986. $('#' + widgetId).removeClass("compound");
  10987. $('#' + widgetId + '_img').removeClass("singleImg");
  10988. jobj[0].setAttribute('compoundmode', 'false');
  10989. var components = object.compoundChildren;
  10990. delete object.generateCompound;
  10991. for (var i = 0; i < components.length; i++) {
  10992. var componentJobj = $jobj($ax.public.fn.getComponentId(widgetId, components[i]));
  10993. componentJobj.css('display', 'none');
  10994. componentJobj.css('visibility', 'hidden');
  10995. }
  10996. }
  10997. $ax.public.fn.getContainerDimensions = function(query) {
  10998. // returns undefined if no containers found.
  10999. var containerDimensions;
  11000. for (var i = 0; i < query[0].children.length; i++) {
  11001. var node = query[0].children[i];
  11002. if (node.id.indexOf(query[0].id) >= 0 && node.id.indexOf('container') >= 0) {
  11003. containerDimensions = node.style;
  11004. }
  11005. }
  11006. return containerDimensions;
  11007. }
  11008. $ax.public.fn.rotationMatrix = function (angleInDegrees) {
  11009. var angleInRadians = angleInDegrees * (Math.PI / 180);
  11010. var cosTheta = Math.cos(angleInRadians);
  11011. var sinTheta = Math.sin(angleInRadians);
  11012. return { m11: cosTheta, m12: -sinTheta, m21: sinTheta, m22: cosTheta, tx: 0.0, ty: 0.0 };
  11013. }
  11014. $ax.public.fn.GetFieldFromStyle = function (query, field) {
  11015. var raw = query[0].style[field];
  11016. if (!raw) raw = query.css(field);
  11017. return Number(raw.replace('px', ''));
  11018. }
  11019. $ax.public.fn.setTransformHowever = function (transformString) {
  11020. return {
  11021. '-webkit-transform': transformString,
  11022. '-moz-transform': transformString,
  11023. '-ms-transform': transformString,
  11024. '-o-transform': transformString,
  11025. 'transform': transformString
  11026. };
  11027. }
  11028. });