planeui.js 182 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350
  1. /*!
  2. * PlaneUI v0.1.0
  3. * @file planeui.js
  4. * @description The Modern HTML5 Cross-Device Responsive Front-end UI Framework.
  5. * @license MIT License
  6. * @author Pandao
  7. * {@link https://github.com/pandao/planeui}
  8. * @updateTime 2015-06-27
  9. */
  10. (function(factory) {
  11. "use strict";
  12. if(typeof exports === "object" && typeof module === "object")
  13. {
  14. module.exports = factory();
  15. }
  16. else if(typeof define === "function" && (define.amd || define.cmd))
  17. {
  18. define(factory);
  19. }
  20. else
  21. {
  22. window.PUI = window.PlaneUI = window.$ = factory();
  23. }
  24. })(function() {
  25. (function(window, $) {
  26. var PlaneUI = PUI = $;
  27. PlaneUI.extend({
  28. version : "0.1.0",
  29. homePage : "https://github.com/pandao/planeui",
  30. dialogIndex : 1000,
  31. getPixelRatio : function(context) {
  32. var backingStore = context.backingStorePixelRatio ||
  33. context.webkitBackingStorePixelRatio ||
  34. context.mozBackingStorePixelRatio ||
  35. context.msBackingStorePixelRatio ||
  36. context.oBackingStorePixelRatio ||
  37. context.backingStorePixelRatio || 1;
  38. return (window.devicePixelRatio || 1) / backingStore;
  39. },
  40. mouseOrTouch : function(mouseType, touchType) {
  41. mouseType = mouseType || "click";
  42. touchType = touchType || "touchend";
  43. var eventType = mouseType;
  44. try {
  45. document.createEvent("TouchEvent");
  46. eventType = touchType;
  47. }
  48. catch(e) {}
  49. return eventType;
  50. },
  51. clickOrTouch : function(touchType) {
  52. return this.mouseOrTouch("click", touchType);
  53. },
  54. contextMenuOrTouch : function() {
  55. return this.mouseOrTouch("contextmenu", "touchend");
  56. },
  57. jsonEncode : function(json) {
  58. return JSON.stringify(json);
  59. },
  60. jsonDecode : function(json) {
  61. return JSON.parse(json);
  62. },
  63. support : {
  64. touchEvent : function() {
  65. try {
  66. document.createEvent("TouchEvent");
  67. return true;
  68. } catch(e) {
  69. return false;
  70. }
  71. },
  72. canvas : function() {
  73. try {
  74. document.createElement('canvas').getContext('2d');
  75. return true;
  76. } catch(e) {
  77. return false;
  78. }
  79. },
  80. worker : function() {
  81. return (typeof(Worker) == "undefined") ? false : true;
  82. },
  83. placeholder : function() {
  84. return ('placeholder' in document.createElement('input'));
  85. }
  86. },
  87. responsive : {
  88. xs : function() {
  89. return ($(window).width() < 640);
  90. },
  91. sm : function() {
  92. return ($(window).width() >= 640 && $(window).width() < 768);
  93. },
  94. md : function() {
  95. return ($(window).width() >= 768 && $(window).width() < 992);
  96. },
  97. lg : function() {
  98. return ($(window).width() >= 992 && $(window).width() < 1200);
  99. },
  100. xl : function() {
  101. return ($(window).width() >= 1200 && $(window).width() < 1400);
  102. },
  103. xxl : function() {
  104. return ($(window).width() >= 1400);
  105. }
  106. }
  107. });
  108. window.PUI = window.PlaneUI = window.$ = PlaneUI;
  109. $(function() {
  110. $("*").bind("touchstart", function(e) {
  111. $(this).addClass("hover");
  112. }).bind("touchcancel touchend", function() {
  113. $(this).removeClass("hover");
  114. });
  115. $("a").click(function() {
  116. $(this).blur();
  117. });
  118. });
  119. })(window, jQuery);
  120. (function ($) {
  121. $(function() {
  122. $('.pui-button-sheets-more').each(function() {
  123. var $this = $(this);
  124. $this.bind($.clickOrTouch(), function() {
  125. var parent = $this.parent();
  126. var parentNext = parent.next();
  127. var moreHeight = parent.parent().attr('pui-button-sheets-show-more-height');
  128. parent.parent().height(moreHeight);
  129. parentNext.fadeIn(1000);
  130. var alternate = parentNext.find('a').eq(0);
  131. parentNext.append('<a href="javascript:;"></a>');
  132. parent.append(alternate);
  133. $this.remove();
  134. });
  135. });
  136. });
  137. })(PlaneUI);
  138. (function ($) {
  139. $(function() {
  140. $("pui-checkbox").each(function(i) {
  141. var $this = $(this);
  142. var checkbox = $('<input type="checkbox"/>');
  143. checkbox.attr("name", $this.attr('name'));
  144. checkbox.val($this.attr('value'));
  145. if($this.hasClass('checked'))
  146. {
  147. checkbox.attr("checked", "checked");
  148. }
  149. if($this.attr('disabled') == "disabled")
  150. {
  151. checkbox.attr("disabled", "disabled");
  152. }
  153. $this.append(checkbox);
  154. $this.bind($.clickOrTouch(), function() {
  155. if($(this).attr('disabled') == "disabled") return ;
  156. $(this).toggleClass('checked');
  157. var input = $(this).find('input');
  158. if(input.attr('checked') == 'checked')
  159. {
  160. input.removeAttr('checked');
  161. }
  162. else
  163. {
  164. input.attr('checked', 'checked');
  165. }
  166. });
  167. });
  168. $("[checkbox-checked-all]").bind($.clickOrTouch(), function() {
  169. var name = $(this).attr("checkbox-checked-all");
  170. $("[name='"+name+"']").each(function() {
  171. if($(this).attr('disabled') != "disabled") {
  172. $(this).addClass("checked");
  173. var input = $(this).find('input');
  174. input.attr('checked', 'checked');
  175. }
  176. });
  177. });
  178. $("[checkbox-cancel]").bind($.clickOrTouch(), function() {
  179. var name = $(this).attr("checkbox-cancel");
  180. $("[name='"+name+"']").each(function() {
  181. if($(this).attr('disabled') != "disabled") {
  182. $(this).removeClass("checked");
  183. var input = $(this).find('input');
  184. input.removeAttr('checked');
  185. }
  186. });
  187. });
  188. $("[checkbox-inverse]").bind($.clickOrTouch(), function() {
  189. var name = $(this).attr("checkbox-inverse");
  190. $("[name='"+name+"']").each(function() {
  191. if($(this).attr('disabled') != "disabled") {
  192. var input = $(this).find('input');
  193. if($(this).attr("class") == "checked") {
  194. $(this).removeClass("checked");
  195. input.removeAttr('checked');
  196. } else {
  197. $(this).addClass("checked");
  198. input.attr('checked', 'checked');
  199. }
  200. }
  201. });
  202. });
  203. });
  204. })(PlaneUI);
  205. (function($) {
  206. function colorPicker(options) {
  207. options = options || {};
  208. var defaults = {
  209. path : "",
  210. width : "",
  211. height : ""
  212. };
  213. var $this = $(this);
  214. var settings = $.extend(defaults, options);
  215. $.getJSON(settings.path + "dist/data/material.design.colors.json", function(json) {
  216. var colorList = [];
  217. var nameList = [];
  218. var sheet = "";
  219. for (var i in json)
  220. {
  221. for (var x in json[i])
  222. {
  223. var name = i + ((x == 500) ? "" : "-" + x);
  224. var color = json[i][x];
  225. if (color) {
  226. nameList.push(name);
  227. colorList.push(color);
  228. sheet += '<a href="javascript:;" class="pui-bg-' + name + '" name="' + name + '" color="' + color + ' "title="' + name + '" style="z-index:' + (total--) + '"></a>';
  229. }
  230. }
  231. }
  232. var total = nameList.length;
  233. $this.each(function() {
  234. var wrap = '<div class="pui-color-picker"></div>';
  235. var textInput = $(this);
  236. textInput.wrap(wrap);
  237. var colorPicker = $(this).parent();
  238. colorPicker.append('<div class="pui-button-sheet-list" style="display:none;"></div>');
  239. var colorSheet = colorPicker.children(".pui-button-sheet-list").eq(0);
  240. textInput.bind("click focus touchend", function() {
  241. colorSheet.show();
  242. });
  243. colorSheet.append(sheet);
  244. var colorBtn = colorSheet.find("a");
  245. if (settings.width !== "") {
  246. colorBtn.width(settings.width);
  247. }
  248. if (settings.height !== "") {
  249. colorBtn.height(settings.height);
  250. }
  251. colorBtn.bind($.clickOrTouch(), function() {
  252. var hex = $(this).attr("color").replace(" ", "");
  253. var $name = $(this).attr("name").replace(" ", "");
  254. textInput.val(hex).css({
  255. color : ($name === "white") ? "#555" : "#fff",
  256. borderColor : ($name === "white") ? "#ddd" : hex,
  257. backgroundColor : hex
  258. });
  259. });
  260. colorPicker.mouseleave(function(){
  261. colorSheet.hide();
  262. });
  263. });
  264. });
  265. }
  266. $.fn.puiColorPicker = $.fn.materialDesignColorPicker = colorPicker;
  267. })(PlaneUI);
  268. (function ($) {
  269. function dialog(options, yes, cancel) {
  270. return new dialog.creater(options, yes, cancel);
  271. };
  272. dialog.creater = function(options, yes, cancel, no) {
  273. this.guid = (new Date()).getTime();
  274. var defaults = {
  275. id : "pui-dialog-" + this.guid,
  276. type : "default",
  277. url : "",
  278. title : "",
  279. header : {
  280. subTitle : "",
  281. icon : "",
  282. titleStyle : "",
  283. style : "",
  284. className : ""
  285. },
  286. radius : true,
  287. cache : false,
  288. from : "",
  289. content : "",
  290. footer : "",
  291. toolbar : "close",
  292. buttons : {
  293. values : {
  294. yes : "确定",
  295. no : "否",
  296. cancel : "取消"
  297. },
  298. styles : {},
  299. "class" : {},
  300. yes : function() {},
  301. no : function() {},
  302. cancel : function() {}
  303. },
  304. animated : true,
  305. speed : 800,
  306. fixed : true,
  307. width : "",
  308. height : "",
  309. padding : 25,
  310. style : {},
  311. addClass : "",
  312. top : "center",
  313. left : "center",
  314. autozIndex : false,
  315. zIndex : $.dialogIndex,
  316. target : "", // only ID
  317. drag : true,
  318. dragEvent : "all", // all|mouse|touch
  319. dragTarget : "header",
  320. mask : true,
  321. maskColor : "#000",
  322. maskStyle : {},
  323. maskOpacity : 0.5,
  324. maskClickClosed : true,
  325. lockScreen : true,
  326. timeout : false,
  327. ajax : false,
  328. yes : function() {},
  329. no : function() {},
  330. cancel : function() {},
  331. onload : function() {},
  332. onshow : function() {},
  333. onclose : function() {},
  334. onreset : function() {},
  335. onremove : function() {},
  336. onmin : function() {},
  337. onblank : function() {},
  338. onrefresh : function() {},
  339. onbeforeload : function() {},
  340. };
  341. var settings = this.settings = $.extend(true, defaults, options);
  342. this.id = settings.id;
  343. this.url = settings.url;
  344. this.type = settings.type;
  345. this.title = settings.title;
  346. this.yes = yes || settings.yes;
  347. this.no = no || settings.no;
  348. this.cancel = cancel || settings.cancel;
  349. this.onload = settings.onload;
  350. this.onshow = settings.onshow;
  351. this.onclose = settings.onclose;
  352. this.onreset = settings.onreset;
  353. this.onremove = settings.onremove;
  354. this.onmin = settings.onmin;
  355. this.onmax = settings.onmax;
  356. this.onblank = settings.onblank;
  357. this.onrefresh = settings.onrefresh;
  358. this.onbeforeload = settings.onbeforeload;
  359. var _this = this;
  360. var $dialog = $('<div class="pui-dialog">');
  361. this.target = $dialog;
  362. $dialog.hide();
  363. this.mask({
  364. show : settings.mask,
  365. fixed : settings.fixed,
  366. color : settings.maskColor,
  367. style : settings.maskStyle,
  368. zIndex : settings.zIndex - 1,
  369. opacity : settings.maskOpacity
  370. });
  371. $("body").append($dialog);
  372. $dialog.attr({
  373. id : settings.id,
  374. type : settings.type
  375. });
  376. if(settings.radius) $dialog.addClass('pui-radius');
  377. var type = settings.type;
  378. this.signleCloseBtn = '<label class="pui-close"></label>';
  379. this.header(settings.header);
  380. this.content({
  381. url : settings.url,
  382. from : settings.from,
  383. padding : settings.padding,
  384. content : settings.content,
  385. buttons : settings.buttons
  386. });
  387. this.footer(settings.footer);
  388. this.width(settings.width);
  389. this.height(settings.height);
  390. this.fixed(settings.fixed);
  391. this.zIndex(settings.zIndex);
  392. this.toolbar(settings.toolbar);
  393. $dialog.css(settings.style).addClass(settings.addClass);
  394. this.show();
  395. if (settings.drag)
  396. {
  397. var dragTarget = $dialog.children(settings.dragTarget);
  398. /*if (settings.dragEvent === "all" || settings.dragEvent === "touch")
  399. {
  400. dragTarget.touchDraggable({
  401. parent : true
  402. });
  403. }*/
  404. $dialog.draggable({
  405. target : dragTarget,
  406. parent : true,
  407. touch : (settings.dragEvent === "all" || settings.dragEvent === "touch") ? true : false
  408. });
  409. }
  410. if (/(iPad|iPhone|iPod)/.test(navigator.userAgent))
  411. {
  412. $dialog.children("section.has-iframe").css("overflow", "auto");
  413. $dialog.children("section").bind("touchmove", function(event) {
  414. $("html, body").css("overflow", "hidden");
  415. event.stopPropagation();
  416. });
  417. }
  418. $(".pui-dialog > *").bind($.clickOrTouch(), function() {
  419. $.dialogIndex ++;
  420. $(this).parent().css("zIndex", $.dialogIndex);
  421. });
  422. $dialog.bind('dialog.reset', function() {
  423. _this.reset(_this.onreset);
  424. });
  425. $(window).resize(function(){
  426. $dialog.trigger('dialog.reset');
  427. });
  428. $.dialogIndex++;
  429. dialog.list[this.id] = this;
  430. this.timeout(settings.timeout);
  431. return this;
  432. };
  433. dialog.proxy = function(func) {
  434. var self = this;
  435. return (function() {
  436. return func.apply(self, arguments);
  437. });
  438. };
  439. dialog.creater.fn = dialog.creater.prototype = {
  440. proxy : dialog.proxy,
  441. status : "",
  442. parent : "",
  443. children : "",
  444. title : function(title) {
  445. var settings = this.settings;
  446. var target = this.target;
  447. if(this.type == "window" || this.type == "iframe")
  448. {
  449. var _header = target.children('header');
  450. var hasHeader = (_header.length > 0);
  451. var title = (title || settings.title) || (_header.find("strong").text() || "");
  452. _header.find('strong').html(title);
  453. }
  454. return this;
  455. },
  456. lockScreen : function(lock) {
  457. $('body,html').css('overflow', (lock) ? 'hidden' : '');
  458. },
  459. mask : function(options) {
  460. var settings = this.settings;
  461. var target = this.target;
  462. if(options.show)
  463. {
  464. var color = options.color || "#000";
  465. var opacity = (typeof options.opacity == "number") ? options.opacity : 0.5;
  466. var style = options.style || {};
  467. var fixed = options.fixed || true;
  468. var id = this.id + '-mask';
  469. var hasMask = ($("#"+id).length > 0);
  470. var mask = (hasMask) ? $("#"+id) : $('<div class="pui-mask pui-mask-bg" id="'+id+'"></div>');
  471. if(options.fixed) mask.addClass('pui-mask-fixed');
  472. mask.hide();
  473. mask.css({
  474. backgroundColor : color,
  475. zIndex: options.zIndex || ($.dialogIndex - 1),
  476. opacity : opacity
  477. }).css(style);
  478. if (!hasMask)
  479. {
  480. $("body").append(mask);
  481. }
  482. mask.fadeIn();
  483. if (settings.maskClickClosed)
  484. {
  485. mask.css("cursor", "pointer").bind($.clickOrTouch(), this.proxy(function(){
  486. this.close();
  487. }));
  488. }
  489. else
  490. {
  491. mask.css("cursor", "default");
  492. }
  493. }
  494. return this;
  495. },
  496. header : function(options) {
  497. var settings = this.settings;
  498. var target = this.target;
  499. var type = this.type;
  500. if (settings.type == "window" || settings.type == "iframe")
  501. {
  502. var _header = target.children('header');
  503. var hasHeader = (_header.length > 0);
  504. var title = (options.title || settings.title) || (_header.find("strong").text() || "");
  505. var subTitle = options.subTitle;
  506. var style = options.style;
  507. var className = options.className;
  508. var icon = options.icon;
  509. var titleStyle = options.titleStyle;
  510. if (hasHeader)
  511. {
  512. if (typeof options == "boolean" && !options)
  513. {
  514. _header.remove();
  515. }
  516. else
  517. {
  518. style = (typeof style == "undefined") ? (_header.attr('style') || "") : style;
  519. className = (typeof className == "undefined") ? (_header.attr('class') || "") : className;
  520. titleStyle = (typeof titleStyle == "undefined") ? (_header.children("strong").attr('style') || "") : titleStyle;
  521. subTitle = (typeof subTitle == "undefined") ? (_header.find('small')[0].outerHTML || "") : subTitle;
  522. icon = (typeof icon == "undefined") ? (_header.find(".fa")[0].outerHTML || "") : icon;
  523. _header.attr({"style" : style, "class" : className});
  524. _header.find('strong').attr("style", titleStyle).html(icon + title + subTitle);
  525. }
  526. }
  527. else
  528. {
  529. style = style || "";
  530. style = (style != "" ? ' style="'+style+'"' : "");
  531. className = className || "";
  532. className = (className != "" ? ' class="'+className+'"' : "");
  533. titleStyle = titleStyle || "";
  534. titleStyle = (titleStyle != "") ? ' style="'+titleStyle+'"' : "";
  535. subTitle = subTitle || "";
  536. icon = icon || "";
  537. var headerHTML = '<header'+className+style+'><strong'+titleStyle+'>'+icon+title+subTitle+'</strong></header>';
  538. if (target.children('section').length > 0)
  539. {
  540. target.children('section').before(headerHTML);
  541. }
  542. else
  543. {
  544. target.append(headerHTML);
  545. }
  546. }
  547. target.trigger('dialog.reset');
  548. }
  549. return this;
  550. },
  551. content : function(options) {
  552. var target = this.target;
  553. var type = this.type;
  554. var settings = this.settings;
  555. var section = target.children('section');
  556. var padding = options.padding;
  557. var content = options.content;
  558. var from = options.from || "";
  559. var buttons = options.buttons || settings.buttons;
  560. if (typeof options === "string") {
  561. content = options;
  562. }
  563. if (type === "iframe") {
  564. padding = 0;
  565. }
  566. if (type !== "iframe" && from !== "") {
  567. content = $(from).html();
  568. }
  569. if (section.length > 0)
  570. {
  571. if (type !== "iframe")
  572. {
  573. padding = (typeof padding == "undefined") ? (section.css('padding') || 0) : padding;
  574. content = (typeof content == "undefined") ? (section.html() || "") : content;
  575. section.css("padding", padding).html(content);
  576. }
  577. else
  578. {
  579. section.children('iframe').attr('src', options.url || content);
  580. }
  581. }
  582. else
  583. {
  584. if (type === "iframe")
  585. {
  586. padding = 0;
  587. content = '<iframe src="'+(options.url || "")+(options.url.indexOf('?') > 0 ? "&" : "?")+'_dialog='+this.id+'" width="99.99%" height="100%" frameborder="0"></iframe>';
  588. }
  589. if (type === "prompt" || type === "prompt-app")
  590. {
  591. if(type === "prompt") {
  592. padding = padding + "px " + padding + "px 0 "+padding;
  593. }
  594. content = '<p class="pui-font-bold pui-text-md">'+settings.title+'</p><p>'+content+'</p><input type="text" pui-dialog-prompt-input />';
  595. }
  596. if (type === "loading")
  597. {
  598. if(content === "") {
  599. content = '<div class="pui-loading pui-loading-spinner pui-animation-rotate pui-animation-repeat pui-animation-reverse"><span class="fa fa-spinner fa-3x"></span></div><p>loading....</p>';
  600. }
  601. }
  602. if (type === "image")
  603. {
  604. var imageURL = content;
  605. }
  606. var buttonsClass = buttons['class'];
  607. var html = '<section style="padding:'+(padding || 0)+'px;"'+(type == "iframe" ? ' class="has-iframe"' : '')+'>'+(content || "")+'</section>';
  608. if (type === "alert")
  609. {
  610. html += '<div class="pui-btn-center"><a href="javascript:;" button="yes" class="pui-btn pui-btn-warning pui-btn-shadow pui-btn-small '+(buttonsClass.yes || '')+'">'+buttons.values.yes+'</a></div>';
  611. }
  612. if (type === "alert-app")
  613. {
  614. html += '<div class="pui-btn-group pui-btn-group-justify"><a href="javascript:;" button="yes" class="pui-btn pui-btn-default '+(buttonsClass.yes || '')+'">'+buttons.values.yes+'</a></div>';
  615. }
  616. if (type === "confirm")
  617. {
  618. html += '<div class="pui-btn-center"><a href="javascript:;" button="yes" class="pui-btn pui-btn-warning '+(buttonsClass.yes || '')+'">'+buttons.values.yes+'</a><a href="javascript:;" button="cancel" class="pui-btn pui-btn-default '+(buttonsClass.cancel || '')+'">'+buttons.values.cancel+'</a></div>';
  619. }
  620. if (type === "confirm-app")
  621. {
  622. html += '<div class="pui-btn-group pui-btn-group-justify"><a href="javascript:;" button="cancel" class="pui-btn pui-btn-default '+(buttonsClass.cancel || '')+'">'+buttons.values.cancel+'</a><a href="javascript:;" button="yes" class="pui-btn pui-btn-default '+(buttonsClass.yes || '')+'">'+buttons.values.yes+'</a></div>';
  623. }
  624. if (type === "prompt")
  625. {
  626. html += '<div class="pui-btn-center"><a href="javascript:;" button="yes" class="pui-btn pui-btn-warning '+(buttonsClass.yes || '')+'">'+buttons.values.yes+'</a><a href="javascript:;" button="cancel" class="pui-btn pui-btn-default '+(buttonsClass.cancel || '')+'">'+buttons.values.cancel+'</a></div>';
  627. }
  628. if (type === "prompt-app")
  629. {
  630. html += '<div class="pui-btn-group pui-btn-group-justify"><a href="javascript:;" button="cancel" class="pui-btn pui-btn-default '+(buttonsClass.cancel || '')+'">'+buttons.values.cancel+'</a><a href="javascript:;" button="yes" class="pui-btn pui-btn-default '+(buttonsClass.yes || '')+'">'+buttons.values.yes+'</a></div>';
  631. }
  632. target.append(html);
  633. if(type === "image")
  634. {
  635. target.children('section').html('图片加载中...');
  636. if(typeof imageURL === "object")
  637. {
  638. }
  639. else
  640. {
  641. var image = new Image();
  642. image.className = "pui-size-auto";
  643. image.onload = function() {
  644. target.children('section').html(image);
  645. target.trigger('dialog.reset');
  646. };
  647. image.src = imageURL;
  648. }
  649. }
  650. }
  651. if(type === "iframe")
  652. {
  653. section = target.children('section');
  654. var iframe = section.children('iframe');
  655. this.proxy(this.onbeforeload)();
  656. iframe[0].contentWindow.onload = iframe[0].contentWindow.onreadystatechange = this.proxy(this.onload);
  657. }
  658. if (type === "alert" || type === "alert-app" || type === "confirm" || type === "confirm-app") {
  659. target.find('[button="yes"]').bind($.clickOrTouch(), this.proxy(function(){
  660. this.proxy(this.yes || new Function)();
  661. this.close();
  662. }));
  663. }
  664. if (type === "prompt" || type === "prompt-app") {
  665. target.find('[button="yes"]').bind($.clickOrTouch(), this.proxy(function(){
  666. this.proxy(this.yes || new Function)();
  667. }));
  668. }
  669. if (type === "confirm" || type === "confirm-app" || type === "prompt" || type === "prompt-app") {
  670. target.find('[button="cancel"]').bind($.clickOrTouch(), this.proxy(function(){
  671. this.proxy(this.cancel || new Function)();
  672. this.close();
  673. }));
  674. }
  675. target.trigger('dialog.reset');
  676. return this;
  677. },
  678. footer : function(content) {
  679. var settings = this.settings;
  680. if (settings.type === "window" || settings.type === "iframe")
  681. {
  682. var target = this.target;
  683. var _footer = target.children('footer');
  684. if (_footer.length > 0)
  685. {
  686. if (typeof content === "boolean" && !content)
  687. {
  688. _footer.remove();
  689. }
  690. else
  691. {
  692. content = (typeof content === "undefined") ? (_footer.html() || "") : content;
  693. _footer.html(content);
  694. }
  695. }
  696. else
  697. {
  698. if(content !== "") target.append('<footer>'+content+'</footer>');
  699. }
  700. target.trigger('dialog.reset');
  701. }
  702. return this;
  703. },
  704. toolbar : function(options) {
  705. var settings = this.settings;
  706. var target = this.target;
  707. var signleClose = target.children('.pui-close');
  708. var hasSignleClose = (signleClose.length > 0);
  709. if (typeof options === "boolean" && !options)
  710. {
  711. if (hasSignleClose) signleClose.remove();
  712. }
  713. if (typeof options === "string" && options === 'close')
  714. {
  715. if (signleClose.length < 1)
  716. {
  717. target.append(this.signleCloseBtn);
  718. target.children('.pui-close').bind($.clickOrTouch(), this.proxy(function(){
  719. this.close();
  720. }));
  721. }
  722. }
  723. if (settings.type === "window" || settings.type === "iframe")
  724. {
  725. var toolbar = target.children('.pui-dialog-toolbar');
  726. var hasToolbar = (toolbar.length > 0);
  727. if (typeof options === "boolean" && !options)
  728. {
  729. if(hasToolbar) toolbar.remove();
  730. }
  731. if (typeof options === "object")
  732. {
  733. if(hasSignleClose) signleClose.remove();
  734. var list = options;
  735. console.log(list);
  736. var defaults = {
  737. close : {
  738. show : true,
  739. title : "关闭"
  740. },
  741. min : {
  742. show : false,
  743. title : "最小化"
  744. },
  745. max : {
  746. show : false,
  747. title : "最大化"
  748. },
  749. blank : {
  750. show : false,
  751. title : "新窗口打开"
  752. },
  753. refresh: {
  754. show : false,
  755. title : "刷新窗口"
  756. }
  757. };
  758. options = $.extend(defaults, options);
  759. var _this = this;
  760. var close = options.close;
  761. var min = options.min;
  762. var max = options.max;
  763. var blank = options.blank;
  764. var refresh = options.refresh;
  765. if (hasToolbar)
  766. {
  767. if(!close) toolbar.find('.pui-dialog-close').remove();
  768. if(!min) toolbar.find('.pui-dialog-min').remove();
  769. if(!max) toolbar.find('.pui-dialog-max').remove();
  770. if(!blank) toolbar.find('.pui-dialog-blank').remove();
  771. if(!refresh) toolbar.find('.pui-dialog-refresh').remove();
  772. }
  773. else
  774. {
  775. toolbar = $('<div class="pui-dialog-toolbar"></div>');
  776. target.append(toolbar);
  777. for (var i in list)
  778. {
  779. var item = list[i];
  780. if ( (typeof item == "boolean" && item) || item.show || typeof item == "function")
  781. {
  782. var btn = "";
  783. switch (i) {
  784. case "close" :
  785. btn = '<a href="javascript:;" class="fa fa-close pui-dialog-close" type="'+i+'" title="'+(i.title || "关闭")+'"></a>';
  786. break;
  787. case "min" :
  788. btn = '<a href="javascript:;" class="fa fa-minus pui-dialog-min" type="'+i+'" title="'+(i.title || "最小化")+'"></a>';
  789. break;
  790. case "max" :
  791. btn = '<a href="javascript:;" class="fa fa-plus pui-dialog-max" type="'+i+'" title="'+(i.title || "最大化")+'"></a>';
  792. break;
  793. case "blank" :
  794. btn = '<a href="'+this.url+'" class="fa fa-external-link pui-dialog-blank" target="_blank" type="'+i+'" title="'+(i.title || "新窗口打开")+'"></a>';
  795. break;
  796. case "refresh" :
  797. btn = '<a href="javascript:;" class="fa fa-refresh pui-dialog-refresh" type="'+i+'" title="'+(i.title || "刷新窗口")+'"></a>';
  798. break;
  799. }
  800. toolbar.append(btn);
  801. var callback = (typeof item == "function") ? this.proxy(item) : new Function;
  802. target.find('.pui-dialog-' + i).bind($.clickOrTouch(), function() {
  803. var type = $(this).attr('type');
  804. //console.log("toolbar.type=>", type);
  805. _this[type](callback);
  806. });
  807. }
  808. }
  809. }
  810. }
  811. }
  812. target.trigger('dialog.reset');
  813. return this;
  814. },
  815. width : function(width) {
  816. var target = this.target;
  817. width = (typeof width == "number") ? width + "px" : width;
  818. if(typeof this._width == "undefined") this._width = width;
  819. if(typeof width == "string" && width.indexOf("%") > 0) {
  820. width = $(window).width() * (parseFloat(width) / 100);
  821. }
  822. target.width(width);
  823. target.trigger('dialog.reset');
  824. return this;
  825. },
  826. height: function(height) {
  827. var target = this.target;
  828. height = (typeof height == "number") ? height + "px" : height;
  829. if(typeof this._height == "undefined") this._height = height;
  830. if(typeof height == "string" && height.indexOf("%") > 0) {
  831. height = $(window).height() * (parseFloat(height) / 100);
  832. }
  833. target.height(height);
  834. target.trigger('dialog.reset');
  835. return this;
  836. },
  837. resize : function(width, height) {
  838. this.width(width);
  839. this.height(height);
  840. return this;
  841. },
  842. reset : function(callback) {
  843. var target = this.target;
  844. var type = this.type;
  845. var section = target.children('section'), height;
  846. if(type == "iframe" || type == "window")
  847. {
  848. height = target.height() - target.children('header').outerHeight() - target.children('footer').outerHeight();
  849. section.height(height);
  850. }
  851. this.position({
  852. top : this.settings.top,
  853. left : this.settings.left
  854. });
  855. this.proxy(callback || this.onreset)();
  856. },
  857. min : function(callback) {
  858. this.status = "min";
  859. this.proxy(callback || this.onmin)();
  860. return this;
  861. },
  862. max : function(callback) {
  863. this.status = "max";
  864. this.resize("100%", "100%");
  865. this.position({top:0, left:0});
  866. this.proxy(callback || this.onmax)();
  867. return this;
  868. },
  869. blank : function(callback) {
  870. this.proxy(callback || this.onblank)();
  871. return this;
  872. },
  873. refresh : function(callback) {
  874. this.status = "refresh";
  875. if(this.type == "iframe")
  876. {
  877. var target = this.target;
  878. var section = target.children('section');
  879. var iframe = section.children('iframe');
  880. this.proxy(this.onbeforeload)();
  881. iframe[0].contentWindow.onload = iframe[0].contentWindow.onreadystatechange = this.proxy(this.onload);
  882. iframe[0].contentWindow.location.reload();
  883. this.proxy(callback || this.onrefresh)();
  884. }
  885. return this;
  886. },
  887. css : function(cssText) {
  888. this.target.css(cssText);
  889. return this;
  890. },
  891. fixed : function(position) {
  892. position = (typeof position == "boolean" && position) ? "fixed" : position;
  893. this.css("position", position);
  894. return this;
  895. },
  896. parentDialog : function(queryString) {
  897. var target = this.target;
  898. var dialogId = "";
  899. queryString = queryString.slice(1, queryString.length).split("&");
  900. for (var i=0, len = queryString.length; i < len; i ++)
  901. {
  902. var item = queryString[i].split('=');
  903. if(item[0] == "_dialog") {
  904. dialogId = item[1];
  905. }
  906. }
  907. return dialog.get(dialogId);
  908. },
  909. position : function(options) {
  910. var target = this.target;
  911. var settings = this.settings;
  912. var $window = $(window);
  913. var top = options.top || "center";
  914. var left = options.left || "center";
  915. switch(top) {
  916. case "top":
  917. top = 0;
  918. break;
  919. case "bottom":
  920. top = $window.height() - target.outerHeight();
  921. break;
  922. case "center":
  923. top = ($window.height() - target.outerHeight()) / 2;
  924. break;
  925. default :
  926. top = top;
  927. break;
  928. }
  929. switch(left) {
  930. case "left":
  931. left = 0;
  932. break;
  933. case "right":
  934. left = $window.width() - target.outerWidth();
  935. break;
  936. case "center":
  937. left = ($window.width() - target.outerWidth()) / 2;
  938. break;
  939. default :
  940. left = left;
  941. break;
  942. }
  943. settings._top = top;
  944. settings._left = left;
  945. target.css({
  946. top : top + "px",
  947. left : left + "px"
  948. });
  949. return this;
  950. },
  951. zIndex : function(index) {
  952. this.target.css('z-index', index);
  953. return this;
  954. },
  955. on : function(event, callback) {
  956. },
  957. show : function(callback) {
  958. this.status = "show";
  959. var target = this.target;
  960. var settings = this.settings;
  961. var mask = $("#" + this.id + '-mask');
  962. var hasMask = (mask.length > 0);
  963. this.position({
  964. top : settings.top,
  965. left : settings.left
  966. });
  967. this.lockScreen(settings.lockScreen);
  968. //console.log("settings._top=>",settings._top);
  969. if(target.length > 0)
  970. {
  971. if(hasMask) mask.fadeIn();
  972. if(settings.animated)
  973. {
  974. //console.log('target.css.top', target.css('top'));
  975. target.css({
  976. top : "-"+ $(window).height() + "px"
  977. }).stop().animate({
  978. top : settings._top + "px",
  979. opacity : "show"
  980. }, settings.speed);
  981. }
  982. else
  983. {
  984. target.fadeIn();
  985. this.proxy(callback || this.onshow)();
  986. }
  987. }
  988. return this;
  989. },
  990. hide : function(callback) {
  991. this.close(callback);
  992. return this;
  993. },
  994. close : function(callback) {
  995. this.status = "close";
  996. var $this = this;
  997. var target = this.target;
  998. var settings = this.settings;
  999. var mask = $("#" + this.id + '-mask');
  1000. var hasMask = (mask.length > 0);
  1001. if(!settings.cache) {
  1002. if(hasMask)
  1003. {
  1004. mask.fadeOut(function(){
  1005. mask.remove();
  1006. });
  1007. }
  1008. if(!settings.animated)
  1009. {
  1010. this.remove(callback);
  1011. }
  1012. else
  1013. {
  1014. target.stop().animate({
  1015. top : $(window).height() * 2 + "px",
  1016. opacity : "hide"
  1017. }, settings.speed, $.proxy(function(){
  1018. $this.remove(callback);
  1019. }));
  1020. }
  1021. }
  1022. else
  1023. {
  1024. if(hasMask) mask.fadeOut();
  1025. if(!settings.animated)
  1026. {
  1027. target.fadeOut();
  1028. this.proxy(callback || this.onclose)();
  1029. }
  1030. else
  1031. {
  1032. callback = this.proxy(callback || this.onclose);
  1033. target.stop().animate({
  1034. top : $(window).height() * 2 + "px",
  1035. opacity : "hide"
  1036. }, settings.speed, $.proxy(function() {
  1037. callback();
  1038. }));
  1039. }
  1040. }
  1041. this.lockScreen(false);
  1042. return this;
  1043. },
  1044. remove : function(callback) {
  1045. this.status = "remove";
  1046. this.target.remove();
  1047. this.proxy(callback || this.onremove)();
  1048. return this;
  1049. },
  1050. buttons : function() {
  1051. return this;
  1052. },
  1053. loading : function() {
  1054. return this;
  1055. },
  1056. mediaQuery : function(queries) {
  1057. queries = queries || [];
  1058. },
  1059. timeout : function(options) {
  1060. if(typeof options == "boolean" && !arguments[0]) return this;
  1061. var _this = this;
  1062. var time = (typeof options == "boolean" && options) ? 3000 : (options[0] || 3000);
  1063. time = (typeof options == "number") ? options : time;
  1064. var callback = (typeof options == "function") ? options : options[1];
  1065. callback = callback || new Function;
  1066. var timer = setTimeout(function() {
  1067. clearTimeout(timer);
  1068. _this.close(callback);
  1069. }, time);
  1070. return this;
  1071. }
  1072. };
  1073. dialog.list = [];
  1074. dialog.get = function(id) {
  1075. return this.list[id];
  1076. };
  1077. $.dialog = dialog;
  1078. })(PlaneUI);
  1079. (function($) {
  1080. $.draggableIndex = 1000;
  1081. $.fn.draggable = function(options) {
  1082. options = options || {};
  1083. var defaults = {
  1084. target : null,
  1085. container : null,
  1086. touch : true,
  1087. x : true, // horizontal drag
  1088. y : true // vertical drag
  1089. };
  1090. var settings = $.extend(defaults, options);
  1091. var posX, posY;
  1092. var body = $("body");
  1093. var classPrefix = "pui-";
  1094. $(this).each(function() {
  1095. var $this = $(this);
  1096. var target = settings.target;
  1097. if (!target) {
  1098. target = $this;
  1099. }
  1100. target.css("cursor", "move").bind($.mouseOrTouch("mousedown", "touchstart"), function(e) {
  1101. e = e || window.event; //IE
  1102. posX = e.clientX - parseInt($this.position().left);
  1103. posY = e.clientY - parseInt($this.position().top);
  1104. if (!settings.target) {
  1105. $.draggableIndex ++;
  1106. target.css("z-index", $.draggableIndex);
  1107. }
  1108. document.onmousemove = moveAction;
  1109. });
  1110. if (settings.touch) {
  1111. target.touchDraggable(settings);
  1112. }
  1113. var userCanSelect = function (obj) {
  1114. obj.removeClass(classPrefix + "user-unselect").off("selectstart");
  1115. };
  1116. var userUnselect = function (obj) {
  1117. // selectstart for IE
  1118. obj.addClass(classPrefix + "user-unselect").on("selectstart", function(event) {
  1119. return false;
  1120. });
  1121. };
  1122. var moveAction = function (e) {
  1123. e = e || window.event; //IE
  1124. var left, top, nowLeft = parseInt($this.position().left), nowTop = parseInt($this.position().top);
  1125. var parentWidth = (settings.container) ? settings.container.width() : $(window).width();
  1126. if ( nowLeft >= 0 )
  1127. {
  1128. if ( nowLeft + $this.width() <= parentWidth)
  1129. {
  1130. left = e.clientX - posX;
  1131. }
  1132. else
  1133. {
  1134. left = parentWidth - $this.width();
  1135. document.onmousemove = null;
  1136. }
  1137. }
  1138. else
  1139. {
  1140. left = 0;
  1141. document.onmousemove = null;
  1142. }
  1143. if ( nowTop >= 0 )
  1144. {
  1145. if (settings.container)
  1146. {
  1147. var parentHeight = settings.container.height();
  1148. if ( nowTop + $this.outerHeight() <= parentHeight)
  1149. {
  1150. top = e.clientY - posY;
  1151. }
  1152. else
  1153. {
  1154. top = parentHeight - $this.outerHeight();
  1155. document.onmousemove = null;
  1156. }
  1157. }
  1158. else
  1159. {
  1160. top = e.clientY - posY;
  1161. }
  1162. }
  1163. else
  1164. {
  1165. top = 0;
  1166. document.onmousemove = null;
  1167. }
  1168. document.onselectstart = function() {
  1169. return false;
  1170. };
  1171. userUnselect(body);
  1172. userUnselect($this);
  1173. if (settings.x) $this[0].style.left = left + "px";
  1174. if (settings.y) $this[0].style.top = top + "px";
  1175. };
  1176. document.onmouseup = function() {
  1177. userCanSelect(body);
  1178. userCanSelect($this);
  1179. document.onselectstart = null;
  1180. document.onmousemove = null;
  1181. };
  1182. });
  1183. };
  1184. })(PlaneUI);
  1185. (function($) {
  1186. $.fn.touchDraggable = function(options) {
  1187. options = options || {};
  1188. var defaults = {
  1189. container : null,
  1190. parent : false,
  1191. x : true,
  1192. y : true
  1193. };
  1194. var settings = $.extend(defaults, options);
  1195. $(this).each(function() {
  1196. var offset = null;
  1197. var start = function(e) {
  1198. var orig = e.originalEvent;
  1199. var parent = (settings.parent) ? $(this).parent() : $(this);
  1200. var pos = parent.position();
  1201. if (settings.parent) {
  1202. $.dialogIndex ++;
  1203. parent.css("zIndex", $.dialogIndex);
  1204. }
  1205. offset = {
  1206. x : orig.changedTouches[0].pageX - pos.left,
  1207. y : orig.changedTouches[0].pageY - pos.top
  1208. };
  1209. $(this).bind("touchmove", moveAction);
  1210. };
  1211. var moveAction = function(e) {
  1212. e.preventDefault();
  1213. var orig = e.originalEvent, top, left;
  1214. var target = (settings.parent) ? $(this).parent() : $(this);
  1215. var nowLeft = parseInt(target.position().left);
  1216. var nowTop = parseInt(target.position().top);
  1217. var parentWidth = (settings.container) ? settings.container.width() : $(window).width();
  1218. if (nowLeft >= 0)
  1219. {
  1220. if ( nowLeft + target.width() <= parentWidth)
  1221. {
  1222. left = orig.changedTouches[0].pageX - offset.x;
  1223. }
  1224. else
  1225. {
  1226. left = parentWidth - target.width();
  1227. $(this).unbind("touchmove", moveAction);
  1228. }
  1229. }
  1230. else
  1231. {
  1232. left = 0;
  1233. $(this).unbind("touchmove", moveAction);
  1234. }
  1235. if ( nowTop >= 0 )
  1236. {
  1237. if (settings.container)
  1238. {
  1239. var parentHeight = settings.container.height();
  1240. if ( nowTop + target.outerHeight() <= parentHeight)
  1241. {
  1242. top = orig.changedTouches[0].pageY - offset.y;
  1243. }
  1244. else
  1245. {
  1246. top = parentHeight - target.outerHeight();
  1247. $(this).unbind("touchmove", moveAction);
  1248. }
  1249. }
  1250. else
  1251. {
  1252. top = orig.changedTouches[0].pageY - offset.y;
  1253. }
  1254. }
  1255. else
  1256. {
  1257. top = 0;
  1258. $(this).unbind("touchmove", moveAction);
  1259. }
  1260. if (settings.x) {
  1261. target.css("left", left);
  1262. }
  1263. if (settings.y) {
  1264. target.css("top", top);
  1265. }
  1266. };
  1267. $(this).bind("touchstart", start);
  1268. });
  1269. };
  1270. })(PlaneUI);
  1271. (function($) {
  1272. $.fn.fileInput = function(onchange) {
  1273. $(this.selector ? this.selector : ".pui-file-input").each(function() {
  1274. var $this = $(this);
  1275. var fileInput = $this.find("input[type=\"file\"]");
  1276. var btn = $this.find(".pui-file-input-btn");
  1277. fileInput.bind("change", function() {
  1278. $.proxy(onchange || function() {}, this)();
  1279. });
  1280. btn.bind("click", function() {
  1281. fileInput.trigger("click");
  1282. });
  1283. });
  1284. };
  1285. })(PlaneUI);
  1286. (function($) {
  1287. $(function(){
  1288. $(".pui-font-sizer > span").bind($.clickOrTouch(), function() {
  1289. var $this = $(this);
  1290. var target = $(this).parent().attr("target");
  1291. $this.each(function(){
  1292. var size = $(this).attr("size");
  1293. if(size == "default") {
  1294. $(target).removeAttr("style");
  1295. } else {
  1296. $(target).css({
  1297. fontSize : size
  1298. });
  1299. }
  1300. });
  1301. });
  1302. });
  1303. })(PUI);
  1304. (function ($) {
  1305. $.formValidatorImageFormats = ['jpg', 'jpeg', 'png', 'gif', 'webp'];
  1306. $.formValidatorRules = {
  1307. username : /^[a-zA-Z]\w{4,15}$/,
  1308. password : /^[a-zA-Z][a-zA-Z0-9\.\-\_]{5,15}$/,
  1309. enName : /^[a-zA-Z]{2,}$/,
  1310. uppercase : /^[A-Z]+$/,
  1311. lowercase : /^[a-z]+$/,
  1312. chinese : /^[\u4e00-\u9fa5]+$/,
  1313. email : /^[0-9a-z][_.0-9a-z-]{0,31}@([0-9a-z][0-9a-z-]{0,30}[0-9a-z]\.){1,3}[a-z]{2,4}$/,
  1314. tel : /^\d{3}-\d{8}|\d{4}-\d{7,8}$/,
  1315. telExt : /^\d{3}-\d{8}|\d{4}-\d{7,8}-?\d+?$/,
  1316. mobile : /^1(30|31|32|33|34|35|36|37|38|39|45|47|50|51|52|53|55|56|57|58|59|76|77|78|80|81|82|83|84|85|86|87|88|89)\d{8}$/,
  1317. mobileI18n : /^(\+86)1(30|31|32|33|34|35|36|37|38|39|45|47|50|51|52|53|55|56|57|58|59|76|77|78|80|81|82|83|84|85|86|87|88|89)\d{8}$/,
  1318. zipcode : /^[1-9]\d{5}$/,
  1319. qq : /^[1-9]\\d{4,10}$/,
  1320. domain : /^([a-zA-Z0-9\-]+)\.([a-zA-Z0-9\-]+)\.(com|net|cn|jp|tw|hk|edu|biz|gov|org|info|asia|mobi|co|cc|tt|me|tv|name|de)\.?(cn|hk|tw|jp)?$/,
  1321. url : /^(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&amp;:/~\+#]*[\w\-\@?^=%&amp;/~\+#])?$/,
  1322. ipv4 : /^((?:(?:25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))\.){3}(?:25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d))))$/,
  1323. idcard : /^\d{17}([0-9]|X)$/,
  1324. idcard1518 : /(^\d{15}$)|(^\d{17}([0-9]|X)$)/,
  1325. integer : /^\d+$/, // 0+,正整数
  1326. number : function(value) {
  1327. return !isNaN(value);
  1328. },
  1329. image : function(value){
  1330. return ($.inArray(value, $.formValidatorImageFormats) >= 0);
  1331. }
  1332. };
  1333. $.formValidatorRules.fax = $.formValidatorRules.telExt;
  1334. $.formValidatorRules.confirmPassword = $.formValidatorRules.password;
  1335. $.formValidatorIcons = {
  1336. error : '<i class="fa fa-close"></i>',
  1337. success : '<i class="fa fa-check-circle"></i>'
  1338. };
  1339. $.formValidatorRuleMessages = {
  1340. username : {
  1341. normal : '* 用户名必须以英文字母开头的英文字母、数字或下划线的5-16位组合。',
  1342. empty : $.formValidatorIcons.error + ' 错误:用户名不能为空。',
  1343. error : $.formValidatorIcons.error + ' 错误:用户名必须以英文字母开头的英文字母、数字或下划线的5-16位组合。',
  1344. },
  1345. password : {
  1346. normal : '* 密码由5-16位以英文字母开头的英文字母、数字、小数点、横线或下划线的组成。',
  1347. empty : $.formValidatorIcons.error + ' 错误:密码不能为空。',
  1348. error : $.formValidatorIcons.error + ' 错误:密码由5-16位以英文字母开头的英文字母、数字、小数点、横线或下划线的组成。',
  1349. },
  1350. confirmPassword : {
  1351. normal : "* 再次填写刚刚输入的密码,以便确认密码。",
  1352. empty : $.formValidatorIcons.error + ' 错误:确认密码不能为空。',
  1353. error : $.formValidatorIcons.error + ' 错误:两次输入的密码不一致或密码不正确。'
  1354. },
  1355. enName : {
  1356. normal : "* 请填写英文名字。",
  1357. empty : $.formValidatorIcons.error + ' 错误:英文名字不能为空。',
  1358. error : $.formValidatorIcons.error + ' 错误:请填写正确的英文名字。'
  1359. },
  1360. uppercase : {
  1361. normal : "* 请填写大写的英文字母。",
  1362. error : $.formValidatorIcons.error + ' 错误:请填写大写的英文字母。'
  1363. },
  1364. lowercase : {
  1365. normal : "* 请填写小写的英文字母。",
  1366. error : $.formValidatorIcons.error + ' 错误:请填写小写的英文字母。'
  1367. },
  1368. chinese : {
  1369. normal : "* 请填写中文字符。",
  1370. error : $.formValidatorIcons.error + ' 错误:只能填写中文字符。'
  1371. },
  1372. email : {
  1373. normal : "* 请填写邮箱地址。",
  1374. empty : $.formValidatorIcons.error + ' 错误:邮箱地址不能为空。',
  1375. error : $.formValidatorIcons.error + ' 错误:请填写正确的邮箱地址。'
  1376. },
  1377. tel : {
  1378. normal : "* 格式:区号-固定电话号码。",
  1379. empty : $.formValidatorIcons.error + ' 错误:固定电话号码不能为空。',
  1380. error : $.formValidatorIcons.error + ' 错误:请填写正确的固定电话号码。'
  1381. },
  1382. telExt : {
  1383. normal : "* 格式:区号-固定电话号码、区号-固定电话号码-分机号。",
  1384. empty : $.formValidatorIcons.error + ' 错误:固定电话号码不能为空。',
  1385. error : $.formValidatorIcons.error + ' 错误:请填写正确的固定电话号码。'
  1386. },
  1387. fax : {
  1388. normal : "* 格式:区号-固定电话号码、区号-固定电话号码-分机号。",
  1389. empty : $.formValidatorIcons.error + ' 错误:传真号码不能为空。',
  1390. error : $.formValidatorIcons.error + ' 错误:请填写正确的传真号码。'
  1391. },
  1392. moblie : {
  1393. empty : $.formValidatorIcons.error + ' 错误:手机号码不能为空。',
  1394. error : $.formValidatorIcons.error + ' 错误:请填写正确的手机号码。'
  1395. },
  1396. moblieI18n : {
  1397. normal : '* 格式:+86手机号码',
  1398. empty : $.formValidatorIcons.error + ' 错误:手机号码不能为空。',
  1399. error : $.formValidatorIcons.error + ' 错误:请填写正确的手机号码,格式:+86手机号码。'
  1400. },
  1401. zipcode : {
  1402. empty : $.formValidatorIcons.error + ' 错误:邮政编码不能为空。',
  1403. error : $.formValidatorIcons.error + ' 错误:请填写正确的邮政编码。'
  1404. },
  1405. qq : {
  1406. empty : $.formValidatorIcons.error + ' 错误:QQ号码不能为空。',
  1407. error : $.formValidatorIcons.error + ' 错误:请填写正确的QQ号码(5-10位数字)。'
  1408. },
  1409. domain : {
  1410. normal : '* 格式:www.xxx.com | xxx.xxx.com 。',
  1411. empty : $.formValidatorIcons.error + ' 错误:域名不能为空。',
  1412. error : $.formValidatorIcons.error + ' 错误:请填写正确的域名。'
  1413. },
  1414. url : {
  1415. normal : '* (http|https|ftp)://www.xxx.com/xxx/xxx.html?xxx',
  1416. empty : $.formValidatorIcons.error + ' 错误:URL(网址)不能为空。',
  1417. error : $.formValidatorIcons.error + ' 错误:请填写正确的URL(网址)。'
  1418. },
  1419. ipv4 : {
  1420. normal : '* IPv4地址:0~255.0~255.0~255.0~255',
  1421. empty : $.formValidatorIcons.error + ' 错误:IP地址不能为空。',
  1422. error : $.formValidatorIcons.error + ' 错误:请填写正确的IP地址。'
  1423. },
  1424. idcard : {
  1425. normal : '* 填写18位的身份证号码',
  1426. empty : $.formValidatorIcons.error + ' 错误:身份证号码不能为空。',
  1427. error : $.formValidatorIcons.error + ' 错误:请填写正确的身份证号码。'
  1428. },
  1429. idcard1518 : {
  1430. normal : '* 填写15或18位的身份证号码',
  1431. empty : $.formValidatorIcons.error + ' 错误:身份证号码不能为空。',
  1432. error : $.formValidatorIcons.error + ' 错误:请填写正确的身份证号码(15或18位)。'
  1433. },
  1434. integer : {
  1435. normal : '* 只能填写正整数(0及以上)。',
  1436. error : $.formValidatorIcons.error + ' 错误:请填写正确的正整数(0及以上)。'
  1437. },
  1438. number : {
  1439. normal : '* 只能填写数字值。',
  1440. error : $.formValidatorIcons.error + ' 错误:请填写正确的数字值。'
  1441. },
  1442. image : {
  1443. normal : '* 只能上传 '+$.formValidatorImageFormats.join(', ')+' 格式的图片文件。',
  1444. error : $.formValidatorIcons.error + ' 错误:只能上传 '+$.formValidatorImageFormats.join(', ')+' 格式的图片文件。',
  1445. }
  1446. };
  1447. var isUndefined = function(obj) {
  1448. return (typeof obj == "undefined");
  1449. };
  1450. $.fn.formValidator = function(options, ajaxSubmit, _messages) {
  1451. ajaxSubmit = ajaxSubmit || false;
  1452. var submitBtn = $(this);
  1453. var form = submitBtn.parent("form");
  1454. var validator = function(_this) {
  1455. var name = _this.attr('name');
  1456. var value = _this.val();
  1457. var option = options[name];
  1458. var empty = option.empty || false;
  1459. var element = form.find('[name="'+name+'"]');
  1460. var role = form.find('[fv-role="'+name+'"]');
  1461. var msgNormal = role.find('[type="normal"]');
  1462. var msgEmpty = role.find('[type="empty"]');
  1463. var msgSuccess = role.find('[type="success"]');
  1464. var msgError = role.find('[type="error"]');
  1465. var equalTo = form.find('[name="'+option.equalTo+'"]');
  1466. var checked = 0;
  1467. var isSuccess = false;
  1468. if( !isUndefined(option.checked) ) checked = form.find('[name="'+name+'"]:checked').length;
  1469. var exp = {
  1470. min : ( !isUndefined(option.min) && parseFloat(value) < option.min),
  1471. max : ( !isUndefined(option.max) && parseFloat(value) > option.max),
  1472. minLength : ( !isUndefined(option.minLength) && value.length < option.minLength),
  1473. maxLength : ( !isUndefined(option.maxLength) && value.length > option.maxLength),
  1474. checkedEmpty : ( !isUndefined(option.checked) && checked == 0),
  1475. checked : ( !isUndefined(option.checked) && typeof option.checked == "number" && checked < option.checked),
  1476. checkedMin : ( !isUndefined(option.checked) && typeof option.checked == "object" && checked < option.checked[0]),
  1477. checkedMax : ( !isUndefined(option.checked) && typeof option.checked == "object" && checked > option.checked[1]),
  1478. equalTo : ( !isUndefined(option.equalTo) && value !== equalTo.val())
  1479. };
  1480. var successHandler = function(){
  1481. _this.removeClass("fv-error").addClass("fv-success");
  1482. role.find('span').hide();
  1483. msgSuccess.show();
  1484. isSuccess = true;
  1485. };
  1486. var errorHandler = function(){
  1487. _this.removeClass("fv-success").addClass("fv-error");
  1488. role.find('span').hide();
  1489. msgError.fadeIn();
  1490. isSuccess = false;
  1491. };
  1492. if(!empty)
  1493. {
  1494. if (value == "" || exp.checkedEmpty)
  1495. {
  1496. _this.removeClass("fv-success").addClass("fv-error");
  1497. role.find('span').hide();
  1498. msgEmpty.show();
  1499. }
  1500. else if (exp.min || exp.max || exp.minLength || exp.maxLength || exp.equalTo || exp.checked || exp.checkedMin || exp.checkedMax)
  1501. {
  1502. errorHandler();
  1503. }
  1504. else if (!isUndefined(option.ajax))
  1505. {
  1506. $.ajax({
  1507. type : "get",
  1508. async : false,
  1509. dataType : (option.jsonp ? "jsonp" : "json" ) || "json",
  1510. url : option.ajax + "&" + name + "=" + value,
  1511. success : function(json) {
  1512. if(json.status == 1) successHandler();
  1513. else errorHandler();
  1514. //console.log(json);
  1515. }
  1516. });
  1517. }
  1518. else if (!isUndefined(option.rule))
  1519. {
  1520. var rule = option.rule;
  1521. var fileExt = value.split('.');
  1522. var ruleExp = (typeof rule == "function") ? rule : $.formValidatorRules[rule];
  1523. fileExt = fileExt[fileExt.length - 1];
  1524. if(typeof ruleExp == "function") {
  1525. if(ruleExp(rule == "image" ? fileExt : value)) successHandler();
  1526. else errorHandler();
  1527. }
  1528. else if(typeof ruleExp == "object")
  1529. {
  1530. if(ruleExp.test(value)) successHandler();
  1531. else errorHandler();
  1532. }
  1533. else
  1534. {
  1535. }
  1536. console.log(typeof ruleExp, ruleExp);
  1537. }
  1538. else
  1539. {
  1540. if(!isUndefined(option.min) || !isUndefined(option.max)) _this.val(parseFloat(value) || 0);
  1541. successHandler();
  1542. }
  1543. }
  1544. else
  1545. {
  1546. if(value !== "")
  1547. {
  1548. }
  1549. }
  1550. //$.proxy(option.success || new Function, element)();
  1551. //$.proxy(option.error || new Function, element)();
  1552. //console.log('isSuccess=>', isSuccess);
  1553. return isSuccess;
  1554. };
  1555. for (var i in options)
  1556. {
  1557. var defaultMessages = {
  1558. normal : '* 必填项',
  1559. empty : $.formValidatorIcons.error + ' 错误:不能为空。',
  1560. error : $.formValidatorIcons.error + ' 错误:请正确填写。',
  1561. success : $.formValidatorIcons.success + ' 正确'
  1562. };
  1563. var element = form.find('[name="'+i+'"]');
  1564. var role = form.find('[fv-role="'+i+'"]');
  1565. var option = options[i];
  1566. var type = element.attr('type'), message;
  1567. var ruleMessages = $.formValidatorRuleMessages;
  1568. if(isUndefined(option.message) && ruleMessages[option.rule]) option.message = "rule";
  1569. if(!isUndefined(option.message) && !isUndefined(option.rule) && option.message == "rule")
  1570. {
  1571. message = $.extend(defaultMessages, ruleMessages[option.rule] || {});
  1572. }
  1573. else
  1574. {
  1575. message = $.extend(defaultMessages, _messages);
  1576. message = $.extend(message, option.message);
  1577. }
  1578. //console.log('option=>', option, i, "message =>", message);
  1579. for (var x in message)
  1580. {
  1581. if(typeof option == "boolean" && x == "error") break;
  1582. role.append('<span type="'+x+'">'+message[x]+'</span>');
  1583. }
  1584. //console.log("$(this).length", element.length);
  1585. element.bind((type == "file" || element[0].tagName == "SELECT") ? "change" : "blur", function(event) {
  1586. validator($(this));
  1587. });
  1588. }
  1589. submitBtn.bind($.clickOrTouch() || "click", function() {
  1590. var errors = 0;
  1591. for (var i in options)
  1592. {
  1593. var element = form.find('[name="'+i+'"]');
  1594. if(!validator(element)) errors++;
  1595. }
  1596. console.log("errors =>", errors);
  1597. if (errors > 0) return false;
  1598. else
  1599. {
  1600. if (typeof ajaxSubmit == "object")
  1601. {
  1602. $.ajax($.extend({
  1603. type : "post",
  1604. data : form.serializeArray()
  1605. }, ajaxSubmit));
  1606. return false;
  1607. }
  1608. else
  1609. {
  1610. form.submit();
  1611. }
  1612. }
  1613. });
  1614. return this;
  1615. };
  1616. })(PlaneUI);
  1617. (function($) {
  1618. $.fn.hoverScroller = function(options) {
  1619. options = options || {};
  1620. var defaults = {
  1621. target : "img",
  1622. scrollType : "marginTop", // transform
  1623. speed : 600
  1624. };
  1625. var settings = $.extend(defaults, options);
  1626. $(this).each(function() {
  1627. var timer;
  1628. var $this = $(this);
  1629. var target = $(this).find(settings.target);
  1630. function scrollTop() {
  1631. var speed = 0;
  1632. var targetHeight = parseInt(target.height());
  1633. $(this).css("cursor", "pointer");
  1634. timer = setInterval(function() {
  1635. speed += Math.floor(targetHeight / 200);
  1636. target.css({marginTop : "-" + speed + "px"});
  1637. var nowTop = parseInt(target.css("marginTop"));
  1638. if (-nowTop >= targetHeight - $this.height())
  1639. {
  1640. target.css({marginTop : "-" + (targetHeight - $this.height()) + "px)"});
  1641. clearInterval(timer);
  1642. }
  1643. }, settings.speed / 10);
  1644. }
  1645. function scrollDown() {
  1646. $(this).css("cursor", "");
  1647. clearInterval(timer);
  1648. target.animate({marginTop : 0}, settings.speed);
  1649. }
  1650. $this.css("overflow", "hidden").hover(scrollTop, scrollDown);
  1651. });
  1652. };
  1653. })(PlaneUI);
  1654. (function($) {
  1655. // 在可视窗口的上面
  1656. $.inScreenAbove = function(element, threshold) {
  1657. var top = $(window).scrollTop(), $el = $(element);
  1658. if ($el.length < 1) {
  1659. throw new TypeError("$.inScreenAbove(): element don't exist.");
  1660. }
  1661. return (top >= $el.offset().top + $el.height() - (threshold || 0));
  1662. };
  1663. // 在可视窗口的下面
  1664. $.inScreenBelow = function(element, threshold) {
  1665. var $window = $(window), $el = $(element);
  1666. if ($el.length < 1) {
  1667. throw new TypeError("$.inScreenBelow(): element don't exist.");
  1668. }
  1669. return ($window.height() + $window.scrollTop() <= $el.offset().top - (threshold || 0));
  1670. };
  1671. $.inScreenLeft = function(element, threshold) {
  1672. var left = $(window).scrollLeft(), $el = $(element);
  1673. if ($el.length < 1) {
  1674. throw new TypeError("$.inScreenLeft(): element don't exist.");
  1675. }
  1676. return (left >= $el.offset().left + $el.width() - (threshold || 0));
  1677. };
  1678. $.inScreenRight = function(element, threshold) {
  1679. var $window = $(window), $el = $(element);
  1680. if ($el.length < 1) {
  1681. throw new TypeError("$.inScreenRight(): element don't exist.");
  1682. }
  1683. return ($window.width() + $window.scrollLeft() <= $el.offset().left - (threshold || 0));
  1684. };
  1685. $.inViewport = function(element, threshold) {
  1686. if ($(element).length < 1) {
  1687. throw new TypeError("$.inViewport(): element don't exist.");
  1688. }
  1689. return (!$.inScreenLeft(element, threshold) &&
  1690. !$.inScreenRight(element, threshold) &&
  1691. !$.inScreenAbove(element, threshold) &&
  1692. !$.inScreenBelow(element, threshold));
  1693. };
  1694. $.extend($.expr[':'], {
  1695. "in-screen-below": function(el) {
  1696. return $.inScreenBelow(el);
  1697. },
  1698. "in-screen-above": function(el) {
  1699. return $.inScreenAbove(el);
  1700. },
  1701. "in-screen-left": function(el) {
  1702. return $.inScreenLeft(el);
  1703. },
  1704. "in-screen-right": function(el) {
  1705. return $.inScreenRight(el);
  1706. },
  1707. "in-viewport": function(el) {
  1708. return $.inViewport(el);
  1709. }
  1710. });
  1711. })(PlaneUI);
  1712. (function($) {
  1713. $(function() {
  1714. var subMenuClass = ".pui-sub-menu";
  1715. $(".pui-menu-accordion.click-toggle > li > a").bind($.clickOrTouch(), function() {
  1716. $(this).parent().toggleClass("submenu-open").children(subMenuClass).slideToggle();
  1717. });
  1718. $(".pui-menu-accordion.click > li > a").bind($.clickOrTouch(), function() {
  1719. var li = $(this).parent();
  1720. if (!li.hasClass("submenu-open")) {
  1721. li.parent().find("li").removeClass("submenu-open").find(subMenuClass).slideUp();
  1722. li.toggleClass("submenu-open").children(subMenuClass).slideDown();
  1723. }
  1724. });
  1725. });
  1726. })(PUI);
  1727. (function ($) {
  1728. $.menuDropdown = function(options) {
  1729. var defaults = {
  1730. bind : "click",
  1731. target : "menu-dropdown-target",
  1732. direction : "default", // bottom-left
  1733. hasArrow : false,
  1734. contextMenuTarget : "show-context-menu",
  1735. callback : new Function
  1736. };
  1737. var settings = $.extend(defaults, options);
  1738. $("["+settings.contextMenuTarget+"]").bind($.contextMenuOrTouch(), function(event){
  1739. event = event || window.event;
  1740. var $this = $(this);
  1741. var target = $this.attr(settings.contextMenuTarget);
  1742. var targetObj = $(target);
  1743. var pageX = event.pageX;
  1744. var pageY = event.pageY;
  1745. if(event.type == "touchend") {
  1746. pageX = $this.offset().left;
  1747. pageY = $this.offset().top + $this.outerHeight();
  1748. }
  1749. targetObj.show().css({
  1750. top : pageY,
  1751. left : pageX
  1752. });
  1753. $(document).bind($.clickOrTouch(), function(){
  1754. targetObj.hide();
  1755. });
  1756. targetObj.mouseleave(function(){
  1757. targetObj.hide();
  1758. });
  1759. return false;
  1760. });
  1761. $("["+settings.target+"]").bind($.clickOrTouch(), function() {
  1762. var $this = $(this);
  1763. var target = $this.attr(settings.target);
  1764. var targetObj = $(target);
  1765. var direction = $this.attr("menu-dropdown-direction");
  1766. if(typeof(direction) == 'undefined' || direction == "") {
  1767. direction = settings.direction;
  1768. }
  1769. $this.find(".pui-btn").addClass("active");
  1770. targetObj.show();
  1771. switch(direction)
  1772. {
  1773. case "left-top":
  1774. targetObj.css({
  1775. top : $this.offset().top,
  1776. left : $this.offset().left - targetObj.outerWidth() - 4
  1777. });
  1778. break;
  1779. case "left-bottom":
  1780. targetObj.css({
  1781. top : $this.offset().top - targetObj.outerHeight() + $this.outerHeight(),
  1782. left : $this.offset().left - targetObj.outerWidth() - 4
  1783. });
  1784. break;
  1785. case "right-top":
  1786. targetObj.css({
  1787. top : $this.offset().top,
  1788. left : $this.offset().left + $this.outerWidth() + 4
  1789. });
  1790. break;
  1791. case "right-bottom":
  1792. targetObj.css({
  1793. top : $this.offset().top - targetObj.outerHeight() + $this.outerHeight(),
  1794. left : $this.offset().left + $this.outerWidth() + 4
  1795. });
  1796. break;
  1797. case "top-left":
  1798. targetObj.css({
  1799. top : $this.offset().top - 2 - (settings.hasArrow ? 8 : 0) - targetObj.outerHeight(),
  1800. left : $this.offset().left
  1801. });
  1802. break;
  1803. case "top-right":
  1804. targetObj.css({
  1805. top : $this.offset().top - 2 - (settings.hasArrow ? 8 : 0) - targetObj.outerHeight(),
  1806. left : $this.offset().left + $this.outerWidth() - targetObj.outerWidth()
  1807. });
  1808. break;
  1809. case "bottom-right":
  1810. targetObj.css({
  1811. top : $this.offset().top + $this.outerHeight() + 2 + (settings.hasArrow ? 8 : 0),
  1812. left : $this.offset().left + $this.outerWidth() - targetObj.outerWidth()
  1813. });
  1814. break;
  1815. case "bottom-left":
  1816. default:
  1817. targetObj.css({
  1818. top : $this.offset().top + $this.outerHeight() + 2 + (settings.hasArrow ? 8 : 0),
  1819. left : $this.offset().left
  1820. });
  1821. break;
  1822. }
  1823. $(document).bind($.clickOrTouch(), function() {
  1824. targetObj.hide();
  1825. $this.find(".pui-btn").removeClass("active");
  1826. });
  1827. return false;
  1828. });
  1829. };
  1830. $(function(){
  1831. $(".pui-menu > li").bind("touchend", function() {
  1832. $(this).children(".pui-menu-dropdown").show().mouseleave(function() {
  1833. $(this).hide();
  1834. });
  1835. });
  1836. $.menuDropdown();
  1837. });
  1838. })(PlaneUI);
  1839. (function ($) {
  1840. $(function() {
  1841. $(".pui-notice").each(function() {
  1842. var timeout = $(this).attr("notice-timeout");
  1843. var closeBtn = $(this).find(".pui-close");
  1844. if(typeof timeout !== "undefined") {
  1845. timeout = parseInt(timeout);
  1846. var timer = setTimeout(function(){
  1847. closeBtn.trigger($.clickOrTouch());
  1848. clearTimeout(timer);
  1849. }, timeout);
  1850. }
  1851. closeBtn.bind($.clickOrTouch(), function() {
  1852. $(this).parent().css({minHeight: 0}).slideUp(500, function() {
  1853. $(this).remove();
  1854. });
  1855. });
  1856. });
  1857. });
  1858. })(PlaneUI);
  1859. (function ($) {
  1860. var drawed = false;
  1861. $.fn.extend({
  1862. ringProgress : function(options) {
  1863. options = options || {};
  1864. var defaults = {
  1865. redraw : false,
  1866. sector : false,
  1867. ringColor : '#30C4E9',
  1868. ringWidth : 6,
  1869. bgColor : '#fff',
  1870. textColor : '#666',
  1871. textFontSize : '16px',
  1872. textFontFamily : 'Arial',
  1873. textAlign : 'center',
  1874. textBaseline : 'middle',
  1875. zero : false
  1876. };
  1877. // 设置优先级:HTML属性设置 > jQuery插件设置 > 默认值
  1878. var settings = $.extend(defaults, options);
  1879. var _this = this;
  1880. this.settings = settings;
  1881. this.test = function(){alert('test')};
  1882. this.each(function(i) {
  1883. var $this = $(this);
  1884. var canvas = this;
  1885. var text = $this.text();
  1886. var progress = parseInt(text);
  1887. var context = canvas.getContext('2d');
  1888. var width = canvas.width;
  1889. var height = canvas.height;
  1890. if(window.devicePixelRatio > 1 && settings.redraw) {
  1891. width /= 2;
  1892. height /= 2;
  1893. }
  1894. var radius = width / 2;
  1895. if(settings.zero) {
  1896. progress = 1;
  1897. text = "0%";
  1898. }
  1899. var sector = $this.attr('sector');
  1900. var ringColor = $this.attr('ring-color');
  1901. var ringWidth = $this.attr('ring-width');
  1902. var bgColor = $this.attr('bg-color');
  1903. var textColor = $this.attr('text-color');
  1904. var textFontSize = $this.attr('text-font-size');
  1905. var textFontFamily = $this.attr('text-font-family');
  1906. var textAlign = $this.attr('text-align');
  1907. var textBaseline = $this.attr('text-baseline');
  1908. if (typeof(sector) == 'undefined' || sector == '') {
  1909. this.sector = sector = settings.sector;
  1910. }
  1911. if (typeof(ringColor) == 'undefined' || ringColor == '') {
  1912. this.ringColor = ringColor = settings.ringColor;
  1913. }
  1914. if (typeof(ringWidth) == 'undefined' || ringWidth == '') {
  1915. this.ringWidth = ringWidth = settings.ringWidth;
  1916. }
  1917. if (typeof(bgColor) == 'undefined' || bgColor == '') {
  1918. this.bgColor = bgColor = settings.bgColor;
  1919. }
  1920. if (typeof(textColor) == 'undefined' || textColor == '') {
  1921. this.textColor = textColor = settings.textColor;
  1922. }
  1923. if (typeof(textFontSize) == 'undefined' || textFontSize == '') {
  1924. this.textFontSize = textFontSize = settings.textFontSize;
  1925. }
  1926. if (typeof(textFontFamily) == 'undefined' || textFontFamily == '') {
  1927. this.textFontFamily = textFontFamily = settings.textFontFamily;
  1928. }
  1929. if (typeof(textAlign) == 'undefined' || textAlign == '') {
  1930. this.textAlign = textAlign = settings.textAlign;
  1931. }
  1932. if (typeof(textBaseline) == 'undefined' || textBaseline == '') {
  1933. this.textBaseline = textBaseline = settings.textBaseline;
  1934. }
  1935. if(progress >= 100) {
  1936. progress = 99.9999;
  1937. }
  1938. else if(progress < 1) {
  1939. progress = 1;
  1940. }
  1941. //console.log(width, height, bgColor, ringColor);
  1942. (function (canvas, context) {
  1943. if(settings.redraw) {
  1944. return ;
  1945. }
  1946. var devicePixelRatio = window.devicePixelRatio || 1;
  1947. var backingStorePixelRatio = context.webkitBackingStorePixelRatio ||
  1948. context.mozBackingStorePixelRatio ||
  1949. context.msBackingStorePixelRatio ||
  1950. context.oBackingStorePixelRatio ||
  1951. context.backingStorePixelRatio || 1;
  1952. var ratio = devicePixelRatio / backingStorePixelRatio;
  1953. if (ratio > 1) {
  1954. canvas.style.height = canvas.height + 'px';
  1955. canvas.style.width = canvas.width + 'px';
  1956. canvas.width *= ratio;
  1957. canvas.height *= ratio;
  1958. context.scale(ratio, ratio);
  1959. }
  1960. })(canvas, context);
  1961. //console.log(window.devicePixelRatio+', '+canvas.width +', '+ canvas.height+', '+width+', '+height);
  1962. // 画底圆
  1963. context.clearRect(0, 0, width, height);
  1964. context.beginPath();
  1965. context.moveTo(width / 2, height / 2);
  1966. context.arc(width / 2, height / 2, radius, 0, Math.PI * 2, false);
  1967. context.closePath();
  1968. context.fillStyle = bgColor;
  1969. context.fill();
  1970. // 直接画圆环
  1971. //context.strokeStyle="#333";
  1972. //context.lineWidth= 5; // 线宽
  1973. //context.arc(width / 2, height / 2, radius - (5/2) , 0, Math.PI * 2, false);
  1974. //context.stroke();
  1975. // 画扇形(进度)
  1976. context.beginPath();
  1977. context.moveTo(width / 2, height / 2);
  1978. //整个圆为2PI,360 -> 1.5PI, 90 -> 0PI, 180 -> 0.5PI, 270 -> 1PI
  1979. // arc(x,y, 半径, 开始角度,结束角度, 顺时或逆时针)
  1980. var endAngle = Math.PI * (2 * (progress / 100)) - (Math.PI * 0.5);
  1981. context.arc(width / 2, height / 2, radius, Math.PI * 1.5, endAngle, false);
  1982. context.closePath();
  1983. context.fillStyle = ringColor;
  1984. context.fill();
  1985. // 画内部空白
  1986. if(sector === 'false' || !sector) {
  1987. context.beginPath();
  1988. context.moveTo(width / 2, height / 2);
  1989. context.arc(width / 2, height / 2, radius - ringWidth, 0, Math.PI * 2, true);
  1990. context.closePath();
  1991. context.fillStyle = '#fff';
  1992. context.fill();
  1993. }
  1994. // 文字
  1995. context.font = textFontSize + " " +textFontFamily;
  1996. context.fillStyle = textColor;
  1997. context.textAlign = textAlign;
  1998. context.textBaseline = textBaseline;
  1999. context.moveTo(width / 2, height / 2);
  2000. context.fillText(text, width / 2, height / 2);
  2001. });
  2002. return this;
  2003. },
  2004. ringProgressAnimation : function(options, options2) {
  2005. var defaults = {
  2006. start : 0,
  2007. end : 100,
  2008. speed : 1000
  2009. };
  2010. var defaults2 = {
  2011. redraw : true
  2012. };
  2013. var settings = $.extend(defaults, options);
  2014. var settings2 = $.extend(defaults2, options2);
  2015. var _this = this;
  2016. var timer = setInterval(function() {
  2017. settings.start ++;
  2018. $(_this).html(settings.start + "%").ringProgress(settings2);
  2019. if(settings.start >= settings.end) clearInterval(timer);
  2020. }, settings.speed);
  2021. return this;
  2022. }
  2023. });
  2024. })(PlaneUI);
  2025. (function ($) {
  2026. $(function(){
  2027. $("pui-radio").each(function(i) {
  2028. var $this = $(this);
  2029. var radio = $('<input type="radio" />');
  2030. radio.attr("name", $this.attr('name'));
  2031. radio.val($this.attr('value'));
  2032. if($this.hasClass('checked')) {
  2033. radio.attr("checked", "checked");
  2034. }
  2035. if($this.attr('disabled') == "disabled") {
  2036. radio.attr("disabled", "disabled");
  2037. }
  2038. $this.append(radio);
  2039. $this.bind($.clickOrTouch(), function() {
  2040. if($(this).attr('disabled') == "disabled") return ;
  2041. var input = $(this).find('input');
  2042. if(input.attr('checked') == "checked") return ;
  2043. var name = $(this).attr('name');
  2044. $('input[name="'+name+'"]').removeAttr('checked');
  2045. $(this).addClass('checked').siblings().removeClass('checked');
  2046. input[0].checked = true;
  2047. });
  2048. });
  2049. });
  2050. })(PlaneUI);
  2051. (function ($) {
  2052. $.fn.rating = function(options) {
  2053. var defaults = {
  2054. score : 0,
  2055. total : 5,
  2056. titles : "非常差,很差,好,很好,非常好",
  2057. showTotal : true,
  2058. showScore : true,
  2059. ajaxURL : "",
  2060. clickHandler : null,
  2061. clickCallback : new Function
  2062. };
  2063. var settings = $.extend(defaults, options);
  2064. $(this).each(function() {
  2065. var $this = $(this);
  2066. var score = function(){
  2067. return (typeof($this.attr('score')) == "undefined") ? settings.score : $this.attr('score');
  2068. };
  2069. var floor = Math.floor(score());
  2070. var ceil = Math.ceil(score());
  2071. var total = $this.attr('total');
  2072. var titles = $this.attr('titles');
  2073. var showTotal = $this.attr('show-total');
  2074. var showScore = $this.attr('show-score');
  2075. var ajaxURL = $this.attr('ajax-url');
  2076. var clickCallback = $this.attr('click-callback');
  2077. total = (typeof(total) == "undefined") ? settings.total : parseInt(total);
  2078. titles = (typeof(titles) == "undefined") ? settings.titles.split(",") : titles.split(",");
  2079. if(typeof(showTotal) == "undefined") showTotal = settings.showTotal;
  2080. if(typeof(showScore) == "undefined") showScore = settings.showScore;
  2081. if(typeof(ajaxURL) == "undefined") ajaxURL = settings.ajaxURL;
  2082. if(typeof(clickCallback) == "undefined" || clickCallback == "")
  2083. {
  2084. clickCallback = settings.clickCallback;
  2085. }
  2086. else
  2087. {
  2088. clickCallback = window[clickCallback];
  2089. }
  2090. console.log(total, titles, showTotal, showScore, clickCallback);
  2091. for (var i = 1, length = total + 1; i < length; i++)
  2092. {
  2093. var className = '';
  2094. if (i <= floor)
  2095. {
  2096. className = ' class="full"';
  2097. }
  2098. else if (i > score() && i == ceil)
  2099. {
  2100. className = ' class="half"';
  2101. }
  2102. else if (i > ceil || score() == 0)
  2103. {
  2104. className = '';
  2105. }
  2106. //console.log(i+", "+score()+", "+floor+", "+ceil+", "+total+"<br/>");
  2107. var span = $('<span title="'+titles[i-1]+'" value="'+i+'"'+className+'></span>');
  2108. $this.append(span);
  2109. }
  2110. if(showTotal || showTotal == "true")
  2111. {
  2112. $this.append('<small>总分:'+total+'分 </small>');
  2113. }
  2114. if(showScore || showScore == "true")
  2115. {
  2116. $this.append('<small>平均分:'+score()+'分</small>');
  2117. }
  2118. $this.find("span").bind({
  2119. "mouseenter" : function(event) {
  2120. var index = $(this).index();
  2121. $this.find("span").each(function(i) {
  2122. $(this).removeClass();
  2123. if (i <= index) {
  2124. $(this).addClass('full');
  2125. }
  2126. //console.log(i, score(), floor, ceil, total, $(this).attr('class'));
  2127. });
  2128. },
  2129. "mouseleave" : function(event) {
  2130. var index = $(this).index();
  2131. $this.find("span").each(function(i) {
  2132. i = i + 1;
  2133. $(this).removeClass();
  2134. if (i <= Math.floor(score()))
  2135. {
  2136. $(this).addClass('full');
  2137. }
  2138. else if (i > score() && i == Math.ceil(score()))
  2139. {
  2140. $(this).addClass("half");
  2141. }
  2142. });
  2143. },
  2144. "click" : function() {
  2145. if(typeof(settings.clickHandler) == "function") {
  2146. settings.clickHandler($this);
  2147. return ;
  2148. }
  2149. if (ajaxURL == "") {
  2150. console.error("错误:URL不能为空,Rating评价组件默认通过Ajax执行点击操作。");
  2151. return ;
  2152. }
  2153. var index = $(this).index();
  2154. $.post(ajaxURL, {score : score(), newscore : (index + 1), total : total}, function(data) {
  2155. $this.attr("score", data).find("small").remove();
  2156. if(showTotal || showTotal == "true") {
  2157. $this.append('<small>总分:'+total+'分 </small>');
  2158. }
  2159. if(showScore || showScore == "true") {
  2160. $this.append('<small>平均分:'+data+'分</small>');
  2161. }
  2162. $this.find("span").each(function(i) {
  2163. i = i + 1;
  2164. $(this).removeClass();
  2165. if (i <= Math.floor(data))
  2166. {
  2167. $(this).addClass('full');
  2168. }
  2169. else if (i > data && i == Math.ceil(data))
  2170. {
  2171. $(this).addClass("half");
  2172. }
  2173. });
  2174. clickCallback($this);
  2175. });
  2176. }
  2177. });
  2178. });
  2179. };
  2180. })(PlaneUI);
  2181. (function($) {
  2182. $.fn.scrollTo = function (options) {
  2183. options = options || {};
  2184. var defaults = {
  2185. speed : 800,
  2186. direction : "top",
  2187. top : null,
  2188. left : null,
  2189. targetHash : true,
  2190. hashEmpty : true,
  2191. callback : function() {},
  2192. scrollTarget : "html, body"
  2193. };
  2194. var settings = $.extend(defaults, (typeof options === "object") ? options : {});
  2195. if (typeof options === "function") {
  2196. settings.callback = options;
  2197. }
  2198. $(this.selector ? this.selector : "[scrollto]").bind($.clickOrTouch(), function() {
  2199. var scrollHandler = function($this, target) {
  2200. var direction = {};
  2201. if (settings.top === 0) {
  2202. settings.top = "0px";
  2203. }
  2204. if (settings.left === 0) {
  2205. settings.left = "0px";
  2206. }
  2207. if (!settings.top && !settings.left) {
  2208. if (settings.direction === "left") {
  2209. direction = { scrollLeft : target.offset().left };
  2210. } else {
  2211. direction = { scrollTop : target.offset().top };
  2212. }
  2213. }
  2214. if (settings.top) {
  2215. direction.scrollTop = settings.top;
  2216. }
  2217. if (settings.left) {
  2218. direction.scrollLeft = settings.left;
  2219. }
  2220. $(settings.scrollTarget).animate(direction, settings.speed, function() {
  2221. if (settings.hashEmpty && window.addEventListener) { // IE9+
  2222. location.hash = "";
  2223. }
  2224. $.proxy(settings.callback, $this)(target);
  2225. });
  2226. };
  2227. if (settings.targetHash)
  2228. {
  2229. if (location.pathname.replace(/^\//, "") == this.pathname.replace(/^\//, "") && location.hostname == this.hostname)
  2230. {
  2231. var hash = this.hash;
  2232. var target = $(hash);
  2233. var $this = $(this);
  2234. target = target.length && target || $("[name=" + hash.slice(1) + "]");
  2235. if (target.length > 0)
  2236. {
  2237. scrollHandler($(this), target);
  2238. }
  2239. }
  2240. }
  2241. else
  2242. {
  2243. scrollHandler($(this), settings.scrollTarget);
  2244. }
  2245. return false;
  2246. });
  2247. };
  2248. })(PlaneUI);
  2249. (function ($) {
  2250. $(function() {
  2251. $(document).keyup(function(event) {
  2252. if (event.keyCode ==13) {
  2253. $(".pui-search-submit").trigger("click");
  2254. }
  2255. });
  2256. $('.pui-search-single-button').hover(function() {
  2257. var $this = $(this);
  2258. var hoverWidth = $this.attr('hover-width');
  2259. var keywordInput = $this.find('.pui-search-keywords');
  2260. $this.width(hoverWidth);
  2261. keywordInput.removeClass('pui-search-keywords-slide-reverse').addClass('pui-search-keywords-slide');
  2262. return false;
  2263. }, function() {
  2264. var $this = $(this);
  2265. var width = $this.attr('width');
  2266. var keywordInput = $this.find('.pui-search-keywords');
  2267. $this.width(width);
  2268. keywordInput.removeClass('pui-search-keywords-slide-reverse').addClass('pui-search-keywords-slide-reverse');
  2269. return false;
  2270. });
  2271. });
  2272. })(PlaneUI);
  2273. (function ($) {
  2274. $.fn.sidePosition = function(options) {
  2275. var defaults = {
  2276. zIndexTop : false,
  2277. attr : "pui-side-position",
  2278. showMode : "slide",
  2279. speed : 300,
  2280. mask : false,
  2281. maskFullOpacity : false
  2282. };
  2283. var settings = $.extend(defaults, options);
  2284. var selector = ($(this).selector === "") ? "[" + settings.attr + "]" : this;
  2285. $(selector).each(function() {
  2286. var $this = $(this);
  2287. var position = $this.attr(settings.attr);
  2288. var side = $("." + settings.attr + "-" + position);
  2289. if (settings.zIndexTop) {
  2290. side.addClass("pui-side-position-zindex-top");
  2291. }
  2292. var handle = function() {
  2293. if (settings.mask)
  2294. {
  2295. var mask = $(".pui-side-position-mask");
  2296. if (settings.maskFullOpacity)
  2297. {
  2298. mask.css({ opacity : 0 });
  2299. }
  2300. mask.fadeToggle(settings.speed);
  2301. if (!mask.is(":hidden"))
  2302. {
  2303. mask.bind($.clickOrTouch(), function() {
  2304. mask.fadeOut(settings.speed);
  2305. switch (position)
  2306. {
  2307. case "top":
  2308. side.animate({
  2309. top : "-" + side.outerHeight() + $(".pui-app-header").outerHeight() + "px",
  2310. opacity : "hide"
  2311. }, settings.speed);
  2312. case "bottom":
  2313. side.animate({bottom : "-" + side.outerHeight() + "px", opacity : "hide"}, settings.speed);
  2314. break;
  2315. case "right":
  2316. case "left":
  2317. default:
  2318. break;
  2319. }
  2320. return false;
  2321. });
  2322. }
  2323. }
  2324. if (position === "left" || position === "right")
  2325. {
  2326. side.height($("body").outerHeight());
  2327. }
  2328. if (settings.showMode === "fade")
  2329. {
  2330. side.fadeToggle(settings.speed);
  2331. }
  2332. else if (settings.showMode === "slide")
  2333. {
  2334. if (position === "left")
  2335. {
  2336. if (side.is(":hidden"))
  2337. {
  2338. side.css({ left : "-" + side.outerWidth() + "px"}).animate({ left : 0, opacity : "show"}, settings.speed);
  2339. }
  2340. else
  2341. {
  2342. side.animate({left : "-" + side.outerWidth() + "px", opacity : "hide"}, settings.speed);
  2343. }
  2344. }
  2345. if (position === "right")
  2346. {
  2347. if(side.is(":hidden"))
  2348. {
  2349. side.css({right : "-" + side.outerWidth() + "px"}).animate({right : 0, opacity : "show"}, settings.speed);
  2350. }
  2351. else
  2352. {
  2353. side.animate({
  2354. right : "-" + side.outerWidth() + "px",
  2355. opacity : "hide"
  2356. }, settings.speed);
  2357. }
  2358. }
  2359. if (position === "top")
  2360. {
  2361. if (side.is(":hidden"))
  2362. {
  2363. side.css({
  2364. top : "-" + side.outerHeight() + $(".pui-app-header").outerHeight() + "px"
  2365. }).animate({
  2366. top : $(".pui-app-header").outerHeight(),
  2367. opacity : "show"
  2368. }, settings.speed);
  2369. }
  2370. else
  2371. {
  2372. side.animate({
  2373. top : "-" + side.outerHeight() + $(".pui-app-header").outerHeight() + "px",
  2374. opacity : "hide"
  2375. }, settings.speed);
  2376. }
  2377. }
  2378. if (position === "bottom")
  2379. {
  2380. if (side.is(":hidden"))
  2381. {
  2382. side.css({
  2383. bottom : "-" + side.outerHeight() + "px"
  2384. }).animate({
  2385. bottom : 0,
  2386. opacity : "show"
  2387. }, settings.speed);
  2388. }
  2389. else
  2390. {
  2391. side.animate({
  2392. bottom : "-" + side.outerHeight() + "px",
  2393. opacity : "hide"
  2394. }, settings.speed);
  2395. }
  2396. }
  2397. }
  2398. else
  2399. {
  2400. side.toggle();
  2401. }
  2402. };
  2403. $this.bind($.clickOrTouch(), handle);
  2404. side.bind("click", handle);
  2405. });
  2406. };
  2407. })(PlaneUI);
  2408. (function ($) {
  2409. $.fn.sideSlide = function(options) {
  2410. var defaults = {
  2411. attr : "pui-side-slide",
  2412. speed : 300,
  2413. mask : false,
  2414. maskFullOpacity: false
  2415. };
  2416. var settings = $.extend(defaults, options);
  2417. $("["+settings.attr+"]").each(function() {
  2418. var $this = $(this);
  2419. var sideName = $this.attr(settings.attr);
  2420. var side = $("."+settings.attr+"-"+sideName);
  2421. var main = $(".pui-app-main");
  2422. var appLayout = $(".pui-app-layout");
  2423. $this.bind($.clickOrTouch(), function() {
  2424. if(sideName == "top" || sideName == "bottom") {
  2425. appLayout.css("overflow-y", "hidden");
  2426. } else {
  2427. appLayout.css("overflow-x", "hidden");
  2428. }
  2429. if(settings.mask)
  2430. {
  2431. var mask = main.find(".pui-mask-bg");
  2432. if(settings.maskFullOpacity) {
  2433. mask.css({opacity:0});
  2434. }
  2435. mask.fadeToggle(settings.speed);
  2436. if(!mask.is(":hidden"))
  2437. {
  2438. mask.bind($.clickOrTouch(), function() {
  2439. mask.fadeOut(settings.speed);
  2440. side.hide();
  2441. switch(sideName)
  2442. {
  2443. case "top":
  2444. case "bottom":
  2445. main.animate({marginTop : 0}, settings.speed, function(){
  2446. appLayout.css("overflow", "auto");
  2447. });
  2448. break;
  2449. case "right":
  2450. case "left":
  2451. default:
  2452. main.animate({marginLeft : 0}, settings.speed, function(){
  2453. appLayout.css("overflow", "auto");
  2454. });
  2455. break;
  2456. }
  2457. return false;
  2458. });
  2459. }
  2460. }
  2461. switch(sideName)
  2462. {
  2463. case "top":
  2464. side.toggle();
  2465. if(!side.is(":hidden")) {
  2466. main.animate({marginTop : side.outerHeight() + "px"}, settings.speed);
  2467. } else {
  2468. main.animate({marginTop : 0}, settings.speed, function(){
  2469. appLayout.css("overflow", "auto");
  2470. });
  2471. }
  2472. break;
  2473. case "bottom":
  2474. if(side.is(":hidden")) {
  2475. main.animate({marginTop : "-"+side.outerHeight() + "px"}, settings.speed, function() {
  2476. side.show();
  2477. });
  2478. } else {
  2479. side.hide();
  2480. main.animate({marginTop : 0}, settings.speed, function(){
  2481. appLayout.css("overflow", "auto");
  2482. });
  2483. }
  2484. break;
  2485. case "right":
  2486. if(side.is(":hidden")) {
  2487. main.animate({marginLeft : "-"+side.outerWidth() + "px"}, settings.speed, function(){
  2488. side.show();
  2489. });
  2490. } else {
  2491. side.hide();
  2492. main.animate({marginLeft : 0}, settings.speed, function(){
  2493. appLayout.css("overflow", "auto");
  2494. });
  2495. }
  2496. break;
  2497. case "left":
  2498. default:
  2499. side.toggle();
  2500. if(!side.is(":hidden")) {
  2501. main.animate({marginLeft : side.outerWidth() + "px"}, settings.speed);
  2502. } else {
  2503. main.animate({marginLeft : 0}, settings.speed, function(){
  2504. appLayout.css("overflow", "auto");
  2505. });
  2506. }
  2507. break;
  2508. }
  2509. return false;
  2510. });
  2511. });
  2512. };
  2513. })(PlaneUI);
  2514. (function($) {
  2515. $(function() {
  2516. $("pui-switch").each(function() {
  2517. var $this = $(this);
  2518. var values = $this.attr('value').split(',');
  2519. try
  2520. {
  2521. var texts = $this.attr('text').split(',');
  2522. }
  2523. catch(e)
  2524. {
  2525. alert("致命错误:请设置switch组件的text属性。");
  2526. return false;
  2527. }
  2528. var switched = $this.attr('switched');
  2529. var name = $this.attr('name');
  2530. var elements = "", switchedValue;
  2531. var innerHTML = $this.html();
  2532. $this.html('');
  2533. if(typeof(switched) == "undefined")
  2534. {
  2535. switched = values[0];
  2536. }
  2537. for (var i = 0, len = values.length; i < len; i++)
  2538. {
  2539. var isSwitched = (switched == values[i]) ? ' class="switched"' : '';
  2540. if(switched == values[i]) switchedValue = values[i];
  2541. elements += '<span value="'+values[i]+'"'+isSwitched+'>'+texts[i]+'</span>';
  2542. }
  2543. $this.append('<switches>'+elements+'</switches>');
  2544. $this.append('<input type="hidden" name="'+name+'" value="'+switchedValue+'" />');
  2545. if(innerHTML != '')
  2546. {
  2547. $this.append(innerHTML);
  2548. }
  2549. var item = $this.find('switches > span');
  2550. var input = $this.find('input');
  2551. if($this.attr('disabled') != 'disabled')
  2552. {
  2553. item.bind($.clickOrTouch(), function() {
  2554. $(this).addClass('switched').siblings().removeClass('switched');
  2555. input.val($(this).attr('value'));
  2556. });
  2557. }
  2558. });
  2559. });
  2560. })(PlaneUI);
  2561. (function($) {
  2562. $(function() {
  2563. $('pui-switch-slide').each(function() {
  2564. var $this = $(this);
  2565. var width = $this.attr('width');
  2566. var name = $this.attr('name');
  2567. var color = $this.attr('color');
  2568. var onColor = $this.attr('on-color');
  2569. var offColor = $this.attr('off-color');
  2570. var btn = $(this).find("span");
  2571. var animated = $this.attr('animated');
  2572. var value = (btn.attr("class") == 'off') ? 0 : 1;
  2573. var input = $('<input type="hidden" name="'+name+'" value="'+value+'" />');
  2574. $this.append(input);
  2575. if(typeof(width) != 'undefined')
  2576. {
  2577. $this.width(width);
  2578. }
  2579. if(typeof(color) != 'undefined')
  2580. {
  2581. $this.css({
  2582. backgroundColor : color,
  2583. color : color
  2584. });
  2585. }
  2586. var btnClassName = btn.attr("class");
  2587. if((btnClassName != 'off') && typeof(onColor) != 'undefined')
  2588. {
  2589. $this.css({
  2590. backgroundColor : onColor,
  2591. color : onColor
  2592. });
  2593. }
  2594. if((btnClassName == 'off') && typeof(offColor) != 'undefined')
  2595. {
  2596. $this.css({
  2597. backgroundColor : offColor,
  2598. color : offColor
  2599. });
  2600. }
  2601. $this.bind($.clickOrTouch(), function() {
  2602. if($this.attr('disabled') == 'disabled') return ;
  2603. if(typeof(animated) != 'undefined' && animated == 'true')
  2604. {
  2605. $this.addClass('pui-switch-slide-animation');
  2606. }
  2607. btn.toggleClass('off');
  2608. if((btn.attr("class") == 'off') && typeof(offColor) != 'undefined')
  2609. {
  2610. $this.css({
  2611. backgroundColor : offColor,
  2612. color : offColor
  2613. });
  2614. }
  2615. else
  2616. {
  2617. $this.css({
  2618. backgroundColor : onColor,
  2619. color : onColor
  2620. });
  2621. }
  2622. $(this).find("input").val( (btn.attr("class") == 'off') ? "0" : "1" );
  2623. var change = btn.attr("change");
  2624. btn.attr("change", btn.html());
  2625. btn.html(change);
  2626. return false;
  2627. });
  2628. });
  2629. });
  2630. })(PlaneUI);
  2631. (function($) {
  2632. $.fn.tab = function(options) {
  2633. var defaults = {
  2634. speed : 0,
  2635. ajax : false,
  2636. ajaxLoading : 'loading...',
  2637. cached : false,
  2638. showMode : "show",
  2639. callback : new Function
  2640. };
  2641. var settings = $.extend(defaults, options);
  2642. $(this).each(function() {
  2643. var $this = $(this);
  2644. var tabHead = $this.find(".pui-tab-head li");
  2645. var tabBox = $this.find(".pui-tab-box");
  2646. tabHead.bind($.clickOrTouch(), function() {
  2647. var thisHead = $(this);
  2648. if(thisHead.hasClass("disabled")) return ;
  2649. var index = thisHead.index();
  2650. var speed = settings.speed;
  2651. var showMode = settings.showMode;
  2652. var ajaxURL = thisHead.attr("tab-ajax-url");
  2653. var cached = thisHead.attr("tab-ajax-cached");
  2654. if(typeof(cached) == "undefined" || cached == "") {
  2655. cached = settings.cached;
  2656. }
  2657. thisHead.addClass("active").siblings().removeClass("active");
  2658. tabBox.removeClass("show");
  2659. if(showMode == "fade")
  2660. {
  2661. tabBox.eq(index).fadeIn(speed).siblings().fadeOut(speed);
  2662. }
  2663. else if(showMode == "slide")
  2664. {
  2665. tabBox.eq(index).slideDown(speed).siblings().slideUp(speed);
  2666. }
  2667. else if(showMode == "scroll-x")
  2668. {
  2669. var scrollbox = tabBox.parent();
  2670. var boxList = tabBox.parent();
  2671. var box = tabBox.eq(index);
  2672. var boxListWidth = 0;
  2673. tabBox.each(function(){
  2674. boxListWidth += $(this).outerWidth();
  2675. });
  2676. //console.log(boxList.html(), index * box[0].offsetWidth);
  2677. scrollbox.outerHeight(box.outerHeight());
  2678. boxList.outerWidth(boxListWidth + 50).animate({
  2679. marginLeft : "-"+(index * box.outerWidth()) + "px"
  2680. }, speed);
  2681. }
  2682. else if(showMode == "scroll-y")
  2683. {
  2684. var scrollbox = tabBox.parent();
  2685. var boxList = tabBox.parent();
  2686. var box = tabBox.eq(index);
  2687. var boxListHeight = 0;
  2688. tabBox.each(function(){
  2689. boxListHeight += $(this).outerHeight();
  2690. });
  2691. //console.log(boxList.html(), index * box.outerHeight());
  2692. scrollbox.outerHeight(box.outerHeight());
  2693. boxList.outerHeight(boxListHeight + 50).animate({
  2694. marginTop : "-"+(index * box.outerHeight()) + "px"
  2695. }, speed);
  2696. }
  2697. else
  2698. {
  2699. tabBox.eq(index).show(speed).siblings().hide(speed);
  2700. }
  2701. console.log(typeof(ajaxURL) != "undefined", settings.ajax , !settings.cached, thisHead.data("cached"));
  2702. if(typeof(ajaxURL) != "undefined" && settings.ajax && typeof(thisHead.data("cached")) == "undefined")
  2703. {
  2704. tabBox.eq(index).html(settings.ajaxLoading);
  2705. var ajaxURL = tabHead.eq(index).attr("tab-ajax-url");
  2706. $.get(ajaxURL, {}, function(data) {
  2707. if(cached)
  2708. {
  2709. thisHead.data("cached", true);
  2710. }
  2711. tabBox.eq(index).html(data);
  2712. settings.callback($this, tabHead, tabBox, index, settings);
  2713. });
  2714. }
  2715. if(!settings.ajax) {
  2716. settings.callback($this, tabHead, tabBox, index, settings);
  2717. }
  2718. });
  2719. });
  2720. $("[tab-onready-ajax*=true]").each(function() {
  2721. var $this = $(this);
  2722. var index = $this.index();
  2723. var tabBox = $this.parent().parent().find(".pui-tab-box");
  2724. var cached = $this.attr("tab-ajax-cached");
  2725. if(typeof(cached) == "undefined" || cached == "") {
  2726. cached = settings.cached;
  2727. }
  2728. tabBox.eq(index).html(settings.ajaxLoading);
  2729. var ajaxURL = $this.attr("tab-ajax-url");
  2730. if(typeof(ajaxURL) != "undefined" && typeof($this.data("cached")) == "undefined")
  2731. {
  2732. $.get(ajaxURL, {}, function(data) {
  2733. if(cached)
  2734. {
  2735. $this.data("cached", true);
  2736. }
  2737. tabBox.eq(index).html(data);
  2738. settings.callback($this, $this.parent(), tabBox, index, settings);
  2739. });
  2740. }
  2741. });
  2742. };
  2743. })(PlaneUI);
  2744. (function($){
  2745. $.fn.tooltip = function(options) {
  2746. var defaults = {
  2747. target : "",
  2748. auto : false,
  2749. position : ["bottom", "center"],
  2750. positionClassPrefix : "pui-tooltip-arrow-",
  2751. addClass : "pui-tooltip-bordered pui-tooltip-primary-light",
  2752. cached : false,
  2753. ajax : new Function,
  2754. showMode : "show",
  2755. touch : true,
  2756. content : new Function,
  2757. callback : new Function
  2758. };
  2759. var settings = $.extend(defaults, options);
  2760. var $this = $(this);
  2761. $this.each(function() {
  2762. var body = $("body");
  2763. var _this = $(this);
  2764. var parseJSON = function() {
  2765. var json = {};
  2766. var string = _this.attr("pui-tooltip");
  2767. try {
  2768. json = $.jsonDecode(string);
  2769. } catch(e) {
  2770. json = eval("("+string+")");
  2771. }
  2772. return json;
  2773. };
  2774. var jsonData = function(key) {
  2775. return parseJSON()[key];
  2776. };
  2777. var setJSONData = function(key, value) {
  2778. var json = parseJSON();
  2779. json[key] = value;
  2780. _this.attr("pui-tooltip", $.jsonEncode(json));
  2781. };
  2782. var target = function() {
  2783. return (typeof(jsonData("target")) == "undefined") ? settings.target : jsonData("target");
  2784. };
  2785. var content = jsonData("content");
  2786. var position = jsonData("position");
  2787. var addClass = jsonData("addClass");
  2788. var cached = jsonData("cached");
  2789. var callback = jsonData("callback");
  2790. var showMode = jsonData("showMode");
  2791. var touch = jsonData("touch");
  2792. if (typeof(content) == "undefined") {
  2793. content = settings.content;
  2794. }
  2795. if (typeof(position) == "undefined") {
  2796. position = settings.position;
  2797. }
  2798. if (typeof(addClass) == "undefined") {
  2799. addClass = settings.addClass;
  2800. }
  2801. if (typeof(cached) == "undefined") {
  2802. cached = settings.cached;
  2803. }
  2804. if (typeof(callback) == "undefined") {
  2805. callback = settings.callback;
  2806. }
  2807. if (typeof(showMode) == "undefined") {
  2808. showMode = settings.showMode;
  2809. }
  2810. if (typeof(touch) == "undefined") {
  2811. touch = settings.touch;
  2812. }
  2813. //console.log("cached", cached);
  2814. var tooltip, arrowHeight = 12;
  2815. var setTooltipStyle = function(tooltip) {
  2816. var arrow = "";
  2817. var posX = position[0];
  2818. var posY = position[1];
  2819. var _top = _left = 0;
  2820. var width = _this[0].offsetWidth;
  2821. var height = _this[0].offsetHeight;
  2822. var top = _this.offset().top;
  2823. var left = _this.offset().left;
  2824. var tooltipWidth = tooltip[0].offsetWidth;
  2825. var tooltipHeight = tooltip[0].offsetHeight;
  2826. var windowWidth = (document.all) ? document.getElementsByTagName("html")[0].offsetWidth : window.innerWidth;
  2827. var windowHeight = (document.all) ? document.getElementsByTagName("html")[0].offsetHeight : window.innerHeight;
  2828. //console.log("windowWidth=>", windowWidth, "windowHeight=>", windowHeight);
  2829. //console.log("tooltip.offsetHeight", _this[0].offsetWidth, tooltip[0].offsetHeight, tooltip.width());
  2830. //console.log(position, "width=>", width, "height=>", height, "tooltip.width=>", tooltipWidth, "tooltip.height=>", tooltipHeight, "top=>", top, "left=>", left, "_top=>", _top, "_left=>", _left);
  2831. var arrowGetPosition = function(arrow) {
  2832. var data = {};
  2833. switch(arrow) {
  2834. case "tc":
  2835. data = {
  2836. top : top + height + arrowHeight,
  2837. left : left + (width - tooltipWidth) / 2,
  2838. posX : "bottom",
  2839. posY : "center"
  2840. }
  2841. break;
  2842. case "tl":
  2843. data = {
  2844. top : top + height + arrowHeight,
  2845. left : left,
  2846. posX : "bottom",
  2847. posY : "left"
  2848. }
  2849. break;
  2850. case "tr":
  2851. data = {
  2852. top : top + height + arrowHeight,
  2853. left : left + width - tooltipWidth,
  2854. posX : "bottom",
  2855. posY : "right"
  2856. }
  2857. break;
  2858. case "bc":
  2859. data = {
  2860. top : top - tooltipHeight - arrowHeight,
  2861. left : left + (width - tooltipWidth) / 2,
  2862. posX : "top",
  2863. posY : "center"
  2864. }
  2865. break;
  2866. case "bl":
  2867. data = {
  2868. top : top - tooltipHeight - arrowHeight,
  2869. left : left,
  2870. posX : "top",
  2871. posY : "left"
  2872. }
  2873. break;
  2874. case "br":
  2875. data = {
  2876. top : top - tooltipHeight - arrowHeight,
  2877. left : left + width - tooltipWidth,
  2878. posX : "top",
  2879. posY : "right"
  2880. }
  2881. break;
  2882. case "lc":
  2883. data = {
  2884. top : top + (height - tooltipHeight) / 2,
  2885. left : left + (width + arrowHeight),
  2886. posX : "right",
  2887. posY : "center"
  2888. }
  2889. break;
  2890. case "lt":
  2891. data = {
  2892. top : top,
  2893. left : left + (width + arrowHeight),
  2894. posX : "right",
  2895. posY : "top"
  2896. }
  2897. break;
  2898. case "lb":
  2899. data = {
  2900. top : top + height - tooltipHeight,
  2901. left : left + (width + arrowHeight),
  2902. posX : "right",
  2903. posY : "bottom"
  2904. }
  2905. break;
  2906. case "rc":
  2907. data = {
  2908. top : top + (height - tooltipHeight) / 2,
  2909. left : left - (tooltipWidth + arrowHeight),
  2910. posX : "left",
  2911. posY : "center"
  2912. }
  2913. break;
  2914. case "rt":
  2915. data = {
  2916. top : top,
  2917. left : left - (tooltipWidth + arrowHeight),
  2918. posX : "left",
  2919. posY : "top"
  2920. }
  2921. break;
  2922. case "rb":
  2923. data = {
  2924. top : top + height - tooltipHeight,
  2925. left : left - (tooltipWidth + arrowHeight),
  2926. posX : "left",
  2927. posY : "bottom"
  2928. }
  2929. break;
  2930. };
  2931. return data;
  2932. };
  2933. if(posX == "top" && posY == "center") {
  2934. arrow = "bc";
  2935. }
  2936. if(posX == "top" && posY == "left") {
  2937. arrow = "bl";
  2938. }
  2939. if(posX == "top" && posY == "right") {
  2940. arrow = "br";
  2941. }
  2942. if(posX == "bottom" && posY == "center") {
  2943. arrow = "tc";
  2944. }
  2945. if(posX == "bottom" && posY == "left") {
  2946. arrow = "tl";
  2947. }
  2948. if(posX == "bottom" && posY == "right") {
  2949. arrow = "tr";
  2950. }
  2951. if(posX == "left" && posY == "center") {
  2952. arrow = "rc";
  2953. }
  2954. if(posX == "left" && posY == "top") {
  2955. arrow = "rt";
  2956. }
  2957. if(posX == "left" && posY == "bottom") {
  2958. arrow = "rb";
  2959. }
  2960. if(posX == "right" && posY == "center") {
  2961. arrow = "lc";
  2962. }
  2963. if(posX == "right" && posY == "top") {
  2964. arrow = "lt";
  2965. }
  2966. if(posX == "right" && posY == "bottom") {
  2967. arrow = "lb";
  2968. }
  2969. _top = arrowGetPosition(arrow).top;
  2970. _left = arrowGetPosition(arrow).left;
  2971. /*var newArrow = "";
  2972. console.log("_top < 0", _top - document.body.scrollTop < 0, _top, document.body.scrollTop);
  2973. console.log("_left < 0", (_left - tooltipWidth) < 0);
  2974. if((_top - document.body.scrollTop) < 0 && (_left - tooltipWidth) < 0) {
  2975. arrow = "tl";
  2976. }
  2977. if((_top + tooltipHeight) > windowHeight && (_left - tooltipWidth) < 0) {
  2978. arrow = "bl";
  2979. }*/
  2980. /*if(_top < 0) {
  2981. arrow = "tc";
  2982. }
  2983. if(_top + tooltipHeight > windowHeight) {
  2984. arrow = "bc";
  2985. }
  2986. if(_left < 0) {
  2987. arrow = "rc";
  2988. }
  2989. if(_left + tooltipWidth > windowWidth) {
  2990. arrow = "rc";
  2991. }*/
  2992. //_top = arrowGetPosition(arrow).top;
  2993. //_left = arrowGetPosition(arrow).left;
  2994. //posX = arrowGetPosition(arrow).posX;
  2995. //posY = arrowGetPosition(arrow).posY;
  2996. //console.log(position, "width=>", width, "height=>", height, "tooltip.width=>", tooltipWidth, "tooltip.height=>", tooltipHeight, "top=>", top, "left=>", left, "_top=>", _top, "_left=>", _left);
  2997. // 箭头居中的设置
  2998. var arrowClassName = settings.positionClassPrefix + arrow;
  2999. if (posY == "center") {
  3000. var head = document.getElementsByTagName("head")[0];
  3001. var style = document.createElement('style');
  3002. style.id = tooltip.attr("id") + "-style";
  3003. var styleText = "";
  3004. styleText += "#"+tooltip.attr("id") + "." + arrowClassName+":before, ";
  3005. styleText += "#"+tooltip.attr("id") + "." + arrowClassName+":after";
  3006. if(posX == "top" && posY == "center") {
  3007. styleText += "{left:"+((tooltipWidth / 2) - 7)+"px;}";
  3008. }
  3009. if(posX == "bottom" && posY == "center") {
  3010. styleText += "{left:"+((tooltipWidth / 2) - 7)+"px;}";
  3011. }
  3012. if(posX == "left" && posY == "center") {
  3013. styleText += "{top:"+((tooltipHeight / 2) - 7)+"px;}";
  3014. }
  3015. if(posX == "right" && posY == "center") {
  3016. styleText += "{top:"+((tooltipHeight / 2) - 7)+"px;}";
  3017. }
  3018. style.innerText = styleText;
  3019. head.appendChild(style);
  3020. }
  3021. //document.styleSheets[0].addRule('.tooltip-arrow-bc:before, .tooltip-arrow-bc:after', 'top:0;left:0;background:red;');
  3022. tooltip.addClass(arrowClassName)
  3023. .css({
  3024. position: "absolute",
  3025. top : _top,
  3026. left : _left
  3027. });
  3028. };
  3029. var showAction = function() {
  3030. //console.log("mouseenter", target(), addClass, content, cached, showMode);
  3031. if (typeof(target()) == "undefined" || target() == "")
  3032. {
  3033. tooltip = $('<div class="pui-tooltip ' + addClass + '"></div>');
  3034. tooltip.data("id", "tooltip-" + (new Date()).getTime() );
  3035. tooltip.attr("id", tooltip.data("id") );
  3036. if(cached)
  3037. {
  3038. setJSONData("target", "#" + tooltip.data("id") );
  3039. }
  3040. body.append(tooltip);
  3041. if(typeof(content) == "function") {
  3042. content(_this, tooltip, setTooltipStyle);
  3043. } else {
  3044. tooltip.html(content);
  3045. setTooltipStyle(tooltip);
  3046. }
  3047. }
  3048. else
  3049. {
  3050. tooltip = $(target());
  3051. tooltip.removeClass('pui-hide');
  3052. if(!cached && !tooltip.data("targetStyled"))
  3053. {
  3054. tooltip.data("targetStyled", true);
  3055. setTooltipStyle(tooltip);
  3056. }
  3057. }
  3058. tooltip[ (showMode == "fade") ? "fadeIn" : "show" ]();
  3059. };
  3060. var hideAction = function() {
  3061. tooltip[ (showMode == "fade") ? "fadeOut" : "hide" ]();
  3062. if (typeof(target()) == "undefined" && !cached || target() == "")
  3063. {
  3064. $("#"+tooltip.attr("id") + "-style").remove();
  3065. tooltip.remove();
  3066. }
  3067. callback(_this, tooltip);
  3068. };
  3069. _this.bind({
  3070. "mouseenter" : showAction,
  3071. "mouseleave" : hideAction
  3072. });
  3073. if(touch) {
  3074. _this.bind({
  3075. "touchstart" : showAction,
  3076. "touchend" : hideAction,
  3077. "touchcancel": hideAction
  3078. });
  3079. }
  3080. });
  3081. };
  3082. })(PlaneUI);
  3083. /*!
  3084. * Modernizr v2.8.3
  3085. * www.modernizr.com
  3086. *
  3087. * Copyright (c) Faruk Ates, Paul Irish, Alex Sexton
  3088. * Available under the BSD and MIT licenses: www.modernizr.com/license/
  3089. */
  3090. /*
  3091. * Modernizr tests which native CSS3 and HTML5 features are available in
  3092. * the current UA and makes the results available to you in two ways:
  3093. * as properties on a global Modernizr object, and as classes on the
  3094. * <html> element. This information allows you to progressively enhance
  3095. * your pages with a granular level of control over the experience.
  3096. *
  3097. * Modernizr has an optional (not included) conditional resource loader
  3098. * called Modernizr.load(), based on Yepnope.js (yepnopejs.com).
  3099. * To get a build that includes Modernizr.load(), as well as choosing
  3100. * which tests to include, go to www.modernizr.com/download/
  3101. *
  3102. * Authors Faruk Ates, Paul Irish, Alex Sexton
  3103. * Contributors Ryan Seddon, Ben Alman
  3104. */
  3105. window.Modernizr = (function( window, document, undefined ) {
  3106. var version = '2.8.3',
  3107. Modernizr = {},
  3108. /*>>cssclasses*/
  3109. // option for enabling the HTML classes to be added
  3110. enableClasses = true,
  3111. /*>>cssclasses*/
  3112. docElement = document.documentElement,
  3113. /**
  3114. * Create our "modernizr" element that we do most feature tests on.
  3115. */
  3116. mod = 'modernizr',
  3117. modElem = document.createElement(mod),
  3118. mStyle = modElem.style,
  3119. /**
  3120. * Create the input element for various Web Forms feature tests.
  3121. */
  3122. inputElem /*>>inputelem*/ = document.createElement('input') /*>>inputelem*/ ,
  3123. /*>>smile*/
  3124. smile = ':)',
  3125. /*>>smile*/
  3126. toString = {}.toString,
  3127. // TODO :: make the prefixes more granular
  3128. /*>>prefixes*/
  3129. // List of property values to set for css tests. See ticket #21
  3130. prefixes = ' -webkit- -moz- -o- -ms- '.split(' '),
  3131. /*>>prefixes*/
  3132. /*>>domprefixes*/
  3133. // Following spec is to expose vendor-specific style properties as:
  3134. // elem.style.WebkitBorderRadius
  3135. // and the following would be incorrect:
  3136. // elem.style.webkitBorderRadius
  3137. // Webkit ghosts their properties in lowercase but Opera & Moz do not.
  3138. // Microsoft uses a lowercase `ms` instead of the correct `Ms` in IE8+
  3139. // erik.eae.net/archives/2008/03/10/21.48.10/
  3140. // More here: github.com/Modernizr/Modernizr/issues/issue/21
  3141. omPrefixes = 'Webkit Moz O ms',
  3142. cssomPrefixes = omPrefixes.split(' '),
  3143. domPrefixes = omPrefixes.toLowerCase().split(' '),
  3144. /*>>domprefixes*/
  3145. /*>>ns*/
  3146. ns = {'svg': 'http://www.w3.org/2000/svg'},
  3147. /*>>ns*/
  3148. tests = {},
  3149. inputs = {},
  3150. attrs = {},
  3151. classes = [],
  3152. slice = classes.slice,
  3153. featureName, // used in testing loop
  3154. /*>>teststyles*/
  3155. // Inject element with style element and some CSS rules
  3156. injectElementWithStyles = function( rule, callback, nodes, testnames ) {
  3157. var style, ret, node, docOverflow,
  3158. div = document.createElement('div'),
  3159. // After page load injecting a fake body doesn't work so check if body exists
  3160. body = document.body,
  3161. // IE6 and 7 won't return offsetWidth or offsetHeight unless it's in the body element, so we fake it.
  3162. fakeBody = body || document.createElement('body');
  3163. if ( parseInt(nodes, 10) ) {
  3164. // In order not to give false positives we create a node for each test
  3165. // This also allows the method to scale for unspecified uses
  3166. while ( nodes-- ) {
  3167. node = document.createElement('div');
  3168. node.id = testnames ? testnames[nodes] : mod + (nodes + 1);
  3169. div.appendChild(node);
  3170. }
  3171. }
  3172. // <style> elements in IE6-9 are considered 'NoScope' elements and therefore will be removed
  3173. // when injected with innerHTML. To get around this you need to prepend the 'NoScope' element
  3174. // with a 'scoped' element, in our case the soft-hyphen entity as it won't mess with our measurements.
  3175. // msdn.microsoft.com/en-us/library/ms533897%28VS.85%29.aspx
  3176. // Documents served as xml will throw if using &shy; so use xml friendly encoded version. See issue #277
  3177. style = ['&#173;','<style id="s', mod, '">', rule, '</style>'].join('');
  3178. div.id = mod;
  3179. // IE6 will false positive on some tests due to the style element inside the test div somehow interfering offsetHeight, so insert it into body or fakebody.
  3180. // Opera will act all quirky when injecting elements in documentElement when page is served as xml, needs fakebody too. #270
  3181. (body ? div : fakeBody).innerHTML += style;
  3182. fakeBody.appendChild(div);
  3183. if ( !body ) {
  3184. //avoid crashing IE8, if background image is used
  3185. fakeBody.style.background = '';
  3186. //Safari 5.13/5.1.4 OSX stops loading if ::-webkit-scrollbar is used and scrollbars are visible
  3187. fakeBody.style.overflow = 'hidden';
  3188. docOverflow = docElement.style.overflow;
  3189. docElement.style.overflow = 'hidden';
  3190. docElement.appendChild(fakeBody);
  3191. }
  3192. ret = callback(div, rule);
  3193. // If this is done after page load we don't want to remove the body so check if body exists
  3194. if ( !body ) {
  3195. fakeBody.parentNode.removeChild(fakeBody);
  3196. docElement.style.overflow = docOverflow;
  3197. } else {
  3198. div.parentNode.removeChild(div);
  3199. }
  3200. return !!ret;
  3201. },
  3202. /*>>teststyles*/
  3203. /*>>mq*/
  3204. // adapted from matchMedia polyfill
  3205. // by Scott Jehl and Paul Irish
  3206. // gist.github.com/786768
  3207. testMediaQuery = function( mq ) {
  3208. var matchMedia = window.matchMedia || window.msMatchMedia;
  3209. if ( matchMedia ) {
  3210. return matchMedia(mq) && matchMedia(mq).matches || false;
  3211. }
  3212. var bool;
  3213. injectElementWithStyles('@media ' + mq + ' { #' + mod + ' { position: absolute; } }', function( node ) {
  3214. bool = (window.getComputedStyle ?
  3215. getComputedStyle(node, null) :
  3216. node.currentStyle)['position'] == 'absolute';
  3217. });
  3218. return bool;
  3219. },
  3220. /*>>mq*/
  3221. /*>>hasevent*/
  3222. //
  3223. // isEventSupported determines if a given element supports the given event
  3224. // kangax.github.com/iseventsupported/
  3225. //
  3226. // The following results are known incorrects:
  3227. // Modernizr.hasEvent("webkitTransitionEnd", elem) // false negative
  3228. // Modernizr.hasEvent("textInput") // in Webkit. github.com/Modernizr/Modernizr/issues/333
  3229. // ...
  3230. isEventSupported = (function() {
  3231. var TAGNAMES = {
  3232. 'select': 'input', 'change': 'input',
  3233. 'submit': 'form', 'reset': 'form',
  3234. 'error': 'img', 'load': 'img', 'abort': 'img'
  3235. };
  3236. function isEventSupported( eventName, element ) {
  3237. element = element || document.createElement(TAGNAMES[eventName] || 'div');
  3238. eventName = 'on' + eventName;
  3239. // When using `setAttribute`, IE skips "unload", WebKit skips "unload" and "resize", whereas `in` "catches" those
  3240. var isSupported = eventName in element;
  3241. if ( !isSupported ) {
  3242. // If it has no `setAttribute` (i.e. doesn't implement Node interface), try generic element
  3243. if ( !element.setAttribute ) {
  3244. element = document.createElement('div');
  3245. }
  3246. if ( element.setAttribute && element.removeAttribute ) {
  3247. element.setAttribute(eventName, '');
  3248. isSupported = is(element[eventName], 'function');
  3249. // If property was created, "remove it" (by setting value to `undefined`)
  3250. if ( !is(element[eventName], 'undefined') ) {
  3251. element[eventName] = undefined;
  3252. }
  3253. element.removeAttribute(eventName);
  3254. }
  3255. }
  3256. element = null;
  3257. return isSupported;
  3258. }
  3259. return isEventSupported;
  3260. })(),
  3261. /*>>hasevent*/
  3262. // TODO :: Add flag for hasownprop ? didn't last time
  3263. // hasOwnProperty shim by kangax needed for Safari 2.0 support
  3264. _hasOwnProperty = ({}).hasOwnProperty, hasOwnProp;
  3265. if ( !is(_hasOwnProperty, 'undefined') && !is(_hasOwnProperty.call, 'undefined') ) {
  3266. hasOwnProp = function (object, property) {
  3267. return _hasOwnProperty.call(object, property);
  3268. };
  3269. }
  3270. else {
  3271. hasOwnProp = function (object, property) { /* yes, this can give false positives/negatives, but most of the time we don't care about those */
  3272. return ((property in object) && is(object.constructor.prototype[property], 'undefined'));
  3273. };
  3274. }
  3275. // Adapted from ES5-shim https://github.com/kriskowal/es5-shim/blob/master/es5-shim.js
  3276. // es5.github.com/#x15.3.4.5
  3277. if (!Function.prototype.bind) {
  3278. Function.prototype.bind = function bind(that) {
  3279. var target = this;
  3280. if (typeof target != "function") {
  3281. throw new TypeError();
  3282. }
  3283. var args = slice.call(arguments, 1),
  3284. bound = function () {
  3285. if (this instanceof bound) {
  3286. var F = function(){};
  3287. F.prototype = target.prototype;
  3288. var self = new F();
  3289. var result = target.apply(
  3290. self,
  3291. args.concat(slice.call(arguments))
  3292. );
  3293. if (Object(result) === result) {
  3294. return result;
  3295. }
  3296. return self;
  3297. } else {
  3298. return target.apply(
  3299. that,
  3300. args.concat(slice.call(arguments))
  3301. );
  3302. }
  3303. };
  3304. return bound;
  3305. };
  3306. }
  3307. /**
  3308. * setCss applies given styles to the Modernizr DOM node.
  3309. */
  3310. function setCss( str ) {
  3311. mStyle.cssText = str;
  3312. }
  3313. /**
  3314. * setCssAll extrapolates all vendor-specific css strings.
  3315. */
  3316. function setCssAll( str1, str2 ) {
  3317. return setCss(prefixes.join(str1 + ';') + ( str2 || '' ));
  3318. }
  3319. /**
  3320. * is returns a boolean for if typeof obj is exactly type.
  3321. */
  3322. function is( obj, type ) {
  3323. return typeof obj === type;
  3324. }
  3325. /**
  3326. * contains returns a boolean for if substr is found within str.
  3327. */
  3328. function contains( str, substr ) {
  3329. return !!~('' + str).indexOf(substr);
  3330. }
  3331. /*>>testprop*/
  3332. // testProps is a generic CSS / DOM property test.
  3333. // In testing support for a given CSS property, it's legit to test:
  3334. // `elem.style[styleName] !== undefined`
  3335. // If the property is supported it will return an empty string,
  3336. // if unsupported it will return undefined.
  3337. // We'll take advantage of this quick test and skip setting a style
  3338. // on our modernizr element, but instead just testing undefined vs
  3339. // empty string.
  3340. // Because the testing of the CSS property names (with "-", as
  3341. // opposed to the camelCase DOM properties) is non-portable and
  3342. // non-standard but works in WebKit and IE (but not Gecko or Opera),
  3343. // we explicitly reject properties with dashes so that authors
  3344. // developing in WebKit or IE first don't end up with
  3345. // browser-specific content by accident.
  3346. function testProps( props, prefixed ) {
  3347. for ( var i in props ) {
  3348. var prop = props[i];
  3349. if ( !contains(prop, "-") && mStyle[prop] !== undefined ) {
  3350. return prefixed == 'pfx' ? prop : true;
  3351. }
  3352. }
  3353. return false;
  3354. }
  3355. /*>>testprop*/
  3356. // TODO :: add testDOMProps
  3357. /**
  3358. * testDOMProps is a generic DOM property test; if a browser supports
  3359. * a certain property, it won't return undefined for it.
  3360. */
  3361. function testDOMProps( props, obj, elem ) {
  3362. for ( var i in props ) {
  3363. var item = obj[props[i]];
  3364. if ( item !== undefined) {
  3365. // return the property name as a string
  3366. if (elem === false) return props[i];
  3367. // let's bind a function
  3368. if (is(item, 'function')){
  3369. // default to autobind unless override
  3370. return item.bind(elem || obj);
  3371. }
  3372. // return the unbound function or obj or value
  3373. return item;
  3374. }
  3375. }
  3376. return false;
  3377. }
  3378. /*>>testallprops*/
  3379. /**
  3380. * testPropsAll tests a list of DOM properties we want to check against.
  3381. * We specify literally ALL possible (known and/or likely) properties on
  3382. * the element including the non-vendor prefixed one, for forward-
  3383. * compatibility.
  3384. */
  3385. function testPropsAll( prop, prefixed, elem ) {
  3386. var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1),
  3387. props = (prop + ' ' + cssomPrefixes.join(ucProp + ' ') + ucProp).split(' ');
  3388. // did they call .prefixed('boxSizing') or are we just testing a prop?
  3389. if(is(prefixed, "string") || is(prefixed, "undefined")) {
  3390. return testProps(props, prefixed);
  3391. // otherwise, they called .prefixed('requestAnimationFrame', window[, elem])
  3392. } else {
  3393. props = (prop + ' ' + (domPrefixes).join(ucProp + ' ') + ucProp).split(' ');
  3394. return testDOMProps(props, prefixed, elem);
  3395. }
  3396. }
  3397. /*>>testallprops*/
  3398. /**
  3399. * Tests
  3400. * -----
  3401. */
  3402. // The *new* flexbox
  3403. // dev.w3.org/csswg/css3-flexbox
  3404. tests['flexbox'] = function() {
  3405. return testPropsAll('flexWrap');
  3406. };
  3407. // The *old* flexbox
  3408. // www.w3.org/TR/2009/WD-css3-flexbox-20090723/
  3409. tests['flexboxlegacy'] = function() {
  3410. return testPropsAll('boxDirection');
  3411. };
  3412. // On the S60 and BB Storm, getContext exists, but always returns undefined
  3413. // so we actually have to call getContext() to verify
  3414. // github.com/Modernizr/Modernizr/issues/issue/97/
  3415. tests['canvas'] = function() {
  3416. var elem = document.createElement('canvas');
  3417. return !!(elem.getContext && elem.getContext('2d'));
  3418. };
  3419. tests['canvastext'] = function() {
  3420. return !!(Modernizr['canvas'] && is(document.createElement('canvas').getContext('2d').fillText, 'function'));
  3421. };
  3422. // webk.it/70117 is tracking a legit WebGL feature detect proposal
  3423. // We do a soft detect which may false positive in order to avoid
  3424. // an expensive context creation: bugzil.la/732441
  3425. tests['webgl'] = function() {
  3426. return !!window.WebGLRenderingContext;
  3427. };
  3428. /*
  3429. * The Modernizr.touch test only indicates if the browser supports
  3430. * touch events, which does not necessarily reflect a touchscreen
  3431. * device, as evidenced by tablets running Windows 7 or, alas,
  3432. * the Palm Pre / WebOS (touch) phones.
  3433. *
  3434. * Additionally, Chrome (desktop) used to lie about its support on this,
  3435. * but that has since been rectified: crbug.com/36415
  3436. *
  3437. * We also test for Firefox 4 Multitouch Support.
  3438. *
  3439. * For more info, see: modernizr.github.com/Modernizr/touch.html
  3440. */
  3441. tests['touch'] = function() {
  3442. var bool;
  3443. if(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) {
  3444. bool = true;
  3445. } else {
  3446. injectElementWithStyles(['@media (',prefixes.join('touch-enabled),('),mod,')','{#modernizr{top:9px;position:absolute}}'].join(''), function( node ) {
  3447. bool = node.offsetTop === 9;
  3448. });
  3449. }
  3450. return bool;
  3451. };
  3452. // geolocation is often considered a trivial feature detect...
  3453. // Turns out, it's quite tricky to get right:
  3454. //
  3455. // Using !!navigator.geolocation does two things we don't want. It:
  3456. // 1. Leaks memory in IE9: github.com/Modernizr/Modernizr/issues/513
  3457. // 2. Disables page caching in WebKit: webk.it/43956
  3458. //
  3459. // Meanwhile, in Firefox < 8, an about:config setting could expose
  3460. // a false positive that would throw an exception: bugzil.la/688158
  3461. tests['geolocation'] = function() {
  3462. return 'geolocation' in navigator;
  3463. };
  3464. tests['postmessage'] = function() {
  3465. return !!window.postMessage;
  3466. };
  3467. // Chrome incognito mode used to throw an exception when using openDatabase
  3468. // It doesn't anymore.
  3469. tests['websqldatabase'] = function() {
  3470. return !!window.openDatabase;
  3471. };
  3472. // Vendors had inconsistent prefixing with the experimental Indexed DB:
  3473. // - Webkit's implementation is accessible through webkitIndexedDB
  3474. // - Firefox shipped moz_indexedDB before FF4b9, but since then has been mozIndexedDB
  3475. // For speed, we don't test the legacy (and beta-only) indexedDB
  3476. tests['indexedDB'] = function() {
  3477. return !!testPropsAll("indexedDB", window);
  3478. };
  3479. // documentMode logic from YUI to filter out IE8 Compat Mode
  3480. // which false positives.
  3481. tests['hashchange'] = function() {
  3482. return isEventSupported('hashchange', window) && (document.documentMode === undefined || document.documentMode > 7);
  3483. };
  3484. // Per 1.6:
  3485. // This used to be Modernizr.historymanagement but the longer
  3486. // name has been deprecated in favor of a shorter and property-matching one.
  3487. // The old API is still available in 1.6, but as of 2.0 will throw a warning,
  3488. // and in the first release thereafter disappear entirely.
  3489. tests['history'] = function() {
  3490. return !!(window.history && history.pushState);
  3491. };
  3492. tests['draganddrop'] = function() {
  3493. var div = document.createElement('div');
  3494. return ('draggable' in div) || ('ondragstart' in div && 'ondrop' in div);
  3495. };
  3496. // FF3.6 was EOL'ed on 4/24/12, but the ESR version of FF10
  3497. // will be supported until FF19 (2/12/13), at which time, ESR becomes FF17.
  3498. // FF10 still uses prefixes, so check for it until then.
  3499. // for more ESR info, see: mozilla.org/en-US/firefox/organizations/faq/
  3500. tests['websockets'] = function() {
  3501. return 'WebSocket' in window || 'MozWebSocket' in window;
  3502. };
  3503. // css-tricks.com/rgba-browser-support/
  3504. tests['rgba'] = function() {
  3505. // Set an rgba() color and check the returned value
  3506. setCss('background-color:rgba(150,255,150,.5)');
  3507. return contains(mStyle.backgroundColor, 'rgba');
  3508. };
  3509. tests['hsla'] = function() {
  3510. // Same as rgba(), in fact, browsers re-map hsla() to rgba() internally,
  3511. // except IE9 who retains it as hsla
  3512. setCss('background-color:hsla(120,40%,100%,.5)');
  3513. return contains(mStyle.backgroundColor, 'rgba') || contains(mStyle.backgroundColor, 'hsla');
  3514. };
  3515. tests['multiplebgs'] = function() {
  3516. // Setting multiple images AND a color on the background shorthand property
  3517. // and then querying the style.background property value for the number of
  3518. // occurrences of "url(" is a reliable method for detecting ACTUAL support for this!
  3519. setCss('background:url(https://),url(https://),red url(https://)');
  3520. // If the UA supports multiple backgrounds, there should be three occurrences
  3521. // of the string "url(" in the return value for elemStyle.background
  3522. return (/(url\s*\(.*?){3}/).test(mStyle.background);
  3523. };
  3524. // this will false positive in Opera Mini
  3525. // github.com/Modernizr/Modernizr/issues/396
  3526. tests['backgroundsize'] = function() {
  3527. return testPropsAll('backgroundSize');
  3528. };
  3529. tests['borderimage'] = function() {
  3530. return testPropsAll('borderImage');
  3531. };
  3532. // Super comprehensive table about all the unique implementations of
  3533. // border-radius: muddledramblings.com/table-of-css3-border-radius-compliance
  3534. tests['borderradius'] = function() {
  3535. return testPropsAll('borderRadius');
  3536. };
  3537. // WebOS unfortunately false positives on this test.
  3538. tests['boxshadow'] = function() {
  3539. return testPropsAll('boxShadow');
  3540. };
  3541. // FF3.0 will false positive on this test
  3542. tests['textshadow'] = function() {
  3543. return document.createElement('div').style.textShadow === '';
  3544. };
  3545. tests['opacity'] = function() {
  3546. // Browsers that actually have CSS Opacity implemented have done so
  3547. // according to spec, which means their return values are within the
  3548. // range of [0.0,1.0] - including the leading zero.
  3549. setCssAll('opacity:.55');
  3550. // The non-literal . in this regex is intentional:
  3551. // German Chrome returns this value as 0,55
  3552. // github.com/Modernizr/Modernizr/issues/#issue/59/comment/516632
  3553. return (/^0.55$/).test(mStyle.opacity);
  3554. };
  3555. // Note, Android < 4 will pass this test, but can only animate
  3556. // a single property at a time
  3557. // goo.gl/v3V4Gp
  3558. tests['cssanimations'] = function() {
  3559. return testPropsAll('animationName');
  3560. };
  3561. tests['csscolumns'] = function() {
  3562. return testPropsAll('columnCount');
  3563. };
  3564. tests['cssgradients'] = function() {
  3565. /**
  3566. * For CSS Gradients syntax, please see:
  3567. * webkit.org/blog/175/introducing-css-gradients/
  3568. * developer.mozilla.org/en/CSS/-moz-linear-gradient
  3569. * developer.mozilla.org/en/CSS/-moz-radial-gradient
  3570. * dev.w3.org/csswg/css3-images/#gradients-
  3571. */
  3572. var str1 = 'background-image:',
  3573. str2 = 'gradient(linear,left top,right bottom,from(#9f9),to(white));',
  3574. str3 = 'linear-gradient(left top,#9f9, white);';
  3575. setCss(
  3576. // legacy webkit syntax (FIXME: remove when syntax not in use anymore)
  3577. (str1 + '-webkit- '.split(' ').join(str2 + str1) +
  3578. // standard syntax // trailing 'background-image:'
  3579. prefixes.join(str3 + str1)).slice(0, -str1.length)
  3580. );
  3581. return contains(mStyle.backgroundImage, 'gradient');
  3582. };
  3583. tests['cssreflections'] = function() {
  3584. return testPropsAll('boxReflect');
  3585. };
  3586. tests['csstransforms'] = function() {
  3587. return !!testPropsAll('transform');
  3588. };
  3589. tests['csstransforms3d'] = function() {
  3590. var ret = !!testPropsAll('perspective');
  3591. // Webkit's 3D transforms are passed off to the browser's own graphics renderer.
  3592. // It works fine in Safari on Leopard and Snow Leopard, but not in Chrome in
  3593. // some conditions. As a result, Webkit typically recognizes the syntax but
  3594. // will sometimes throw a false positive, thus we must do a more thorough check:
  3595. if ( ret && 'webkitPerspective' in docElement.style ) {
  3596. // Webkit allows this media query to succeed only if the feature is enabled.
  3597. // `@media (transform-3d),(-webkit-transform-3d){ ... }`
  3598. injectElementWithStyles('@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}', function( node, rule ) {
  3599. ret = node.offsetLeft === 9 && node.offsetHeight === 3;
  3600. });
  3601. }
  3602. return ret;
  3603. };
  3604. tests['csstransitions'] = function() {
  3605. return testPropsAll('transition');
  3606. };
  3607. /*>>fontface*/
  3608. // @font-face detection routine by Diego Perini
  3609. // javascript.nwbox.com/CSSSupport/
  3610. // false positives:
  3611. // WebOS github.com/Modernizr/Modernizr/issues/342
  3612. // WP7 github.com/Modernizr/Modernizr/issues/538
  3613. tests['fontface'] = function() {
  3614. var bool;
  3615. injectElementWithStyles('@font-face {font-family:"font";src:url("https://")}', function( node, rule ) {
  3616. var style = document.getElementById('smodernizr'),
  3617. sheet = style.sheet || style.styleSheet,
  3618. cssText = sheet ? (sheet.cssRules && sheet.cssRules[0] ? sheet.cssRules[0].cssText : sheet.cssText || '') : '';
  3619. bool = /src/i.test(cssText) && cssText.indexOf(rule.split(' ')[0]) === 0;
  3620. });
  3621. return bool;
  3622. };
  3623. /*>>fontface*/
  3624. // CSS generated content detection
  3625. tests['generatedcontent'] = function() {
  3626. var bool;
  3627. injectElementWithStyles(['#',mod,'{font:0/0 a}#',mod,':after{content:"',smile,'";visibility:hidden;font:3px/1 a}'].join(''), function( node ) {
  3628. bool = node.offsetHeight >= 3;
  3629. });
  3630. return bool;
  3631. };
  3632. // These tests evaluate support of the video/audio elements, as well as
  3633. // testing what types of content they support.
  3634. //
  3635. // We're using the Boolean constructor here, so that we can extend the value
  3636. // e.g. Modernizr.video // true
  3637. // Modernizr.video.ogg // 'probably'
  3638. //
  3639. // Codec values from : github.com/NielsLeenheer/html5test/blob/9106a8/index.html#L845
  3640. // thx to NielsLeenheer and zcorpan
  3641. // Note: in some older browsers, "no" was a return value instead of empty string.
  3642. // It was live in FF3.5.0 and 3.5.1, but fixed in 3.5.2
  3643. // It was also live in Safari 4.0.0 - 4.0.4, but fixed in 4.0.5
  3644. tests['video'] = function() {
  3645. var elem = document.createElement('video'),
  3646. bool = false;
  3647. // IE9 Running on Windows Server SKU can cause an exception to be thrown, bug #224
  3648. try {
  3649. if ( bool = !!elem.canPlayType ) {
  3650. bool = new Boolean(bool);
  3651. bool.ogg = elem.canPlayType('video/ogg; codecs="theora"') .replace(/^no$/,'');
  3652. // Without QuickTime, this value will be `undefined`. github.com/Modernizr/Modernizr/issues/546
  3653. bool.h264 = elem.canPlayType('video/mp4; codecs="avc1.42E01E"') .replace(/^no$/,'');
  3654. bool.webm = elem.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,'');
  3655. }
  3656. } catch(e) { }
  3657. return bool;
  3658. };
  3659. tests['audio'] = function() {
  3660. var elem = document.createElement('audio'),
  3661. bool = false;
  3662. try {
  3663. if ( bool = !!elem.canPlayType ) {
  3664. bool = new Boolean(bool);
  3665. bool.ogg = elem.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,'');
  3666. bool.mp3 = elem.canPlayType('audio/mpeg;') .replace(/^no$/,'');
  3667. // Mimetypes accepted:
  3668. // developer.mozilla.org/En/Media_formats_supported_by_the_audio_and_video_elements
  3669. // bit.ly/iphoneoscodecs
  3670. bool.wav = elem.canPlayType('audio/wav; codecs="1"') .replace(/^no$/,'');
  3671. bool.m4a = ( elem.canPlayType('audio/x-m4a;') ||
  3672. elem.canPlayType('audio/aac;')) .replace(/^no$/,'');
  3673. }
  3674. } catch(e) { }
  3675. return bool;
  3676. };
  3677. // In FF4, if disabled, window.localStorage should === null.
  3678. // Normally, we could not test that directly and need to do a
  3679. // `('localStorage' in window) && ` test first because otherwise Firefox will
  3680. // throw bugzil.la/365772 if cookies are disabled
  3681. // Also in iOS5 Private Browsing mode, attempting to use localStorage.setItem
  3682. // will throw the exception:
  3683. // QUOTA_EXCEEDED_ERRROR DOM Exception 22.
  3684. // Peculiarly, getItem and removeItem calls do not throw.
  3685. // Because we are forced to try/catch this, we'll go aggressive.
  3686. // Just FWIW: IE8 Compat mode supports these features completely:
  3687. // www.quirksmode.org/dom/html5.html
  3688. // But IE8 doesn't support either with local files
  3689. tests['localstorage'] = function() {
  3690. try {
  3691. localStorage.setItem(mod, mod);
  3692. localStorage.removeItem(mod);
  3693. return true;
  3694. } catch(e) {
  3695. return false;
  3696. }
  3697. };
  3698. tests['sessionstorage'] = function() {
  3699. try {
  3700. sessionStorage.setItem(mod, mod);
  3701. sessionStorage.removeItem(mod);
  3702. return true;
  3703. } catch(e) {
  3704. return false;
  3705. }
  3706. };
  3707. tests['webworkers'] = function() {
  3708. return !!window.Worker;
  3709. };
  3710. tests['applicationcache'] = function() {
  3711. return !!window.applicationCache;
  3712. };
  3713. // Thanks to Erik Dahlstrom
  3714. tests['svg'] = function() {
  3715. return !!document.createElementNS && !!document.createElementNS(ns.svg, 'svg').createSVGRect;
  3716. };
  3717. // specifically for SVG inline in HTML, not within XHTML
  3718. // test page: paulirish.com/demo/inline-svg
  3719. tests['inlinesvg'] = function() {
  3720. var div = document.createElement('div');
  3721. div.innerHTML = '<svg/>';
  3722. return (div.firstChild && div.firstChild.namespaceURI) == ns.svg;
  3723. };
  3724. // SVG SMIL animation
  3725. tests['smil'] = function() {
  3726. return !!document.createElementNS && /SVGAnimate/.test(toString.call(document.createElementNS(ns.svg, 'animate')));
  3727. };
  3728. // This test is only for clip paths in SVG proper, not clip paths on HTML content
  3729. // demo: srufaculty.sru.edu/david.dailey/svg/newstuff/clipPath4.svg
  3730. // However read the comments to dig into applying SVG clippaths to HTML content here:
  3731. // github.com/Modernizr/Modernizr/issues/213#issuecomment-1149491
  3732. tests['svgclippaths'] = function() {
  3733. return !!document.createElementNS && /SVGClipPath/.test(toString.call(document.createElementNS(ns.svg, 'clipPath')));
  3734. };
  3735. /*>>webforms*/
  3736. // input features and input types go directly onto the ret object, bypassing the tests loop.
  3737. // Hold this guy to execute in a moment.
  3738. function webforms() {
  3739. /*>>input*/
  3740. // Run through HTML5's new input attributes to see if the UA understands any.
  3741. // We're using f which is the <input> element created early on
  3742. // Mike Taylr has created a comprehensive resource for testing these attributes
  3743. // when applied to all input types:
  3744. // miketaylr.com/code/input-type-attr.html
  3745. // spec: www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
  3746. // Only input placeholder is tested while textarea's placeholder is not.
  3747. // Currently Safari 4 and Opera 11 have support only for the input placeholder
  3748. // Both tests are available in feature-detects/forms-placeholder.js
  3749. Modernizr['input'] = (function( props ) {
  3750. for ( var i = 0, len = props.length; i < len; i++ ) {
  3751. attrs[ props[i] ] = !!(props[i] in inputElem);
  3752. }
  3753. if (attrs.list){
  3754. // safari false positive's on datalist: webk.it/74252
  3755. // see also github.com/Modernizr/Modernizr/issues/146
  3756. attrs.list = !!(document.createElement('datalist') && window.HTMLDataListElement);
  3757. }
  3758. return attrs;
  3759. })('autocomplete autofocus list placeholder max min multiple pattern required step'.split(' '));
  3760. /*>>input*/
  3761. /*>>inputtypes*/
  3762. // Run through HTML5's new input types to see if the UA understands any.
  3763. // This is put behind the tests runloop because it doesn't return a
  3764. // true/false like all the other tests; instead, it returns an object
  3765. // containing each input type with its corresponding true/false value
  3766. // Big thanks to @miketaylr for the html5 forms expertise. miketaylr.com/
  3767. Modernizr['inputtypes'] = (function(props) {
  3768. for ( var i = 0, bool, inputElemType, defaultView, len = props.length; i < len; i++ ) {
  3769. inputElem.setAttribute('type', inputElemType = props[i]);
  3770. bool = inputElem.type !== 'text';
  3771. // We first check to see if the type we give it sticks..
  3772. // If the type does, we feed it a textual value, which shouldn't be valid.
  3773. // If the value doesn't stick, we know there's input sanitization which infers a custom UI
  3774. if ( bool ) {
  3775. inputElem.value = smile;
  3776. inputElem.style.cssText = 'position:absolute;visibility:hidden;';
  3777. if ( /^range$/.test(inputElemType) && inputElem.style.WebkitAppearance !== undefined ) {
  3778. docElement.appendChild(inputElem);
  3779. defaultView = document.defaultView;
  3780. // Safari 2-4 allows the smiley as a value, despite making a slider
  3781. bool = defaultView.getComputedStyle &&
  3782. defaultView.getComputedStyle(inputElem, null).WebkitAppearance !== 'textfield' &&
  3783. // Mobile android web browser has false positive, so must
  3784. // check the height to see if the widget is actually there.
  3785. (inputElem.offsetHeight !== 0);
  3786. docElement.removeChild(inputElem);
  3787. } else if ( /^(search|tel)$/.test(inputElemType) ){
  3788. // Spec doesn't define any special parsing or detectable UI
  3789. // behaviors so we pass these through as true
  3790. // Interestingly, opera fails the earlier test, so it doesn't
  3791. // even make it here.
  3792. } else if ( /^(url|email)$/.test(inputElemType) ) {
  3793. // Real url and email support comes with prebaked validation.
  3794. bool = inputElem.checkValidity && inputElem.checkValidity() === false;
  3795. } else {
  3796. // If the upgraded input compontent rejects the :) text, we got a winner
  3797. bool = inputElem.value != smile;
  3798. }
  3799. }
  3800. inputs[ props[i] ] = !!bool;
  3801. }
  3802. return inputs;
  3803. })('search tel url email datetime date month week time datetime-local number range color'.split(' '));
  3804. /*>>inputtypes*/
  3805. }
  3806. /*>>webforms*/
  3807. // End of test definitions
  3808. // -----------------------
  3809. // Run through all tests and detect their support in the current UA.
  3810. // todo: hypothetically we could be doing an array of tests and use a basic loop here.
  3811. for ( var feature in tests ) {
  3812. if ( hasOwnProp(tests, feature) ) {
  3813. // run the test, throw the return value into the Modernizr,
  3814. // then based on that boolean, define an appropriate className
  3815. // and push it into an array of classes we'll join later.
  3816. featureName = feature.toLowerCase();
  3817. Modernizr[featureName] = tests[feature]();
  3818. classes.push((Modernizr[featureName] ? '' : 'no-') + featureName);
  3819. }
  3820. }
  3821. /*>>webforms*/
  3822. // input tests need to run.
  3823. Modernizr.input || webforms();
  3824. /*>>webforms*/
  3825. /**
  3826. * addTest allows the user to define their own feature tests
  3827. * the result will be added onto the Modernizr object,
  3828. * as well as an appropriate className set on the html element
  3829. *
  3830. * @param feature - String naming the feature
  3831. * @param test - Function returning true if feature is supported, false if not
  3832. */
  3833. Modernizr.addTest = function ( feature, test ) {
  3834. if ( typeof feature == 'object' ) {
  3835. for ( var key in feature ) {
  3836. if ( hasOwnProp( feature, key ) ) {
  3837. Modernizr.addTest( key, feature[ key ] );
  3838. }
  3839. }
  3840. } else {
  3841. feature = feature.toLowerCase();
  3842. if ( Modernizr[feature] !== undefined ) {
  3843. // we're going to quit if you're trying to overwrite an existing test
  3844. // if we were to allow it, we'd do this:
  3845. // var re = new RegExp("\\b(no-)?" + feature + "\\b");
  3846. // docElement.className = docElement.className.replace( re, '' );
  3847. // but, no rly, stuff 'em.
  3848. return Modernizr;
  3849. }
  3850. test = typeof test == 'function' ? test() : test;
  3851. if (typeof enableClasses !== "undefined" && enableClasses) {
  3852. docElement.className += ' ' + (test ? '' : 'no-') + feature;
  3853. }
  3854. Modernizr[feature] = test;
  3855. }
  3856. return Modernizr; // allow chaining.
  3857. };
  3858. // Reset modElem.cssText to nothing to reduce memory footprint.
  3859. setCss('');
  3860. modElem = inputElem = null;
  3861. /*>>shiv*/
  3862. /**
  3863. * @preserve HTML5 Shiv prev3.7.1 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
  3864. */
  3865. ;(function(window, document) {
  3866. /*jshint evil:true */
  3867. /** version */
  3868. var version = '3.7.0';
  3869. /** Preset options */
  3870. var options = window.html5 || {};
  3871. /** Used to skip problem elements */
  3872. var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i;
  3873. /** Not all elements can be cloned in IE **/
  3874. var saveClones = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i;
  3875. /** Detect whether the browser supports default html5 styles */
  3876. var supportsHtml5Styles;
  3877. /** Name of the expando, to work with multiple documents or to re-shiv one document */
  3878. var expando = '_html5shiv';
  3879. /** The id for the the documents expando */
  3880. var expanID = 0;
  3881. /** Cached data for each document */
  3882. var expandoData = {};
  3883. /** Detect whether the browser supports unknown elements */
  3884. var supportsUnknownElements;
  3885. (function() {
  3886. try {
  3887. var a = document.createElement('a');
  3888. a.innerHTML = '<xyz></xyz>';
  3889. //if the hidden property is implemented we can assume, that the browser supports basic HTML5 Styles
  3890. supportsHtml5Styles = ('hidden' in a);
  3891. supportsUnknownElements = a.childNodes.length == 1 || (function() {
  3892. // assign a false positive if unable to shiv
  3893. (document.createElement)('a');
  3894. var frag = document.createDocumentFragment();
  3895. return (
  3896. typeof frag.cloneNode == 'undefined' ||
  3897. typeof frag.createDocumentFragment == 'undefined' ||
  3898. typeof frag.createElement == 'undefined'
  3899. );
  3900. }());
  3901. } catch(e) {
  3902. // assign a false positive if detection fails => unable to shiv
  3903. supportsHtml5Styles = true;
  3904. supportsUnknownElements = true;
  3905. }
  3906. }());
  3907. /*--------------------------------------------------------------------------*/
  3908. /**
  3909. * Creates a style sheet with the given CSS text and adds it to the document.
  3910. * @private
  3911. * @param {Document} ownerDocument The document.
  3912. * @param {String} cssText The CSS text.
  3913. * @returns {StyleSheet} The style element.
  3914. */
  3915. function addStyleSheet(ownerDocument, cssText) {
  3916. var p = ownerDocument.createElement('p'),
  3917. parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement;
  3918. p.innerHTML = 'x<style>' + cssText + '</style>';
  3919. return parent.insertBefore(p.lastChild, parent.firstChild);
  3920. }
  3921. /**
  3922. * Returns the value of `html5.elements` as an array.
  3923. * @private
  3924. * @returns {Array} An array of shived element node names.
  3925. */
  3926. function getElements() {
  3927. var elements = html5.elements;
  3928. return typeof elements == 'string' ? elements.split(' ') : elements;
  3929. }
  3930. /**
  3931. * Returns the data associated to the given document
  3932. * @private
  3933. * @param {Document} ownerDocument The document.
  3934. * @returns {Object} An object of data.
  3935. */
  3936. function getExpandoData(ownerDocument) {
  3937. var data = expandoData[ownerDocument[expando]];
  3938. if (!data) {
  3939. data = {};
  3940. expanID++;
  3941. ownerDocument[expando] = expanID;
  3942. expandoData[expanID] = data;
  3943. }
  3944. return data;
  3945. }
  3946. /**
  3947. * returns a shived element for the given nodeName and document
  3948. * @memberOf html5
  3949. * @param {String} nodeName name of the element
  3950. * @param {Document} ownerDocument The context document.
  3951. * @returns {Object} The shived element.
  3952. */
  3953. function createElement(nodeName, ownerDocument, data){
  3954. if (!ownerDocument) {
  3955. ownerDocument = document;
  3956. }
  3957. if(supportsUnknownElements){
  3958. return ownerDocument.createElement(nodeName);
  3959. }
  3960. if (!data) {
  3961. data = getExpandoData(ownerDocument);
  3962. }
  3963. var node;
  3964. if (data.cache[nodeName]) {
  3965. node = data.cache[nodeName].cloneNode();
  3966. } else if (saveClones.test(nodeName)) {
  3967. node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode();
  3968. } else {
  3969. node = data.createElem(nodeName);
  3970. }
  3971. // Avoid adding some elements to fragments in IE < 9 because
  3972. // * Attributes like `name` or `type` cannot be set/changed once an element
  3973. // is inserted into a document/fragment
  3974. // * Link elements with `src` attributes that are inaccessible, as with
  3975. // a 403 response, will cause the tab/window to crash
  3976. // * Script elements appended to fragments will execute when their `src`
  3977. // or `text` property is set
  3978. return node.canHaveChildren && !reSkip.test(nodeName) && !node.tagUrn ? data.frag.appendChild(node) : node;
  3979. }
  3980. /**
  3981. * returns a shived DocumentFragment for the given document
  3982. * @memberOf html5
  3983. * @param {Document} ownerDocument The context document.
  3984. * @returns {Object} The shived DocumentFragment.
  3985. */
  3986. function createDocumentFragment(ownerDocument, data){
  3987. if (!ownerDocument) {
  3988. ownerDocument = document;
  3989. }
  3990. if(supportsUnknownElements){
  3991. return ownerDocument.createDocumentFragment();
  3992. }
  3993. data = data || getExpandoData(ownerDocument);
  3994. var clone = data.frag.cloneNode(),
  3995. i = 0,
  3996. elems = getElements(),
  3997. l = elems.length;
  3998. for(;i<l;i++){
  3999. clone.createElement(elems[i]);
  4000. }
  4001. return clone;
  4002. }
  4003. /**
  4004. * Shivs the `createElement` and `createDocumentFragment` methods of the document.
  4005. * @private
  4006. * @param {Document|DocumentFragment} ownerDocument The document.
  4007. * @param {Object} data of the document.
  4008. */
  4009. function shivMethods(ownerDocument, data) {
  4010. if (!data.cache) {
  4011. data.cache = {};
  4012. data.createElem = ownerDocument.createElement;
  4013. data.createFrag = ownerDocument.createDocumentFragment;
  4014. data.frag = data.createFrag();
  4015. }
  4016. ownerDocument.createElement = function(nodeName) {
  4017. //abort shiv
  4018. if (!html5.shivMethods) {
  4019. return data.createElem(nodeName);
  4020. }
  4021. return createElement(nodeName, ownerDocument, data);
  4022. };
  4023. ownerDocument.createDocumentFragment = Function('h,f', 'return function(){' +
  4024. 'var n=f.cloneNode(),c=n.createElement;' +
  4025. 'h.shivMethods&&(' +
  4026. // unroll the `createElement` calls
  4027. getElements().join().replace(/[\w\-]+/g, function(nodeName) {
  4028. data.createElem(nodeName);
  4029. data.frag.createElement(nodeName);
  4030. return 'c("' + nodeName + '")';
  4031. }) +
  4032. ');return n}'
  4033. )(html5, data.frag);
  4034. }
  4035. /*--------------------------------------------------------------------------*/
  4036. /**
  4037. * Shivs the given document.
  4038. * @memberOf html5
  4039. * @param {Document} ownerDocument The document to shiv.
  4040. * @returns {Document} The shived document.
  4041. */
  4042. function shivDocument(ownerDocument) {
  4043. if (!ownerDocument) {
  4044. ownerDocument = document;
  4045. }
  4046. var data = getExpandoData(ownerDocument);
  4047. if (html5.shivCSS && !supportsHtml5Styles && !data.hasCSS) {
  4048. data.hasCSS = !!addStyleSheet(ownerDocument,
  4049. // corrects block display not defined in IE6/7/8/9
  4050. 'article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}' +
  4051. // adds styling not present in IE6/7/8/9
  4052. 'mark{background:#FF0;color:#000}' +
  4053. // hides non-rendered elements
  4054. 'template{display:none}'
  4055. );
  4056. }
  4057. if (!supportsUnknownElements) {
  4058. shivMethods(ownerDocument, data);
  4059. }
  4060. return ownerDocument;
  4061. }
  4062. /*--------------------------------------------------------------------------*/
  4063. /**
  4064. * The `html5` object is exposed so that more elements can be shived and
  4065. * existing shiving can be detected on iframes.
  4066. * @type Object
  4067. * @example
  4068. *
  4069. * // options can be changed before the script is included
  4070. * html5 = { 'elements': 'mark section', 'shivCSS': false, 'shivMethods': false };
  4071. */
  4072. var html5 = {
  4073. /**
  4074. * An array or space separated string of node names of the elements to shiv.
  4075. * @memberOf html5
  4076. * @type Array|String
  4077. */
  4078. 'elements': options.elements || 'abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video',
  4079. /**
  4080. * current version of html5shiv
  4081. */
  4082. 'version': version,
  4083. /**
  4084. * A flag to indicate that the HTML5 style sheet should be inserted.
  4085. * @memberOf html5
  4086. * @type Boolean
  4087. */
  4088. 'shivCSS': (options.shivCSS !== false),
  4089. /**
  4090. * Is equal to true if a browser supports creating unknown/HTML5 elements
  4091. * @memberOf html5
  4092. * @type boolean
  4093. */
  4094. 'supportsUnknownElements': supportsUnknownElements,
  4095. /**
  4096. * A flag to indicate that the document's `createElement` and `createDocumentFragment`
  4097. * methods should be overwritten.
  4098. * @memberOf html5
  4099. * @type Boolean
  4100. */
  4101. 'shivMethods': (options.shivMethods !== false),
  4102. /**
  4103. * A string to describe the type of `html5` object ("default" or "default print").
  4104. * @memberOf html5
  4105. * @type String
  4106. */
  4107. 'type': 'default',
  4108. // shivs the document according to the specified `html5` object options
  4109. 'shivDocument': shivDocument,
  4110. //creates a shived element
  4111. createElement: createElement,
  4112. //creates a shived documentFragment
  4113. createDocumentFragment: createDocumentFragment
  4114. };
  4115. /*--------------------------------------------------------------------------*/
  4116. // expose html5
  4117. window.html5 = html5;
  4118. // shiv the document
  4119. shivDocument(document);
  4120. }(this, document));
  4121. /*>>shiv*/
  4122. // Assign private properties to the return object with prefix
  4123. Modernizr._version = version;
  4124. // expose these for the plugin API. Look in the source for how to join() them against your input
  4125. /*>>prefixes*/
  4126. Modernizr._prefixes = prefixes;
  4127. /*>>prefixes*/
  4128. /*>>domprefixes*/
  4129. Modernizr._domPrefixes = domPrefixes;
  4130. Modernizr._cssomPrefixes = cssomPrefixes;
  4131. /*>>domprefixes*/
  4132. /*>>mq*/
  4133. // Modernizr.mq tests a given media query, live against the current state of the window
  4134. // A few important notes:
  4135. // * If a browser does not support media queries at all (eg. oldIE) the mq() will always return false
  4136. // * A max-width or orientation query will be evaluated against the current state, which may change later.
  4137. // * You must specify values. Eg. If you are testing support for the min-width media query use:
  4138. // Modernizr.mq('(min-width:0)')
  4139. // usage:
  4140. // Modernizr.mq('only screen and (max-width:768)')
  4141. Modernizr.mq = testMediaQuery;
  4142. /*>>mq*/
  4143. /*>>hasevent*/
  4144. // Modernizr.hasEvent() detects support for a given event, with an optional element to test on
  4145. // Modernizr.hasEvent('gesturestart', elem)
  4146. Modernizr.hasEvent = isEventSupported;
  4147. /*>>hasevent*/
  4148. /*>>testprop*/
  4149. // Modernizr.testProp() investigates whether a given style property is recognized
  4150. // Note that the property names must be provided in the camelCase variant.
  4151. // Modernizr.testProp('pointerEvents')
  4152. Modernizr.testProp = function(prop){
  4153. return testProps([prop]);
  4154. };
  4155. /*>>testprop*/
  4156. /*>>testallprops*/
  4157. // Modernizr.testAllProps() investigates whether a given style property,
  4158. // or any of its vendor-prefixed variants, is recognized
  4159. // Note that the property names must be provided in the camelCase variant.
  4160. // Modernizr.testAllProps('boxSizing')
  4161. Modernizr.testAllProps = testPropsAll;
  4162. /*>>testallprops*/
  4163. /*>>teststyles*/
  4164. // Modernizr.testStyles() allows you to add custom styles to the document and test an element afterwards
  4165. // Modernizr.testStyles('#modernizr { position:absolute }', function(elem, rule){ ... })
  4166. Modernizr.testStyles = injectElementWithStyles;
  4167. /*>>teststyles*/
  4168. /*>>prefixed*/
  4169. // Modernizr.prefixed() returns the prefixed or nonprefixed property name variant of your input
  4170. // Modernizr.prefixed('boxSizing') // 'MozBoxSizing'
  4171. // Properties must be passed as dom-style camelcase, rather than `box-sizing` hypentated style.
  4172. // Return values will also be the camelCase variant, if you need to translate that to hypenated style use:
  4173. //
  4174. // str.replace(/([A-Z])/g, function(str,m1){ return '-' + m1.toLowerCase(); }).replace(/^ms-/,'-ms-');
  4175. // If you're trying to ascertain which transition end event to bind to, you might do something like...
  4176. //
  4177. // var transEndEventNames = {
  4178. // 'WebkitTransition' : 'webkitTransitionEnd',
  4179. // 'MozTransition' : 'transitionend',
  4180. // 'OTransition' : 'oTransitionEnd',
  4181. // 'msTransition' : 'MSTransitionEnd',
  4182. // 'transition' : 'transitionend'
  4183. // },
  4184. // transEndEventName = transEndEventNames[ Modernizr.prefixed('transition') ];
  4185. Modernizr.prefixed = function(prop, obj, elem){
  4186. if(!obj) {
  4187. return testPropsAll(prop, 'pfx');
  4188. } else {
  4189. // Testing DOM property e.g. Modernizr.prefixed('requestAnimationFrame', window) // 'mozRequestAnimationFrame'
  4190. return testPropsAll(prop, obj, elem);
  4191. }
  4192. };
  4193. /*>>prefixed*/
  4194. /*>>cssclasses*/
  4195. // Remove "no-js" class from <html> element, if it exists:
  4196. docElement.className = docElement.className.replace(/(^|\s)no-js(\s|$)/, '$1$2') +
  4197. // Add the new classes to the <html> element.
  4198. (enableClasses ? ' js ' + classes.join(' ') : '');
  4199. /*>>cssclasses*/
  4200. return Modernizr;
  4201. })(this, this.document);
  4202. return PlaneUI;
  4203. });