1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871 |
- /*
- Copyright (c) 2009, Yahoo! Inc. All rights reserved.
- Code licensed under the BSD License:
- http://developer.yahoo.net/yui/license.txt
- version: 2.8.0r4
- */
- /**
- * @module menu
- * @description <p>The Menu family of components features a collection of
- * controls that make it easy to add menus to your website or web application.
- * With the Menu Controls you can create website fly-out menus, customized
- * context menus, or application-style menu bars with just a small amount of
- * scripting.</p><p>The Menu family of controls features:</p>
- * <ul>
- * <li>Keyboard and mouse navigation.</li>
- * <li>A rich event model that provides access to all of a menu's
- * interesting moments.</li>
- * <li>Support for
- * <a href="http://en.wikipedia.org/wiki/Progressive_Enhancement">Progressive
- * Enhancement</a>; Menus can be created from simple,
- * semantic markup on the page or purely through JavaScript.</li>
- * </ul>
- * @title Menu
- * @namespace YAHOO.widget
- * @requires Event, Dom, Container
- */
- (function () {
- var UA = YAHOO.env.ua,
- Dom = YAHOO.util.Dom,
- Event = YAHOO.util.Event,
- Lang = YAHOO.lang,
- _DIV = "DIV",
- _HD = "hd",
- _BD = "bd",
- _FT = "ft",
- _LI = "LI",
- _DISABLED = "disabled",
- _MOUSEOVER = "mouseover",
- _MOUSEOUT = "mouseout",
- _MOUSEDOWN = "mousedown",
- _MOUSEUP = "mouseup",
- _CLICK = "click",
- _KEYDOWN = "keydown",
- _KEYUP = "keyup",
- _KEYPRESS = "keypress",
- _CLICK_TO_HIDE = "clicktohide",
- _POSITION = "position",
- _DYNAMIC = "dynamic",
- _SHOW_DELAY = "showdelay",
- _SELECTED = "selected",
- _VISIBLE = "visible",
- _UL = "UL",
- _MENUMANAGER = "MenuManager";
- /**
- * Singleton that manages a collection of all menus and menu items. Listens
- * for DOM events at the document level and dispatches the events to the
- * corresponding menu or menu item.
- *
- * @namespace YAHOO.widget
- * @class MenuManager
- * @static
- */
- YAHOO.widget.MenuManager = function () {
-
- // Private member variables
-
-
- // Flag indicating if the DOM event handlers have been attached
-
- var m_bInitializedEventHandlers = false,
-
-
- // Collection of menus
- m_oMenus = {},
- // Collection of visible menus
-
- m_oVisibleMenus = {},
-
-
- // Collection of menu items
- m_oItems = {},
- // Map of DOM event types to their equivalent CustomEvent types
-
- m_oEventTypes = {
- "click": "clickEvent",
- "mousedown": "mouseDownEvent",
- "mouseup": "mouseUpEvent",
- "mouseover": "mouseOverEvent",
- "mouseout": "mouseOutEvent",
- "keydown": "keyDownEvent",
- "keyup": "keyUpEvent",
- "keypress": "keyPressEvent",
- "focus": "focusEvent",
- "focusin": "focusEvent",
- "blur": "blurEvent",
- "focusout": "blurEvent"
- },
-
-
- m_oFocusedMenuItem = null;
-
-
-
- // Private methods
-
-
- /**
- * @method getMenuRootElement
- * @description Finds the root DIV node of a menu or the root LI node of
- * a menu item.
- * @private
- * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
- * level-one-html.html#ID-58190037">HTMLElement</a>} p_oElement Object
- * specifying an HTML element.
- */
- function getMenuRootElement(p_oElement) {
-
- var oParentNode,
- returnVal;
-
- if (p_oElement && p_oElement.tagName) {
-
- switch (p_oElement.tagName.toUpperCase()) {
-
- case _DIV:
-
- oParentNode = p_oElement.parentNode;
-
- // Check if the DIV is the inner "body" node of a menu
- if ((
- Dom.hasClass(p_oElement, _HD) ||
- Dom.hasClass(p_oElement, _BD) ||
- Dom.hasClass(p_oElement, _FT)
- ) &&
- oParentNode &&
- oParentNode.tagName &&
- oParentNode.tagName.toUpperCase() == _DIV) {
-
- returnVal = oParentNode;
-
- }
- else {
-
- returnVal = p_oElement;
-
- }
-
- break;
- case _LI:
-
- returnVal = p_oElement;
-
- break;
- default:
-
- oParentNode = p_oElement.parentNode;
-
- if (oParentNode) {
-
- returnVal = getMenuRootElement(oParentNode);
-
- }
-
- break;
-
- }
-
- }
-
- return returnVal;
-
- }
-
-
-
- // Private event handlers
-
-
- /**
- * @method onDOMEvent
- * @description Generic, global event handler for all of a menu's
- * DOM-based events. This listens for events against the document
- * object. If the target of a given event is a member of a menu or
- * menu item's DOM, the instance's corresponding Custom Event is fired.
- * @private
- * @param {Event} p_oEvent Object representing the DOM event object
- * passed back by the event utility (YAHOO.util.Event).
- */
- function onDOMEvent(p_oEvent) {
-
- // Get the target node of the DOM event
-
- var oTarget = Event.getTarget(p_oEvent),
-
- // See if the target of the event was a menu, or a menu item
-
- oElement = getMenuRootElement(oTarget),
- bFireEvent = true,
- sEventType = p_oEvent.type,
- sCustomEventType,
- sTagName,
- sId,
- oMenuItem,
- oMenu;
-
-
- if (oElement) {
-
- sTagName = oElement.tagName.toUpperCase();
-
- if (sTagName == _LI) {
-
- sId = oElement.id;
-
- if (sId && m_oItems[sId]) {
-
- oMenuItem = m_oItems[sId];
- oMenu = oMenuItem.parent;
-
- }
-
- }
- else if (sTagName == _DIV) {
-
- if (oElement.id) {
-
- oMenu = m_oMenus[oElement.id];
-
- }
-
- }
-
- }
-
-
- if (oMenu) {
-
- sCustomEventType = m_oEventTypes[sEventType];
- /*
- There is an inconsistency between Firefox for Mac OS X and
- Firefox Windows & Linux regarding the triggering of the
- display of the browser's context menu and the subsequent
- firing of the "click" event. In Firefox for Windows & Linux,
- when the user triggers the display of the browser's context
- menu the "click" event also fires for the document object,
- even though the "click" event did not fire for the element
- that was the original target of the "contextmenu" event.
- This is unique to Firefox on Windows & Linux. For all
- other A-Grade browsers, including Firefox for Mac OS X, the
- "click" event doesn't fire for the document object.
- This bug in Firefox for Windows affects Menu, as Menu
- instances listen for events at the document level and
- dispatches Custom Events of the same name. Therefore users
- of Menu will get an unwanted firing of the "click"
- custom event. The following line fixes this bug.
- */
-
- if (sEventType == "click" &&
- (UA.gecko && oMenu.platform != "mac") &&
- p_oEvent.button > 0) {
- bFireEvent = false;
- }
-
- // Fire the Custom Event that corresponds the current DOM event
-
- if (bFireEvent && oMenuItem && !oMenuItem.cfg.getProperty(_DISABLED)) {
- oMenuItem[sCustomEventType].fire(p_oEvent);
- }
-
- if (bFireEvent) {
- oMenu[sCustomEventType].fire(p_oEvent, oMenuItem);
- }
-
- }
- else if (sEventType == _MOUSEDOWN) {
-
- /*
- If the target of the event wasn't a menu, hide all
- dynamically positioned menus
- */
-
- for (var i in m_oVisibleMenus) {
-
- if (Lang.hasOwnProperty(m_oVisibleMenus, i)) {
-
- oMenu = m_oVisibleMenus[i];
- if (oMenu.cfg.getProperty(_CLICK_TO_HIDE) &&
- !(oMenu instanceof YAHOO.widget.MenuBar) &&
- oMenu.cfg.getProperty(_POSITION) == _DYNAMIC) {
- oMenu.hide();
- // In IE when the user mouses down on a focusable
- // element that element will be focused and become
- // the "activeElement".
- // (http://msdn.microsoft.com/en-us/library/ms533065(VS.85).aspx)
- // However, there is a bug in IE where if there is
- // a positioned element with a focused descendant
- // that is hidden in response to the mousedown
- // event, the target of the mousedown event will
- // appear to have focus, but will not be set as
- // the activeElement. This will result in the
- // element not firing key events, even though it
- // appears to have focus. The following call to
- // "setActive" fixes this bug.
- if (UA.ie && oTarget.focus) {
- oTarget.setActive();
- }
-
- }
- else {
-
- if (oMenu.cfg.getProperty(_SHOW_DELAY) > 0) {
-
- oMenu._cancelShowDelay();
-
- }
- if (oMenu.activeItem) {
-
- oMenu.activeItem.blur();
- oMenu.activeItem.cfg.setProperty(_SELECTED, false);
-
- oMenu.activeItem = null;
-
- }
-
- }
-
- }
-
- }
-
- }
-
- }
-
-
- /**
- * @method onMenuDestroy
- * @description "destroy" event handler for a menu.
- * @private
- * @param {String} p_sType String representing the name of the event
- * that was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event
- * was fired.
- * @param {YAHOO.widget.Menu} p_oMenu The menu that fired the event.
- */
- function onMenuDestroy(p_sType, p_aArgs, p_oMenu) {
-
- if (m_oMenus[p_oMenu.id]) {
-
- this.removeMenu(p_oMenu);
-
- }
-
- }
-
-
- /**
- * @method onMenuFocus
- * @description "focus" event handler for a MenuItem instance.
- * @private
- * @param {String} p_sType String representing the name of the event
- * that was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event
- * was fired.
- */
- function onMenuFocus(p_sType, p_aArgs) {
-
- var oItem = p_aArgs[1];
-
- if (oItem) {
-
- m_oFocusedMenuItem = oItem;
-
- }
-
- }
-
-
- /**
- * @method onMenuBlur
- * @description "blur" event handler for a MenuItem instance.
- * @private
- * @param {String} p_sType String representing the name of the event
- * that was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event
- * was fired.
- */
- function onMenuBlur(p_sType, p_aArgs) {
-
- m_oFocusedMenuItem = null;
-
- }
-
- /**
- * @method onMenuVisibleConfigChange
- * @description Event handler for when the "visible" configuration
- * property of a Menu instance changes.
- * @private
- * @param {String} p_sType String representing the name of the event
- * that was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event
- * was fired.
- */
- function onMenuVisibleConfigChange(p_sType, p_aArgs) {
-
- var bVisible = p_aArgs[0],
- sId = this.id;
-
- if (bVisible) {
-
- m_oVisibleMenus[sId] = this;
-
- YAHOO.log(this + " added to the collection of visible menus.",
- "info", _MENUMANAGER);
-
- }
- else if (m_oVisibleMenus[sId]) {
-
- delete m_oVisibleMenus[sId];
-
- YAHOO.log(this + " removed from the collection of visible menus.",
- "info", _MENUMANAGER);
-
- }
-
- }
-
-
- /**
- * @method onItemDestroy
- * @description "destroy" event handler for a MenuItem instance.
- * @private
- * @param {String} p_sType String representing the name of the event
- * that was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event
- * was fired.
- */
- function onItemDestroy(p_sType, p_aArgs) {
-
- removeItem(this);
-
- }
- /**
- * @method removeItem
- * @description Removes a MenuItem instance from the MenuManager's collection of MenuItems.
- * @private
- * @param {MenuItem} p_oMenuItem The MenuItem instance to be removed.
- */
- function removeItem(p_oMenuItem) {
- var sId = p_oMenuItem.id;
-
- if (sId && m_oItems[sId]) {
-
- if (m_oFocusedMenuItem == p_oMenuItem) {
-
- m_oFocusedMenuItem = null;
-
- }
-
- delete m_oItems[sId];
-
- p_oMenuItem.destroyEvent.unsubscribe(onItemDestroy);
-
- YAHOO.log(p_oMenuItem + " successfully unregistered.", "info", _MENUMANAGER);
-
- }
- }
-
-
- /**
- * @method onItemAdded
- * @description "itemadded" event handler for a Menu instance.
- * @private
- * @param {String} p_sType String representing the name of the event
- * that was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event
- * was fired.
- */
- function onItemAdded(p_sType, p_aArgs) {
-
- var oItem = p_aArgs[0],
- sId;
-
- if (oItem instanceof YAHOO.widget.MenuItem) {
-
- sId = oItem.id;
-
- if (!m_oItems[sId]) {
-
- m_oItems[sId] = oItem;
-
- oItem.destroyEvent.subscribe(onItemDestroy);
-
- YAHOO.log(oItem + " successfully registered.", "info", _MENUMANAGER);
-
- }
-
- }
-
- }
-
-
- return {
-
- // Privileged methods
-
-
- /**
- * @method addMenu
- * @description Adds a menu to the collection of known menus.
- * @param {YAHOO.widget.Menu} p_oMenu Object specifying the Menu
- * instance to be added.
- */
- addMenu: function (p_oMenu) {
-
- var oDoc;
-
- if (p_oMenu instanceof YAHOO.widget.Menu && p_oMenu.id &&
- !m_oMenus[p_oMenu.id]) {
-
- m_oMenus[p_oMenu.id] = p_oMenu;
-
-
- if (!m_bInitializedEventHandlers) {
-
- oDoc = document;
-
- Event.on(oDoc, _MOUSEOVER, onDOMEvent, this, true);
- Event.on(oDoc, _MOUSEOUT, onDOMEvent, this, true);
- Event.on(oDoc, _MOUSEDOWN, onDOMEvent, this, true);
- Event.on(oDoc, _MOUSEUP, onDOMEvent, this, true);
- Event.on(oDoc, _CLICK, onDOMEvent, this, true);
- Event.on(oDoc, _KEYDOWN, onDOMEvent, this, true);
- Event.on(oDoc, _KEYUP, onDOMEvent, this, true);
- Event.on(oDoc, _KEYPRESS, onDOMEvent, this, true);
-
- Event.onFocus(oDoc, onDOMEvent, this, true);
- Event.onBlur(oDoc, onDOMEvent, this, true);
-
- m_bInitializedEventHandlers = true;
-
- YAHOO.log("DOM event handlers initialized.", "info", _MENUMANAGER);
-
- }
-
- p_oMenu.cfg.subscribeToConfigEvent(_VISIBLE, onMenuVisibleConfigChange);
- p_oMenu.destroyEvent.subscribe(onMenuDestroy, p_oMenu, this);
- p_oMenu.itemAddedEvent.subscribe(onItemAdded);
- p_oMenu.focusEvent.subscribe(onMenuFocus);
- p_oMenu.blurEvent.subscribe(onMenuBlur);
-
- YAHOO.log(p_oMenu + " successfully registered.", "info", _MENUMANAGER);
-
- }
-
- },
-
-
- /**
- * @method removeMenu
- * @description Removes a menu from the collection of known menus.
- * @param {YAHOO.widget.Menu} p_oMenu Object specifying the Menu
- * instance to be removed.
- */
- removeMenu: function (p_oMenu) {
-
- var sId,
- aItems,
- i;
-
- if (p_oMenu) {
-
- sId = p_oMenu.id;
-
- if ((sId in m_oMenus) && (m_oMenus[sId] == p_oMenu)) {
- // Unregister each menu item
- aItems = p_oMenu.getItems();
- if (aItems && aItems.length > 0) {
- i = aItems.length - 1;
- do {
- removeItem(aItems[i]);
- }
- while (i--);
- }
- // Unregister the menu
- delete m_oMenus[sId];
-
- YAHOO.log(p_oMenu + " successfully unregistered.", "info", _MENUMANAGER);
-
- /*
- Unregister the menu from the collection of
- visible menus
- */
- if ((sId in m_oVisibleMenus) && (m_oVisibleMenus[sId] == p_oMenu)) {
-
- delete m_oVisibleMenus[sId];
-
- YAHOO.log(p_oMenu + " unregistered from the" +
- " collection of visible menus.", "info", _MENUMANAGER);
-
- }
- // Unsubscribe event listeners
- if (p_oMenu.cfg) {
- p_oMenu.cfg.unsubscribeFromConfigEvent(_VISIBLE,
- onMenuVisibleConfigChange);
-
- }
- p_oMenu.destroyEvent.unsubscribe(onMenuDestroy,
- p_oMenu);
-
- p_oMenu.itemAddedEvent.unsubscribe(onItemAdded);
- p_oMenu.focusEvent.unsubscribe(onMenuFocus);
- p_oMenu.blurEvent.unsubscribe(onMenuBlur);
- }
-
- }
-
- },
-
-
- /**
- * @method hideVisible
- * @description Hides all visible, dynamically positioned menus
- * (excluding instances of YAHOO.widget.MenuBar).
- */
- hideVisible: function () {
-
- var oMenu;
-
- for (var i in m_oVisibleMenus) {
-
- if (Lang.hasOwnProperty(m_oVisibleMenus, i)) {
-
- oMenu = m_oVisibleMenus[i];
-
- if (!(oMenu instanceof YAHOO.widget.MenuBar) &&
- oMenu.cfg.getProperty(_POSITION) == _DYNAMIC) {
-
- oMenu.hide();
-
- }
-
- }
-
- }
-
- },
- /**
- * @method getVisible
- * @description Returns a collection of all visible menus registered
- * with the menu manger.
- * @return {Object}
- */
- getVisible: function () {
-
- return m_oVisibleMenus;
-
- },
-
- /**
- * @method getMenus
- * @description Returns a collection of all menus registered with the
- * menu manger.
- * @return {Object}
- */
- getMenus: function () {
-
- return m_oMenus;
-
- },
-
-
- /**
- * @method getMenu
- * @description Returns a menu with the specified id.
- * @param {String} p_sId String specifying the id of the
- * <code><div></code> element representing the menu to
- * be retrieved.
- * @return {YAHOO.widget.Menu}
- */
- getMenu: function (p_sId) {
-
- var returnVal;
-
- if (p_sId in m_oMenus) {
-
- returnVal = m_oMenus[p_sId];
-
- }
-
- return returnVal;
-
- },
-
-
- /**
- * @method getMenuItem
- * @description Returns a menu item with the specified id.
- * @param {String} p_sId String specifying the id of the
- * <code><li></code> element representing the menu item to
- * be retrieved.
- * @return {YAHOO.widget.MenuItem}
- */
- getMenuItem: function (p_sId) {
-
- var returnVal;
-
- if (p_sId in m_oItems) {
-
- returnVal = m_oItems[p_sId];
-
- }
-
- return returnVal;
-
- },
- /**
- * @method getMenuItemGroup
- * @description Returns an array of menu item instances whose
- * corresponding <code><li></code> elements are child
- * nodes of the <code><ul></code> element with the
- * specified id.
- * @param {String} p_sId String specifying the id of the
- * <code><ul></code> element representing the group of
- * menu items to be retrieved.
- * @return {Array}
- */
- getMenuItemGroup: function (p_sId) {
- var oUL = Dom.get(p_sId),
- aItems,
- oNode,
- oItem,
- sId,
- returnVal;
-
- if (oUL && oUL.tagName && oUL.tagName.toUpperCase() == _UL) {
- oNode = oUL.firstChild;
- if (oNode) {
- aItems = [];
-
- do {
- sId = oNode.id;
- if (sId) {
-
- oItem = this.getMenuItem(sId);
-
- if (oItem) {
-
- aItems[aItems.length] = oItem;
-
- }
-
- }
-
- }
- while ((oNode = oNode.nextSibling));
- if (aItems.length > 0) {
- returnVal = aItems;
-
- }
- }
-
- }
- return returnVal;
-
- },
-
- /**
- * @method getFocusedMenuItem
- * @description Returns a reference to the menu item that currently
- * has focus.
- * @return {YAHOO.widget.MenuItem}
- */
- getFocusedMenuItem: function () {
-
- return m_oFocusedMenuItem;
-
- },
-
-
- /**
- * @method getFocusedMenu
- * @description Returns a reference to the menu that currently
- * has focus.
- * @return {YAHOO.widget.Menu}
- */
- getFocusedMenu: function () {
- var returnVal;
-
- if (m_oFocusedMenuItem) {
-
- returnVal = m_oFocusedMenuItem.parent.getRoot();
-
- }
-
- return returnVal;
-
- },
-
-
- /**
- * @method toString
- * @description Returns a string representing the menu manager.
- * @return {String}
- */
- toString: function () {
-
- return _MENUMANAGER;
-
- }
-
- };
-
- }();
- })();
- (function () {
- var Lang = YAHOO.lang,
- // String constants
-
- _MENU = "Menu",
- _DIV_UPPERCASE = "DIV",
- _DIV_LOWERCASE = "div",
- _ID = "id",
- _SELECT = "SELECT",
- _XY = "xy",
- _Y = "y",
- _UL_UPPERCASE = "UL",
- _UL_LOWERCASE = "ul",
- _FIRST_OF_TYPE = "first-of-type",
- _LI = "LI",
- _OPTGROUP = "OPTGROUP",
- _OPTION = "OPTION",
- _DISABLED = "disabled",
- _NONE = "none",
- _SELECTED = "selected",
- _GROUP_INDEX = "groupindex",
- _INDEX = "index",
- _SUBMENU = "submenu",
- _VISIBLE = "visible",
- _HIDE_DELAY = "hidedelay",
- _POSITION = "position",
- _DYNAMIC = "dynamic",
- _STATIC = "static",
- _DYNAMIC_STATIC = _DYNAMIC + "," + _STATIC,
- _URL = "url",
- _HASH = "#",
- _TARGET = "target",
- _MAX_HEIGHT = "maxheight",
- _TOP_SCROLLBAR = "topscrollbar",
- _BOTTOM_SCROLLBAR = "bottomscrollbar",
- _UNDERSCORE = "_",
- _TOP_SCROLLBAR_DISABLED = _TOP_SCROLLBAR + _UNDERSCORE + _DISABLED,
- _BOTTOM_SCROLLBAR_DISABLED = _BOTTOM_SCROLLBAR + _UNDERSCORE + _DISABLED,
- _MOUSEMOVE = "mousemove",
- _SHOW_DELAY = "showdelay",
- _SUBMENU_HIDE_DELAY = "submenuhidedelay",
- _IFRAME = "iframe",
- _CONSTRAIN_TO_VIEWPORT = "constraintoviewport",
- _PREVENT_CONTEXT_OVERLAP = "preventcontextoverlap",
- _SUBMENU_ALIGNMENT = "submenualignment",
- _AUTO_SUBMENU_DISPLAY = "autosubmenudisplay",
- _CLICK_TO_HIDE = "clicktohide",
- _CONTAINER = "container",
- _SCROLL_INCREMENT = "scrollincrement",
- _MIN_SCROLL_HEIGHT = "minscrollheight",
- _CLASSNAME = "classname",
- _SHADOW = "shadow",
- _KEEP_OPEN = "keepopen",
- _HD = "hd",
- _HAS_TITLE = "hastitle",
- _CONTEXT = "context",
- _EMPTY_STRING = "",
- _MOUSEDOWN = "mousedown",
- _KEYDOWN = "keydown",
- _HEIGHT = "height",
- _WIDTH = "width",
- _PX = "px",
- _EFFECT = "effect",
- _MONITOR_RESIZE = "monitorresize",
- _DISPLAY = "display",
- _BLOCK = "block",
- _VISIBILITY = "visibility",
- _ABSOLUTE = "absolute",
- _ZINDEX = "zindex",
- _YUI_MENU_BODY_SCROLLED = "yui-menu-body-scrolled",
- _NON_BREAKING_SPACE = " ",
- _SPACE = " ",
- _MOUSEOVER = "mouseover",
- _MOUSEOUT = "mouseout",
- _ITEM_ADDED = "itemAdded",
- _ITEM_REMOVED = "itemRemoved",
- _HIDDEN = "hidden",
- _YUI_MENU_SHADOW = "yui-menu-shadow",
- _YUI_MENU_SHADOW_VISIBLE = _YUI_MENU_SHADOW + "-visible",
- _YUI_MENU_SHADOW_YUI_MENU_SHADOW_VISIBLE = _YUI_MENU_SHADOW + _SPACE + _YUI_MENU_SHADOW_VISIBLE;
- /**
- * The Menu class creates a container that holds a vertical list representing
- * a set of options or commands. Menu is the base class for all
- * menu containers.
- * @param {String} p_oElement String specifying the id attribute of the
- * <code><div></code> element of the menu.
- * @param {String} p_oElement String specifying the id attribute of the
- * <code><select></code> element to be used as the data source
- * for the menu.
- * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
- * level-one-html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object
- * specifying the <code><div></code> element of the menu.
- * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
- * level-one-html.html#ID-94282980">HTMLSelectElement</a>} p_oElement
- * Object specifying the <code><select></code> element to be used as
- * the data source for the menu.
- * @param {Object} p_oConfig Optional. Object literal specifying the
- * configuration for the menu. See configuration class documentation for
- * more details.
- * @namespace YAHOO.widget
- * @class Menu
- * @constructor
- * @extends YAHOO.widget.Overlay
- */
- YAHOO.widget.Menu = function (p_oElement, p_oConfig) {
- if (p_oConfig) {
- this.parent = p_oConfig.parent;
- this.lazyLoad = p_oConfig.lazyLoad || p_oConfig.lazyload;
- this.itemData = p_oConfig.itemData || p_oConfig.itemdata;
- }
- YAHOO.widget.Menu.superclass.constructor.call(this, p_oElement, p_oConfig);
- };
- /**
- * @method checkPosition
- * @description Checks to make sure that the value of the "position" property
- * is one of the supported strings. Returns true if the position is supported.
- * @private
- * @param {Object} p_sPosition String specifying the position of the menu.
- * @return {Boolean}
- */
- function checkPosition(p_sPosition) {
- var returnVal = false;
- if (Lang.isString(p_sPosition)) {
- returnVal = (_DYNAMIC_STATIC.indexOf((p_sPosition.toLowerCase())) != -1);
- }
- return returnVal;
- }
- var Dom = YAHOO.util.Dom,
- Event = YAHOO.util.Event,
- Module = YAHOO.widget.Module,
- Overlay = YAHOO.widget.Overlay,
- Menu = YAHOO.widget.Menu,
- MenuManager = YAHOO.widget.MenuManager,
- CustomEvent = YAHOO.util.CustomEvent,
- UA = YAHOO.env.ua,
-
- m_oShadowTemplate,
- bFocusListenerInitialized = false,
- oFocusedElement,
- EVENT_TYPES = [
-
- ["mouseOverEvent", _MOUSEOVER],
- ["mouseOutEvent", _MOUSEOUT],
- ["mouseDownEvent", _MOUSEDOWN],
- ["mouseUpEvent", "mouseup"],
- ["clickEvent", "click"],
- ["keyPressEvent", "keypress"],
- ["keyDownEvent", _KEYDOWN],
- ["keyUpEvent", "keyup"],
- ["focusEvent", "focus"],
- ["blurEvent", "blur"],
- ["itemAddedEvent", _ITEM_ADDED],
- ["itemRemovedEvent", _ITEM_REMOVED]
- ],
- VISIBLE_CONFIG = {
- key: _VISIBLE,
- value: false,
- validator: Lang.isBoolean
- },
- CONSTRAIN_TO_VIEWPORT_CONFIG = {
- key: _CONSTRAIN_TO_VIEWPORT,
- value: true,
- validator: Lang.isBoolean,
- supercedes: [_IFRAME,"x",_Y,_XY]
- },
- PREVENT_CONTEXT_OVERLAP_CONFIG = {
- key: _PREVENT_CONTEXT_OVERLAP,
- value: true,
- validator: Lang.isBoolean,
- supercedes: [_CONSTRAIN_TO_VIEWPORT]
- },
- POSITION_CONFIG = {
- key: _POSITION,
- value: _DYNAMIC,
- validator: checkPosition,
- supercedes: [_VISIBLE, _IFRAME]
- },
- SUBMENU_ALIGNMENT_CONFIG = {
- key: _SUBMENU_ALIGNMENT,
- value: ["tl","tr"]
- },
- AUTO_SUBMENU_DISPLAY_CONFIG = {
- key: _AUTO_SUBMENU_DISPLAY,
- value: true,
- validator: Lang.isBoolean,
- suppressEvent: true
- },
- SHOW_DELAY_CONFIG = {
- key: _SHOW_DELAY,
- value: 250,
- validator: Lang.isNumber,
- suppressEvent: true
- },
- HIDE_DELAY_CONFIG = {
- key: _HIDE_DELAY,
- value: 0,
- validator: Lang.isNumber,
- suppressEvent: true
- },
- SUBMENU_HIDE_DELAY_CONFIG = {
- key: _SUBMENU_HIDE_DELAY,
- value: 250,
- validator: Lang.isNumber,
- suppressEvent: true
- },
- CLICK_TO_HIDE_CONFIG = {
- key: _CLICK_TO_HIDE,
- value: true,
- validator: Lang.isBoolean,
- suppressEvent: true
- },
- CONTAINER_CONFIG = {
- key: _CONTAINER,
- suppressEvent: true
- },
- SCROLL_INCREMENT_CONFIG = {
- key: _SCROLL_INCREMENT,
- value: 1,
- validator: Lang.isNumber,
- supercedes: [_MAX_HEIGHT],
- suppressEvent: true
- },
- MIN_SCROLL_HEIGHT_CONFIG = {
- key: _MIN_SCROLL_HEIGHT,
- value: 90,
- validator: Lang.isNumber,
- supercedes: [_MAX_HEIGHT],
- suppressEvent: true
- },
- MAX_HEIGHT_CONFIG = {
- key: _MAX_HEIGHT,
- value: 0,
- validator: Lang.isNumber,
- supercedes: [_IFRAME],
- suppressEvent: true
- },
- CLASS_NAME_CONFIG = {
- key: _CLASSNAME,
- value: null,
- validator: Lang.isString,
- suppressEvent: true
- },
- DISABLED_CONFIG = {
- key: _DISABLED,
- value: false,
- validator: Lang.isBoolean,
- suppressEvent: true
- },
-
- SHADOW_CONFIG = {
- key: _SHADOW,
- value: true,
- validator: Lang.isBoolean,
- suppressEvent: true,
- supercedes: [_VISIBLE]
- },
-
- KEEP_OPEN_CONFIG = {
- key: _KEEP_OPEN,
- value: false,
- validator: Lang.isBoolean
- };
- function onDocFocus(event) {
- oFocusedElement = Event.getTarget(event);
- }
- YAHOO.lang.extend(Menu, Overlay, {
- // Constants
- /**
- * @property CSS_CLASS_NAME
- * @description String representing the CSS class(es) to be applied to the
- * menu's <code><div></code> element.
- * @default "yuimenu"
- * @final
- * @type String
- */
- CSS_CLASS_NAME: "yuimenu",
- /**
- * @property ITEM_TYPE
- * @description Object representing the type of menu item to instantiate and
- * add when parsing the child nodes (either <code><li></code> element,
- * <code><optgroup></code> element or <code><option></code>)
- * of the menu's source HTML element.
- * @default YAHOO.widget.MenuItem
- * @final
- * @type YAHOO.widget.MenuItem
- */
- ITEM_TYPE: null,
- /**
- * @property GROUP_TITLE_TAG_NAME
- * @description String representing the tagname of the HTML element used to
- * title the menu's item groups.
- * @default H6
- * @final
- * @type String
- */
- GROUP_TITLE_TAG_NAME: "h6",
- /**
- * @property OFF_SCREEN_POSITION
- * @description Array representing the default x and y position that a menu
- * should have when it is positioned outside the viewport by the
- * "poistionOffScreen" method.
- * @default "-999em"
- * @final
- * @type String
- */
- OFF_SCREEN_POSITION: "-999em",
- // Private properties
- /**
- * @property _useHideDelay
- * @description Boolean indicating if the "mouseover" and "mouseout" event
- * handlers used for hiding the menu via a call to "YAHOO.lang.later" have
- * already been assigned.
- * @default false
- * @private
- * @type Boolean
- */
- _useHideDelay: false,
- /**
- * @property _bHandledMouseOverEvent
- * @description Boolean indicating the current state of the menu's
- * "mouseover" event.
- * @default false
- * @private
- * @type Boolean
- */
- _bHandledMouseOverEvent: false,
- /**
- * @property _bHandledMouseOutEvent
- * @description Boolean indicating the current state of the menu's
- * "mouseout" event.
- * @default false
- * @private
- * @type Boolean
- */
- _bHandledMouseOutEvent: false,
- /**
- * @property _aGroupTitleElements
- * @description Array of HTML element used to title groups of menu items.
- * @default []
- * @private
- * @type Array
- */
- _aGroupTitleElements: null,
- /**
- * @property _aItemGroups
- * @description Multi-dimensional Array representing the menu items as they
- * are grouped in the menu.
- * @default []
- * @private
- * @type Array
- */
- _aItemGroups: null,
- /**
- * @property _aListElements
- * @description Array of <code><ul></code> elements, each of which is
- * the parent node for each item's <code><li></code> element.
- * @default []
- * @private
- * @type Array
- */
- _aListElements: null,
- /**
- * @property _nCurrentMouseX
- * @description The current x coordinate of the mouse inside the area of
- * the menu.
- * @default 0
- * @private
- * @type Number
- */
- _nCurrentMouseX: 0,
- /**
- * @property _bStopMouseEventHandlers
- * @description Stops "mouseover," "mouseout," and "mousemove" event handlers
- * from executing.
- * @default false
- * @private
- * @type Boolean
- */
- _bStopMouseEventHandlers: false,
- /**
- * @property _sClassName
- * @description The current value of the "classname" configuration attribute.
- * @default null
- * @private
- * @type String
- */
- _sClassName: null,
- // Public properties
- /**
- * @property lazyLoad
- * @description Boolean indicating if the menu's "lazy load" feature is
- * enabled. If set to "true," initialization and rendering of the menu's
- * items will be deferred until the first time it is made visible. This
- * property should be set via the constructor using the configuration
- * object literal.
- * @default false
- * @type Boolean
- */
- lazyLoad: false,
- /**
- * @property itemData
- * @description Array of items to be added to the menu. The array can contain
- * strings representing the text for each item to be created, object literals
- * representing the menu item configuration properties, or MenuItem instances.
- * This property should be set via the constructor using the configuration
- * object literal.
- * @default null
- * @type Array
- */
- itemData: null,
- /**
- * @property activeItem
- * @description Object reference to the item in the menu that has is selected.
- * @default null
- * @type YAHOO.widget.MenuItem
- */
- activeItem: null,
- /**
- * @property parent
- * @description Object reference to the menu's parent menu or menu item.
- * This property can be set via the constructor using the configuration
- * object literal.
- * @default null
- * @type YAHOO.widget.MenuItem
- */
- parent: null,
- /**
- * @property srcElement
- * @description Object reference to the HTML element (either
- * <code><select></code> or <code><div></code>) used to
- * create the menu.
- * @default null
- * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
- * level-one-html.html#ID-94282980">HTMLSelectElement</a>|<a
- * href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-html.
- * html#ID-22445964">HTMLDivElement</a>
- */
- srcElement: null,
- // Events
- /**
- * @event mouseOverEvent
- * @description Fires when the mouse has entered the menu. Passes back
- * the DOM Event object as an argument.
- */
- /**
- * @event mouseOutEvent
- * @description Fires when the mouse has left the menu. Passes back the DOM
- * Event object as an argument.
- * @type YAHOO.util.CustomEvent
- */
- /**
- * @event mouseDownEvent
- * @description Fires when the user mouses down on the menu. Passes back the
- * DOM Event object as an argument.
- * @type YAHOO.util.CustomEvent
- */
- /**
- * @event mouseUpEvent
- * @description Fires when the user releases a mouse button while the mouse is
- * over the menu. Passes back the DOM Event object as an argument.
- * @type YAHOO.util.CustomEvent
- */
- /**
- * @event clickEvent
- * @description Fires when the user clicks the on the menu. Passes back the
- * DOM Event object as an argument.
- * @type YAHOO.util.CustomEvent
- */
- /**
- * @event keyPressEvent
- * @description Fires when the user presses an alphanumeric key when one of the
- * menu's items has focus. Passes back the DOM Event object as an argument.
- * @type YAHOO.util.CustomEvent
- */
- /**
- * @event keyDownEvent
- * @description Fires when the user presses a key when one of the menu's items
- * has focus. Passes back the DOM Event object as an argument.
- * @type YAHOO.util.CustomEvent
- */
- /**
- * @event keyUpEvent
- * @description Fires when the user releases a key when one of the menu's items
- * has focus. Passes back the DOM Event object as an argument.
- * @type YAHOO.util.CustomEvent
- */
- /**
- * @event itemAddedEvent
- * @description Fires when an item is added to the menu.
- * @type YAHOO.util.CustomEvent
- */
- /**
- * @event itemRemovedEvent
- * @description Fires when an item is removed to the menu.
- * @type YAHOO.util.CustomEvent
- */
- /**
- * @method init
- * @description The Menu class's initialization method. This method is
- * automatically called by the constructor, and sets up all DOM references
- * for pre-existing markup, and creates required markup if it is not
- * already present.
- * @param {String} p_oElement String specifying the id attribute of the
- * <code><div></code> element of the menu.
- * @param {String} p_oElement String specifying the id attribute of the
- * <code><select></code> element to be used as the data source
- * for the menu.
- * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
- * level-one-html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object
- * specifying the <code><div></code> element of the menu.
- * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
- * level-one-html.html#ID-94282980">HTMLSelectElement</a>} p_oElement
- * Object specifying the <code><select></code> element to be used as
- * the data source for the menu.
- * @param {Object} p_oConfig Optional. Object literal specifying the
- * configuration for the menu. See configuration class documentation for
- * more details.
- */
- init: function (p_oElement, p_oConfig) {
- this._aItemGroups = [];
- this._aListElements = [];
- this._aGroupTitleElements = [];
- if (!this.ITEM_TYPE) {
- this.ITEM_TYPE = YAHOO.widget.MenuItem;
- }
- var oElement;
- if (Lang.isString(p_oElement)) {
- oElement = Dom.get(p_oElement);
- }
- else if (p_oElement.tagName) {
- oElement = p_oElement;
- }
- if (oElement && oElement.tagName) {
- switch(oElement.tagName.toUpperCase()) {
-
- case _DIV_UPPERCASE:
- this.srcElement = oElement;
- if (!oElement.id) {
- oElement.setAttribute(_ID, Dom.generateId());
- }
- /*
- Note: we don't pass the user config in here yet
- because we only want it executed once, at the lowest
- subclass level.
- */
-
- Menu.superclass.init.call(this, oElement);
- this.beforeInitEvent.fire(Menu);
- YAHOO.log("Source element: " + this.srcElement.tagName, "info", this.toString());
-
- break;
-
- case _SELECT:
-
- this.srcElement = oElement;
-
- /*
- The source element is not something that we can use
- outright, so we need to create a new Overlay
- Note: we don't pass the user config in here yet
- because we only want it executed once, at the lowest
- subclass level.
- */
- Menu.superclass.init.call(this, Dom.generateId());
- this.beforeInitEvent.fire(Menu);
- YAHOO.log("Source element: " + this.srcElement.tagName, "info", this.toString());
- break;
- }
- }
- else {
- /*
- Note: we don't pass the user config in here yet
- because we only want it executed once, at the lowest
- subclass level.
- */
-
- Menu.superclass.init.call(this, p_oElement);
- this.beforeInitEvent.fire(Menu);
- YAHOO.log("No source element found. Created element with id: " + this.id, "info", this.toString());
- }
- if (this.element) {
- Dom.addClass(this.element, this.CSS_CLASS_NAME);
- // Subscribe to Custom Events
- this.initEvent.subscribe(this._onInit);
- this.beforeRenderEvent.subscribe(this._onBeforeRender);
- this.renderEvent.subscribe(this._onRender);
- this.beforeShowEvent.subscribe(this._onBeforeShow);
- this.hideEvent.subscribe(this._onHide);
- this.showEvent.subscribe(this._onShow);
- this.beforeHideEvent.subscribe(this._onBeforeHide);
- this.mouseOverEvent.subscribe(this._onMouseOver);
- this.mouseOutEvent.subscribe(this._onMouseOut);
- this.clickEvent.subscribe(this._onClick);
- this.keyDownEvent.subscribe(this._onKeyDown);
- this.keyPressEvent.subscribe(this._onKeyPress);
- this.blurEvent.subscribe(this._onBlur);
- if (!bFocusListenerInitialized) {
- Event.onFocus(document, onDocFocus);
- bFocusListenerInitialized = true;
- }
- // Fixes an issue in Firefox 2 and Webkit where Dom's "getX" and "getY"
- // methods return values that don't take scrollTop into consideration
- if ((UA.gecko && UA.gecko < 1.9) || UA.webkit) {
- this.cfg.subscribeToConfigEvent(_Y, this._onYChange);
- }
- if (p_oConfig) {
-
- this.cfg.applyConfig(p_oConfig, true);
-
- }
- // Register the Menu instance with the MenuManager
- MenuManager.addMenu(this);
- this.initEvent.fire(Menu);
- }
- },
- // Private methods
- /**
- * @method _initSubTree
- * @description Iterates the childNodes of the source element to find nodes
- * used to instantiate menu and menu items.
- * @private
- */
- _initSubTree: function () {
- var oSrcElement = this.srcElement,
- sSrcElementTagName,
- nGroup,
- sGroupTitleTagName,
- oNode,
- aListElements,
- nListElements,
- i;
- if (oSrcElement) {
-
- sSrcElementTagName =
- (oSrcElement.tagName && oSrcElement.tagName.toUpperCase());
- if (sSrcElementTagName == _DIV_UPPERCASE) {
-
- // Populate the collection of item groups and item group titles
-
- oNode = this.body.firstChild;
-
- if (oNode) {
-
- nGroup = 0;
- sGroupTitleTagName = this.GROUP_TITLE_TAG_NAME.toUpperCase();
-
- do {
-
- if (oNode && oNode.tagName) {
-
- switch (oNode.tagName.toUpperCase()) {
-
- case sGroupTitleTagName:
-
- this._aGroupTitleElements[nGroup] = oNode;
-
- break;
-
- case _UL_UPPERCASE:
-
- this._aListElements[nGroup] = oNode;
- this._aItemGroups[nGroup] = [];
- nGroup++;
-
- break;
-
- }
-
- }
-
- }
- while ((oNode = oNode.nextSibling));
-
-
- /*
- Apply the "first-of-type" class to the first UL to mimic
- the ":first-of-type" CSS3 psuedo class.
- */
-
- if (this._aListElements[0]) {
-
- Dom.addClass(this._aListElements[0], _FIRST_OF_TYPE);
-
- }
-
- }
-
- }
-
-
- oNode = null;
-
- YAHOO.log("Searching DOM for items to initialize.", "info", this.toString());
-
- if (sSrcElementTagName) {
-
- switch (sSrcElementTagName) {
-
- case _DIV_UPPERCASE:
- aListElements = this._aListElements;
- nListElements = aListElements.length;
-
- if (nListElements > 0) {
-
- YAHOO.log("Found " + nListElements + " item groups to initialize.",
- "info", this.toString());
-
- i = nListElements - 1;
-
- do {
-
- oNode = aListElements[i].firstChild;
-
- if (oNode) {
- YAHOO.log("Scanning " +
- aListElements[i].childNodes.length +
- " child nodes for items to initialize.", "info", this.toString());
-
- do {
-
- if (oNode && oNode.tagName &&
- oNode.tagName.toUpperCase() == _LI) {
-
- YAHOO.log("Initializing " +
- oNode.tagName + " node.", "info", this.toString());
-
- this.addItem(new this.ITEM_TYPE(oNode,
- { parent: this }), i);
-
- }
-
- }
- while ((oNode = oNode.nextSibling));
-
- }
-
- }
- while (i--);
-
- }
-
- break;
-
- case _SELECT:
-
- YAHOO.log("Scanning " +
- oSrcElement.childNodes.length +
- " child nodes for items to initialize.", "info", this.toString());
-
- oNode = oSrcElement.firstChild;
-
- do {
-
- if (oNode && oNode.tagName) {
-
- switch (oNode.tagName.toUpperCase()) {
-
- case _OPTGROUP:
- case _OPTION:
-
- YAHOO.log("Initializing " +
- oNode.tagName + " node.", "info", this.toString());
-
- this.addItem(
- new this.ITEM_TYPE(
- oNode,
- { parent: this }
- )
- );
-
- break;
-
- }
-
- }
-
- }
- while ((oNode = oNode.nextSibling));
-
- break;
-
- }
-
- }
-
- }
- },
- /**
- * @method _getFirstEnabledItem
- * @description Returns the first enabled item in the menu.
- * @return {YAHOO.widget.MenuItem}
- * @private
- */
- _getFirstEnabledItem: function () {
- var aItems = this.getItems(),
- nItems = aItems.length,
- oItem,
- returnVal;
-
- for(var i=0; i<nItems; i++) {
- oItem = aItems[i];
- if (oItem && !oItem.cfg.getProperty(_DISABLED) && oItem.element.style.display != _NONE) {
- returnVal = oItem;
- break;
- }
-
- }
-
- return returnVal;
-
- },
- /**
- * @method _addItemToGroup
- * @description Adds a menu item to a group.
- * @private
- * @param {Number} p_nGroupIndex Number indicating the group to which the
- * item belongs.
- * @param {YAHOO.widget.MenuItem} p_oItem Object reference for the MenuItem
- * instance to be added to the menu.
- * @param {String} p_oItem String specifying the text of the item to be added
- * to the menu.
- * @param {Object} p_oItem Object literal containing a set of menu item
- * configuration properties.
- * @param {Number} p_nItemIndex Optional. Number indicating the index at
- * which the menu item should be added.
- * @return {YAHOO.widget.MenuItem}
- */
- _addItemToGroup: function (p_nGroupIndex, p_oItem, p_nItemIndex) {
- var oItem,
- nGroupIndex,
- aGroup,
- oGroupItem,
- bAppend,
- oNextItemSibling,
- nItemIndex,
- returnVal;
- function getNextItemSibling(p_aArray, p_nStartIndex) {
- return (p_aArray[p_nStartIndex] || getNextItemSibling(p_aArray, (p_nStartIndex+1)));
- }
- if (p_oItem instanceof this.ITEM_TYPE) {
- oItem = p_oItem;
- oItem.parent = this;
- }
- else if (Lang.isString(p_oItem)) {
- oItem = new this.ITEM_TYPE(p_oItem, { parent: this });
-
- }
- else if (Lang.isObject(p_oItem)) {
- p_oItem.parent = this;
- oItem = new this.ITEM_TYPE(p_oItem.text, p_oItem);
- }
- if (oItem) {
- if (oItem.cfg.getProperty(_SELECTED)) {
- this.activeItem = oItem;
-
- }
- nGroupIndex = Lang.isNumber(p_nGroupIndex) ? p_nGroupIndex : 0;
- aGroup = this._getItemGroup(nGroupIndex);
- if (!aGroup) {
- aGroup = this._createItemGroup(nGroupIndex);
- }
- if (Lang.isNumber(p_nItemIndex)) {
- bAppend = (p_nItemIndex >= aGroup.length);
- if (aGroup[p_nItemIndex]) {
-
- aGroup.splice(p_nItemIndex, 0, oItem);
-
- }
- else {
-
- aGroup[p_nItemIndex] = oItem;
-
- }
- oGroupItem = aGroup[p_nItemIndex];
- if (oGroupItem) {
- if (bAppend && (!oGroupItem.element.parentNode ||
- oGroupItem.element.parentNode.nodeType == 11)) {
-
- this._aListElements[nGroupIndex].appendChild(oGroupItem.element);
-
- }
- else {
-
- oNextItemSibling = getNextItemSibling(aGroup, (p_nItemIndex+1));
-
- if (oNextItemSibling && (!oGroupItem.element.parentNode ||
- oGroupItem.element.parentNode.nodeType == 11)) {
-
- this._aListElements[nGroupIndex].insertBefore(
- oGroupItem.element, oNextItemSibling.element);
-
- }
-
- }
-
- oGroupItem.parent = this;
-
- this._subscribeToItemEvents(oGroupItem);
-
- this._configureSubmenu(oGroupItem);
-
- this._updateItemProperties(nGroupIndex);
-
- YAHOO.log("Item inserted." +
- " Text: " + oGroupItem.cfg.getProperty("text") + ", " +
- " Index: " + oGroupItem.index + ", " +
- " Group Index: " + oGroupItem.groupIndex, "info", this.toString());
- this.itemAddedEvent.fire(oGroupItem);
- this.changeContentEvent.fire();
- returnVal = oGroupItem;
-
- }
- }
- else {
-
- nItemIndex = aGroup.length;
-
- aGroup[nItemIndex] = oItem;
- oGroupItem = aGroup[nItemIndex];
-
- if (oGroupItem) {
-
- if (!Dom.isAncestor(this._aListElements[nGroupIndex], oGroupItem.element)) {
-
- this._aListElements[nGroupIndex].appendChild(oGroupItem.element);
-
- }
-
- oGroupItem.element.setAttribute(_GROUP_INDEX, nGroupIndex);
- oGroupItem.element.setAttribute(_INDEX, nItemIndex);
-
- oGroupItem.parent = this;
-
- oGroupItem.index = nItemIndex;
- oGroupItem.groupIndex = nGroupIndex;
-
- this._subscribeToItemEvents(oGroupItem);
-
- this._configureSubmenu(oGroupItem);
-
- if (nItemIndex === 0) {
-
- Dom.addClass(oGroupItem.element, _FIRST_OF_TYPE);
-
- }
- YAHOO.log("Item added." +
- " Text: " + oGroupItem.cfg.getProperty("text") + ", " +
- " Index: " + oGroupItem.index + ", " +
- " Group Index: " + oGroupItem.groupIndex, "info", this.toString());
-
- this.itemAddedEvent.fire(oGroupItem);
- this.changeContentEvent.fire();
- returnVal = oGroupItem;
-
- }
-
- }
- }
-
- return returnVal;
-
- },
- /**
- * @method _removeItemFromGroupByIndex
- * @description Removes a menu item from a group by index. Returns the menu
- * item that was removed.
- * @private
- * @param {Number} p_nGroupIndex Number indicating the group to which the menu
- * item belongs.
- * @param {Number} p_nItemIndex Number indicating the index of the menu item
- * to be removed.
- * @return {YAHOO.widget.MenuItem}
- */
- _removeItemFromGroupByIndex: function (p_nGroupIndex, p_nItemIndex) {
- var nGroupIndex = Lang.isNumber(p_nGroupIndex) ? p_nGroupIndex : 0,
- aGroup = this._getItemGroup(nGroupIndex),
- aArray,
- oItem,
- oUL;
- if (aGroup) {
- aArray = aGroup.splice(p_nItemIndex, 1);
- oItem = aArray[0];
-
- if (oItem) {
-
- // Update the index and className properties of each member
-
- this._updateItemProperties(nGroupIndex);
-
- if (aGroup.length === 0) {
-
- // Remove the UL
-
- oUL = this._aListElements[nGroupIndex];
-
- if (this.body && oUL) {
-
- this.body.removeChild(oUL);
-
- }
-
- // Remove the group from the array of items
-
- this._aItemGroups.splice(nGroupIndex, 1);
-
-
- // Remove the UL from the array of ULs
-
- this._aListElements.splice(nGroupIndex, 1);
-
-
- /*
- Assign the "first-of-type" class to the new first UL
- in the collection
- */
-
- oUL = this._aListElements[0];
-
- if (oUL) {
-
- Dom.addClass(oUL, _FIRST_OF_TYPE);
-
- }
-
- }
-
- this.itemRemovedEvent.fire(oItem);
- this.changeContentEvent.fire();
-
- }
- }
- // Return a reference to the item that was removed
- return oItem;
-
- },
- /**
- * @method _removeItemFromGroupByValue
- * @description Removes a menu item from a group by reference. Returns the
- * menu item that was removed.
- * @private
- * @param {Number} p_nGroupIndex Number indicating the group to which the
- * menu item belongs.
- * @param {YAHOO.widget.MenuItem} p_oItem Object reference for the MenuItem
- * instance to be removed.
- * @return {YAHOO.widget.MenuItem}
- */
- _removeItemFromGroupByValue: function (p_nGroupIndex, p_oItem) {
- var aGroup = this._getItemGroup(p_nGroupIndex),
- nItems,
- nItemIndex,
- returnVal,
- i;
- if (aGroup) {
- nItems = aGroup.length;
- nItemIndex = -1;
-
- if (nItems > 0) {
-
- i = nItems-1;
-
- do {
-
- if (aGroup[i] == p_oItem) {
-
- nItemIndex = i;
- break;
-
- }
-
- }
- while (i--);
-
- if (nItemIndex > -1) {
-
- returnVal = this._removeItemFromGroupByIndex(p_nGroupIndex, nItemIndex);
-
- }
-
- }
-
- }
-
- return returnVal;
- },
- /**
- * @method _updateItemProperties
- * @description Updates the "index," "groupindex," and "className" properties
- * of the menu items in the specified group.
- * @private
- * @param {Number} p_nGroupIndex Number indicating the group of items to update.
- */
- _updateItemProperties: function (p_nGroupIndex) {
- var aGroup = this._getItemGroup(p_nGroupIndex),
- nItems = aGroup.length,
- oItem,
- oLI,
- i;
- if (nItems > 0) {
- i = nItems - 1;
- // Update the index and className properties of each member
-
- do {
- oItem = aGroup[i];
- if (oItem) {
-
- oLI = oItem.element;
- oItem.index = i;
- oItem.groupIndex = p_nGroupIndex;
- oLI.setAttribute(_GROUP_INDEX, p_nGroupIndex);
- oLI.setAttribute(_INDEX, i);
- Dom.removeClass(oLI, _FIRST_OF_TYPE);
- }
-
- }
- while (i--);
- if (oLI) {
- Dom.addClass(oLI, _FIRST_OF_TYPE);
- }
- }
- },
- /**
- * @method _createItemGroup
- * @description Creates a new menu item group (array) and its associated
- * <code><ul></code> element. Returns an aray of menu item groups.
- * @private
- * @param {Number} p_nIndex Number indicating the group to create.
- * @return {Array}
- */
- _createItemGroup: function (p_nIndex) {
- var oUL,
- returnVal;
- if (!this._aItemGroups[p_nIndex]) {
- this._aItemGroups[p_nIndex] = [];
- oUL = document.createElement(_UL_LOWERCASE);
- this._aListElements[p_nIndex] = oUL;
- returnVal = this._aItemGroups[p_nIndex];
- }
-
- return returnVal;
- },
- /**
- * @method _getItemGroup
- * @description Returns the menu item group at the specified index.
- * @private
- * @param {Number} p_nIndex Number indicating the index of the menu item group
- * to be retrieved.
- * @return {Array}
- */
- _getItemGroup: function (p_nIndex) {
- var nIndex = Lang.isNumber(p_nIndex) ? p_nIndex : 0,
- aGroups = this._aItemGroups,
- returnVal;
- if (nIndex in aGroups) {
- returnVal = aGroups[nIndex];
- }
-
- return returnVal;
- },
- /**
- * @method _configureSubmenu
- * @description Subscribes the menu item's submenu to its parent menu's events.
- * @private
- * @param {YAHOO.widget.MenuItem} p_oItem Object reference for the MenuItem
- * instance with the submenu to be configured.
- */
- _configureSubmenu: function (p_oItem) {
- var oSubmenu = p_oItem.cfg.getProperty(_SUBMENU);
- if (oSubmenu) {
-
- /*
- Listen for configuration changes to the parent menu
- so they they can be applied to the submenu.
- */
- this.cfg.configChangedEvent.subscribe(this._onParentMenuConfigChange, oSubmenu, true);
- this.renderEvent.subscribe(this._onParentMenuRender, oSubmenu, true);
- }
- },
- /**
- * @method _subscribeToItemEvents
- * @description Subscribes a menu to a menu item's event.
- * @private
- * @param {YAHOO.widget.MenuItem} p_oItem Object reference for the MenuItem
- * instance whose events should be subscribed to.
- */
- _subscribeToItemEvents: function (p_oItem) {
- p_oItem.destroyEvent.subscribe(this._onMenuItemDestroy, p_oItem, this);
- p_oItem.cfg.configChangedEvent.subscribe(this._onMenuItemConfigChange, p_oItem, this);
- },
- /**
- * @method _onVisibleChange
- * @description Change event handler for the the menu's "visible" configuration
- * property.
- * @private
- * @param {String} p_sType String representing the name of the event that
- * was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event was fired.
- */
- _onVisibleChange: function (p_sType, p_aArgs) {
- var bVisible = p_aArgs[0];
-
- if (bVisible) {
- Dom.addClass(this.element, _VISIBLE);
- }
- else {
- Dom.removeClass(this.element, _VISIBLE);
- }
- },
- /**
- * @method _cancelHideDelay
- * @description Cancels the call to "hideMenu."
- * @private
- */
- _cancelHideDelay: function () {
- var oTimer = this.getRoot()._hideDelayTimer;
- if (oTimer) {
- oTimer.cancel();
- }
- },
- /**
- * @method _execHideDelay
- * @description Hides the menu after the number of milliseconds specified by
- * the "hidedelay" configuration property.
- * @private
- */
- _execHideDelay: function () {
- this._cancelHideDelay();
- var oRoot = this.getRoot();
-
- oRoot._hideDelayTimer = Lang.later(oRoot.cfg.getProperty(_HIDE_DELAY), this, function () {
-
- if (oRoot.activeItem) {
- if (oRoot.hasFocus()) {
- oRoot.activeItem.focus();
-
- }
-
- oRoot.clearActiveItem();
- }
- if (oRoot == this && !(this instanceof YAHOO.widget.MenuBar) &&
- this.cfg.getProperty(_POSITION) == _DYNAMIC) {
- this.hide();
-
- }
-
- });
- },
- /**
- * @method _cancelShowDelay
- * @description Cancels the call to the "showMenu."
- * @private
- */
- _cancelShowDelay: function () {
- var oTimer = this.getRoot()._showDelayTimer;
- if (oTimer) {
- oTimer.cancel();
- }
- },
- /**
- * @method _execSubmenuHideDelay
- * @description Hides a submenu after the number of milliseconds specified by
- * the "submenuhidedelay" configuration property have ellapsed.
- * @private
- * @param {YAHOO.widget.Menu} p_oSubmenu Object specifying the submenu that
- * should be hidden.
- * @param {Number} p_nMouseX The x coordinate of the mouse when it left
- * the specified submenu's parent menu item.
- * @param {Number} p_nHideDelay The number of milliseconds that should ellapse
- * before the submenu is hidden.
- */
- _execSubmenuHideDelay: function (p_oSubmenu, p_nMouseX, p_nHideDelay) {
- p_oSubmenu._submenuHideDelayTimer = Lang.later(50, this, function () {
- if (this._nCurrentMouseX > (p_nMouseX + 10)) {
- p_oSubmenu._submenuHideDelayTimer = Lang.later(p_nHideDelay, p_oSubmenu, function () {
-
- this.hide();
- });
- }
- else {
- p_oSubmenu.hide();
-
- }
-
- });
- },
- // Protected methods
- /**
- * @method _disableScrollHeader
- * @description Disables the header used for scrolling the body of the menu.
- * @protected
- */
- _disableScrollHeader: function () {
- if (!this._bHeaderDisabled) {
- Dom.addClass(this.header, _TOP_SCROLLBAR_DISABLED);
- this._bHeaderDisabled = true;
- }
- },
- /**
- * @method _disableScrollFooter
- * @description Disables the footer used for scrolling the body of the menu.
- * @protected
- */
- _disableScrollFooter: function () {
- if (!this._bFooterDisabled) {
- Dom.addClass(this.footer, _BOTTOM_SCROLLBAR_DISABLED);
- this._bFooterDisabled = true;
- }
- },
- /**
- * @method _enableScrollHeader
- * @description Enables the header used for scrolling the body of the menu.
- * @protected
- */
- _enableScrollHeader: function () {
- if (this._bHeaderDisabled) {
- Dom.removeClass(this.header, _TOP_SCROLLBAR_DISABLED);
- this._bHeaderDisabled = false;
- }
- },
- /**
- * @method _enableScrollFooter
- * @description Enables the footer used for scrolling the body of the menu.
- * @protected
- */
- _enableScrollFooter: function () {
- if (this._bFooterDisabled) {
- Dom.removeClass(this.footer, _BOTTOM_SCROLLBAR_DISABLED);
- this._bFooterDisabled = false;
- }
- },
- /**
- * @method _onMouseOver
- * @description "mouseover" event handler for the menu.
- * @protected
- * @param {String} p_sType String representing the name of the event that
- * was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event was fired.
- */
- _onMouseOver: function (p_sType, p_aArgs) {
- var oEvent = p_aArgs[0],
- oItem = p_aArgs[1],
- oTarget = Event.getTarget(oEvent),
- oRoot = this.getRoot(),
- oSubmenuHideDelayTimer = this._submenuHideDelayTimer,
- oParentMenu,
- nShowDelay,
- bShowDelay,
- oActiveItem,
- oItemCfg,
- oSubmenu;
- var showSubmenu = function () {
- if (this.parent.cfg.getProperty(_SELECTED)) {
- this.show();
- }
- };
- if (!this._bStopMouseEventHandlers) {
-
- if (!this._bHandledMouseOverEvent && (oTarget == this.element ||
- Dom.isAncestor(this.element, oTarget))) {
-
- // Menu mouseover logic
- if (this._useHideDelay) {
- this._cancelHideDelay();
- }
-
- this._nCurrentMouseX = 0;
-
- Event.on(this.element, _MOUSEMOVE, this._onMouseMove, this, true);
- /*
- If the mouse is moving from the submenu back to its corresponding menu item,
- don't hide the submenu or clear the active MenuItem.
- */
- if (!(oItem && Dom.isAncestor(oItem.element, Event.getRelatedTarget(oEvent)))) {
- this.clearActiveItem();
- }
-
- if (this.parent && oSubmenuHideDelayTimer) {
-
- oSubmenuHideDelayTimer.cancel();
-
- this.parent.cfg.setProperty(_SELECTED, true);
-
- oParentMenu = this.parent.parent;
-
- oParentMenu._bHandledMouseOutEvent = true;
- oParentMenu._bHandledMouseOverEvent = false;
-
- }
-
-
- this._bHandledMouseOverEvent = true;
- this._bHandledMouseOutEvent = false;
-
- }
-
-
- if (oItem && !oItem.handledMouseOverEvent && !oItem.cfg.getProperty(_DISABLED) &&
- (oTarget == oItem.element || Dom.isAncestor(oItem.element, oTarget))) {
-
- // Menu Item mouseover logic
-
- nShowDelay = this.cfg.getProperty(_SHOW_DELAY);
- bShowDelay = (nShowDelay > 0);
-
-
- if (bShowDelay) {
-
- this._cancelShowDelay();
-
- }
-
-
- oActiveItem = this.activeItem;
-
- if (oActiveItem) {
-
- oActiveItem.cfg.setProperty(_SELECTED, false);
-
- }
-
-
- oItemCfg = oItem.cfg;
-
- // Select and focus the current menu item
-
- oItemCfg.setProperty(_SELECTED, true);
-
-
- if (this.hasFocus() || oRoot._hasFocus) {
-
- oItem.focus();
-
- oRoot._hasFocus = false;
-
- }
-
-
- if (this.cfg.getProperty(_AUTO_SUBMENU_DISPLAY)) {
-
- // Show the submenu this menu item
-
- oSubmenu = oItemCfg.getProperty(_SUBMENU);
-
- if (oSubmenu) {
-
- if (bShowDelay) {
-
- oRoot._showDelayTimer =
- Lang.later(oRoot.cfg.getProperty(_SHOW_DELAY), oSubmenu, showSubmenu);
-
- }
- else {
-
- oSubmenu.show();
-
- }
-
- }
-
- }
-
- oItem.handledMouseOverEvent = true;
- oItem.handledMouseOutEvent = false;
-
- }
-
- }
- },
- /**
- * @method _onMouseOut
- * @description "mouseout" event handler for the menu.
- * @protected
- * @param {String} p_sType String representing the name of the event that
- * was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event was fired.
- */
- _onMouseOut: function (p_sType, p_aArgs) {
- var oEvent = p_aArgs[0],
- oItem = p_aArgs[1],
- oRelatedTarget = Event.getRelatedTarget(oEvent),
- bMovingToSubmenu = false,
- oItemCfg,
- oSubmenu,
- nSubmenuHideDelay,
- nShowDelay;
- if (!this._bStopMouseEventHandlers) {
-
- if (oItem && !oItem.cfg.getProperty(_DISABLED)) {
-
- oItemCfg = oItem.cfg;
- oSubmenu = oItemCfg.getProperty(_SUBMENU);
-
-
- if (oSubmenu && (oRelatedTarget == oSubmenu.element ||
- Dom.isAncestor(oSubmenu.element, oRelatedTarget))) {
-
- bMovingToSubmenu = true;
-
- }
-
-
- if (!oItem.handledMouseOutEvent && ((oRelatedTarget != oItem.element &&
- !Dom.isAncestor(oItem.element, oRelatedTarget)) || bMovingToSubmenu)) {
-
- // Menu Item mouseout logic
-
- if (!bMovingToSubmenu) {
-
- oItem.cfg.setProperty(_SELECTED, false);
-
-
- if (oSubmenu) {
-
- nSubmenuHideDelay = this.cfg.getProperty(_SUBMENU_HIDE_DELAY);
-
- nShowDelay = this.cfg.getProperty(_SHOW_DELAY);
-
- if (!(this instanceof YAHOO.widget.MenuBar) && nSubmenuHideDelay > 0 &&
- nShowDelay >= nSubmenuHideDelay) {
-
- this._execSubmenuHideDelay(oSubmenu, Event.getPageX(oEvent),
- nSubmenuHideDelay);
-
- }
- else {
-
- oSubmenu.hide();
-
- }
-
- }
-
- }
-
-
- oItem.handledMouseOutEvent = true;
- oItem.handledMouseOverEvent = false;
-
- }
-
- }
- if (!this._bHandledMouseOutEvent && ((oRelatedTarget != this.element &&
- !Dom.isAncestor(this.element, oRelatedTarget)) || bMovingToSubmenu)) {
-
- // Menu mouseout logic
- if (this._useHideDelay) {
- this._execHideDelay();
- }
- Event.removeListener(this.element, _MOUSEMOVE, this._onMouseMove);
-
- this._nCurrentMouseX = Event.getPageX(oEvent);
-
- this._bHandledMouseOutEvent = true;
- this._bHandledMouseOverEvent = false;
-
- }
-
- }
- },
- /**
- * @method _onMouseMove
- * @description "click" event handler for the menu.
- * @protected
- * @param {Event} p_oEvent Object representing the DOM event object passed
- * back by the event utility (YAHOO.util.Event).
- * @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that
- * fired the event.
- */
- _onMouseMove: function (p_oEvent, p_oMenu) {
- if (!this._bStopMouseEventHandlers) {
-
- this._nCurrentMouseX = Event.getPageX(p_oEvent);
-
- }
- },
- /**
- * @method _onClick
- * @description "click" event handler for the menu.
- * @protected
- * @param {String} p_sType String representing the name of the event that
- * was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event was fired.
- */
- _onClick: function (p_sType, p_aArgs) {
- var oEvent = p_aArgs[0],
- oItem = p_aArgs[1],
- bInMenuAnchor = false,
- oSubmenu,
- oMenu,
- oRoot,
- sId,
- sURL,
- nHashPos,
- nLen;
- var hide = function () {
-
- oRoot = this.getRoot();
- if (oRoot instanceof YAHOO.widget.MenuBar ||
- oRoot.cfg.getProperty(_POSITION) == _STATIC) {
- oRoot.clearActiveItem();
- }
- else {
- oRoot.hide();
-
- }
-
- };
- if (oItem) {
-
- if (oItem.cfg.getProperty(_DISABLED)) {
-
- Event.preventDefault(oEvent);
- hide.call(this);
- }
- else {
- oSubmenu = oItem.cfg.getProperty(_SUBMENU);
-
-
- /*
- Check if the URL of the anchor is pointing to an element that is
- a child of the menu.
- */
-
- sURL = oItem.cfg.getProperty(_URL);
-
- if (sURL) {
-
- nHashPos = sURL.indexOf(_HASH);
-
- nLen = sURL.length;
-
-
- if (nHashPos != -1) {
-
- sURL = sURL.substr(nHashPos, nLen);
-
- nLen = sURL.length;
-
-
- if (nLen > 1) {
-
- sId = sURL.substr(1, nLen);
-
- oMenu = YAHOO.widget.MenuManager.getMenu(sId);
-
- if (oMenu) {
- bInMenuAnchor =
- (this.getRoot() === oMenu.getRoot());
- }
-
- }
- else if (nLen === 1) {
-
- bInMenuAnchor = true;
-
- }
-
- }
-
- }
-
- if (bInMenuAnchor && !oItem.cfg.getProperty(_TARGET)) {
-
- Event.preventDefault(oEvent);
-
- if (UA.webkit) {
-
- oItem.focus();
-
- }
- else {
- oItem.focusEvent.fire();
-
- }
-
- }
-
-
- if (!oSubmenu && !this.cfg.getProperty(_KEEP_OPEN)) {
-
- hide.call(this);
-
- }
-
- }
-
- }
- },
- /**
- * @method _onKeyDown
- * @description "keydown" event handler for the menu.
- * @protected
- * @param {String} p_sType String representing the name of the event that
- * was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event was fired.
- */
- _onKeyDown: function (p_sType, p_aArgs) {
- var oEvent = p_aArgs[0],
- oItem = p_aArgs[1],
- oSubmenu,
- oItemCfg,
- oParentItem,
- oRoot,
- oNextItem,
- oBody,
- nBodyScrollTop,
- nBodyOffsetHeight,
- aItems,
- nItems,
- nNextItemOffsetTop,
- nScrollTarget,
- oParentMenu,
- oFocusedEl;
- if (this._useHideDelay) {
- this._cancelHideDelay();
- }
- /*
- This function is called to prevent a bug in Firefox. In Firefox,
- moving a DOM element into a stationary mouse pointer will cause the
- browser to fire mouse events. This can result in the menu mouse
- event handlers being called uncessarily, especially when menus are
- moved into a stationary mouse pointer as a result of a
- key event handler.
- */
- function stopMouseEventHandlers() {
- this._bStopMouseEventHandlers = true;
-
- Lang.later(10, this, function () {
- this._bStopMouseEventHandlers = false;
-
- });
- }
- if (oItem && !oItem.cfg.getProperty(_DISABLED)) {
- oItemCfg = oItem.cfg;
- oParentItem = this.parent;
- switch(oEvent.keyCode) {
-
- case 38: // Up arrow
- case 40: // Down arrow
-
- oNextItem = (oEvent.keyCode == 38) ?
- oItem.getPreviousEnabledSibling() :
- oItem.getNextEnabledSibling();
-
- if (oNextItem) {
- this.clearActiveItem();
- oNextItem.cfg.setProperty(_SELECTED, true);
- oNextItem.focus();
- if (this.cfg.getProperty(_MAX_HEIGHT) > 0) {
- oBody = this.body;
- nBodyScrollTop = oBody.scrollTop;
- nBodyOffsetHeight = oBody.offsetHeight;
- aItems = this.getItems();
- nItems = aItems.length - 1;
- nNextItemOffsetTop = oNextItem.element.offsetTop;
- if (oEvent.keyCode == 40 ) { // Down
-
- if (nNextItemOffsetTop >= (nBodyOffsetHeight + nBodyScrollTop)) {
- oBody.scrollTop = nNextItemOffsetTop - nBodyOffsetHeight;
- }
- else if (nNextItemOffsetTop <= nBodyScrollTop) {
-
- oBody.scrollTop = 0;
-
- }
- if (oNextItem == aItems[nItems]) {
- oBody.scrollTop = oNextItem.element.offsetTop;
- }
- }
- else { // Up
- if (nNextItemOffsetTop <= nBodyScrollTop) {
- oBody.scrollTop = nNextItemOffsetTop - oNextItem.element.offsetHeight;
-
- }
- else if (nNextItemOffsetTop >= (nBodyScrollTop + nBodyOffsetHeight)) {
-
- oBody.scrollTop = nNextItemOffsetTop;
-
- }
- if (oNextItem == aItems[0]) {
-
- oBody.scrollTop = 0;
-
- }
- }
- nBodyScrollTop = oBody.scrollTop;
- nScrollTarget = oBody.scrollHeight - oBody.offsetHeight;
- if (nBodyScrollTop === 0) {
- this._disableScrollHeader();
- this._enableScrollFooter();
- }
- else if (nBodyScrollTop == nScrollTarget) {
- this._enableScrollHeader();
- this._disableScrollFooter();
- }
- else {
- this._enableScrollHeader();
- this._enableScrollFooter();
- }
- }
- }
-
- Event.preventDefault(oEvent);
- stopMouseEventHandlers();
-
- break;
-
-
- case 39: // Right arrow
-
- oSubmenu = oItemCfg.getProperty(_SUBMENU);
-
- if (oSubmenu) {
-
- if (!oItemCfg.getProperty(_SELECTED)) {
-
- oItemCfg.setProperty(_SELECTED, true);
-
- }
-
- oSubmenu.show();
- oSubmenu.setInitialFocus();
- oSubmenu.setInitialSelection();
-
- }
- else {
-
- oRoot = this.getRoot();
-
- if (oRoot instanceof YAHOO.widget.MenuBar) {
-
- oNextItem = oRoot.activeItem.getNextEnabledSibling();
-
- if (oNextItem) {
-
- oRoot.clearActiveItem();
-
- oNextItem.cfg.setProperty(_SELECTED, true);
-
- oSubmenu = oNextItem.cfg.getProperty(_SUBMENU);
-
- if (oSubmenu) {
-
- oSubmenu.show();
- oSubmenu.setInitialFocus();
-
- }
- else {
-
- oNextItem.focus();
-
- }
-
- }
-
- }
-
- }
-
-
- Event.preventDefault(oEvent);
- stopMouseEventHandlers();
- break;
-
-
- case 37: // Left arrow
-
- if (oParentItem) {
-
- oParentMenu = oParentItem.parent;
-
- if (oParentMenu instanceof YAHOO.widget.MenuBar) {
-
- oNextItem =
- oParentMenu.activeItem.getPreviousEnabledSibling();
-
- if (oNextItem) {
-
- oParentMenu.clearActiveItem();
-
- oNextItem.cfg.setProperty(_SELECTED, true);
-
- oSubmenu = oNextItem.cfg.getProperty(_SUBMENU);
-
- if (oSubmenu) {
-
- oSubmenu.show();
- oSubmenu.setInitialFocus();
-
- }
- else {
-
- oNextItem.focus();
-
- }
-
- }
-
- }
- else {
-
- this.hide();
-
- oParentItem.focus();
-
- }
-
- }
-
- Event.preventDefault(oEvent);
- stopMouseEventHandlers();
- break;
-
- }
- }
- if (oEvent.keyCode == 27) { // Esc key
- if (this.cfg.getProperty(_POSITION) == _DYNAMIC) {
-
- this.hide();
- if (this.parent) {
- this.parent.focus();
-
- }
- else {
- // Focus the element that previously had focus
- oFocusedEl = this._focusedElement;
- if (oFocusedEl && oFocusedEl.focus) {
- try {
- oFocusedEl.focus();
- }
- catch(ex) {
- }
- }
-
- }
- }
- else if (this.activeItem) {
- oSubmenu = this.activeItem.cfg.getProperty(_SUBMENU);
- if (oSubmenu && oSubmenu.cfg.getProperty(_VISIBLE)) {
-
- oSubmenu.hide();
- this.activeItem.focus();
-
- }
- else {
- this.activeItem.blur();
- this.activeItem.cfg.setProperty(_SELECTED, false);
-
- }
-
- }
- Event.preventDefault(oEvent);
-
- }
-
- },
- /**
- * @method _onKeyPress
- * @description "keypress" event handler for a Menu instance.
- * @protected
- * @param {String} p_sType The name of the event that was fired.
- * @param {Array} p_aArgs Collection of arguments sent when the event
- * was fired.
- */
- _onKeyPress: function (p_sType, p_aArgs) {
-
- var oEvent = p_aArgs[0];
- if (oEvent.keyCode == 40 || oEvent.keyCode == 38) {
- Event.preventDefault(oEvent);
- }
- },
- /**
- * @method _onBlur
- * @description "blur" event handler for a Menu instance.
- * @protected
- * @param {String} p_sType The name of the event that was fired.
- * @param {Array} p_aArgs Collection of arguments sent when the event
- * was fired.
- */
- _onBlur: function (p_sType, p_aArgs) {
-
- if (this._hasFocus) {
- this._hasFocus = false;
- }
- },
- /**
- * @method _onYChange
- * @description "y" event handler for a Menu instance.
- * @protected
- * @param {String} p_sType The name of the event that was fired.
- * @param {Array} p_aArgs Collection of arguments sent when the event
- * was fired.
- */
- _onYChange: function (p_sType, p_aArgs) {
- var oParent = this.parent,
- nScrollTop,
- oIFrame,
- nY;
- if (oParent) {
- nScrollTop = oParent.parent.body.scrollTop;
- if (nScrollTop > 0) {
-
- nY = (this.cfg.getProperty(_Y) - nScrollTop);
-
- Dom.setY(this.element, nY);
- oIFrame = this.iframe;
-
- if (oIFrame) {
-
- Dom.setY(oIFrame, nY);
-
- }
-
- this.cfg.setProperty(_Y, nY, true);
-
- }
-
- }
- },
- /**
- * @method _onScrollTargetMouseOver
- * @description "mouseover" event handler for the menu's "header" and "footer"
- * elements. Used to scroll the body of the menu up and down when the
- * menu's "maxheight" configuration property is set to a value greater than 0.
- * @protected
- * @param {Event} p_oEvent Object representing the DOM event object passed
- * back by the event utility (YAHOO.util.Event).
- * @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that
- * fired the event.
- */
- _onScrollTargetMouseOver: function (p_oEvent, p_oMenu) {
- var oBodyScrollTimer = this._bodyScrollTimer;
- if (oBodyScrollTimer) {
- oBodyScrollTimer.cancel();
- }
- this._cancelHideDelay();
- var oTarget = Event.getTarget(p_oEvent),
- oBody = this.body,
- nScrollIncrement = this.cfg.getProperty(_SCROLL_INCREMENT),
- nScrollTarget,
- fnScrollFunction;
- function scrollBodyDown() {
- var nScrollTop = oBody.scrollTop;
- if (nScrollTop < nScrollTarget) {
- oBody.scrollTop = (nScrollTop + nScrollIncrement);
- this._enableScrollHeader();
- }
- else {
- oBody.scrollTop = nScrollTarget;
- this._bodyScrollTimer.cancel();
- this._disableScrollFooter();
- }
- }
- function scrollBodyUp() {
- var nScrollTop = oBody.scrollTop;
- if (nScrollTop > 0) {
- oBody.scrollTop = (nScrollTop - nScrollIncrement);
- this._enableScrollFooter();
- }
- else {
- oBody.scrollTop = 0;
- this._bodyScrollTimer.cancel();
- this._disableScrollHeader();
- }
- }
-
- if (Dom.hasClass(oTarget, _HD)) {
- fnScrollFunction = scrollBodyUp;
-
- }
- else {
- nScrollTarget = oBody.scrollHeight - oBody.offsetHeight;
- fnScrollFunction = scrollBodyDown;
-
- }
-
- this._bodyScrollTimer = Lang.later(10, this, fnScrollFunction, null, true);
- },
- /**
- * @method _onScrollTargetMouseOut
- * @description "mouseout" event handler for the menu's "header" and "footer"
- * elements. Used to stop scrolling the body of the menu up and down when the
- * menu's "maxheight" configuration property is set to a value greater than 0.
- * @protected
- * @param {Event} p_oEvent Object representing the DOM event object passed
- * back by the event utility (YAHOO.util.Event).
- * @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that
- * fired the event.
- */
- _onScrollTargetMouseOut: function (p_oEvent, p_oMenu) {
- var oBodyScrollTimer = this._bodyScrollTimer;
- if (oBodyScrollTimer) {
- oBodyScrollTimer.cancel();
- }
-
- this._cancelHideDelay();
- },
- // Private methods
- /**
- * @method _onInit
- * @description "init" event handler for the menu.
- * @private
- * @param {String} p_sType String representing the name of the event that
- * was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event was fired.
- */
- _onInit: function (p_sType, p_aArgs) {
- this.cfg.subscribeToConfigEvent(_VISIBLE, this._onVisibleChange);
- var bRootMenu = !this.parent,
- bLazyLoad = this.lazyLoad;
- /*
- Automatically initialize a menu's subtree if:
- 1) This is the root menu and lazyload is off
-
- 2) This is the root menu, lazyload is on, but the menu is
- already visible
- 3) This menu is a submenu and lazyload is off
- */
- if (((bRootMenu && !bLazyLoad) ||
- (bRootMenu && (this.cfg.getProperty(_VISIBLE) ||
- this.cfg.getProperty(_POSITION) == _STATIC)) ||
- (!bRootMenu && !bLazyLoad)) && this.getItemGroups().length === 0) {
- if (this.srcElement) {
- this._initSubTree();
-
- }
- if (this.itemData) {
- this.addItems(this.itemData);
- }
-
- }
- else if (bLazyLoad) {
- this.cfg.fireQueue();
-
- }
- },
- /**
- * @method _onBeforeRender
- * @description "beforerender" event handler for the menu. Appends all of the
- * <code><ul></code>, <code><li></code> and their accompanying
- * title elements to the body element of the menu.
- * @private
- * @param {String} p_sType String representing the name of the event that
- * was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event was fired.
- */
- _onBeforeRender: function (p_sType, p_aArgs) {
- var oEl = this.element,
- nListElements = this._aListElements.length,
- bFirstList = true,
- i = 0,
- oUL,
- oGroupTitle;
- if (nListElements > 0) {
- do {
- oUL = this._aListElements[i];
- if (oUL) {
- if (bFirstList) {
-
- Dom.addClass(oUL, _FIRST_OF_TYPE);
- bFirstList = false;
-
- }
- if (!Dom.isAncestor(oEl, oUL)) {
- this.appendToBody(oUL);
- }
- oGroupTitle = this._aGroupTitleElements[i];
- if (oGroupTitle) {
- if (!Dom.isAncestor(oEl, oGroupTitle)) {
- oUL.parentNode.insertBefore(oGroupTitle, oUL);
- }
- Dom.addClass(oUL, _HAS_TITLE);
- }
- }
- i++;
- }
- while (i < nListElements);
- }
- },
- /**
- * @method _onRender
- * @description "render" event handler for the menu.
- * @private
- * @param {String} p_sType String representing the name of the event that
- * was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event was fired.
- */
- _onRender: function (p_sType, p_aArgs) {
- if (this.cfg.getProperty(_POSITION) == _DYNAMIC) {
- if (!this.cfg.getProperty(_VISIBLE)) {
- this.positionOffScreen();
- }
-
- }
- },
- /**
- * @method _onBeforeShow
- * @description "beforeshow" event handler for the menu.
- * @private
- * @param {String} p_sType String representing the name of the event that
- * was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event was fired.
- */
- _onBeforeShow: function (p_sType, p_aArgs) {
- var nOptions,
- n,
- oSrcElement,
- oContainer = this.cfg.getProperty(_CONTAINER);
- if (this.lazyLoad && this.getItemGroups().length === 0) {
- if (this.srcElement) {
-
- this._initSubTree();
- }
- if (this.itemData) {
- if (this.parent && this.parent.parent &&
- this.parent.parent.srcElement &&
- this.parent.parent.srcElement.tagName.toUpperCase() ==
- _SELECT) {
- nOptions = this.itemData.length;
-
- for(n=0; n<nOptions; n++) {
- if (this.itemData[n].tagName) {
- this.addItem((new this.ITEM_TYPE(this.itemData[n])));
-
- }
-
- }
-
- }
- else {
- this.addItems(this.itemData);
-
- }
-
- }
- oSrcElement = this.srcElement;
- if (oSrcElement) {
- if (oSrcElement.tagName.toUpperCase() == _SELECT) {
- if (Dom.inDocument(oSrcElement)) {
- this.render(oSrcElement.parentNode);
-
- }
- else {
-
- this.render(oContainer);
-
- }
- }
- else {
- this.render();
- }
- }
- else {
- if (this.parent) {
- this.render(this.parent.element);
- }
- else {
- this.render(oContainer);
- }
- }
- }
- var oParent = this.parent,
- aAlignment;
- if (!oParent && this.cfg.getProperty(_POSITION) == _DYNAMIC) {
- this.cfg.refireEvent(_XY);
-
- }
- if (oParent) {
- aAlignment = oParent.parent.cfg.getProperty(_SUBMENU_ALIGNMENT);
-
- this.cfg.setProperty(_CONTEXT, [oParent.element, aAlignment[0], aAlignment[1]]);
- this.align();
-
- }
- },
- getConstrainedY: function (y) {
- var oMenu = this,
-
- aContext = oMenu.cfg.getProperty(_CONTEXT),
- nInitialMaxHeight = oMenu.cfg.getProperty(_MAX_HEIGHT),
- nMaxHeight,
- oOverlapPositions = {
- "trbr": true,
- "tlbl": true,
- "bltl": true,
- "brtr": true
- },
- bPotentialContextOverlap = (aContext && oOverlapPositions[aContext[1] + aContext[2]]),
-
- oMenuEl = oMenu.element,
- nMenuOffsetHeight = oMenuEl.offsetHeight,
-
- nViewportOffset = Overlay.VIEWPORT_OFFSET,
- viewPortHeight = Dom.getViewportHeight(),
- scrollY = Dom.getDocumentScrollTop(),
- bCanConstrain =
- (oMenu.cfg.getProperty(_MIN_SCROLL_HEIGHT) + nViewportOffset < viewPortHeight),
- nAvailableHeight,
- oContextEl,
- nContextElY,
- nContextElHeight,
- bFlipped = false,
- nTopRegionHeight,
- nBottomRegionHeight,
- topConstraint = scrollY + nViewportOffset,
- bottomConstraint = scrollY + viewPortHeight - nMenuOffsetHeight - nViewportOffset,
- yNew = y;
-
- var flipVertical = function () {
- var nNewY;
-
- // The Menu is below the context element, flip it above
- if ((oMenu.cfg.getProperty(_Y) - scrollY) > nContextElY) {
- nNewY = (nContextElY - nMenuOffsetHeight);
- }
- else { // The Menu is above the context element, flip it below
- nNewY = (nContextElY + nContextElHeight);
- }
- oMenu.cfg.setProperty(_Y, (nNewY + scrollY), true);
-
- return nNewY;
-
- };
- /*
- Uses the context element's position to calculate the availble height
- above and below it to display its corresponding Menu.
- */
- var getDisplayRegionHeight = function () {
- // The Menu is below the context element
- if ((oMenu.cfg.getProperty(_Y) - scrollY) > nContextElY) {
- return (nBottomRegionHeight - nViewportOffset);
- }
- else { // The Menu is above the context element
- return (nTopRegionHeight - nViewportOffset);
- }
- };
- /*
- Sets the Menu's "y" configuration property to the correct value based on its
- current orientation.
- */
- var alignY = function () {
- var nNewY;
- if ((oMenu.cfg.getProperty(_Y) - scrollY) > nContextElY) {
- nNewY = (nContextElY + nContextElHeight);
- }
- else {
- nNewY = (nContextElY - oMenuEl.offsetHeight);
- }
- oMenu.cfg.setProperty(_Y, (nNewY + scrollY), true);
-
- };
- // Resets the maxheight of the Menu to the value set by the user
- var resetMaxHeight = function () {
- oMenu._setScrollHeight(this.cfg.getProperty(_MAX_HEIGHT));
- oMenu.hideEvent.unsubscribe(resetMaxHeight);
-
- };
- /*
- Trys to place the Menu in the best possible position (either above or
- below its corresponding context element).
- */
- var setVerticalPosition = function () {
- var nDisplayRegionHeight = getDisplayRegionHeight(),
- bMenuHasItems = (oMenu.getItems().length > 0),
- nMenuMinScrollHeight,
- fnReturnVal;
- if (nMenuOffsetHeight > nDisplayRegionHeight) {
- nMenuMinScrollHeight =
- bMenuHasItems ? oMenu.cfg.getProperty(_MIN_SCROLL_HEIGHT) : nMenuOffsetHeight;
- if ((nDisplayRegionHeight > nMenuMinScrollHeight) && bMenuHasItems) {
- nMaxHeight = nDisplayRegionHeight;
- }
- else {
- nMaxHeight = nInitialMaxHeight;
- }
- oMenu._setScrollHeight(nMaxHeight);
- oMenu.hideEvent.subscribe(resetMaxHeight);
-
- // Re-align the Menu since its height has just changed
- // as a result of the setting of the maxheight property.
- alignY();
-
- if (nDisplayRegionHeight < nMenuMinScrollHeight) {
- if (bFlipped) {
-
- /*
- All possible positions and values for the "maxheight"
- configuration property have been tried, but none were
- successful, so fall back to the original size and position.
- */
- flipVertical();
-
- }
- else {
-
- flipVertical();
- bFlipped = true;
-
- fnReturnVal = setVerticalPosition();
-
- }
-
- }
-
- }
- else if (nMaxHeight && (nMaxHeight !== nInitialMaxHeight)) {
-
- oMenu._setScrollHeight(nInitialMaxHeight);
- oMenu.hideEvent.subscribe(resetMaxHeight);
- // Re-align the Menu since its height has just changed
- // as a result of the setting of the maxheight property.
- alignY();
-
- }
- return fnReturnVal;
- };
- // Determine if the current value for the Menu's "y" configuration property will
- // result in the Menu being positioned outside the boundaries of the viewport
- if (y < topConstraint || y > bottomConstraint) {
- // The current value for the Menu's "y" configuration property WILL
- // result in the Menu being positioned outside the boundaries of the viewport
- if (bCanConstrain) {
- if (oMenu.cfg.getProperty(_PREVENT_CONTEXT_OVERLAP) && bPotentialContextOverlap) {
-
- // SOLUTION #1:
- // If the "preventcontextoverlap" configuration property is set to "true",
- // try to flip and/or scroll the Menu to both keep it inside the boundaries of the
- // viewport AND from overlaping its context element (MenuItem or MenuBarItem).
- oContextEl = aContext[0];
- nContextElHeight = oContextEl.offsetHeight;
- nContextElY = (Dom.getY(oContextEl) - scrollY);
-
- nTopRegionHeight = nContextElY;
- nBottomRegionHeight = (viewPortHeight - (nContextElY + nContextElHeight));
-
- setVerticalPosition();
-
- yNew = oMenu.cfg.getProperty(_Y);
-
- }
- else if (!(oMenu instanceof YAHOO.widget.MenuBar) &&
- nMenuOffsetHeight >= viewPortHeight) {
- // SOLUTION #2:
- // If the Menu exceeds the height of the viewport, introduce scroll bars
- // to keep the Menu inside the boundaries of the viewport
- nAvailableHeight = (viewPortHeight - (nViewportOffset * 2));
-
- if (nAvailableHeight > oMenu.cfg.getProperty(_MIN_SCROLL_HEIGHT)) {
-
- oMenu._setScrollHeight(nAvailableHeight);
- oMenu.hideEvent.subscribe(resetMaxHeight);
-
- alignY();
-
- yNew = oMenu.cfg.getProperty(_Y);
-
- }
-
- }
- else {
- // SOLUTION #3:
-
- if (y < topConstraint) {
- yNew = topConstraint;
- } else if (y > bottomConstraint) {
- yNew = bottomConstraint;
- }
-
- }
- }
- else {
- // The "y" configuration property cannot be set to a value that will keep
- // entire Menu inside the boundary of the viewport. Therefore, set
- // the "y" configuration property to scrollY to keep as much of the
- // Menu inside the viewport as possible.
- yNew = nViewportOffset + scrollY;
- }
- }
- return yNew;
- },
- /**
- * @method _onHide
- * @description "hide" event handler for the menu.
- * @private
- * @param {String} p_sType String representing the name of the event that
- * was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event was fired.
- */
- _onHide: function (p_sType, p_aArgs) {
- if (this.cfg.getProperty(_POSITION) === _DYNAMIC) {
-
- this.positionOffScreen();
-
- }
- },
- /**
- * @method _onShow
- * @description "show" event handler for the menu.
- * @private
- * @param {String} p_sType String representing the name of the event that
- * was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event was fired.
- */
- _onShow: function (p_sType, p_aArgs) {
- var oParent = this.parent,
- oParentMenu,
- oElement,
- nOffsetWidth,
- sWidth;
- function disableAutoSubmenuDisplay(p_oEvent) {
- var oTarget;
- if (p_oEvent.type == _MOUSEDOWN || (p_oEvent.type == _KEYDOWN && p_oEvent.keyCode == 27)) {
- /*
- Set the "autosubmenudisplay" to "false" if the user
- clicks outside the menu bar.
- */
- oTarget = Event.getTarget(p_oEvent);
- if (oTarget != oParentMenu.element || !Dom.isAncestor(oParentMenu.element, oTarget)) {
- oParentMenu.cfg.setProperty(_AUTO_SUBMENU_DISPLAY, false);
- Event.removeListener(document, _MOUSEDOWN, disableAutoSubmenuDisplay);
- Event.removeListener(document, _KEYDOWN, disableAutoSubmenuDisplay);
- }
-
- }
- }
- function onSubmenuHide(p_sType, p_aArgs, p_sWidth) {
-
- this.cfg.setProperty(_WIDTH, _EMPTY_STRING);
- this.hideEvent.unsubscribe(onSubmenuHide, p_sWidth);
-
- }
- if (oParent) {
- oParentMenu = oParent.parent;
- if (!oParentMenu.cfg.getProperty(_AUTO_SUBMENU_DISPLAY) &&
- (oParentMenu instanceof YAHOO.widget.MenuBar ||
- oParentMenu.cfg.getProperty(_POSITION) == _STATIC)) {
- oParentMenu.cfg.setProperty(_AUTO_SUBMENU_DISPLAY, true);
- Event.on(document, _MOUSEDOWN, disableAutoSubmenuDisplay);
- Event.on(document, _KEYDOWN, disableAutoSubmenuDisplay);
- }
- // The following fixes an issue with the selected state of a MenuItem
- // not rendering correctly when a submenu is aligned to the left of
- // its parent Menu instance.
- if ((this.cfg.getProperty("x") < oParentMenu.cfg.getProperty("x")) &&
- (UA.gecko && UA.gecko < 1.9) && !this.cfg.getProperty(_WIDTH)) {
- oElement = this.element;
- nOffsetWidth = oElement.offsetWidth;
-
- /*
- Measuring the difference of the offsetWidth before and after
- setting the "width" style attribute allows us to compute the
- about of padding and borders applied to the element, which in
- turn allows us to set the "width" property correctly.
- */
-
- oElement.style.width = nOffsetWidth + _PX;
-
- sWidth = (nOffsetWidth - (oElement.offsetWidth - nOffsetWidth)) + _PX;
-
- this.cfg.setProperty(_WIDTH, sWidth);
-
- this.hideEvent.subscribe(onSubmenuHide, sWidth);
-
- }
- }
- /*
- Dynamically positioned, root Menus focus themselves when visible, and
- will then, when hidden, restore focus to the UI control that had focus
- before the Menu was made visible.
- */
- if (this === this.getRoot() && this.cfg.getProperty(_POSITION) === _DYNAMIC) {
- this._focusedElement = oFocusedElement;
-
- this.focus();
-
- }
- },
- /**
- * @method _onBeforeHide
- * @description "beforehide" event handler for the menu.
- * @private
- * @param {String} p_sType String representing the name of the event that
- * was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event was fired.
- */
- _onBeforeHide: function (p_sType, p_aArgs) {
- var oActiveItem = this.activeItem,
- oRoot = this.getRoot(),
- oConfig,
- oSubmenu;
- if (oActiveItem) {
- oConfig = oActiveItem.cfg;
- oConfig.setProperty(_SELECTED, false);
- oSubmenu = oConfig.getProperty(_SUBMENU);
- if (oSubmenu) {
- oSubmenu.hide();
- }
- }
- /*
- Focus can get lost in IE when the mouse is moving from a submenu back to its parent Menu.
- For this reason, it is necessary to maintain the focused state in a private property
- so that the _onMouseOver event handler is able to determined whether or not to set focus
- to MenuItems as the user is moving the mouse.
- */
- if (UA.ie && this.cfg.getProperty(_POSITION) === _DYNAMIC && this.parent) {
- oRoot._hasFocus = this.hasFocus();
-
- }
- if (oRoot == this) {
- oRoot.blur();
-
- }
- },
- /**
- * @method _onParentMenuConfigChange
- * @description "configchange" event handler for a submenu.
- * @private
- * @param {String} p_sType String representing the name of the event that
- * was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event was fired.
- * @param {YAHOO.widget.Menu} p_oSubmenu Object representing the submenu that
- * subscribed to the event.
- */
- _onParentMenuConfigChange: function (p_sType, p_aArgs, p_oSubmenu) {
-
- var sPropertyName = p_aArgs[0][0],
- oPropertyValue = p_aArgs[0][1];
- switch(sPropertyName) {
- case _IFRAME:
- case _CONSTRAIN_TO_VIEWPORT:
- case _HIDE_DELAY:
- case _SHOW_DELAY:
- case _SUBMENU_HIDE_DELAY:
- case _CLICK_TO_HIDE:
- case _EFFECT:
- case _CLASSNAME:
- case _SCROLL_INCREMENT:
- case _MAX_HEIGHT:
- case _MIN_SCROLL_HEIGHT:
- case _MONITOR_RESIZE:
- case _SHADOW:
- case _PREVENT_CONTEXT_OVERLAP:
- case _KEEP_OPEN:
- p_oSubmenu.cfg.setProperty(sPropertyName, oPropertyValue);
-
- break;
-
- case _SUBMENU_ALIGNMENT:
- if (!(this.parent.parent instanceof YAHOO.widget.MenuBar)) {
-
- p_oSubmenu.cfg.setProperty(sPropertyName, oPropertyValue);
-
- }
-
- break;
-
- }
-
- },
- /**
- * @method _onParentMenuRender
- * @description "render" event handler for a submenu. Renders a
- * submenu in response to the firing of its parent's "render" event.
- * @private
- * @param {String} p_sType String representing the name of the event that
- * was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event was fired.
- * @param {YAHOO.widget.Menu} p_oSubmenu Object representing the submenu that
- * subscribed to the event.
- */
- _onParentMenuRender: function (p_sType, p_aArgs, p_oSubmenu) {
- var oParentMenu = p_oSubmenu.parent.parent,
- oParentCfg = oParentMenu.cfg,
- oConfig = {
- constraintoviewport: oParentCfg.getProperty(_CONSTRAIN_TO_VIEWPORT),
- xy: [0,0],
- clicktohide: oParentCfg.getProperty(_CLICK_TO_HIDE),
-
- effect: oParentCfg.getProperty(_EFFECT),
- showdelay: oParentCfg.getProperty(_SHOW_DELAY),
-
- hidedelay: oParentCfg.getProperty(_HIDE_DELAY),
- submenuhidedelay: oParentCfg.getProperty(_SUBMENU_HIDE_DELAY),
- classname: oParentCfg.getProperty(_CLASSNAME),
-
- scrollincrement: oParentCfg.getProperty(_SCROLL_INCREMENT),
-
- maxheight: oParentCfg.getProperty(_MAX_HEIGHT),
- minscrollheight: oParentCfg.getProperty(_MIN_SCROLL_HEIGHT),
-
- iframe: oParentCfg.getProperty(_IFRAME),
-
- shadow: oParentCfg.getProperty(_SHADOW),
- preventcontextoverlap: oParentCfg.getProperty(_PREVENT_CONTEXT_OVERLAP),
-
- monitorresize: oParentCfg.getProperty(_MONITOR_RESIZE),
- keepopen: oParentCfg.getProperty(_KEEP_OPEN)
- },
-
- oLI;
-
- if (!(oParentMenu instanceof YAHOO.widget.MenuBar)) {
- oConfig[_SUBMENU_ALIGNMENT] = oParentCfg.getProperty(_SUBMENU_ALIGNMENT);
- }
- p_oSubmenu.cfg.applyConfig(oConfig);
- if (!this.lazyLoad) {
- oLI = this.parent.element;
- if (this.element.parentNode == oLI) {
-
- this.render();
-
- }
- else {
- this.render(oLI);
-
- }
- }
-
- },
- /**
- * @method _onMenuItemDestroy
- * @description "destroy" event handler for the menu's items.
- * @private
- * @param {String} p_sType String representing the name of the event
- * that was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event was fired.
- * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
- * that fired the event.
- */
- _onMenuItemDestroy: function (p_sType, p_aArgs, p_oItem) {
- this._removeItemFromGroupByValue(p_oItem.groupIndex, p_oItem);
- },
- /**
- * @method _onMenuItemConfigChange
- * @description "configchange" event handler for the menu's items.
- * @private
- * @param {String} p_sType String representing the name of the event that
- * was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event was fired.
- * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
- * that fired the event.
- */
- _onMenuItemConfigChange: function (p_sType, p_aArgs, p_oItem) {
- var sPropertyName = p_aArgs[0][0],
- oPropertyValue = p_aArgs[0][1],
- oSubmenu;
- switch(sPropertyName) {
- case _SELECTED:
- if (oPropertyValue === true) {
- this.activeItem = p_oItem;
-
- }
- break;
- case _SUBMENU:
- oSubmenu = p_aArgs[0][1];
- if (oSubmenu) {
- this._configureSubmenu(p_oItem);
- }
- break;
- }
- },
- // Public event handlers for configuration properties
- /**
- * @method configVisible
- * @description Event handler for when the "visible" configuration property
- * the menu changes.
- * @param {String} p_sType String representing the name of the event that
- * was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event was fired.
- * @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that
- * fired the event.
- */
- configVisible: function (p_sType, p_aArgs, p_oMenu) {
- var bVisible,
- sDisplay;
- if (this.cfg.getProperty(_POSITION) == _DYNAMIC) {
- Menu.superclass.configVisible.call(this, p_sType, p_aArgs, p_oMenu);
- }
- else {
- bVisible = p_aArgs[0];
- sDisplay = Dom.getStyle(this.element, _DISPLAY);
- Dom.setStyle(this.element, _VISIBILITY, _VISIBLE);
- if (bVisible) {
- if (sDisplay != _BLOCK) {
- this.beforeShowEvent.fire();
- Dom.setStyle(this.element, _DISPLAY, _BLOCK);
- this.showEvent.fire();
- }
-
- }
- else {
- if (sDisplay == _BLOCK) {
- this.beforeHideEvent.fire();
- Dom.setStyle(this.element, _DISPLAY, _NONE);
- this.hideEvent.fire();
- }
-
- }
- }
- },
- /**
- * @method configPosition
- * @description Event handler for when the "position" configuration property
- * of the menu changes.
- * @param {String} p_sType String representing the name of the event that
- * was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event was fired.
- * @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that
- * fired the event.
- */
- configPosition: function (p_sType, p_aArgs, p_oMenu) {
- var oElement = this.element,
- sCSSPosition = p_aArgs[0] == _STATIC ? _STATIC : _ABSOLUTE,
- oCfg = this.cfg,
- nZIndex;
- Dom.setStyle(oElement, _POSITION, sCSSPosition);
- if (sCSSPosition == _STATIC) {
- // Statically positioned menus are visible by default
-
- Dom.setStyle(oElement, _DISPLAY, _BLOCK);
- oCfg.setProperty(_VISIBLE, true);
- }
- else {
- /*
- Even though the "visible" property is queued to
- "false" by default, we need to set the "visibility" property to
- "hidden" since Overlay's "configVisible" implementation checks the
- element's "visibility" style property before deciding whether
- or not to show an Overlay instance.
- */
- Dom.setStyle(oElement, _VISIBILITY, _HIDDEN);
-
- }
-
- if (sCSSPosition == _ABSOLUTE) {
-
- nZIndex = oCfg.getProperty(_ZINDEX);
-
- if (!nZIndex || nZIndex === 0) {
-
- oCfg.setProperty(_ZINDEX, 1);
-
- }
-
- }
- },
- /**
- * @method configIframe
- * @description Event handler for when the "iframe" configuration property of
- * the menu changes.
- * @param {String} p_sType String representing the name of the event that
- * was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event was fired.
- * @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that
- * fired the event.
- */
- configIframe: function (p_sType, p_aArgs, p_oMenu) {
- if (this.cfg.getProperty(_POSITION) == _DYNAMIC) {
- Menu.superclass.configIframe.call(this, p_sType, p_aArgs, p_oMenu);
- }
- },
- /**
- * @method configHideDelay
- * @description Event handler for when the "hidedelay" configuration property
- * of the menu changes.
- * @param {String} p_sType String representing the name of the event that
- * was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event was fired.
- * @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that
- * fired the event.
- */
- configHideDelay: function (p_sType, p_aArgs, p_oMenu) {
- var nHideDelay = p_aArgs[0];
- this._useHideDelay = (nHideDelay > 0);
- },
- /**
- * @method configContainer
- * @description Event handler for when the "container" configuration property
- * of the menu changes.
- * @param {String} p_sType String representing the name of the event that
- * was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event was fired.
- * @param {YAHOO.widget.Menu} p_oMenu Object representing the menu that
- * fired the event.
- */
- configContainer: function (p_sType, p_aArgs, p_oMenu) {
- var oElement = p_aArgs[0];
- if (Lang.isString(oElement)) {
- this.cfg.setProperty(_CONTAINER, Dom.get(oElement), true);
- }
- },
- /**
- * @method _clearSetWidthFlag
- * @description Change event listener for the "width" configuration property. This listener is
- * added when a Menu's "width" configuration property is set by the "_setScrollHeight" method, and
- * is used to set the "_widthSetForScroll" property to "false" if the "width" configuration property
- * is changed after it was set by the "_setScrollHeight" method. If the "_widthSetForScroll"
- * property is set to "false", and the "_setScrollHeight" method is in the process of tearing down
- * scrolling functionality, it will maintain the Menu's new width rather than reseting it.
- * @private
- */
- _clearSetWidthFlag: function () {
- this._widthSetForScroll = false;
-
- this.cfg.unsubscribeFromConfigEvent(_WIDTH, this._clearSetWidthFlag);
- },
- /**
- * @method _setScrollHeight
- * @description
- * @param {String} p_nScrollHeight Number representing the scrolling height of the Menu.
- * @private
- */
- _setScrollHeight: function (p_nScrollHeight) {
- var nScrollHeight = p_nScrollHeight,
- bRefireIFrameAndShadow = false,
- bSetWidth = false,
- oElement,
- oBody,
- oHeader,
- oFooter,
- fnMouseOver,
- fnMouseOut,
- nMinScrollHeight,
- nHeight,
- nOffsetWidth,
- sWidth;
- if (this.getItems().length > 0) {
-
- oElement = this.element;
- oBody = this.body;
- oHeader = this.header;
- oFooter = this.footer;
- fnMouseOver = this._onScrollTargetMouseOver;
- fnMouseOut = this._onScrollTargetMouseOut;
- nMinScrollHeight = this.cfg.getProperty(_MIN_SCROLL_HEIGHT);
- if (nScrollHeight > 0 && nScrollHeight < nMinScrollHeight) {
-
- nScrollHeight = nMinScrollHeight;
-
- }
- Dom.setStyle(oBody, _HEIGHT, _EMPTY_STRING);
- Dom.removeClass(oBody, _YUI_MENU_BODY_SCROLLED);
- oBody.scrollTop = 0;
- // Need to set a width for the Menu to fix the following problems in
- // Firefox 2 and IE:
- // #1) Scrolled Menus will render at 1px wide in Firefox 2
- // #2) There is a bug in gecko-based browsers where an element whose
- // "position" property is set to "absolute" and "overflow" property is
- // set to "hidden" will not render at the correct width when its
- // offsetParent's "position" property is also set to "absolute." It is
- // possible to work around this bug by specifying a value for the width
- // property in addition to overflow.
- // #3) In IE it is necessary to give the Menu a width before the
- // scrollbars are rendered to prevent the Menu from rendering with a
- // width that is 100% of the browser viewport.
-
- bSetWidth = ((UA.gecko && UA.gecko < 1.9) || UA.ie);
- if (nScrollHeight > 0 && bSetWidth && !this.cfg.getProperty(_WIDTH)) {
- nOffsetWidth = oElement.offsetWidth;
-
- /*
- Measuring the difference of the offsetWidth before and after
- setting the "width" style attribute allows us to compute the
- about of padding and borders applied to the element, which in
- turn allows us to set the "width" property correctly.
- */
-
- oElement.style.width = nOffsetWidth + _PX;
-
- sWidth = (nOffsetWidth - (oElement.offsetWidth - nOffsetWidth)) + _PX;
- this.cfg.unsubscribeFromConfigEvent(_WIDTH, this._clearSetWidthFlag);
- YAHOO.log("Setting the \"width\" configuration property to " + sWidth + " for srolling.",
- "info", this.toString());
- this.cfg.setProperty(_WIDTH, sWidth);
- /*
- Set a flag (_widthSetForScroll) to maintain some history regarding how the
- "width" configuration property was set. If the "width" configuration property
- is set by something other than the "_setScrollHeight" method, it will be
- necessary to maintain that new value and not clear the width if scrolling
- is turned off.
- */
- this._widthSetForScroll = true;
- this.cfg.subscribeToConfigEvent(_WIDTH, this._clearSetWidthFlag);
-
- }
-
-
- if (nScrollHeight > 0 && (!oHeader && !oFooter)) {
-
- YAHOO.log("Creating header and footer for scrolling.", "info", this.toString());
-
- this.setHeader(_NON_BREAKING_SPACE);
- this.setFooter(_NON_BREAKING_SPACE);
-
- oHeader = this.header;
- oFooter = this.footer;
-
- Dom.addClass(oHeader, _TOP_SCROLLBAR);
- Dom.addClass(oFooter, _BOTTOM_SCROLLBAR);
-
- oElement.insertBefore(oHeader, oBody);
- oElement.appendChild(oFooter);
-
- }
-
-
- nHeight = nScrollHeight;
-
-
- if (oHeader && oFooter) {
- nHeight = (nHeight - (oHeader.offsetHeight + oFooter.offsetHeight));
- }
-
-
- if ((nHeight > 0) && (oBody.offsetHeight > nScrollHeight)) {
- YAHOO.log("Setting up styles and event handlers for scrolling.",
- "info", this.toString());
-
- Dom.addClass(oBody, _YUI_MENU_BODY_SCROLLED);
- Dom.setStyle(oBody, _HEIGHT, (nHeight + _PX));
- if (!this._hasScrollEventHandlers) {
-
- Event.on(oHeader, _MOUSEOVER, fnMouseOver, this, true);
- Event.on(oHeader, _MOUSEOUT, fnMouseOut, this, true);
- Event.on(oFooter, _MOUSEOVER, fnMouseOver, this, true);
- Event.on(oFooter, _MOUSEOUT, fnMouseOut, this, true);
-
- this._hasScrollEventHandlers = true;
-
- }
-
- this._disableScrollHeader();
- this._enableScrollFooter();
-
- bRefireIFrameAndShadow = true;
-
- }
- else if (oHeader && oFooter) {
- YAHOO.log("Removing styles and event handlers for scrolling.", "info", this.toString());
-
- /*
- Only clear the the "width" configuration property if it was set the
- "_setScrollHeight" method and wasn't changed by some other means after it was set.
- */
-
- if (this._widthSetForScroll) {
-
- YAHOO.log("Clearing width used for scrolling.", "info", this.toString());
- this._widthSetForScroll = false;
- this.cfg.unsubscribeFromConfigEvent(_WIDTH, this._clearSetWidthFlag);
-
- this.cfg.setProperty(_WIDTH, _EMPTY_STRING);
-
- }
-
-
- this._enableScrollHeader();
- this._enableScrollFooter();
-
- if (this._hasScrollEventHandlers) {
-
- Event.removeListener(oHeader, _MOUSEOVER, fnMouseOver);
- Event.removeListener(oHeader, _MOUSEOUT, fnMouseOut);
- Event.removeListener(oFooter, _MOUSEOVER, fnMouseOver);
- Event.removeListener(oFooter, _MOUSEOUT, fnMouseOut);
- this._hasScrollEventHandlers = false;
-
- }
- oElement.removeChild(oHeader);
- oElement.removeChild(oFooter);
-
- this.header = null;
- this.footer = null;
-
- bRefireIFrameAndShadow = true;
-
- }
- if (bRefireIFrameAndShadow) {
-
- this.cfg.refireEvent(_IFRAME);
- this.cfg.refireEvent(_SHADOW);
-
- }
-
- }
- },
- /**
- * @method _setMaxHeight
- * @description "renderEvent" handler used to defer the setting of the
- * "maxheight" configuration property until the menu is rendered in lazy
- * load scenarios.
- * @param {String} p_sType The name of the event that was fired.
- * @param {Array} p_aArgs Collection of arguments sent when the event
- * was fired.
- * @param {Number} p_nMaxHeight Number representing the value to set for the
- * "maxheight" configuration property.
- * @private
- */
- _setMaxHeight: function (p_sType, p_aArgs, p_nMaxHeight) {
- this._setScrollHeight(p_nMaxHeight);
- this.renderEvent.unsubscribe(this._setMaxHeight);
- },
- /**
- * @method configMaxHeight
- * @description Event handler for when the "maxheight" configuration property of
- * a Menu changes.
- * @param {String} p_sType The name of the event that was fired.
- * @param {Array} p_aArgs Collection of arguments sent when the event
- * was fired.
- * @param {YAHOO.widget.Menu} p_oMenu The Menu instance fired
- * the event.
- */
- configMaxHeight: function (p_sType, p_aArgs, p_oMenu) {
- var nMaxHeight = p_aArgs[0];
- if (this.lazyLoad && !this.body && nMaxHeight > 0) {
-
- this.renderEvent.subscribe(this._setMaxHeight, nMaxHeight, this);
- }
- else {
- this._setScrollHeight(nMaxHeight);
-
- }
- },
- /**
- * @method configClassName
- * @description Event handler for when the "classname" configuration property of
- * a menu changes.
- * @param {String} p_sType The name of the event that was fired.
- * @param {Array} p_aArgs Collection of arguments sent when the event was fired.
- * @param {YAHOO.widget.Menu} p_oMenu The Menu instance fired the event.
- */
- configClassName: function (p_sType, p_aArgs, p_oMenu) {
- var sClassName = p_aArgs[0];
- if (this._sClassName) {
- Dom.removeClass(this.element, this._sClassName);
- }
- Dom.addClass(this.element, sClassName);
- this._sClassName = sClassName;
- },
- /**
- * @method _onItemAdded
- * @description "itemadded" event handler for a Menu instance.
- * @private
- * @param {String} p_sType The name of the event that was fired.
- * @param {Array} p_aArgs Collection of arguments sent when the event
- * was fired.
- */
- _onItemAdded: function (p_sType, p_aArgs) {
- var oItem = p_aArgs[0];
-
- if (oItem) {
- oItem.cfg.setProperty(_DISABLED, true);
-
- }
- },
- /**
- * @method configDisabled
- * @description Event handler for when the "disabled" configuration property of
- * a menu changes.
- * @param {String} p_sType The name of the event that was fired.
- * @param {Array} p_aArgs Collection of arguments sent when the event was fired.
- * @param {YAHOO.widget.Menu} p_oMenu The Menu instance fired the event.
- */
- configDisabled: function (p_sType, p_aArgs, p_oMenu) {
- var bDisabled = p_aArgs[0],
- aItems = this.getItems(),
- nItems,
- i;
- if (Lang.isArray(aItems)) {
- nItems = aItems.length;
-
- if (nItems > 0) {
-
- i = nItems - 1;
-
- do {
-
- aItems[i].cfg.setProperty(_DISABLED, bDisabled);
-
- }
- while (i--);
-
- }
- if (bDisabled) {
- this.clearActiveItem(true);
- Dom.addClass(this.element, _DISABLED);
- this.itemAddedEvent.subscribe(this._onItemAdded);
- }
- else {
- Dom.removeClass(this.element, _DISABLED);
- this.itemAddedEvent.unsubscribe(this._onItemAdded);
- }
-
- }
- },
- /**
- * @method configShadow
- * @description Event handler for when the "shadow" configuration property of
- * a menu changes.
- * @param {String} p_sType The name of the event that was fired.
- * @param {Array} p_aArgs Collection of arguments sent when the event was fired.
- * @param {YAHOO.widget.Menu} p_oMenu The Menu instance fired the event.
- */
- configShadow: function (p_sType, p_aArgs, p_oMenu) {
- var sizeShadow = function () {
- var oElement = this.element,
- oShadow = this._shadow;
-
- if (oShadow && oElement) {
- // Clear the previous width
- if (oShadow.style.width && oShadow.style.height) {
-
- oShadow.style.width = _EMPTY_STRING;
- oShadow.style.height = _EMPTY_STRING;
-
- }
- oShadow.style.width = (oElement.offsetWidth + 6) + _PX;
- oShadow.style.height = (oElement.offsetHeight + 1) + _PX;
-
- }
-
- };
- var replaceShadow = function () {
- this.element.appendChild(this._shadow);
- };
- var addShadowVisibleClass = function () {
-
- Dom.addClass(this._shadow, _YUI_MENU_SHADOW_VISIBLE);
-
- };
-
- var removeShadowVisibleClass = function () {
- Dom.removeClass(this._shadow, _YUI_MENU_SHADOW_VISIBLE);
-
- };
- var createShadow = function () {
- var oShadow = this._shadow,
- oElement;
- if (!oShadow) {
- oElement = this.element;
- if (!m_oShadowTemplate) {
- m_oShadowTemplate = document.createElement(_DIV_LOWERCASE);
- m_oShadowTemplate.className = _YUI_MENU_SHADOW_YUI_MENU_SHADOW_VISIBLE;
-
- }
- oShadow = m_oShadowTemplate.cloneNode(false);
- oElement.appendChild(oShadow);
-
- this._shadow = oShadow;
- this.beforeShowEvent.subscribe(addShadowVisibleClass);
- this.beforeHideEvent.subscribe(removeShadowVisibleClass);
- if (UA.ie) {
-
- /*
- Need to call sizeShadow & syncIframe via setTimeout for
- IE 7 Quirks Mode and IE 6 Standards Mode and Quirks Mode
- or the shadow and iframe shim will not be sized and
- positioned properly.
- */
-
- Lang.later(0, this, function () {
- sizeShadow.call(this);
- this.syncIframe();
-
- });
- this.cfg.subscribeToConfigEvent(_WIDTH, sizeShadow);
- this.cfg.subscribeToConfigEvent(_HEIGHT, sizeShadow);
- this.cfg.subscribeToConfigEvent(_MAX_HEIGHT, sizeShadow);
- this.changeContentEvent.subscribe(sizeShadow);
- Module.textResizeEvent.subscribe(sizeShadow, this, true);
-
- this.destroyEvent.subscribe(function () {
-
- Module.textResizeEvent.unsubscribe(sizeShadow, this);
-
- });
-
- }
- this.cfg.subscribeToConfigEvent(_MAX_HEIGHT, replaceShadow);
- }
- };
- var onBeforeShow = function () {
- if (this._shadow) {
- // If called because the "shadow" event was refired - just append again and resize
-
- replaceShadow.call(this);
-
- if (UA.ie) {
- sizeShadow.call(this);
- }
-
- }
- else {
-
- createShadow.call(this);
-
- }
- this.beforeShowEvent.unsubscribe(onBeforeShow);
-
- };
- var bShadow = p_aArgs[0];
- if (bShadow && this.cfg.getProperty(_POSITION) == _DYNAMIC) {
- if (this.cfg.getProperty(_VISIBLE)) {
- if (this._shadow) {
- // If the "shadow" event was refired - just append again and resize
-
- replaceShadow.call(this);
-
- if (UA.ie) {
- sizeShadow.call(this);
- }
-
- }
- else {
- createShadow.call(this);
- }
-
- }
- else {
- this.beforeShowEvent.subscribe(onBeforeShow);
-
- }
-
- }
-
- },
- // Public methods
- /**
- * @method initEvents
- * @description Initializes the custom events for the menu.
- */
- initEvents: function () {
- Menu.superclass.initEvents.call(this);
- // Create custom events
- var i = EVENT_TYPES.length - 1,
- aEventData,
- oCustomEvent;
- do {
- aEventData = EVENT_TYPES[i];
- oCustomEvent = this.createEvent(aEventData[1]);
- oCustomEvent.signature = CustomEvent.LIST;
-
- this[aEventData[0]] = oCustomEvent;
- }
- while (i--);
- },
- /**
- * @method positionOffScreen
- * @description Positions the menu outside of the boundaries of the browser's
- * viewport. Called automatically when a menu is hidden to ensure that
- * it doesn't force the browser to render uncessary scrollbars.
- */
- positionOffScreen: function () {
- var oIFrame = this.iframe,
- oElement = this.element,
- sPos = this.OFF_SCREEN_POSITION;
-
- oElement.style.top = _EMPTY_STRING;
- oElement.style.left = _EMPTY_STRING;
-
- if (oIFrame) {
- oIFrame.style.top = sPos;
- oIFrame.style.left = sPos;
-
- }
- },
- /**
- * @method getRoot
- * @description Finds the menu's root menu.
- */
- getRoot: function () {
- var oItem = this.parent,
- oParentMenu,
- returnVal;
- if (oItem) {
- oParentMenu = oItem.parent;
- returnVal = oParentMenu ? oParentMenu.getRoot() : this;
- }
- else {
-
- returnVal = this;
-
- }
-
- return returnVal;
- },
- /**
- * @method toString
- * @description Returns a string representing the menu.
- * @return {String}
- */
- toString: function () {
- var sReturnVal = _MENU,
- sId = this.id;
- if (sId) {
- sReturnVal += (_SPACE + sId);
-
- }
- return sReturnVal;
- },
- /**
- * @method setItemGroupTitle
- * @description Sets the title of a group of menu items.
- * @param {String} p_sGroupTitle String specifying the title of the group.
- * @param {Number} p_nGroupIndex Optional. Number specifying the group to which
- * the title belongs.
- */
- setItemGroupTitle: function (p_sGroupTitle, p_nGroupIndex) {
- var nGroupIndex,
- oTitle,
- i,
- nFirstIndex;
-
- if (Lang.isString(p_sGroupTitle) && p_sGroupTitle.length > 0) {
- nGroupIndex = Lang.isNumber(p_nGroupIndex) ? p_nGroupIndex : 0;
- oTitle = this._aGroupTitleElements[nGroupIndex];
- if (oTitle) {
- oTitle.innerHTML = p_sGroupTitle;
-
- }
- else {
- oTitle = document.createElement(this.GROUP_TITLE_TAG_NAME);
-
- oTitle.innerHTML = p_sGroupTitle;
- this._aGroupTitleElements[nGroupIndex] = oTitle;
- }
- i = this._aGroupTitleElements.length - 1;
- do {
- if (this._aGroupTitleElements[i]) {
- Dom.removeClass(this._aGroupTitleElements[i], _FIRST_OF_TYPE);
- nFirstIndex = i;
- }
- }
- while (i--);
- if (nFirstIndex !== null) {
- Dom.addClass(this._aGroupTitleElements[nFirstIndex],
- _FIRST_OF_TYPE);
- }
- this.changeContentEvent.fire();
- }
- },
- /**
- * @method addItem
- * @description Appends an item to the menu.
- * @param {YAHOO.widget.MenuItem} p_oItem Object reference for the MenuItem
- * instance to be added to the menu.
- * @param {String} p_oItem String specifying the text of the item to be added
- * to the menu.
- * @param {Object} p_oItem Object literal containing a set of menu item
- * configuration properties.
- * @param {Number} p_nGroupIndex Optional. Number indicating the group to
- * which the item belongs.
- * @return {YAHOO.widget.MenuItem}
- */
- addItem: function (p_oItem, p_nGroupIndex) {
- return this._addItemToGroup(p_nGroupIndex, p_oItem);
- },
- /**
- * @method addItems
- * @description Adds an array of items to the menu.
- * @param {Array} p_aItems Array of items to be added to the menu. The array
- * can contain strings specifying the text for each item to be created, object
- * literals specifying each of the menu item configuration properties,
- * or MenuItem instances.
- * @param {Number} p_nGroupIndex Optional. Number specifying the group to
- * which the items belongs.
- * @return {Array}
- */
- addItems: function (p_aItems, p_nGroupIndex) {
- var nItems,
- aItems,
- oItem,
- i,
- returnVal;
- if (Lang.isArray(p_aItems)) {
- nItems = p_aItems.length;
- aItems = [];
- for(i=0; i<nItems; i++) {
- oItem = p_aItems[i];
- if (oItem) {
- if (Lang.isArray(oItem)) {
-
- aItems[aItems.length] = this.addItems(oItem, i);
-
- }
- else {
-
- aItems[aItems.length] = this._addItemToGroup(p_nGroupIndex, oItem);
-
- }
- }
-
- }
- if (aItems.length) {
-
- returnVal = aItems;
-
- }
- }
- return returnVal;
- },
- /**
- * @method insertItem
- * @description Inserts an item into the menu at the specified index.
- * @param {YAHOO.widget.MenuItem} p_oItem Object reference for the MenuItem
- * instance to be added to the menu.
- * @param {String} p_oItem String specifying the text of the item to be added
- * to the menu.
- * @param {Object} p_oItem Object literal containing a set of menu item
- * configuration properties.
- * @param {Number} p_nItemIndex Number indicating the ordinal position at which
- * the item should be added.
- * @param {Number} p_nGroupIndex Optional. Number indicating the group to which
- * the item belongs.
- * @return {YAHOO.widget.MenuItem}
- */
- insertItem: function (p_oItem, p_nItemIndex, p_nGroupIndex) {
-
- return this._addItemToGroup(p_nGroupIndex, p_oItem, p_nItemIndex);
- },
- /**
- * @method removeItem
- * @description Removes the specified item from the menu.
- * @param {YAHOO.widget.MenuItem} p_oObject Object reference for the MenuItem
- * instance to be removed from the menu.
- * @param {Number} p_oObject Number specifying the index of the item
- * to be removed.
- * @param {Number} p_nGroupIndex Optional. Number specifying the group to
- * which the item belongs.
- * @return {YAHOO.widget.MenuItem}
- */
- removeItem: function (p_oObject, p_nGroupIndex) {
- var oItem,
- returnVal;
-
- if (!Lang.isUndefined(p_oObject)) {
- if (p_oObject instanceof YAHOO.widget.MenuItem) {
- oItem = this._removeItemFromGroupByValue(p_nGroupIndex, p_oObject);
- }
- else if (Lang.isNumber(p_oObject)) {
- oItem = this._removeItemFromGroupByIndex(p_nGroupIndex, p_oObject);
- }
- if (oItem) {
- oItem.destroy();
- YAHOO.log("Item removed." +
- " Text: " + oItem.cfg.getProperty("text") + ", " +
- " Index: " + oItem.index + ", " +
- " Group Index: " + oItem.groupIndex, "info", this.toString());
- returnVal = oItem;
- }
- }
- return returnVal;
- },
- /**
- * @method getItems
- * @description Returns an array of all of the items in the menu.
- * @return {Array}
- */
- getItems: function () {
- var aGroups = this._aItemGroups,
- nGroups,
- returnVal,
- aItems = [];
- if (Lang.isArray(aGroups)) {
- nGroups = aGroups.length;
- returnVal = ((nGroups == 1) ? aGroups[0] : (Array.prototype.concat.apply(aItems, aGroups)));
- }
- return returnVal;
- },
- /**
- * @method getItemGroups
- * @description Multi-dimensional Array representing the menu items as they
- * are grouped in the menu.
- * @return {Array}
- */
- getItemGroups: function () {
- return this._aItemGroups;
- },
- /**
- * @method getItem
- * @description Returns the item at the specified index.
- * @param {Number} p_nItemIndex Number indicating the ordinal position of the
- * item to be retrieved.
- * @param {Number} p_nGroupIndex Optional. Number indicating the group to which
- * the item belongs.
- * @return {YAHOO.widget.MenuItem}
- */
- getItem: function (p_nItemIndex, p_nGroupIndex) {
-
- var aGroup,
- returnVal;
-
- if (Lang.isNumber(p_nItemIndex)) {
- aGroup = this._getItemGroup(p_nGroupIndex);
- if (aGroup) {
- returnVal = aGroup[p_nItemIndex];
-
- }
- }
-
- return returnVal;
-
- },
- /**
- * @method getSubmenus
- * @description Returns an array of all of the submenus that are immediate
- * children of the menu.
- * @return {Array}
- */
- getSubmenus: function () {
- var aItems = this.getItems(),
- nItems = aItems.length,
- aSubmenus,
- oSubmenu,
- oItem,
- i;
- if (nItems > 0) {
-
- aSubmenus = [];
- for(i=0; i<nItems; i++) {
- oItem = aItems[i];
-
- if (oItem) {
- oSubmenu = oItem.cfg.getProperty(_SUBMENU);
-
- if (oSubmenu) {
- aSubmenus[aSubmenus.length] = oSubmenu;
- }
-
- }
-
- }
-
- }
- return aSubmenus;
- },
- /**
- * @method clearContent
- * @description Removes all of the content from the menu, including the menu
- * items, group titles, header and footer.
- */
- clearContent: function () {
- var aItems = this.getItems(),
- nItems = aItems.length,
- oElement = this.element,
- oBody = this.body,
- oHeader = this.header,
- oFooter = this.footer,
- oItem,
- oSubmenu,
- i;
- if (nItems > 0) {
- i = nItems - 1;
- do {
- oItem = aItems[i];
- if (oItem) {
- oSubmenu = oItem.cfg.getProperty(_SUBMENU);
- if (oSubmenu) {
- this.cfg.configChangedEvent.unsubscribe(
- this._onParentMenuConfigChange, oSubmenu);
- this.renderEvent.unsubscribe(this._onParentMenuRender,
- oSubmenu);
- }
-
- this.removeItem(oItem, oItem.groupIndex);
- }
-
- }
- while (i--);
- }
- if (oHeader) {
- Event.purgeElement(oHeader);
- oElement.removeChild(oHeader);
- }
-
- if (oFooter) {
- Event.purgeElement(oFooter);
- oElement.removeChild(oFooter);
- }
- if (oBody) {
- Event.purgeElement(oBody);
- oBody.innerHTML = _EMPTY_STRING;
- }
- this.activeItem = null;
- this._aItemGroups = [];
- this._aListElements = [];
- this._aGroupTitleElements = [];
- this.cfg.setProperty(_WIDTH, null);
- },
- /**
- * @method destroy
- * @description Removes the menu's <code><div></code> element
- * (and accompanying child nodes) from the document.
- */
- destroy: function () {
- // Remove all items
- this.clearContent();
- this._aItemGroups = null;
- this._aListElements = null;
- this._aGroupTitleElements = null;
- // Continue with the superclass implementation of this method
- Menu.superclass.destroy.call(this);
-
- YAHOO.log("Destroyed.", "info", this.toString());
- },
- /**
- * @method setInitialFocus
- * @description Sets focus to the menu's first enabled item.
- */
- setInitialFocus: function () {
- var oItem = this._getFirstEnabledItem();
-
- if (oItem) {
- oItem.focus();
- }
-
- },
- /**
- * @method setInitialSelection
- * @description Sets the "selected" configuration property of the menu's first
- * enabled item to "true."
- */
- setInitialSelection: function () {
- var oItem = this._getFirstEnabledItem();
-
- if (oItem) {
-
- oItem.cfg.setProperty(_SELECTED, true);
- }
- },
- /**
- * @method clearActiveItem
- * @description Sets the "selected" configuration property of the menu's active
- * item to "false" and hides the item's submenu.
- * @param {Boolean} p_bBlur Boolean indicating if the menu's active item
- * should be blurred.
- */
- clearActiveItem: function (p_bBlur) {
- if (this.cfg.getProperty(_SHOW_DELAY) > 0) {
-
- this._cancelShowDelay();
-
- }
- var oActiveItem = this.activeItem,
- oConfig,
- oSubmenu;
- if (oActiveItem) {
- oConfig = oActiveItem.cfg;
- if (p_bBlur) {
- oActiveItem.blur();
-
- this.getRoot()._hasFocus = true;
-
- }
- oConfig.setProperty(_SELECTED, false);
- oSubmenu = oConfig.getProperty(_SUBMENU);
- if (oSubmenu) {
- oSubmenu.hide();
- }
- this.activeItem = null;
- }
- },
- /**
- * @method focus
- * @description Causes the menu to receive focus and fires the "focus" event.
- */
- focus: function () {
- if (!this.hasFocus()) {
- this.setInitialFocus();
-
- }
- },
- /**
- * @method blur
- * @description Causes the menu to lose focus and fires the "blur" event.
- */
- blur: function () {
- var oItem;
- if (this.hasFocus()) {
-
- oItem = MenuManager.getFocusedMenuItem();
-
- if (oItem) {
- oItem.blur();
- }
- }
- },
- /**
- * @method hasFocus
- * @description Returns a boolean indicating whether or not the menu has focus.
- * @return {Boolean}
- */
- hasFocus: function () {
- return (MenuManager.getFocusedMenu() == this.getRoot());
- },
- _doItemSubmenuSubscribe: function (p_sType, p_aArgs, p_oObject) {
- var oItem = p_aArgs[0],
- oSubmenu = oItem.cfg.getProperty(_SUBMENU);
- if (oSubmenu) {
- oSubmenu.subscribe.apply(oSubmenu, p_oObject);
- }
- },
- _doSubmenuSubscribe: function (p_sType, p_aArgs, p_oObject) {
- var oSubmenu = this.cfg.getProperty(_SUBMENU);
-
- if (oSubmenu) {
- oSubmenu.subscribe.apply(oSubmenu, p_oObject);
- }
- },
- /**
- * Adds the specified CustomEvent subscriber to the menu and each of
- * its submenus.
- * @method subscribe
- * @param p_type {string} the type, or name of the event
- * @param p_fn {function} the function to exectute when the event fires
- * @param p_obj {Object} An object to be passed along when the event
- * fires
- * @param p_override {boolean} If true, the obj passed in becomes the
- * execution scope of the listener
- */
- subscribe: function () {
- // Subscribe to the event for this Menu instance
- Menu.superclass.subscribe.apply(this, arguments);
- // Subscribe to the "itemAdded" event so that all future submenus
- // also subscribe to this event
- Menu.superclass.subscribe.call(this, _ITEM_ADDED, this._doItemSubmenuSubscribe, arguments);
- var aItems = this.getItems(),
- nItems,
- oItem,
- oSubmenu,
- i;
-
- if (aItems) {
- nItems = aItems.length;
-
- if (nItems > 0) {
-
- i = nItems - 1;
-
- do {
- oItem = aItems[i];
- oSubmenu = oItem.cfg.getProperty(_SUBMENU);
-
- if (oSubmenu) {
- oSubmenu.subscribe.apply(oSubmenu, arguments);
- }
- else {
- oItem.cfg.subscribeToConfigEvent(_SUBMENU, this._doSubmenuSubscribe, arguments);
- }
- }
- while (i--);
-
- }
- }
- },
- unsubscribe: function () {
- // Remove the event for this Menu instance
- Menu.superclass.unsubscribe.apply(this, arguments);
- // Remove the "itemAdded" event so that all future submenus don't have
- // the event handler
- Menu.superclass.unsubscribe.call(this, _ITEM_ADDED, this._doItemSubmenuSubscribe, arguments);
- var aItems = this.getItems(),
- nItems,
- oItem,
- oSubmenu,
- i;
-
- if (aItems) {
- nItems = aItems.length;
-
- if (nItems > 0) {
-
- i = nItems - 1;
-
- do {
- oItem = aItems[i];
- oSubmenu = oItem.cfg.getProperty(_SUBMENU);
-
- if (oSubmenu) {
- oSubmenu.unsubscribe.apply(oSubmenu, arguments);
- }
- else {
- oItem.cfg.unsubscribeFromConfigEvent(_SUBMENU, this._doSubmenuSubscribe, arguments);
- }
- }
- while (i--);
-
- }
- }
- },
- /**
- * @description Initializes the class's configurable properties which can be
- * changed using the menu's Config object ("cfg").
- * @method initDefaultConfig
- */
- initDefaultConfig: function () {
- Menu.superclass.initDefaultConfig.call(this);
- var oConfig = this.cfg;
- // Module documentation overrides
- /**
- * @config effect
- * @description Object or array of objects representing the ContainerEffect
- * classes that are active for animating the container. When set this
- * property is automatically applied to all submenus.
- * @type Object
- * @default null
- */
- // Overlay documentation overrides
- /**
- * @config x
- * @description Number representing the absolute x-coordinate position of
- * the Menu. This property is only applied when the "position"
- * configuration property is set to dynamic.
- * @type Number
- * @default null
- */
-
- /**
- * @config y
- * @description Number representing the absolute y-coordinate position of
- * the Menu. This property is only applied when the "position"
- * configuration property is set to dynamic.
- * @type Number
- * @default null
- */
- /**
- * @description Array of the absolute x and y positions of the Menu. This
- * property is only applied when the "position" configuration property is
- * set to dynamic.
- * @config xy
- * @type Number[]
- * @default null
- */
-
- /**
- * @config context
- * @description Array of context arguments for context-sensitive positioning.
- * The format is: [id or element, element corner, context corner].
- * For example, setting this property to ["img1", "tl", "bl"] would
- * align the Menu's top left corner to the context element's
- * bottom left corner. This property is only applied when the "position"
- * configuration property is set to dynamic.
- * @type Array
- * @default null
- */
-
-
- /**
- * @config fixedcenter
- * @description Boolean indicating if the Menu should be anchored to the
- * center of the viewport. This property is only applied when the
- * "position" configuration property is set to dynamic.
- * @type Boolean
- * @default false
- */
-
-
- /**
- * @config iframe
- * @description Boolean indicating whether or not the Menu should
- * have an IFRAME shim; used to prevent SELECT elements from
- * poking through an Overlay instance in IE6. When set to "true",
- * the iframe shim is created when the Menu instance is intially
- * made visible. This property is only applied when the "position"
- * configuration property is set to dynamic and is automatically applied
- * to all submenus.
- * @type Boolean
- * @default true for IE6 and below, false for all other browsers.
- */
- // Add configuration attributes
- /*
- Change the default value for the "visible" configuration
- property to "false" by re-adding the property.
- */
- /**
- * @config visible
- * @description Boolean indicating whether or not the menu is visible. If
- * the menu's "position" configuration property is set to "dynamic" (the
- * default), this property toggles the menu's <code><div></code>
- * element's "visibility" style property between "visible" (true) or
- * "hidden" (false). If the menu's "position" configuration property is
- * set to "static" this property toggles the menu's
- * <code><div></code> element's "display" style property
- * between "block" (true) or "none" (false).
- * @default false
- * @type Boolean
- */
- oConfig.addProperty(
- VISIBLE_CONFIG.key,
- {
- handler: this.configVisible,
- value: VISIBLE_CONFIG.value,
- validator: VISIBLE_CONFIG.validator
- }
- );
- /*
- Change the default value for the "constraintoviewport" configuration
- property (inherited by YAHOO.widget.Overlay) to "true" by re-adding the property.
- */
- /**
- * @config constraintoviewport
- * @description Boolean indicating if the menu will try to remain inside
- * the boundaries of the size of viewport. This property is only applied
- * when the "position" configuration property is set to dynamic and is
- * automatically applied to all submenus.
- * @default true
- * @type Boolean
- */
- oConfig.addProperty(
- CONSTRAIN_TO_VIEWPORT_CONFIG.key,
- {
- handler: this.configConstrainToViewport,
- value: CONSTRAIN_TO_VIEWPORT_CONFIG.value,
- validator: CONSTRAIN_TO_VIEWPORT_CONFIG.validator,
- supercedes: CONSTRAIN_TO_VIEWPORT_CONFIG.supercedes
- }
- );
- /*
- Change the default value for the "preventcontextoverlap" configuration
- property (inherited by YAHOO.widget.Overlay) to "true" by re-adding the property.
- */
- /**
- * @config preventcontextoverlap
- * @description Boolean indicating whether or not a submenu should overlap its parent MenuItem
- * when the "constraintoviewport" configuration property is set to "true".
- * @type Boolean
- * @default true
- */
- oConfig.addProperty(PREVENT_CONTEXT_OVERLAP_CONFIG.key, {
- value: PREVENT_CONTEXT_OVERLAP_CONFIG.value,
- validator: PREVENT_CONTEXT_OVERLAP_CONFIG.validator,
- supercedes: PREVENT_CONTEXT_OVERLAP_CONFIG.supercedes
- });
- /**
- * @config position
- * @description String indicating how a menu should be positioned on the
- * screen. Possible values are "static" and "dynamic." Static menus are
- * visible by default and reside in the normal flow of the document
- * (CSS position: static). Dynamic menus are hidden by default, reside
- * out of the normal flow of the document (CSS position: absolute), and
- * can overlay other elements on the screen.
- * @default dynamic
- * @type String
- */
- oConfig.addProperty(
- POSITION_CONFIG.key,
- {
- handler: this.configPosition,
- value: POSITION_CONFIG.value,
- validator: POSITION_CONFIG.validator,
- supercedes: POSITION_CONFIG.supercedes
- }
- );
- /**
- * @config submenualignment
- * @description Array defining how submenus should be aligned to their
- * parent menu item. The format is: [itemCorner, submenuCorner]. By default
- * a submenu's top left corner is aligned to its parent menu item's top
- * right corner.
- * @default ["tl","tr"]
- * @type Array
- */
- oConfig.addProperty(
- SUBMENU_ALIGNMENT_CONFIG.key,
- {
- value: SUBMENU_ALIGNMENT_CONFIG.value,
- suppressEvent: SUBMENU_ALIGNMENT_CONFIG.suppressEvent
- }
- );
- /**
- * @config autosubmenudisplay
- * @description Boolean indicating if submenus are automatically made
- * visible when the user mouses over the menu's items.
- * @default true
- * @type Boolean
- */
- oConfig.addProperty(
- AUTO_SUBMENU_DISPLAY_CONFIG.key,
- {
- value: AUTO_SUBMENU_DISPLAY_CONFIG.value,
- validator: AUTO_SUBMENU_DISPLAY_CONFIG.validator,
- suppressEvent: AUTO_SUBMENU_DISPLAY_CONFIG.suppressEvent
- }
- );
- /**
- * @config showdelay
- * @description Number indicating the time (in milliseconds) that should
- * expire before a submenu is made visible when the user mouses over
- * the menu's items. This property is only applied when the "position"
- * configuration property is set to dynamic and is automatically applied
- * to all submenus.
- * @default 250
- * @type Number
- */
- oConfig.addProperty(
- SHOW_DELAY_CONFIG.key,
- {
- value: SHOW_DELAY_CONFIG.value,
- validator: SHOW_DELAY_CONFIG.validator,
- suppressEvent: SHOW_DELAY_CONFIG.suppressEvent
- }
- );
- /**
- * @config hidedelay
- * @description Number indicating the time (in milliseconds) that should
- * expire before the menu is hidden. This property is only applied when
- * the "position" configuration property is set to dynamic and is
- * automatically applied to all submenus.
- * @default 0
- * @type Number
- */
- oConfig.addProperty(
- HIDE_DELAY_CONFIG.key,
- {
- handler: this.configHideDelay,
- value: HIDE_DELAY_CONFIG.value,
- validator: HIDE_DELAY_CONFIG.validator,
- suppressEvent: HIDE_DELAY_CONFIG.suppressEvent
- }
- );
- /**
- * @config submenuhidedelay
- * @description Number indicating the time (in milliseconds) that should
- * expire before a submenu is hidden when the user mouses out of a menu item
- * heading in the direction of a submenu. The value must be greater than or
- * equal to the value specified for the "showdelay" configuration property.
- * This property is only applied when the "position" configuration property
- * is set to dynamic and is automatically applied to all submenus.
- * @default 250
- * @type Number
- */
- oConfig.addProperty(
- SUBMENU_HIDE_DELAY_CONFIG.key,
- {
- value: SUBMENU_HIDE_DELAY_CONFIG.value,
- validator: SUBMENU_HIDE_DELAY_CONFIG.validator,
- suppressEvent: SUBMENU_HIDE_DELAY_CONFIG.suppressEvent
- }
- );
- /**
- * @config clicktohide
- * @description Boolean indicating if the menu will automatically be
- * hidden if the user clicks outside of it. This property is only
- * applied when the "position" configuration property is set to dynamic
- * and is automatically applied to all submenus.
- * @default true
- * @type Boolean
- */
- oConfig.addProperty(
- CLICK_TO_HIDE_CONFIG.key,
- {
- value: CLICK_TO_HIDE_CONFIG.value,
- validator: CLICK_TO_HIDE_CONFIG.validator,
- suppressEvent: CLICK_TO_HIDE_CONFIG.suppressEvent
- }
- );
- /**
- * @config container
- * @description HTML element reference or string specifying the id
- * attribute of the HTML element that the menu's markup should be
- * rendered into.
- * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
- * level-one-html.html#ID-58190037">HTMLElement</a>|String
- * @default document.body
- */
- oConfig.addProperty(
- CONTAINER_CONFIG.key,
- {
- handler: this.configContainer,
- value: document.body,
- suppressEvent: CONTAINER_CONFIG.suppressEvent
- }
- );
- /**
- * @config scrollincrement
- * @description Number used to control the scroll speed of a menu. Used to
- * increment the "scrollTop" property of the menu's body by when a menu's
- * content is scrolling. When set this property is automatically applied
- * to all submenus.
- * @default 1
- * @type Number
- */
- oConfig.addProperty(
- SCROLL_INCREMENT_CONFIG.key,
- {
- value: SCROLL_INCREMENT_CONFIG.value,
- validator: SCROLL_INCREMENT_CONFIG.validator,
- supercedes: SCROLL_INCREMENT_CONFIG.supercedes,
- suppressEvent: SCROLL_INCREMENT_CONFIG.suppressEvent
- }
- );
- /**
- * @config minscrollheight
- * @description Number defining the minimum threshold for the "maxheight"
- * configuration property. When set this property is automatically applied
- * to all submenus.
- * @default 90
- * @type Number
- */
- oConfig.addProperty(
- MIN_SCROLL_HEIGHT_CONFIG.key,
- {
- value: MIN_SCROLL_HEIGHT_CONFIG.value,
- validator: MIN_SCROLL_HEIGHT_CONFIG.validator,
- supercedes: MIN_SCROLL_HEIGHT_CONFIG.supercedes,
- suppressEvent: MIN_SCROLL_HEIGHT_CONFIG.suppressEvent
- }
- );
- /**
- * @config maxheight
- * @description Number defining the maximum height (in pixels) for a menu's
- * body element (<code><div class="bd"></code>). Once a menu's body
- * exceeds this height, the contents of the body are scrolled to maintain
- * this value. This value cannot be set lower than the value of the
- * "minscrollheight" configuration property.
- * @default 0
- * @type Number
- */
- oConfig.addProperty(
- MAX_HEIGHT_CONFIG.key,
- {
- handler: this.configMaxHeight,
- value: MAX_HEIGHT_CONFIG.value,
- validator: MAX_HEIGHT_CONFIG.validator,
- suppressEvent: MAX_HEIGHT_CONFIG.suppressEvent,
- supercedes: MAX_HEIGHT_CONFIG.supercedes
- }
- );
- /**
- * @config classname
- * @description String representing the CSS class to be applied to the
- * menu's root <code><div></code> element. The specified class(es)
- * are appended in addition to the default class as specified by the menu's
- * CSS_CLASS_NAME constant. When set this property is automatically
- * applied to all submenus.
- * @default null
- * @type String
- */
- oConfig.addProperty(
- CLASS_NAME_CONFIG.key,
- {
- handler: this.configClassName,
- value: CLASS_NAME_CONFIG.value,
- validator: CLASS_NAME_CONFIG.validator,
- supercedes: CLASS_NAME_CONFIG.supercedes
- }
- );
- /**
- * @config disabled
- * @description Boolean indicating if the menu should be disabled.
- * Disabling a menu disables each of its items. (Disabled menu items are
- * dimmed and will not respond to user input or fire events.) Disabled
- * menus have a corresponding "disabled" CSS class applied to their root
- * <code><div></code> element.
- * @default false
- * @type Boolean
- */
- oConfig.addProperty(
- DISABLED_CONFIG.key,
- {
- handler: this.configDisabled,
- value: DISABLED_CONFIG.value,
- validator: DISABLED_CONFIG.validator,
- suppressEvent: DISABLED_CONFIG.suppressEvent
- }
- );
- /**
- * @config shadow
- * @description Boolean indicating if the menu should have a shadow.
- * @default true
- * @type Boolean
- */
- oConfig.addProperty(
- SHADOW_CONFIG.key,
- {
- handler: this.configShadow,
- value: SHADOW_CONFIG.value,
- validator: SHADOW_CONFIG.validator
- }
- );
- /**
- * @config keepopen
- * @description Boolean indicating if the menu should remain open when clicked.
- * @default false
- * @type Boolean
- */
- oConfig.addProperty(
- KEEP_OPEN_CONFIG.key,
- {
- value: KEEP_OPEN_CONFIG.value,
- validator: KEEP_OPEN_CONFIG.validator
- }
- );
- }
- }); // END YAHOO.lang.extend
- })();
- (function () {
- /**
- * Creates an item for a menu.
- *
- * @param {String} p_oObject String specifying the text of the menu item.
- * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
- * one-html.html#ID-74680021">HTMLLIElement</a>} p_oObject Object specifying
- * the <code><li></code> element of the menu item.
- * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
- * one-html.html#ID-38450247">HTMLOptGroupElement</a>} p_oObject Object
- * specifying the <code><optgroup></code> element of the menu item.
- * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
- * one-html.html#ID-70901257">HTMLOptionElement</a>} p_oObject Object
- * specifying the <code><option></code> element of the menu item.
- * @param {Object} p_oConfig Optional. Object literal specifying the
- * configuration for the menu item. See configuration class documentation
- * for more details.
- * @class MenuItem
- * @constructor
- */
- YAHOO.widget.MenuItem = function (p_oObject, p_oConfig) {
- if (p_oObject) {
- if (p_oConfig) {
-
- this.parent = p_oConfig.parent;
- this.value = p_oConfig.value;
- this.id = p_oConfig.id;
- }
- this.init(p_oObject, p_oConfig);
- }
- };
- var Dom = YAHOO.util.Dom,
- Module = YAHOO.widget.Module,
- Menu = YAHOO.widget.Menu,
- MenuItem = YAHOO.widget.MenuItem,
- CustomEvent = YAHOO.util.CustomEvent,
- UA = YAHOO.env.ua,
- Lang = YAHOO.lang,
- // Private string constants
- _TEXT = "text",
- _HASH = "#",
- _HYPHEN = "-",
- _HELP_TEXT = "helptext",
- _URL = "url",
- _TARGET = "target",
- _EMPHASIS = "emphasis",
- _STRONG_EMPHASIS = "strongemphasis",
- _CHECKED = "checked",
- _SUBMENU = "submenu",
- _DISABLED = "disabled",
- _SELECTED = "selected",
- _HAS_SUBMENU = "hassubmenu",
- _CHECKED_DISABLED = "checked-disabled",
- _HAS_SUBMENU_DISABLED = "hassubmenu-disabled",
- _HAS_SUBMENU_SELECTED = "hassubmenu-selected",
- _CHECKED_SELECTED = "checked-selected",
- _ONCLICK = "onclick",
- _CLASSNAME = "classname",
- _EMPTY_STRING = "",
- _OPTION = "OPTION",
- _OPTGROUP = "OPTGROUP",
- _LI_UPPERCASE = "LI",
- _HREF = "href",
- _SELECT = "SELECT",
- _DIV = "DIV",
- _START_HELP_TEXT = "<em class=\"helptext\">",
- _START_EM = "<em>",
- _END_EM = "</em>",
- _START_STRONG = "<strong>",
- _END_STRONG = "</strong>",
- _PREVENT_CONTEXT_OVERLAP = "preventcontextoverlap",
- _OBJ = "obj",
- _SCOPE = "scope",
- _NONE = "none",
- _VISIBLE = "visible",
- _SPACE = " ",
- _MENUITEM = "MenuItem",
- _CLICK = "click",
- _SHOW = "show",
- _HIDE = "hide",
- _LI_LOWERCASE = "li",
- _ANCHOR_TEMPLATE = "<a href=\"#\"></a>",
- EVENT_TYPES = [
-
- ["mouseOverEvent", "mouseover"],
- ["mouseOutEvent", "mouseout"],
- ["mouseDownEvent", "mousedown"],
- ["mouseUpEvent", "mouseup"],
- ["clickEvent", _CLICK],
- ["keyPressEvent", "keypress"],
- ["keyDownEvent", "keydown"],
- ["keyUpEvent", "keyup"],
- ["focusEvent", "focus"],
- ["blurEvent", "blur"],
- ["destroyEvent", "destroy"]
-
- ],
- TEXT_CONFIG = {
- key: _TEXT,
- value: _EMPTY_STRING,
- validator: Lang.isString,
- suppressEvent: true
- },
- HELP_TEXT_CONFIG = {
- key: _HELP_TEXT,
- supercedes: [_TEXT],
- suppressEvent: true
- },
- URL_CONFIG = {
- key: _URL,
- value: _HASH,
- suppressEvent: true
- },
- TARGET_CONFIG = {
- key: _TARGET,
- suppressEvent: true
- },
- EMPHASIS_CONFIG = {
- key: _EMPHASIS,
- value: false,
- validator: Lang.isBoolean,
- suppressEvent: true,
- supercedes: [_TEXT]
- },
- STRONG_EMPHASIS_CONFIG = {
- key: _STRONG_EMPHASIS,
- value: false,
- validator: Lang.isBoolean,
- suppressEvent: true,
- supercedes: [_TEXT]
- },
- CHECKED_CONFIG = {
- key: _CHECKED,
- value: false,
- validator: Lang.isBoolean,
- suppressEvent: true,
- supercedes: [_DISABLED, _SELECTED]
- },
- SUBMENU_CONFIG = {
- key: _SUBMENU,
- suppressEvent: true,
- supercedes: [_DISABLED, _SELECTED]
- },
- DISABLED_CONFIG = {
- key: _DISABLED,
- value: false,
- validator: Lang.isBoolean,
- suppressEvent: true,
- supercedes: [_TEXT, _SELECTED]
- },
- SELECTED_CONFIG = {
- key: _SELECTED,
- value: false,
- validator: Lang.isBoolean,
- suppressEvent: true
- },
- ONCLICK_CONFIG = {
- key: _ONCLICK,
- suppressEvent: true
- },
- CLASS_NAME_CONFIG = {
- key: _CLASSNAME,
- value: null,
- validator: Lang.isString,
- suppressEvent: true
- },
-
- KEY_LISTENER_CONFIG = {
- key: "keylistener",
- value: null,
- suppressEvent: true
- },
- m_oMenuItemTemplate = null,
- CLASS_NAMES = {};
- /**
- * @method getClassNameForState
- * @description Returns a class name for the specified prefix and state. If the class name does not
- * yet exist, it is created and stored in the CLASS_NAMES object to increase performance.
- * @private
- * @param {String} prefix String representing the prefix for the class name
- * @param {String} state String representing a state - "disabled," "checked," etc.
- */
- var getClassNameForState = function (prefix, state) {
- var oClassNames = CLASS_NAMES[prefix];
-
- if (!oClassNames) {
- CLASS_NAMES[prefix] = {};
- oClassNames = CLASS_NAMES[prefix];
- }
- var sClassName = oClassNames[state];
- if (!sClassName) {
- sClassName = prefix + _HYPHEN + state;
- oClassNames[state] = sClassName;
- }
- return sClassName;
-
- };
- /**
- * @method addClassNameForState
- * @description Applies a class name to a MenuItem instance's <LI> and <A> elements
- * that represents a MenuItem's state - "disabled," "checked," etc.
- * @private
- * @param {String} state String representing a state - "disabled," "checked," etc.
- */
- var addClassNameForState = function (state) {
- Dom.addClass(this.element, getClassNameForState(this.CSS_CLASS_NAME, state));
- Dom.addClass(this._oAnchor, getClassNameForState(this.CSS_LABEL_CLASS_NAME, state));
- };
- /**
- * @method removeClassNameForState
- * @description Removes a class name from a MenuItem instance's <LI> and <A> elements
- * that represents a MenuItem's state - "disabled," "checked," etc.
- * @private
- * @param {String} state String representing a state - "disabled," "checked," etc.
- */
- var removeClassNameForState = function (state) {
- Dom.removeClass(this.element, getClassNameForState(this.CSS_CLASS_NAME, state));
- Dom.removeClass(this._oAnchor, getClassNameForState(this.CSS_LABEL_CLASS_NAME, state));
- };
- MenuItem.prototype = {
- /**
- * @property CSS_CLASS_NAME
- * @description String representing the CSS class(es) to be applied to the
- * <code><li></code> element of the menu item.
- * @default "yuimenuitem"
- * @final
- * @type String
- */
- CSS_CLASS_NAME: "yuimenuitem",
- /**
- * @property CSS_LABEL_CLASS_NAME
- * @description String representing the CSS class(es) to be applied to the
- * menu item's <code><a></code> element.
- * @default "yuimenuitemlabel"
- * @final
- * @type String
- */
- CSS_LABEL_CLASS_NAME: "yuimenuitemlabel",
- /**
- * @property SUBMENU_TYPE
- * @description Object representing the type of menu to instantiate and
- * add when parsing the child nodes of the menu item's source HTML element.
- * @final
- * @type YAHOO.widget.Menu
- */
- SUBMENU_TYPE: null,
- // Private member variables
-
- /**
- * @property _oAnchor
- * @description Object reference to the menu item's
- * <code><a></code> element.
- * @default null
- * @private
- * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
- * one-html.html#ID-48250443">HTMLAnchorElement</a>
- */
- _oAnchor: null,
-
-
- /**
- * @property _oHelpTextEM
- * @description Object reference to the menu item's help text
- * <code><em></code> element.
- * @default null
- * @private
- * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
- * one-html.html#ID-58190037">HTMLElement</a>
- */
- _oHelpTextEM: null,
-
-
- /**
- * @property _oSubmenu
- * @description Object reference to the menu item's submenu.
- * @default null
- * @private
- * @type YAHOO.widget.Menu
- */
- _oSubmenu: null,
- /**
- * @property _oOnclickAttributeValue
- * @description Object reference to the menu item's current value for the
- * "onclick" configuration attribute.
- * @default null
- * @private
- * @type Object
- */
- _oOnclickAttributeValue: null,
- /**
- * @property _sClassName
- * @description The current value of the "classname" configuration attribute.
- * @default null
- * @private
- * @type String
- */
- _sClassName: null,
- // Public properties
- /**
- * @property constructor
- * @description Object reference to the menu item's constructor function.
- * @default YAHOO.widget.MenuItem
- * @type YAHOO.widget.MenuItem
- */
- constructor: MenuItem,
- /**
- * @property index
- * @description Number indicating the ordinal position of the menu item in
- * its group.
- * @default null
- * @type Number
- */
- index: null,
- /**
- * @property groupIndex
- * @description Number indicating the index of the group to which the menu
- * item belongs.
- * @default null
- * @type Number
- */
- groupIndex: null,
- /**
- * @property parent
- * @description Object reference to the menu item's parent menu.
- * @default null
- * @type YAHOO.widget.Menu
- */
- parent: null,
- /**
- * @property element
- * @description Object reference to the menu item's
- * <code><li></code> element.
- * @default <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level
- * -one-html.html#ID-74680021">HTMLLIElement</a>
- * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
- * one-html.html#ID-74680021">HTMLLIElement</a>
- */
- element: null,
- /**
- * @property srcElement
- * @description Object reference to the HTML element (either
- * <code><li></code>, <code><optgroup></code> or
- * <code><option></code>) used create the menu item.
- * @default <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
- * level-one-html.html#ID-74680021">HTMLLIElement</a>|<a href="http://www.
- * w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-html.html#ID-38450247"
- * >HTMLOptGroupElement</a>|<a href="http://www.w3.org/TR/2000/WD-DOM-
- * Level-1-20000929/level-one-html.html#ID-70901257">HTMLOptionElement</a>
- * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
- * one-html.html#ID-74680021">HTMLLIElement</a>|<a href="http://www.w3.
- * org/TR/2000/WD-DOM-Level-1-20000929/level-one-html.html#ID-38450247">
- * HTMLOptGroupElement</a>|<a href="http://www.w3.org/TR/2000/WD-DOM-
- * Level-1-20000929/level-one-html.html#ID-70901257">HTMLOptionElement</a>
- */
- srcElement: null,
- /**
- * @property value
- * @description Object reference to the menu item's value.
- * @default null
- * @type Object
- */
- value: null,
- /**
- * @property browser
- * @deprecated Use YAHOO.env.ua
- * @description String representing the browser.
- * @type String
- */
- browser: Module.prototype.browser,
- /**
- * @property id
- * @description Id of the menu item's root <code><li></code>
- * element. This property should be set via the constructor using the
- * configuration object literal. If an id is not specified, then one will
- * be created using the "generateId" method of the Dom utility.
- * @default null
- * @type String
- */
- id: null,
- // Events
- /**
- * @event destroyEvent
- * @description Fires when the menu item's <code><li></code>
- * element is removed from its parent <code><ul></code> element.
- * @type YAHOO.util.CustomEvent
- */
- /**
- * @event mouseOverEvent
- * @description Fires when the mouse has entered the menu item. Passes
- * back the DOM Event object as an argument.
- * @type YAHOO.util.CustomEvent
- */
- /**
- * @event mouseOutEvent
- * @description Fires when the mouse has left the menu item. Passes back
- * the DOM Event object as an argument.
- * @type YAHOO.util.CustomEvent
- */
- /**
- * @event mouseDownEvent
- * @description Fires when the user mouses down on the menu item. Passes
- * back the DOM Event object as an argument.
- * @type YAHOO.util.CustomEvent
- */
- /**
- * @event mouseUpEvent
- * @description Fires when the user releases a mouse button while the mouse
- * is over the menu item. Passes back the DOM Event object as an argument.
- * @type YAHOO.util.CustomEvent
- */
- /**
- * @event clickEvent
- * @description Fires when the user clicks the on the menu item. Passes
- * back the DOM Event object as an argument.
- * @type YAHOO.util.CustomEvent
- */
- /**
- * @event keyPressEvent
- * @description Fires when the user presses an alphanumeric key when the
- * menu item has focus. Passes back the DOM Event object as an argument.
- * @type YAHOO.util.CustomEvent
- */
- /**
- * @event keyDownEvent
- * @description Fires when the user presses a key when the menu item has
- * focus. Passes back the DOM Event object as an argument.
- * @type YAHOO.util.CustomEvent
- */
- /**
- * @event keyUpEvent
- * @description Fires when the user releases a key when the menu item has
- * focus. Passes back the DOM Event object as an argument.
- * @type YAHOO.util.CustomEvent
- */
- /**
- * @event focusEvent
- * @description Fires when the menu item receives focus.
- * @type YAHOO.util.CustomEvent
- */
- /**
- * @event blurEvent
- * @description Fires when the menu item loses the input focus.
- * @type YAHOO.util.CustomEvent
- */
- /**
- * @method init
- * @description The MenuItem class's initialization method. This method is
- * automatically called by the constructor, and sets up all DOM references
- * for pre-existing markup, and creates required markup if it is not
- * already present.
- * @param {String} p_oObject String specifying the text of the menu item.
- * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
- * one-html.html#ID-74680021">HTMLLIElement</a>} p_oObject Object specifying
- * the <code><li></code> element of the menu item.
- * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
- * one-html.html#ID-38450247">HTMLOptGroupElement</a>} p_oObject Object
- * specifying the <code><optgroup></code> element of the menu item.
- * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
- * one-html.html#ID-70901257">HTMLOptionElement</a>} p_oObject Object
- * specifying the <code><option></code> element of the menu item.
- * @param {Object} p_oConfig Optional. Object literal specifying the
- * configuration for the menu item. See configuration class documentation
- * for more details.
- */
- init: function (p_oObject, p_oConfig) {
- if (!this.SUBMENU_TYPE) {
-
- this.SUBMENU_TYPE = Menu;
-
- }
- // Create the config object
- this.cfg = new YAHOO.util.Config(this);
- this.initDefaultConfig();
- var oConfig = this.cfg,
- sURL = _HASH,
- oCustomEvent,
- aEventData,
- oAnchor,
- sTarget,
- sText,
- sId,
- i;
- if (Lang.isString(p_oObject)) {
- this._createRootNodeStructure();
- oConfig.queueProperty(_TEXT, p_oObject);
- }
- else if (p_oObject && p_oObject.tagName) {
- switch(p_oObject.tagName.toUpperCase()) {
- case _OPTION:
- this._createRootNodeStructure();
- oConfig.queueProperty(_TEXT, p_oObject.text);
- oConfig.queueProperty(_DISABLED, p_oObject.disabled);
- this.value = p_oObject.value;
- this.srcElement = p_oObject;
- break;
- case _OPTGROUP:
- this._createRootNodeStructure();
- oConfig.queueProperty(_TEXT, p_oObject.label);
- oConfig.queueProperty(_DISABLED, p_oObject.disabled);
- this.srcElement = p_oObject;
- this._initSubTree();
- break;
- case _LI_UPPERCASE:
- // Get the anchor node (if it exists)
-
- oAnchor = Dom.getFirstChild(p_oObject);
- // Capture the "text" and/or the "URL"
- if (oAnchor) {
- sURL = oAnchor.getAttribute(_HREF, 2);
- sTarget = oAnchor.getAttribute(_TARGET);
- sText = oAnchor.innerHTML;
- }
- this.srcElement = p_oObject;
- this.element = p_oObject;
- this._oAnchor = oAnchor;
- /*
- Set these properties silently to sync up the
- configuration object without making changes to the
- element's DOM
- */
- oConfig.setProperty(_TEXT, sText, true);
- oConfig.setProperty(_URL, sURL, true);
- oConfig.setProperty(_TARGET, sTarget, true);
- this._initSubTree();
- break;
- }
- }
- if (this.element) {
- sId = (this.srcElement || this.element).id;
- if (!sId) {
- sId = this.id || Dom.generateId();
- this.element.id = sId;
- }
- this.id = sId;
- Dom.addClass(this.element, this.CSS_CLASS_NAME);
- Dom.addClass(this._oAnchor, this.CSS_LABEL_CLASS_NAME);
- i = EVENT_TYPES.length - 1;
- do {
- aEventData = EVENT_TYPES[i];
- oCustomEvent = this.createEvent(aEventData[1]);
- oCustomEvent.signature = CustomEvent.LIST;
-
- this[aEventData[0]] = oCustomEvent;
- }
- while (i--);
- if (p_oConfig) {
-
- oConfig.applyConfig(p_oConfig);
-
- }
- oConfig.fireQueue();
- }
- },
- // Private methods
- /**
- * @method _createRootNodeStructure
- * @description Creates the core DOM structure for the menu item.
- * @private
- */
- _createRootNodeStructure: function () {
- var oElement,
- oAnchor;
- if (!m_oMenuItemTemplate) {
- m_oMenuItemTemplate = document.createElement(_LI_LOWERCASE);
- m_oMenuItemTemplate.innerHTML = _ANCHOR_TEMPLATE;
- }
- oElement = m_oMenuItemTemplate.cloneNode(true);
- oElement.className = this.CSS_CLASS_NAME;
- oAnchor = oElement.firstChild;
- oAnchor.className = this.CSS_LABEL_CLASS_NAME;
- this.element = oElement;
- this._oAnchor = oAnchor;
- },
- /**
- * @method _initSubTree
- * @description Iterates the source element's childNodes collection and uses
- * the child nodes to instantiate other menus.
- * @private
- */
- _initSubTree: function () {
- var oSrcEl = this.srcElement,
- oConfig = this.cfg,
- oNode,
- aOptions,
- nOptions,
- oMenu,
- n;
- if (oSrcEl.childNodes.length > 0) {
- if (this.parent.lazyLoad && this.parent.srcElement &&
- this.parent.srcElement.tagName.toUpperCase() == _SELECT) {
- oConfig.setProperty(
- _SUBMENU,
- { id: Dom.generateId(), itemdata: oSrcEl.childNodes }
- );
- }
- else {
- oNode = oSrcEl.firstChild;
- aOptions = [];
-
- do {
-
- if (oNode && oNode.tagName) {
-
- switch(oNode.tagName.toUpperCase()) {
-
- case _DIV:
-
- oConfig.setProperty(_SUBMENU, oNode);
-
- break;
-
- case _OPTION:
-
- aOptions[aOptions.length] = oNode;
-
- break;
-
- }
-
- }
-
- }
- while((oNode = oNode.nextSibling));
-
-
- nOptions = aOptions.length;
-
- if (nOptions > 0) {
-
- oMenu = new this.SUBMENU_TYPE(Dom.generateId());
-
- oConfig.setProperty(_SUBMENU, oMenu);
-
- for(n=0; n<nOptions; n++) {
-
- oMenu.addItem((new oMenu.ITEM_TYPE(aOptions[n])));
-
- }
-
- }
-
- }
- }
- },
- // Event handlers for configuration properties
- /**
- * @method configText
- * @description Event handler for when the "text" configuration property of
- * the menu item changes.
- * @param {String} p_sType String representing the name of the event that
- * was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event was fired.
- * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
- * that fired the event.
- */
- configText: function (p_sType, p_aArgs, p_oItem) {
- var sText = p_aArgs[0],
- oConfig = this.cfg,
- oAnchor = this._oAnchor,
- sHelpText = oConfig.getProperty(_HELP_TEXT),
- sHelpTextHTML = _EMPTY_STRING,
- sEmphasisStartTag = _EMPTY_STRING,
- sEmphasisEndTag = _EMPTY_STRING;
- if (sText) {
- if (sHelpText) {
-
- sHelpTextHTML = _START_HELP_TEXT + sHelpText + _END_EM;
-
- }
- if (oConfig.getProperty(_EMPHASIS)) {
- sEmphasisStartTag = _START_EM;
- sEmphasisEndTag = _END_EM;
- }
- if (oConfig.getProperty(_STRONG_EMPHASIS)) {
- sEmphasisStartTag = _START_STRONG;
- sEmphasisEndTag = _END_STRONG;
-
- }
- oAnchor.innerHTML = (sEmphasisStartTag + sText + sEmphasisEndTag + sHelpTextHTML);
- }
- },
- /**
- * @method configHelpText
- * @description Event handler for when the "helptext" configuration property
- * of the menu item changes.
- * @param {String} p_sType String representing the name of the event that
- * was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event was fired.
- * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
- * that fired the event.
- */
- configHelpText: function (p_sType, p_aArgs, p_oItem) {
- this.cfg.refireEvent(_TEXT);
- },
- /**
- * @method configURL
- * @description Event handler for when the "url" configuration property of
- * the menu item changes.
- * @param {String} p_sType String representing the name of the event that
- * was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event was fired.
- * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
- * that fired the event.
- */
- configURL: function (p_sType, p_aArgs, p_oItem) {
- var sURL = p_aArgs[0];
- if (!sURL) {
- sURL = _HASH;
- }
- var oAnchor = this._oAnchor;
- if (UA.opera) {
- oAnchor.removeAttribute(_HREF);
-
- }
- oAnchor.setAttribute(_HREF, sURL);
- },
- /**
- * @method configTarget
- * @description Event handler for when the "target" configuration property
- * of the menu item changes.
- * @param {String} p_sType String representing the name of the event that
- * was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event was fired.
- * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
- * that fired the event.
- */
- configTarget: function (p_sType, p_aArgs, p_oItem) {
- var sTarget = p_aArgs[0],
- oAnchor = this._oAnchor;
- if (sTarget && sTarget.length > 0) {
- oAnchor.setAttribute(_TARGET, sTarget);
- }
- else {
- oAnchor.removeAttribute(_TARGET);
-
- }
- },
- /**
- * @method configEmphasis
- * @description Event handler for when the "emphasis" configuration property
- * of the menu item changes.
- * @param {String} p_sType String representing the name of the event that
- * was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event was fired.
- * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
- * that fired the event.
- */
- configEmphasis: function (p_sType, p_aArgs, p_oItem) {
- var bEmphasis = p_aArgs[0],
- oConfig = this.cfg;
- if (bEmphasis && oConfig.getProperty(_STRONG_EMPHASIS)) {
- oConfig.setProperty(_STRONG_EMPHASIS, false);
- }
- oConfig.refireEvent(_TEXT);
- },
- /**
- * @method configStrongEmphasis
- * @description Event handler for when the "strongemphasis" configuration
- * property of the menu item changes.
- * @param {String} p_sType String representing the name of the event that
- * was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event was fired.
- * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
- * that fired the event.
- */
- configStrongEmphasis: function (p_sType, p_aArgs, p_oItem) {
- var bStrongEmphasis = p_aArgs[0],
- oConfig = this.cfg;
- if (bStrongEmphasis && oConfig.getProperty(_EMPHASIS)) {
- oConfig.setProperty(_EMPHASIS, false);
- }
- oConfig.refireEvent(_TEXT);
- },
- /**
- * @method configChecked
- * @description Event handler for when the "checked" configuration property
- * of the menu item changes.
- * @param {String} p_sType String representing the name of the event that
- * was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event was fired.
- * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
- * that fired the event.
- */
- configChecked: function (p_sType, p_aArgs, p_oItem) {
- var bChecked = p_aArgs[0],
- oConfig = this.cfg;
- if (bChecked) {
- addClassNameForState.call(this, _CHECKED);
- }
- else {
- removeClassNameForState.call(this, _CHECKED);
- }
- oConfig.refireEvent(_TEXT);
- if (oConfig.getProperty(_DISABLED)) {
- oConfig.refireEvent(_DISABLED);
- }
- if (oConfig.getProperty(_SELECTED)) {
- oConfig.refireEvent(_SELECTED);
- }
- },
- /**
- * @method configDisabled
- * @description Event handler for when the "disabled" configuration property
- * of the menu item changes.
- * @param {String} p_sType String representing the name of the event that
- * was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event was fired.
- * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
- * that fired the event.
- */
- configDisabled: function (p_sType, p_aArgs, p_oItem) {
- var bDisabled = p_aArgs[0],
- oConfig = this.cfg,
- oSubmenu = oConfig.getProperty(_SUBMENU),
- bChecked = oConfig.getProperty(_CHECKED);
- if (bDisabled) {
- if (oConfig.getProperty(_SELECTED)) {
- oConfig.setProperty(_SELECTED, false);
- }
- addClassNameForState.call(this, _DISABLED);
- if (oSubmenu) {
- addClassNameForState.call(this, _HAS_SUBMENU_DISABLED);
-
- }
-
- if (bChecked) {
- addClassNameForState.call(this, _CHECKED_DISABLED);
- }
- }
- else {
- removeClassNameForState.call(this, _DISABLED);
- if (oSubmenu) {
- removeClassNameForState.call(this, _HAS_SUBMENU_DISABLED);
-
- }
-
- if (bChecked) {
- removeClassNameForState.call(this, _CHECKED_DISABLED);
- }
- }
- },
- /**
- * @method configSelected
- * @description Event handler for when the "selected" configuration property
- * of the menu item changes.
- * @param {String} p_sType String representing the name of the event that
- * was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event was fired.
- * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
- * that fired the event.
- */
- configSelected: function (p_sType, p_aArgs, p_oItem) {
- var oConfig = this.cfg,
- oAnchor = this._oAnchor,
-
- bSelected = p_aArgs[0],
- bChecked = oConfig.getProperty(_CHECKED),
- oSubmenu = oConfig.getProperty(_SUBMENU);
- if (UA.opera) {
- oAnchor.blur();
-
- }
- if (bSelected && !oConfig.getProperty(_DISABLED)) {
- addClassNameForState.call(this, _SELECTED);
- if (oSubmenu) {
- addClassNameForState.call(this, _HAS_SUBMENU_SELECTED);
-
- }
- if (bChecked) {
- addClassNameForState.call(this, _CHECKED_SELECTED);
- }
- }
- else {
- removeClassNameForState.call(this, _SELECTED);
- if (oSubmenu) {
- removeClassNameForState.call(this, _HAS_SUBMENU_SELECTED);
-
- }
- if (bChecked) {
- removeClassNameForState.call(this, _CHECKED_SELECTED);
- }
- }
- if (this.hasFocus() && UA.opera) {
-
- oAnchor.focus();
-
- }
- },
- /**
- * @method _onSubmenuBeforeHide
- * @description "beforehide" Custom Event handler for a submenu.
- * @private
- * @param {String} p_sType String representing the name of the event that
- * was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event was fired.
- */
- _onSubmenuBeforeHide: function (p_sType, p_aArgs) {
- var oItem = this.parent,
- oMenu;
- function onHide() {
- oItem._oAnchor.blur();
- oMenu.beforeHideEvent.unsubscribe(onHide);
-
- }
- if (oItem.hasFocus()) {
- oMenu = oItem.parent;
- oMenu.beforeHideEvent.subscribe(onHide);
-
- }
-
- },
- /**
- * @method configSubmenu
- * @description Event handler for when the "submenu" configuration property
- * of the menu item changes.
- * @param {String} p_sType String representing the name of the event that
- * was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event was fired.
- * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
- * that fired the event.
- */
- configSubmenu: function (p_sType, p_aArgs, p_oItem) {
- var oSubmenu = p_aArgs[0],
- oConfig = this.cfg,
- bLazyLoad = this.parent && this.parent.lazyLoad,
- oMenu,
- sSubmenuId,
- oSubmenuConfig;
- if (oSubmenu) {
- if (oSubmenu instanceof Menu) {
- oMenu = oSubmenu;
- oMenu.parent = this;
- oMenu.lazyLoad = bLazyLoad;
- }
- else if (Lang.isObject(oSubmenu) && oSubmenu.id && !oSubmenu.nodeType) {
- sSubmenuId = oSubmenu.id;
- oSubmenuConfig = oSubmenu;
- oSubmenuConfig.lazyload = bLazyLoad;
- oSubmenuConfig.parent = this;
- oMenu = new this.SUBMENU_TYPE(sSubmenuId, oSubmenuConfig);
- // Set the value of the property to the Menu instance
- oConfig.setProperty(_SUBMENU, oMenu, true);
- }
- else {
- oMenu = new this.SUBMENU_TYPE(oSubmenu, { lazyload: bLazyLoad, parent: this });
- // Set the value of the property to the Menu instance
-
- oConfig.setProperty(_SUBMENU, oMenu, true);
- }
- if (oMenu) {
- oMenu.cfg.setProperty(_PREVENT_CONTEXT_OVERLAP, true);
- addClassNameForState.call(this, _HAS_SUBMENU);
- if (oConfig.getProperty(_URL) === _HASH) {
-
- oConfig.setProperty(_URL, (_HASH + oMenu.id));
-
- }
- this._oSubmenu = oMenu;
- if (UA.opera) {
-
- oMenu.beforeHideEvent.subscribe(this._onSubmenuBeforeHide);
-
- }
-
- }
- }
- else {
- removeClassNameForState.call(this, _HAS_SUBMENU);
- if (this._oSubmenu) {
- this._oSubmenu.destroy();
- }
- }
- if (oConfig.getProperty(_DISABLED)) {
- oConfig.refireEvent(_DISABLED);
- }
- if (oConfig.getProperty(_SELECTED)) {
- oConfig.refireEvent(_SELECTED);
- }
- },
- /**
- * @method configOnClick
- * @description Event handler for when the "onclick" configuration property
- * of the menu item changes.
- * @param {String} p_sType String representing the name of the event that
- * was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event was fired.
- * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
- * that fired the event.
- */
- configOnClick: function (p_sType, p_aArgs, p_oItem) {
- var oObject = p_aArgs[0];
- /*
- Remove any existing listeners if a "click" event handler has
- already been specified.
- */
- if (this._oOnclickAttributeValue && (this._oOnclickAttributeValue != oObject)) {
- this.clickEvent.unsubscribe(this._oOnclickAttributeValue.fn,
- this._oOnclickAttributeValue.obj);
- this._oOnclickAttributeValue = null;
- }
- if (!this._oOnclickAttributeValue && Lang.isObject(oObject) &&
- Lang.isFunction(oObject.fn)) {
-
- this.clickEvent.subscribe(oObject.fn,
- ((_OBJ in oObject) ? oObject.obj : this),
- ((_SCOPE in oObject) ? oObject.scope : null) );
- this._oOnclickAttributeValue = oObject;
- }
-
- },
- /**
- * @method configClassName
- * @description Event handler for when the "classname" configuration
- * property of a menu item changes.
- * @param {String} p_sType String representing the name of the event that
- * was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event was fired.
- * @param {YAHOO.widget.MenuItem} p_oItem Object representing the menu item
- * that fired the event.
- */
- configClassName: function (p_sType, p_aArgs, p_oItem) {
-
- var sClassName = p_aArgs[0];
-
- if (this._sClassName) {
-
- Dom.removeClass(this.element, this._sClassName);
-
- }
-
- Dom.addClass(this.element, sClassName);
- this._sClassName = sClassName;
-
- },
- /**
- * @method _dispatchClickEvent
- * @description Dispatches a DOM "click" event to the anchor element of a
- * MenuItem instance.
- * @private
- */
- _dispatchClickEvent: function () {
- var oMenuItem = this,
- oAnchor,
- oEvent;
- if (!oMenuItem.cfg.getProperty(_DISABLED)) {
- oAnchor = Dom.getFirstChild(oMenuItem.element);
- // Dispatch a "click" event to the MenuItem's anchor so that its
- // "click" event handlers will get called in response to the user
- // pressing the keyboard shortcut defined by the "keylistener"
- // configuration property.
- if (UA.ie) {
- oAnchor.fireEvent(_ONCLICK);
- }
- else {
- if ((UA.gecko && UA.gecko >= 1.9) || UA.opera || UA.webkit) {
- oEvent = document.createEvent("HTMLEvents");
- oEvent.initEvent(_CLICK, true, true);
- }
- else {
- oEvent = document.createEvent("MouseEvents");
- oEvent.initMouseEvent(_CLICK, true, true, window, 0, 0, 0,
- 0, 0, false, false, false, false, 0, null);
- }
- oAnchor.dispatchEvent(oEvent);
- }
- }
- },
- /**
- * @method _createKeyListener
- * @description "show" event handler for a Menu instance - responsible for
- * setting up the KeyListener instance for a MenuItem.
- * @private
- * @param {String} type String representing the name of the event that
- * was fired.
- * @param {Array} args Array of arguments sent when the event was fired.
- * @param {Array} keyData Array of arguments sent when the event was fired.
- */
- _createKeyListener: function (type, args, keyData) {
- var oMenuItem = this,
- oMenu = oMenuItem.parent;
- var oKeyListener = new YAHOO.util.KeyListener(
- oMenu.element.ownerDocument,
- keyData,
- {
- fn: oMenuItem._dispatchClickEvent,
- scope: oMenuItem,
- correctScope: true });
- if (oMenu.cfg.getProperty(_VISIBLE)) {
- oKeyListener.enable();
- }
- oMenu.subscribe(_SHOW, oKeyListener.enable, null, oKeyListener);
- oMenu.subscribe(_HIDE, oKeyListener.disable, null, oKeyListener);
-
- oMenuItem._keyListener = oKeyListener;
-
- oMenu.unsubscribe(_SHOW, oMenuItem._createKeyListener, keyData);
-
- },
- /**
- * @method configKeyListener
- * @description Event handler for when the "keylistener" configuration
- * property of a menu item changes.
- * @param {String} p_sType String representing the name of the event that
- * was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event was fired.
- */
- configKeyListener: function (p_sType, p_aArgs) {
- var oKeyData = p_aArgs[0],
- oMenuItem = this,
- oMenu = oMenuItem.parent;
- if (oMenuItem._keyData) {
- // Unsubscribe from the "show" event in case the keylistener
- // config was changed before the Menu was ever made visible.
- oMenu.unsubscribe(_SHOW,
- oMenuItem._createKeyListener, oMenuItem._keyData);
- oMenuItem._keyData = null;
-
- }
- // Tear down for the previous value of the "keylistener" property
- if (oMenuItem._keyListener) {
- oMenu.unsubscribe(_SHOW, oMenuItem._keyListener.enable);
- oMenu.unsubscribe(_HIDE, oMenuItem._keyListener.disable);
- oMenuItem._keyListener.disable();
- oMenuItem._keyListener = null;
- }
- if (oKeyData) {
-
- oMenuItem._keyData = oKeyData;
- // Defer the creation of the KeyListener instance until the
- // parent Menu is visible. This is necessary since the
- // KeyListener instance needs to be bound to the document the
- // Menu has been rendered into. Deferring creation of the
- // KeyListener instance also improves performance.
- oMenu.subscribe(_SHOW, oMenuItem._createKeyListener,
- oKeyData, oMenuItem);
- }
-
- },
- // Public methods
- /**
- * @method initDefaultConfig
- * @description Initializes an item's configurable properties.
- */
- initDefaultConfig : function () {
- var oConfig = this.cfg;
- // Define the configuration attributes
- /**
- * @config text
- * @description String specifying the text label for the menu item.
- * When building a menu from existing HTML the value of this property
- * will be interpreted from the menu's markup.
- * @default ""
- * @type String
- */
- oConfig.addProperty(
- TEXT_CONFIG.key,
- {
- handler: this.configText,
- value: TEXT_CONFIG.value,
- validator: TEXT_CONFIG.validator,
- suppressEvent: TEXT_CONFIG.suppressEvent
- }
- );
-
- /**
- * @config helptext
- * @description String specifying additional instructional text to
- * accompany the text for the menu item.
- * @deprecated Use "text" configuration property to add help text markup.
- * For example: <code>oMenuItem.cfg.setProperty("text", "Copy <em
- * class=\"helptext\">Ctrl + C</em>");</code>
- * @default null
- * @type String|<a href="http://www.w3.org/TR/
- * 2000/WD-DOM-Level-1-20000929/level-one-html.html#ID-58190037">
- * HTMLElement</a>
- */
- oConfig.addProperty(
- HELP_TEXT_CONFIG.key,
- {
- handler: this.configHelpText,
- supercedes: HELP_TEXT_CONFIG.supercedes,
- suppressEvent: HELP_TEXT_CONFIG.suppressEvent
- }
- );
- /**
- * @config url
- * @description String specifying the URL for the menu item's anchor's
- * "href" attribute. When building a menu from existing HTML the value
- * of this property will be interpreted from the menu's markup.
- * @default "#"
- * @type String
- */
- oConfig.addProperty(
- URL_CONFIG.key,
- {
- handler: this.configURL,
- value: URL_CONFIG.value,
- suppressEvent: URL_CONFIG.suppressEvent
- }
- );
- /**
- * @config target
- * @description String specifying the value for the "target" attribute
- * of the menu item's anchor element. <strong>Specifying a target will
- * require the user to click directly on the menu item's anchor node in
- * order to cause the browser to navigate to the specified URL.</strong>
- * When building a menu from existing HTML the value of this property
- * will be interpreted from the menu's markup.
- * @default null
- * @type String
- */
- oConfig.addProperty(
- TARGET_CONFIG.key,
- {
- handler: this.configTarget,
- suppressEvent: TARGET_CONFIG.suppressEvent
- }
- );
- /**
- * @config emphasis
- * @description Boolean indicating if the text of the menu item will be
- * rendered with emphasis.
- * @deprecated Use the "text" configuration property to add emphasis.
- * For example: <code>oMenuItem.cfg.setProperty("text", "<em>Some
- * Text</em>");</code>
- * @default false
- * @type Boolean
- */
- oConfig.addProperty(
- EMPHASIS_CONFIG.key,
- {
- handler: this.configEmphasis,
- value: EMPHASIS_CONFIG.value,
- validator: EMPHASIS_CONFIG.validator,
- suppressEvent: EMPHASIS_CONFIG.suppressEvent,
- supercedes: EMPHASIS_CONFIG.supercedes
- }
- );
- /**
- * @config strongemphasis
- * @description Boolean indicating if the text of the menu item will be
- * rendered with strong emphasis.
- * @deprecated Use the "text" configuration property to add strong emphasis.
- * For example: <code>oMenuItem.cfg.setProperty("text", "<strong>
- * Some Text</strong>");</code>
- * @default false
- * @type Boolean
- */
- oConfig.addProperty(
- STRONG_EMPHASIS_CONFIG.key,
- {
- handler: this.configStrongEmphasis,
- value: STRONG_EMPHASIS_CONFIG.value,
- validator: STRONG_EMPHASIS_CONFIG.validator,
- suppressEvent: STRONG_EMPHASIS_CONFIG.suppressEvent,
- supercedes: STRONG_EMPHASIS_CONFIG.supercedes
- }
- );
- /**
- * @config checked
- * @description Boolean indicating if the menu item should be rendered
- * with a checkmark.
- * @default false
- * @type Boolean
- */
- oConfig.addProperty(
- CHECKED_CONFIG.key,
- {
- handler: this.configChecked,
- value: CHECKED_CONFIG.value,
- validator: CHECKED_CONFIG.validator,
- suppressEvent: CHECKED_CONFIG.suppressEvent,
- supercedes: CHECKED_CONFIG.supercedes
- }
- );
- /**
- * @config disabled
- * @description Boolean indicating if the menu item should be disabled.
- * (Disabled menu items are dimmed and will not respond to user input
- * or fire events.)
- * @default false
- * @type Boolean
- */
- oConfig.addProperty(
- DISABLED_CONFIG.key,
- {
- handler: this.configDisabled,
- value: DISABLED_CONFIG.value,
- validator: DISABLED_CONFIG.validator,
- suppressEvent: DISABLED_CONFIG.suppressEvent
- }
- );
- /**
- * @config selected
- * @description Boolean indicating if the menu item should
- * be highlighted.
- * @default false
- * @type Boolean
- */
- oConfig.addProperty(
- SELECTED_CONFIG.key,
- {
- handler: this.configSelected,
- value: SELECTED_CONFIG.value,
- validator: SELECTED_CONFIG.validator,
- suppressEvent: SELECTED_CONFIG.suppressEvent
- }
- );
- /**
- * @config submenu
- * @description Object specifying the submenu to be appended to the
- * menu item. The value can be one of the following: <ul><li>Object
- * specifying a Menu instance.</li><li>Object literal specifying the
- * menu to be created. Format: <code>{ id: [menu id], itemdata:
- * [<a href="YAHOO.widget.Menu.html#itemData">array of values for
- * items</a>] }</code>.</li><li>String specifying the id attribute
- * of the <code><div></code> element of the menu.</li><li>
- * Object specifying the <code><div></code> element of the
- * menu.</li></ul>
- * @default null
- * @type Menu|String|Object|<a href="http://www.w3.org/TR/2000/
- * WD-DOM-Level-1-20000929/level-one-html.html#ID-58190037">
- * HTMLElement</a>
- */
- oConfig.addProperty(
- SUBMENU_CONFIG.key,
- {
- handler: this.configSubmenu,
- supercedes: SUBMENU_CONFIG.supercedes,
- suppressEvent: SUBMENU_CONFIG.suppressEvent
- }
- );
- /**
- * @config onclick
- * @description Object literal representing the code to be executed when
- * the item is clicked. Format:<br> <code> {<br>
- * <strong>fn:</strong> Function, // The handler to call when
- * the event fires.<br> <strong>obj:</strong> Object, // An
- * object to pass back to the handler.<br> <strong>scope:</strong>
- * Object // The object to use for the scope of the handler.
- * <br> } </code>
- * @type Object
- * @default null
- */
- oConfig.addProperty(
- ONCLICK_CONFIG.key,
- {
- handler: this.configOnClick,
- suppressEvent: ONCLICK_CONFIG.suppressEvent
- }
- );
- /**
- * @config classname
- * @description CSS class to be applied to the menu item's root
- * <code><li></code> element. The specified class(es) are
- * appended in addition to the default class as specified by the menu
- * item's CSS_CLASS_NAME constant.
- * @default null
- * @type String
- */
- oConfig.addProperty(
- CLASS_NAME_CONFIG.key,
- {
- handler: this.configClassName,
- value: CLASS_NAME_CONFIG.value,
- validator: CLASS_NAME_CONFIG.validator,
- suppressEvent: CLASS_NAME_CONFIG.suppressEvent
- }
- );
- /**
- * @config keylistener
- * @description Object literal representing the key(s) that can be used
- * to trigger the MenuItem's "click" event. Possible attributes are
- * shift (boolean), alt (boolean), ctrl (boolean) and keys (either an int
- * or an array of ints representing keycodes).
- * @default null
- * @type Object
- */
- oConfig.addProperty(
- KEY_LISTENER_CONFIG.key,
- {
- handler: this.configKeyListener,
- value: KEY_LISTENER_CONFIG.value,
- suppressEvent: KEY_LISTENER_CONFIG.suppressEvent
- }
- );
- },
- /**
- * @method getNextSibling
- * @description Finds the menu item's next sibling.
- * @return YAHOO.widget.MenuItem
- */
- getNextSibling: function () {
-
- var isUL = function (el) {
- return (el.nodeName.toLowerCase() === "ul");
- },
-
- menuitemEl = this.element,
- next = Dom.getNextSibling(menuitemEl),
- parent,
- sibling,
- list;
-
- if (!next) {
-
- parent = menuitemEl.parentNode;
- sibling = Dom.getNextSiblingBy(parent, isUL);
-
- if (sibling) {
- list = sibling;
- }
- else {
- list = Dom.getFirstChildBy(parent.parentNode, isUL);
- }
-
- next = Dom.getFirstChild(list);
-
- }
- return YAHOO.widget.MenuManager.getMenuItem(next.id);
- },
- /**
- * @method getNextEnabledSibling
- * @description Finds the menu item's next enabled sibling.
- * @return YAHOO.widget.MenuItem
- */
- getNextEnabledSibling: function () {
-
- var next = this.getNextSibling();
-
- return (next.cfg.getProperty(_DISABLED) || next.element.style.display == _NONE) ? next.getNextEnabledSibling() : next;
-
- },
- /**
- * @method getPreviousSibling
- * @description Finds the menu item's previous sibling.
- * @return {YAHOO.widget.MenuItem}
- */
- getPreviousSibling: function () {
- var isUL = function (el) {
- return (el.nodeName.toLowerCase() === "ul");
- },
- menuitemEl = this.element,
- next = Dom.getPreviousSibling(menuitemEl),
- parent,
- sibling,
- list;
-
- if (!next) {
-
- parent = menuitemEl.parentNode;
- sibling = Dom.getPreviousSiblingBy(parent, isUL);
-
- if (sibling) {
- list = sibling;
- }
- else {
- list = Dom.getLastChildBy(parent.parentNode, isUL);
- }
-
- next = Dom.getLastChild(list);
-
- }
- return YAHOO.widget.MenuManager.getMenuItem(next.id);
-
- },
- /**
- * @method getPreviousEnabledSibling
- * @description Finds the menu item's previous enabled sibling.
- * @return {YAHOO.widget.MenuItem}
- */
- getPreviousEnabledSibling: function () {
-
- var next = this.getPreviousSibling();
-
- return (next.cfg.getProperty(_DISABLED) || next.element.style.display == _NONE) ? next.getPreviousEnabledSibling() : next;
-
- },
- /**
- * @method focus
- * @description Causes the menu item to receive the focus and fires the
- * focus event.
- */
- focus: function () {
- var oParent = this.parent,
- oAnchor = this._oAnchor,
- oActiveItem = oParent.activeItem;
- function setFocus() {
- try {
- if (!(UA.ie && !document.hasFocus())) {
-
- if (oActiveItem) {
-
- oActiveItem.blurEvent.fire();
-
- }
-
- oAnchor.focus();
-
- this.focusEvent.fire();
-
- }
- }
- catch(e) {
-
- }
- }
- if (!this.cfg.getProperty(_DISABLED) && oParent && oParent.cfg.getProperty(_VISIBLE) &&
- this.element.style.display != _NONE) {
- /*
- Setting focus via a timer fixes a race condition in Firefox, IE
- and Opera where the browser viewport jumps as it trys to
- position and focus the menu.
- */
- Lang.later(0, this, setFocus);
- }
- },
- /**
- * @method blur
- * @description Causes the menu item to lose focus and fires the
- * blur event.
- */
- blur: function () {
- var oParent = this.parent;
- if (!this.cfg.getProperty(_DISABLED) && oParent && oParent.cfg.getProperty(_VISIBLE)) {
- Lang.later(0, this, function () {
- try {
-
- this._oAnchor.blur();
- this.blurEvent.fire();
- }
- catch (e) {
-
- }
-
- }, 0);
- }
- },
- /**
- * @method hasFocus
- * @description Returns a boolean indicating whether or not the menu item
- * has focus.
- * @return {Boolean}
- */
- hasFocus: function () {
-
- return (YAHOO.widget.MenuManager.getFocusedMenuItem() == this);
-
- },
- /**
- * @method destroy
- * @description Removes the menu item's <code><li></code> element
- * from its parent <code><ul></code> element.
- */
- destroy: function () {
- var oEl = this.element,
- oSubmenu,
- oParentNode,
- aEventData,
- i;
- if (oEl) {
- // If the item has a submenu, destroy it first
- oSubmenu = this.cfg.getProperty(_SUBMENU);
- if (oSubmenu) {
-
- oSubmenu.destroy();
-
- }
- // Remove the element from the parent node
- oParentNode = oEl.parentNode;
- if (oParentNode) {
- oParentNode.removeChild(oEl);
- this.destroyEvent.fire();
- }
- // Remove CustomEvent listeners
- i = EVENT_TYPES.length - 1;
- do {
- aEventData = EVENT_TYPES[i];
-
- this[aEventData[0]].unsubscribeAll();
- }
- while (i--);
-
-
- this.cfg.configChangedEvent.unsubscribeAll();
- }
- },
- /**
- * @method toString
- * @description Returns a string representing the menu item.
- * @return {String}
- */
- toString: function () {
- var sReturnVal = _MENUITEM,
- sId = this.id;
- if (sId) {
-
- sReturnVal += (_SPACE + sId);
-
- }
- return sReturnVal;
-
- }
- };
- Lang.augmentProto(MenuItem, YAHOO.util.EventProvider);
- })();
- (function () {
- var _XY = "xy",
- _MOUSEDOWN = "mousedown",
- _CONTEXTMENU = "ContextMenu",
- _SPACE = " ";
- /**
- * Creates a list of options or commands which are made visible in response to
- * an HTML element's "contextmenu" event ("mousedown" for Opera).
- *
- * @param {String} p_oElement String specifying the id attribute of the
- * <code><div></code> element of the context menu.
- * @param {String} p_oElement String specifying the id attribute of the
- * <code><select></code> element to be used as the data source for the
- * context menu.
- * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-
- * html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object specifying the
- * <code><div></code> element of the context menu.
- * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-
- * html.html#ID-94282980">HTMLSelectElement</a>} p_oElement Object specifying
- * the <code><select></code> element to be used as the data source for
- * the context menu.
- * @param {Object} p_oConfig Optional. Object literal specifying the
- * configuration for the context menu. See configuration class documentation
- * for more details.
- * @class ContextMenu
- * @constructor
- * @extends YAHOO.widget.Menu
- * @namespace YAHOO.widget
- */
- YAHOO.widget.ContextMenu = function(p_oElement, p_oConfig) {
- YAHOO.widget.ContextMenu.superclass.constructor.call(this, p_oElement, p_oConfig);
- };
- var Event = YAHOO.util.Event,
- UA = YAHOO.env.ua,
- ContextMenu = YAHOO.widget.ContextMenu,
- /**
- * Constant representing the name of the ContextMenu's events
- * @property EVENT_TYPES
- * @private
- * @final
- * @type Object
- */
- EVENT_TYPES = {
- "TRIGGER_CONTEXT_MENU": "triggerContextMenu",
- "CONTEXT_MENU": (UA.opera ? _MOUSEDOWN : "contextmenu"),
- "CLICK": "click"
- },
-
-
- /**
- * Constant representing the ContextMenu's configuration properties
- * @property DEFAULT_CONFIG
- * @private
- * @final
- * @type Object
- */
- TRIGGER_CONFIG = {
- key: "trigger",
- suppressEvent: true
- };
- /**
- * @method position
- * @description "beforeShow" event handler used to position the contextmenu.
- * @private
- * @param {String} p_sType String representing the name of the event that
- * was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event was fired.
- * @param {Array} p_aPos Array representing the xy position for the context menu.
- */
- function position(p_sType, p_aArgs, p_aPos) {
- this.cfg.setProperty(_XY, p_aPos);
-
- this.beforeShowEvent.unsubscribe(position, p_aPos);
- }
- YAHOO.lang.extend(ContextMenu, YAHOO.widget.Menu, {
- // Private properties
- /**
- * @property _oTrigger
- * @description Object reference to the current value of the "trigger"
- * configuration property.
- * @default null
- * @private
- * @type String|<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/leve
- * l-one-html.html#ID-58190037">HTMLElement</a>|Array
- */
- _oTrigger: null,
- /**
- * @property _bCancelled
- * @description Boolean indicating if the display of the context menu should
- * be cancelled.
- * @default false
- * @private
- * @type Boolean
- */
- _bCancelled: false,
- // Public properties
- /**
- * @property contextEventTarget
- * @description Object reference for the HTML element that was the target of the
- * "contextmenu" DOM event ("mousedown" for Opera) that triggered the display of
- * the context menu.
- * @default null
- * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-
- * html.html#ID-58190037">HTMLElement</a>
- */
- contextEventTarget: null,
- // Events
- /**
- * @event triggerContextMenuEvent
- * @description Custom Event wrapper for the "contextmenu" DOM event
- * ("mousedown" for Opera) fired by the element(s) that trigger the display of
- * the context menu.
- */
- triggerContextMenuEvent: null,
- /**
- * @method init
- * @description The ContextMenu class's initialization method. This method is
- * automatically called by the constructor, and sets up all DOM references for
- * pre-existing markup, and creates required markup if it is not already present.
- * @param {String} p_oElement String specifying the id attribute of the
- * <code><div></code> element of the context menu.
- * @param {String} p_oElement String specifying the id attribute of the
- * <code><select></code> element to be used as the data source for
- * the context menu.
- * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-
- * html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object specifying the
- * <code><div></code> element of the context menu.
- * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-
- * html.html#ID-94282980">HTMLSelectElement</a>} p_oElement Object specifying
- * the <code><select></code> element to be used as the data source for
- * the context menu.
- * @param {Object} p_oConfig Optional. Object literal specifying the
- * configuration for the context menu. See configuration class documentation
- * for more details.
- */
- init: function(p_oElement, p_oConfig) {
- // Call the init of the superclass (YAHOO.widget.Menu)
- ContextMenu.superclass.init.call(this, p_oElement);
- this.beforeInitEvent.fire(ContextMenu);
- if (p_oConfig) {
- this.cfg.applyConfig(p_oConfig, true);
- }
-
- this.initEvent.fire(ContextMenu);
-
- },
- /**
- * @method initEvents
- * @description Initializes the custom events for the context menu.
- */
- initEvents: function() {
- ContextMenu.superclass.initEvents.call(this);
- // Create custom events
- this.triggerContextMenuEvent = this.createEvent(EVENT_TYPES.TRIGGER_CONTEXT_MENU);
- this.triggerContextMenuEvent.signature = YAHOO.util.CustomEvent.LIST;
- },
- /**
- * @method cancel
- * @description Cancels the display of the context menu.
- */
- cancel: function() {
- this._bCancelled = true;
- },
- // Private methods
- /**
- * @method _removeEventHandlers
- * @description Removes all of the DOM event handlers from the HTML element(s)
- * whose "context menu" event ("click" for Opera) trigger the display of
- * the context menu.
- * @private
- */
- _removeEventHandlers: function() {
- var oTrigger = this._oTrigger;
- // Remove the event handlers from the trigger(s)
- if (oTrigger) {
- Event.removeListener(oTrigger, EVENT_TYPES.CONTEXT_MENU, this._onTriggerContextMenu);
-
- if (UA.opera) {
-
- Event.removeListener(oTrigger, EVENT_TYPES.CLICK, this._onTriggerClick);
-
- }
- }
- },
- // Private event handlers
- /**
- * @method _onTriggerClick
- * @description "click" event handler for the HTML element(s) identified as the
- * "trigger" for the context menu. Used to cancel default behaviors in Opera.
- * @private
- * @param {Event} p_oEvent Object representing the DOM event object passed back
- * by the event utility (YAHOO.util.Event).
- * @param {YAHOO.widget.ContextMenu} p_oMenu Object representing the context
- * menu that is handling the event.
- */
- _onTriggerClick: function(p_oEvent, p_oMenu) {
- if (p_oEvent.ctrlKey) {
-
- Event.stopEvent(p_oEvent);
- }
-
- },
- /**
- * @method _onTriggerContextMenu
- * @description "contextmenu" event handler ("mousedown" for Opera) for the HTML
- * element(s) that trigger the display of the context menu.
- * @private
- * @param {Event} p_oEvent Object representing the DOM event object passed back
- * by the event utility (YAHOO.util.Event).
- * @param {YAHOO.widget.ContextMenu} p_oMenu Object representing the context
- * menu that is handling the event.
- */
- _onTriggerContextMenu: function(p_oEvent, p_oMenu) {
- var aXY;
- if (!(p_oEvent.type == _MOUSEDOWN && !p_oEvent.ctrlKey)) {
-
- this.contextEventTarget = Event.getTarget(p_oEvent);
-
- this.triggerContextMenuEvent.fire(p_oEvent);
-
-
- if (!this._bCancelled) {
- /*
- Prevent the browser's default context menu from appearing and
- stop the propagation of the "contextmenu" event so that
- other ContextMenu instances are not displayed.
- */
- Event.stopEvent(p_oEvent);
- // Hide any other Menu instances that might be visible
- YAHOO.widget.MenuManager.hideVisible();
-
-
- // Position and display the context menu
-
- aXY = Event.getXY(p_oEvent);
-
-
- if (!YAHOO.util.Dom.inDocument(this.element)) {
-
- this.beforeShowEvent.subscribe(position, aXY);
-
- }
- else {
-
- this.cfg.setProperty(_XY, aXY);
-
- }
-
-
- this.show();
-
- }
-
- this._bCancelled = false;
- }
- },
- // Public methods
- /**
- * @method toString
- * @description Returns a string representing the context menu.
- * @return {String}
- */
- toString: function() {
- var sReturnVal = _CONTEXTMENU,
- sId = this.id;
- if (sId) {
- sReturnVal += (_SPACE + sId);
-
- }
- return sReturnVal;
- },
- /**
- * @method initDefaultConfig
- * @description Initializes the class's configurable properties which can be
- * changed using the context menu's Config object ("cfg").
- */
- initDefaultConfig: function() {
- ContextMenu.superclass.initDefaultConfig.call(this);
- /**
- * @config trigger
- * @description The HTML element(s) whose "contextmenu" event ("mousedown"
- * for Opera) trigger the display of the context menu. Can be a string
- * representing the id attribute of the HTML element, an object reference
- * for the HTML element, or an array of strings or HTML element references.
- * @default null
- * @type String|<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
- * level-one-html.html#ID-58190037">HTMLElement</a>|Array
- */
- this.cfg.addProperty(TRIGGER_CONFIG.key,
- {
- handler: this.configTrigger,
- suppressEvent: TRIGGER_CONFIG.suppressEvent
- }
- );
- },
- /**
- * @method destroy
- * @description Removes the context menu's <code><div></code> element
- * (and accompanying child nodes) from the document.
- */
- destroy: function() {
- // Remove the DOM event handlers from the current trigger(s)
- this._removeEventHandlers();
- // Continue with the superclass implementation of this method
- ContextMenu.superclass.destroy.call(this);
- },
- // Public event handlers for configuration properties
- /**
- * @method configTrigger
- * @description Event handler for when the value of the "trigger" configuration
- * property changes.
- * @param {String} p_sType String representing the name of the event that
- * was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event was fired.
- * @param {YAHOO.widget.ContextMenu} p_oMenu Object representing the context
- * menu that fired the event.
- */
- configTrigger: function(p_sType, p_aArgs, p_oMenu) {
-
- var oTrigger = p_aArgs[0];
- if (oTrigger) {
- /*
- If there is a current "trigger" - remove the event handlers
- from that element(s) before assigning new ones
- */
- if (this._oTrigger) {
-
- this._removeEventHandlers();
- }
- this._oTrigger = oTrigger;
- /*
- Listen for the "mousedown" event in Opera b/c it does not
- support the "contextmenu" event
- */
-
- Event.on(oTrigger, EVENT_TYPES.CONTEXT_MENU, this._onTriggerContextMenu, this, true);
- /*
- Assign a "click" event handler to the trigger element(s) for
- Opera to prevent default browser behaviors.
- */
- if (UA.opera) {
-
- Event.on(oTrigger, EVENT_TYPES.CLICK, this._onTriggerClick, this, true);
- }
- }
- else {
-
- this._removeEventHandlers();
-
- }
-
- }
- }); // END YAHOO.lang.extend
- }());
- /**
- * Creates an item for a context menu.
- *
- * @param {String} p_oObject String specifying the text of the context menu item.
- * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
- * one-html.html#ID-74680021">HTMLLIElement</a>} p_oObject Object specifying the
- * <code><li></code> element of the context menu item.
- * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
- * one-html.html#ID-38450247">HTMLOptGroupElement</a>} p_oObject Object
- * specifying the <code><optgroup></code> element of the context
- * menu item.
- * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
- * one-html.html#ID-70901257">HTMLOptionElement</a>} p_oObject Object specifying
- * the <code><option></code> element of the context menu item.
- * @param {Object} p_oConfig Optional. Object literal specifying the
- * configuration for the context menu item. See configuration class
- * documentation for more details.
- * @class ContextMenuItem
- * @constructor
- * @extends YAHOO.widget.MenuItem
- * @deprecated As of version 2.4.0 items for YAHOO.widget.ContextMenu instances
- * are of type YAHOO.widget.MenuItem.
- */
- YAHOO.widget.ContextMenuItem = YAHOO.widget.MenuItem;
- (function () {
- var Lang = YAHOO.lang,
- // String constants
-
- _STATIC = "static",
- _DYNAMIC_STATIC = "dynamic," + _STATIC,
- _DISABLED = "disabled",
- _SELECTED = "selected",
- _AUTO_SUBMENU_DISPLAY = "autosubmenudisplay",
- _SUBMENU = "submenu",
- _VISIBLE = "visible",
- _SPACE = " ",
- _SUBMENU_TOGGLE_REGION = "submenutoggleregion",
- _MENUBAR = "MenuBar";
- /**
- * Horizontal collection of items, each of which can contain a submenu.
- *
- * @param {String} p_oElement String specifying the id attribute of the
- * <code><div></code> element of the menu bar.
- * @param {String} p_oElement String specifying the id attribute of the
- * <code><select></code> element to be used as the data source for the
- * menu bar.
- * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
- * one-html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object specifying
- * the <code><div></code> element of the menu bar.
- * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
- * one-html.html#ID-94282980">HTMLSelectElement</a>} p_oElement Object
- * specifying the <code><select></code> element to be used as the data
- * source for the menu bar.
- * @param {Object} p_oConfig Optional. Object literal specifying the
- * configuration for the menu bar. See configuration class documentation for
- * more details.
- * @class MenuBar
- * @constructor
- * @extends YAHOO.widget.Menu
- * @namespace YAHOO.widget
- */
- YAHOO.widget.MenuBar = function(p_oElement, p_oConfig) {
- YAHOO.widget.MenuBar.superclass.constructor.call(this, p_oElement, p_oConfig);
- };
- /**
- * @method checkPosition
- * @description Checks to make sure that the value of the "position" property
- * is one of the supported strings. Returns true if the position is supported.
- * @private
- * @param {Object} p_sPosition String specifying the position of the menu.
- * @return {Boolean}
- */
- function checkPosition(p_sPosition) {
- var returnVal = false;
- if (Lang.isString(p_sPosition)) {
- returnVal = (_DYNAMIC_STATIC.indexOf((p_sPosition.toLowerCase())) != -1);
- }
-
- return returnVal;
- }
- var Event = YAHOO.util.Event,
- MenuBar = YAHOO.widget.MenuBar,
- POSITION_CONFIG = {
- key: "position",
- value: _STATIC,
- validator: checkPosition,
- supercedes: [_VISIBLE]
- },
- SUBMENU_ALIGNMENT_CONFIG = {
- key: "submenualignment",
- value: ["tl","bl"]
- },
- AUTO_SUBMENU_DISPLAY_CONFIG = {
- key: _AUTO_SUBMENU_DISPLAY,
- value: false,
- validator: Lang.isBoolean,
- suppressEvent: true
- },
-
- SUBMENU_TOGGLE_REGION_CONFIG = {
- key: _SUBMENU_TOGGLE_REGION,
- value: false,
- validator: Lang.isBoolean
- };
- Lang.extend(MenuBar, YAHOO.widget.Menu, {
- /**
- * @method init
- * @description The MenuBar class's initialization method. This method is
- * automatically called by the constructor, and sets up all DOM references for
- * pre-existing markup, and creates required markup if it is not already present.
- * @param {String} p_oElement String specifying the id attribute of the
- * <code><div></code> element of the menu bar.
- * @param {String} p_oElement String specifying the id attribute of the
- * <code><select></code> element to be used as the data source for the
- * menu bar.
- * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
- * one-html.html#ID-22445964">HTMLDivElement</a>} p_oElement Object specifying
- * the <code><div></code> element of the menu bar.
- * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
- * one-html.html#ID-94282980">HTMLSelectElement</a>} p_oElement Object
- * specifying the <code><select></code> element to be used as the data
- * source for the menu bar.
- * @param {Object} p_oConfig Optional. Object literal specifying the
- * configuration for the menu bar. See configuration class documentation for
- * more details.
- */
- init: function(p_oElement, p_oConfig) {
- if(!this.ITEM_TYPE) {
- this.ITEM_TYPE = YAHOO.widget.MenuBarItem;
- }
- // Call the init of the superclass (YAHOO.widget.Menu)
- MenuBar.superclass.init.call(this, p_oElement);
- this.beforeInitEvent.fire(MenuBar);
- if(p_oConfig) {
- this.cfg.applyConfig(p_oConfig, true);
- }
- this.initEvent.fire(MenuBar);
- },
- // Constants
- /**
- * @property CSS_CLASS_NAME
- * @description String representing the CSS class(es) to be applied to the menu
- * bar's <code><div></code> element.
- * @default "yuimenubar"
- * @final
- * @type String
- */
- CSS_CLASS_NAME: "yuimenubar",
- /**
- * @property SUBMENU_TOGGLE_REGION_WIDTH
- * @description Width (in pixels) of the area of a MenuBarItem that, when pressed, will toggle the
- * display of the MenuBarItem's submenu.
- * @default 20
- * @final
- * @type Number
- */
- SUBMENU_TOGGLE_REGION_WIDTH: 20,
- // Protected event handlers
- /**
- * @method _onKeyDown
- * @description "keydown" Custom Event handler for the menu bar.
- * @private
- * @param {String} p_sType String representing the name of the event that
- * was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event was fired.
- * @param {YAHOO.widget.MenuBar} p_oMenuBar Object representing the menu bar
- * that fired the event.
- */
- _onKeyDown: function(p_sType, p_aArgs, p_oMenuBar) {
- var oEvent = p_aArgs[0],
- oItem = p_aArgs[1],
- oSubmenu,
- oItemCfg,
- oNextItem;
- if(oItem && !oItem.cfg.getProperty(_DISABLED)) {
- oItemCfg = oItem.cfg;
- switch(oEvent.keyCode) {
-
- case 37: // Left arrow
- case 39: // Right arrow
-
- if(oItem == this.activeItem && !oItemCfg.getProperty(_SELECTED)) {
-
- oItemCfg.setProperty(_SELECTED, true);
-
- }
- else {
-
- oNextItem = (oEvent.keyCode == 37) ?
- oItem.getPreviousEnabledSibling() :
- oItem.getNextEnabledSibling();
-
- if(oNextItem) {
-
- this.clearActiveItem();
-
- oNextItem.cfg.setProperty(_SELECTED, true);
-
- oSubmenu = oNextItem.cfg.getProperty(_SUBMENU);
-
- if(oSubmenu) {
-
- oSubmenu.show();
- oSubmenu.setInitialFocus();
-
- }
- else {
- oNextItem.focus();
- }
-
- }
-
- }
-
- Event.preventDefault(oEvent);
-
- break;
-
- case 40: // Down arrow
-
- if(this.activeItem != oItem) {
-
- this.clearActiveItem();
-
- oItemCfg.setProperty(_SELECTED, true);
- oItem.focus();
-
- }
-
- oSubmenu = oItemCfg.getProperty(_SUBMENU);
-
- if(oSubmenu) {
-
- if(oSubmenu.cfg.getProperty(_VISIBLE)) {
-
- oSubmenu.setInitialSelection();
- oSubmenu.setInitialFocus();
-
- }
- else {
-
- oSubmenu.show();
- oSubmenu.setInitialFocus();
-
- }
-
- }
-
- Event.preventDefault(oEvent);
-
- break;
-
- }
- }
- if(oEvent.keyCode == 27 && this.activeItem) { // Esc key
- oSubmenu = this.activeItem.cfg.getProperty(_SUBMENU);
- if(oSubmenu && oSubmenu.cfg.getProperty(_VISIBLE)) {
-
- oSubmenu.hide();
- this.activeItem.focus();
-
- }
- else {
- this.activeItem.cfg.setProperty(_SELECTED, false);
- this.activeItem.blur();
-
- }
- Event.preventDefault(oEvent);
-
- }
- },
- /**
- * @method _onClick
- * @description "click" event handler for the menu bar.
- * @protected
- * @param {String} p_sType String representing the name of the event that
- * was fired.
- * @param {Array} p_aArgs Array of arguments sent when the event was fired.
- * @param {YAHOO.widget.MenuBar} p_oMenuBar Object representing the menu bar
- * that fired the event.
- */
- _onClick: function(p_sType, p_aArgs, p_oMenuBar) {
- MenuBar.superclass._onClick.call(this, p_sType, p_aArgs, p_oMenuBar);
- var oItem = p_aArgs[1],
- bReturnVal = true,
- oItemEl,
- oEvent,
- oTarget,
- oActiveItem,
- oConfig,
- oSubmenu,
- nMenuItemX,
- nToggleRegion;
- var toggleSubmenuDisplay = function () {
- if(oSubmenu.cfg.getProperty(_VISIBLE)) {
-
- oSubmenu.hide();
-
- }
- else {
-
- oSubmenu.show();
-
- }
-
- };
-
- if(oItem && !oItem.cfg.getProperty(_DISABLED)) {
- oEvent = p_aArgs[0];
- oTarget = Event.getTarget(oEvent);
- oActiveItem = this.activeItem;
- oConfig = this.cfg;
- // Hide any other submenus that might be visible
-
- if(oActiveItem && oActiveItem != oItem) {
-
- this.clearActiveItem();
-
- }
-
- oItem.cfg.setProperty(_SELECTED, true);
-
- // Show the submenu for the item
-
- oSubmenu = oItem.cfg.getProperty(_SUBMENU);
- if(oSubmenu) {
- oItemEl = oItem.element;
- nMenuItemX = YAHOO.util.Dom.getX(oItemEl);
- nToggleRegion = nMenuItemX + (oItemEl.offsetWidth - this.SUBMENU_TOGGLE_REGION_WIDTH);
- if (oConfig.getProperty(_SUBMENU_TOGGLE_REGION)) {
- if (Event.getPageX(oEvent) > nToggleRegion) {
- toggleSubmenuDisplay();
- Event.preventDefault(oEvent);
- /*
- Return false so that other click event handlers are not called when the
- user clicks inside the toggle region.
- */
- bReturnVal = false;
-
- }
-
- }
- else {
- toggleSubmenuDisplay();
-
- }
-
- }
-
- }
- return bReturnVal;
- },
- // Public methods
- /**
- * @method configSubmenuToggle
- * @description Event handler for when the "submenutoggleregion" configuration property of
- * a MenuBar changes.
- * @param {String} p_sType The name of the event that was fired.
- * @param {Array} p_aArgs Collection of arguments sent when the event was fired.
- */
- configSubmenuToggle: function (p_sType, p_aArgs) {
- var bSubmenuToggle = p_aArgs[0];
-
- if (bSubmenuToggle) {
-
- this.cfg.setProperty(_AUTO_SUBMENU_DISPLAY, false);
-
- }
- },
- /**
- * @method toString
- * @description Returns a string representing the menu bar.
- * @return {String}
- */
- toString: function() {
- var sReturnVal = _MENUBAR,
- sId = this.id;
- if(sId) {
- sReturnVal += (_SPACE + sId);
-
- }
- return sReturnVal;
- },
- /**
- * @description Initializes the class's configurable properties which can be
- * changed using the menu bar's Config object ("cfg").
- * @method initDefaultConfig
- */
- initDefaultConfig: function() {
- MenuBar.superclass.initDefaultConfig.call(this);
- var oConfig = this.cfg;
- // Add configuration properties
- /*
- Set the default value for the "position" configuration property
- to "static" by re-adding the property.
- */
- /**
- * @config position
- * @description String indicating how a menu bar should be positioned on the
- * screen. Possible values are "static" and "dynamic." Static menu bars
- * are visible by default and reside in the normal flow of the document
- * (CSS position: static). Dynamic menu bars are hidden by default, reside
- * out of the normal flow of the document (CSS position: absolute), and can
- * overlay other elements on the screen.
- * @default static
- * @type String
- */
- oConfig.addProperty(
- POSITION_CONFIG.key,
- {
- handler: this.configPosition,
- value: POSITION_CONFIG.value,
- validator: POSITION_CONFIG.validator,
- supercedes: POSITION_CONFIG.supercedes
- }
- );
- /*
- Set the default value for the "submenualignment" configuration property
- to ["tl","bl"] by re-adding the property.
- */
- /**
- * @config submenualignment
- * @description Array defining how submenus should be aligned to their
- * parent menu bar item. The format is: [itemCorner, submenuCorner].
- * @default ["tl","bl"]
- * @type Array
- */
- oConfig.addProperty(
- SUBMENU_ALIGNMENT_CONFIG.key,
- {
- value: SUBMENU_ALIGNMENT_CONFIG.value,
- suppressEvent: SUBMENU_ALIGNMENT_CONFIG.suppressEvent
- }
- );
- /*
- Change the default value for the "autosubmenudisplay" configuration
- property to "false" by re-adding the property.
- */
- /**
- * @config autosubmenudisplay
- * @description Boolean indicating if submenus are automatically made
- * visible when the user mouses over the menu bar's items.
- * @default false
- * @type Boolean
- */
- oConfig.addProperty(
- AUTO_SUBMENU_DISPLAY_CONFIG.key,
- {
- value: AUTO_SUBMENU_DISPLAY_CONFIG.value,
- validator: AUTO_SUBMENU_DISPLAY_CONFIG.validator,
- suppressEvent: AUTO_SUBMENU_DISPLAY_CONFIG.suppressEvent
- }
- );
- /**
- * @config submenutoggleregion
- * @description Boolean indicating if only a specific region of a MenuBarItem should toggle the
- * display of a submenu. The default width of the region is determined by the value of the
- * SUBMENU_TOGGLE_REGION_WIDTH property. If set to true, the autosubmenudisplay
- * configuration property will be set to false, and any click event listeners will not be
- * called when the user clicks inside the submenu toggle region of a MenuBarItem. If the
- * user clicks outside of the submenu toggle region, the MenuBarItem will maintain its
- * standard behavior.
- * @default false
- * @type Boolean
- */
- oConfig.addProperty(
- SUBMENU_TOGGLE_REGION_CONFIG.key,
- {
- value: SUBMENU_TOGGLE_REGION_CONFIG.value,
- validator: SUBMENU_TOGGLE_REGION_CONFIG.validator,
- handler: this.configSubmenuToggle
- }
- );
- }
-
- }); // END YAHOO.lang.extend
- }());
- /**
- * Creates an item for a menu bar.
- *
- * @param {String} p_oObject String specifying the text of the menu bar item.
- * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
- * one-html.html#ID-74680021">HTMLLIElement</a>} p_oObject Object specifying the
- * <code><li></code> element of the menu bar item.
- * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
- * one-html.html#ID-38450247">HTMLOptGroupElement</a>} p_oObject Object
- * specifying the <code><optgroup></code> element of the menu bar item.
- * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
- * one-html.html#ID-70901257">HTMLOptionElement</a>} p_oObject Object specifying
- * the <code><option></code> element of the menu bar item.
- * @param {Object} p_oConfig Optional. Object literal specifying the
- * configuration for the menu bar item. See configuration class documentation
- * for more details.
- * @class MenuBarItem
- * @constructor
- * @extends YAHOO.widget.MenuItem
- */
- YAHOO.widget.MenuBarItem = function(p_oObject, p_oConfig) {
- YAHOO.widget.MenuBarItem.superclass.constructor.call(this, p_oObject, p_oConfig);
- };
- YAHOO.lang.extend(YAHOO.widget.MenuBarItem, YAHOO.widget.MenuItem, {
- /**
- * @method init
- * @description The MenuBarItem class's initialization method. This method is
- * automatically called by the constructor, and sets up all DOM references for
- * pre-existing markup, and creates required markup if it is not already present.
- * @param {String} p_oObject String specifying the text of the menu bar item.
- * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
- * one-html.html#ID-74680021">HTMLLIElement</a>} p_oObject Object specifying the
- * <code><li></code> element of the menu bar item.
- * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
- * one-html.html#ID-38450247">HTMLOptGroupElement</a>} p_oObject Object
- * specifying the <code><optgroup></code> element of the menu bar item.
- * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
- * one-html.html#ID-70901257">HTMLOptionElement</a>} p_oObject Object specifying
- * the <code><option></code> element of the menu bar item.
- * @param {Object} p_oConfig Optional. Object literal specifying the
- * configuration for the menu bar item. See configuration class documentation
- * for more details.
- */
- init: function(p_oObject, p_oConfig) {
- if(!this.SUBMENU_TYPE) {
- this.SUBMENU_TYPE = YAHOO.widget.Menu;
- }
- /*
- Call the init of the superclass (YAHOO.widget.MenuItem)
- Note: We don't pass the user config in here yet
- because we only want it executed once, at the lowest
- subclass level.
- */
- YAHOO.widget.MenuBarItem.superclass.init.call(this, p_oObject);
- var oConfig = this.cfg;
- if(p_oConfig) {
- oConfig.applyConfig(p_oConfig, true);
- }
- oConfig.fireQueue();
- },
- // Constants
- /**
- * @property CSS_CLASS_NAME
- * @description String representing the CSS class(es) to be applied to the
- * <code><li></code> element of the menu bar item.
- * @default "yuimenubaritem"
- * @final
- * @type String
- */
- CSS_CLASS_NAME: "yuimenubaritem",
- /**
- * @property CSS_LABEL_CLASS_NAME
- * @description String representing the CSS class(es) to be applied to the
- * menu bar item's <code><a></code> element.
- * @default "yuimenubaritemlabel"
- * @final
- * @type String
- */
- CSS_LABEL_CLASS_NAME: "yuimenubaritemlabel",
- // Public methods
- /**
- * @method toString
- * @description Returns a string representing the menu bar item.
- * @return {String}
- */
- toString: function() {
- var sReturnVal = "MenuBarItem";
- if(this.cfg && this.cfg.getProperty("text")) {
- sReturnVal += (": " + this.cfg.getProperty("text"));
- }
- return sReturnVal;
- }
-
- }); // END YAHOO.lang.extend
- YAHOO.register("menu", YAHOO.widget.Menu, {version: "2.8.0r4", build: "2449"});
|