From 765b74ffca6c5df013b4a376ebd5159fd7a1a369 Mon Sep 17 00:00:00 2001 From: Ferdinand Majerech Date: Fri, 14 Oct 2011 10:34:53 +0200 Subject: [PATCH] Updated the API documentation. Updated examples based on the new Loader API. (Dumper API still needs examples) --- autoddoc.cfg | 2 +- autoddoc.py | 0 .../articles/spec_differences.doctree | Bin 14319 -> 13330 bytes doc/doctrees/environment.pickle | Bin 12354 -> 12384 bytes doc/doctrees/tutorials/custom_types.doctree | Bin 26067 -> 25570 bytes .../tutorials/getting_started.doctree | Bin 31788 -> 32261 bytes doc/doctrees/tutorials/yaml_syntax.doctree | Bin 29099 -> 29040 bytes .../_sources/articles/spec_differences.txt | 6 +- doc/html/_sources/tutorials/custom_types.txt | 42 +- .../_sources/tutorials/getting_started.txt | 40 +- doc/html/_sources/tutorials/yaml_syntax.txt | 11 +- doc/html/_static/basic.css | 23 +- doc/html/_static/default.css | 3 +- doc/html/_static/doctools.js | 2 +- doc/html/_static/file.png | Bin 392 -> 312 bytes doc/html/_static/jquery.js | 3835 ++++++++++------- doc/html/_static/minus.png | Bin 199 -> 118 bytes doc/html/_static/plus.png | Bin 199 -> 118 bytes doc/html/_static/pygments.css | 123 +- doc/html/_static/searchtools.js | 4 +- doc/html/_static/sidebar.js | 5 +- doc/html/_static/underscore.js | 823 +++- doc/html/api/dyaml.constructor.html | 9 +- doc/html/api/dyaml.dumper.html | 223 + doc/html/api/dyaml.encoding.html | 71 + doc/html/api/dyaml.exception.html | 11 +- doc/html/api/dyaml.linebreak.html | 71 + doc/html/api/dyaml.loader.html | 175 +- doc/html/api/dyaml.node.html | 312 +- doc/html/api/dyaml.representer.html | 326 ++ doc/html/api/dyaml.resolver.html | 19 + doc/html/api/index.html | 4 + doc/html/articles/spec_differences.html | 11 +- doc/html/index.html | 4 +- doc/html/search.html | 4 +- doc/html/searchindex.js | 2 +- doc/html/tutorials/custom_types.html | 46 +- doc/html/tutorials/getting_started.html | 43 +- doc/html/tutorials/yaml_syntax.html | 21 +- docsrc/tutorials/custom_types.rst | 3 +- docsrc/tutorials/getting_started.rst | 2 +- dyaml/dumper.d | 32 +- dyaml/encoding.d | 5 +- dyaml/exception.d | 6 +- dyaml/linebreak.d | 8 +- dyaml/loader.d | 19 +- dyaml/node.d | 133 +- dyaml/representer.d | 54 +- 48 files changed, 4555 insertions(+), 1978 deletions(-) mode change 100644 => 100755 autoddoc.py create mode 100644 doc/html/api/dyaml.dumper.html create mode 100644 doc/html/api/dyaml.encoding.html create mode 100644 doc/html/api/dyaml.linebreak.html create mode 100644 doc/html/api/dyaml.representer.html diff --git a/autoddoc.cfg b/autoddoc.cfg index 080db8e..7f390b0 100644 --- a/autoddoc.cfg +++ b/autoddoc.cfg @@ -29,7 +29,7 @@ links = ../index.html Documentation home # Source files or patterns to ignore. Supports regexp syntax. # E.g; To ignore main.d and all source files in the test/ directory, # you would use: "main.d test/*" -ignore = test/*, examples/*, docsrc/*, autoddoc/*, yaml.d, unittest.d, cdc.d, dyaml/composer.d, dyaml/event.d, dyaml/parser.d, dyaml/reader.d, dyaml/scanner.d, dyaml/token.d, dyaml/util.d +ignore = test/*, examples/*, docsrc/*, autoddoc/*, yaml.d, unittest.d, cdc.d, dyaml/composer.d, dyaml/event.d, dyaml/parser.d, dyaml/reader.d, dyaml/scanner.d, dyaml/token.d, dyaml/util.d, dyaml/anchor.d, dyaml/emitter.d, dyaml/flags.d, dyaml/serializer.d, dyaml/sharedobject.d, dyaml/tag.d, dyaml/tagdirectives.d [DDOC] # Command to use to generate the documentation. diff --git a/autoddoc.py b/autoddoc.py old mode 100644 new mode 100755 diff --git a/doc/doctrees/articles/spec_differences.doctree b/doc/doctrees/articles/spec_differences.doctree index 5599e061853ec021104943bc775b18f8ba38e24a..202761c158e9f487e35a5d4b9beae64fe52f9b93 100644 GIT binary patch delta 4353 zcmZ`+YhV=B70yBvvI)C+Zjucl*=#~ygg^)c5)`nt6pZCzS&iB-ncbaaCfVKDduKKQ z^kzW?1Qn4hDkv)WeuBmaAc`m|BBFg*YinDreflWHwzkz)dd{6)vIY4wJ9Ex=zVn@P z&z-q@T;Htj9y`XC&mCjtk6K{z%g3BdeK!U{|VUzOwH zPvt$suguHL5F}S7NwSzA8Db>PcjxVMuC%hM=V7WP&h)gjwC?W4?rsdfwoaYUrPg$*)m>^;ms;Bu12IF$ zwq9-Pv;njc_%<+d9fbPQz_~W&m!ae_At;y1A##1p56Dr7^pG0>ypfR`F^^?}i1-jd zP{AffZW>Y0ZYkJ&Rs}qvpdCnWW@JlJ!6u9kXrzDDR7NI=OVk3hp8W#low&ehuZIIi`sI$s6=VpLNf$Hj&vx7I#o)px6He1of{>Iq2q zBqPH~Est8OZa@pm{1JIVCG`_KDm7Tl@X$~^-5})f{Z`;q0xT~{Y zh7^Ywc?BENU0SpV8nOrG(vg@;$sf`K{p3|F{IxoteR(+4ZbapPLJs>fqf{{zI-ro( z&*(#4M+GK7!k3l0tKWdMM;UoD*@Z(^b-1OEG4d9eJFEGL(wh8skzKqDtZn(W*p`(@ z^&|dS>BP(*1JzF$`6>5|YlS6Vp zlvW}A&!J7H1(Ww6*)JIRWm5M$Bf8&b9*R`Ew*{}UsBPD=i0MDoXs ze8TsZEzSS*^e%sfQu)bo>7)MwbGyH6iT60r{FRXtK%*l3V?hH`DMs>hM*ha7@(3?0 z&$g!W@4z75)LH)!L-_?G|3pLq`4>cgo;sTU#$=fdDEUjs_Qd%9I`S2y`wt`k#dH|( zg-Dm&0bet65i!t!F?;+e~jl{aQI0x8Yl4|?WtQc>qZ zxiDii3*NtsX2TU&_)ukuYb@MDnnfwPsDn2*6lXQ5_39|3aq<efD~8|@rF;btFU)yA^)JVqI61<-6e3ay=jq%E9P$Rt$E0ikc6Ku zT7nhkxdj#rDHYgp{DgOH9>%50FGKl`DJXqBy4pGid8Kz{F)fEDD4{~cdfL2%gH<)vEbOWPROei!e{)wz@*wbV%olyZg|MM6LL1 zea^kWFhf9R!WCMIOWudUP?=hB`d5{kYWIyV7wS_h3< z@tvi!QBwPeq&a{}NU8tN&WO3`fV@*`a1%BKJTcXU1GIh-m3QJN- zyDk$^mk)p1xWrcY4ZZpy_A0jvP@-4M1Y836MYfV|w7UC{BDGaAwko>~Yw@G2ZFt$l z4jV6+=(6`ELYDClC)dV%z`M}r=+SjEqMM2YrwfDjf{{@buD(n#MC7nyP)!*7(3oqi z2>bPrl#DWHKbX5{2%ULy%+!+}i!Us^5%d=Re`q|BQ5T3PBJ2Uplub>K7?cPrg)6@N zd}9MK3P&qb3TY9A8em@N%QvYUF?w_wmO!K-_kvPWgvH>B@}oM1V=^5O@JuZz8Kz84 zItb6uk&Nct_;P_?fp|wUxg~rh*ciP6J-J#Ws8J3bZa9 zr8j^9Rf^V1A!R@b(T!m1fF+XP3=EwR3rKGiz${e`!I}x!CVp_L%XSlgcWRAoGyi&O zk%I%qmmXC7v0i#JuWTu{ZQ*S#)!tjso`Hn~OnNImI1K21Bo>yI<8ss6c)X?f(ybze z0}kO@q(@JR@bmv5R@9KTOE^RXf$<~KDHBD%Rm7u~|dcy={BJ-zUbwiSHR{MAts#AEgE9b9m!~iAZhhetw|UTk*VLcO+^PQ(({+z}Q6( zz?Fa1>Yn%_+`#Z;Q+W`&imeFJgO<%9#GcygFY!4u$_rjbUz%^U7BuJ~xM%bg9-ZMW pcvalL23Po|*W;P&Fu!j`gXeXybkQSl75@b>>3{v_Rj~j7 literal 14319 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 Ee+0Lj3IG5A diff --git a/doc/doctrees/environment.pickle b/doc/doctrees/environment.pickle index 9c54a3afdcbb019c0adc5e539d1345bdff37a901..9ea0e9f19d8aec42c8c660d7361683d86436ff09 100644 GIT binary patch literal 12384 zcmb_i2YejG^_Gj;$sOC+7KFvZAV9?hn=WHpU_jUy+XFIi9D8?rnmym$-puY<5-@-P z8=Kyf5JD;;y*JW3Ata=bkdTm&UP*x@q(I8|-tOs6T(LZTmS#O_l;!o@dk{?V>4NDpI(iXkTq1Ibc#n~-{i_jLZ$;TkI>Dgh6s+D; zIAFVwwgTx`Vf66iX55q=xL!fEqZ7v(bsTl#e{bb@Y00C|O?jl`ZdFn|-~@P21`>XN zt~zPe!QJXKs%xZM-4k|eIl46)-P#x$u*wEjAmEiot)hS@YCi#?bXG!HSP3On@&hlQ z2!@M*cQwbc#;6lV;y7u-I8H_!3lYZ#)(#;|+ktI`c1}S!ry6w{g>wM0(-GC0N>uf3 zA?*yQ9u8uyQD=+#s52>?NhzF# zz}AigRuZwam$wledZ;!Ub#}X$<_BqYj#1}gn%L!NpWd3jJ{o@ouaL8oPR>{78MO)H zFYl$pj%^k##o^8}E9&-&rU9oAww*7}r-}yOv2{wSE#(p_OQIn%c!5z{+vQj@<;f}M zrR6X#vW;W6w%7xXx&&gELhO<~Dh{y{x~{ze zuSmnoSC<);5RG0k>!bo-U2c?J5>rw}CEF#KlmwC`F||0X(ndL4ml2Hs4srTwz$h6> zWPRltm1T*YVcj(C2P$V&o+}GcWePK}XH=0Z6<3zT%z>PjOaxvk&<^Zs$rH9OW@=0~ zb~<6_2JK;A1z|nE1uU9&wb~`tbW6N+-8)@3ke$BW4Xg*WozG)jclUNXg#owVbf;-D z@5bv$|3f!}qB-S;Z>Fz?3}QJ3$<`^dIxLp|kE}vXT_GA$ULoTSs4L594*A#yu8ygz zFl8E}u5K4|oS{^%ly(wDEEA4KCa#IAYefUETxqr27PE@O12l4c%uT~NM_q^5c+phX zi@7q$=cJP>CX%+#OQ5Hl#(t_4_L`ztIySL zE@y3X^IpN*C1!>pxoIb9YhT@B)U9IbamU5gZDJ-5FT5;WB%^M(ec30bE$>>P?hws+ zy8uWB@Dkk_S9i6`eWIQ--#;H=M$1ia^_-;cj;nk6=b?3c`08G}Z%Ux9%%*BPJ9TwMgSiYm(jC#9huE6mQdB2z)Mo@A0PWiByv&;2eEVvcXcTsnM z+`B~!K~N6lJ)$9#qCfRsF((49qVzr}rPFEke$ia9{{c~-%wb2RK8T%_mmcOWd`PUm z5bvj5pf2<}S=+j>gwU6+cLN{Oft|O|Y+KtfW24#!=?wex;gXmYIQb&xamT0OD%D5g z>Z2l-7^zi{*kU%d57Eft_0Crxi>r^fM`KJh^VsZyguGkcD;j`X$;OcUge~TTZ#vCG zsnGl<lE^WX*vtKlOSnxDnCSQHlh*>OE@*NVv>ixO> zVgXlSqZuShMXZ@lI+4i->hq#`S<+gT?y#2a5RF(4X!ciM=x-PqBceIf#6qFIC|Yu$ zD_1Ppk>xqU&1~XFO!2ot{#@ff}TC7vjF3@;=+=$s2)QLhVpTM-IUDSQmsINh@uTi%3O_d#eO>%YL zG}+TP1uLn47u97-ls_RyP@p&ctcgOIcop*Gzoq`6#M}jtq6|Yb3Q||KMZAmgvBl6 zl?rKklYI3oHT@V6$R61tSIagBLH0;K)i`5YZA{xWikwA1PEOoq*8(M|;zM%u;}peSSNuQ2$cQGXjT`1gqnK2HY!F*Yt7 z$-?7KO#KsPUNY+C5i|d4ryXWWdYVt5b)o^%CG8>;IQ!rP6dr{Z;dJK~Xoa_P`%2i% zzDS<_js5c2gtT1f+zgQBOv|~?|pH$EQg|}qBX3XJFdHW8aGNLLQiK~ z^`R|3py>u?#-7nENxj#N+z9-26KghCYsMzl%#ssQZXpV&^$Zk@p2_0ju~5%qW}Me7 zxgp)zM1ilKgM!g>Sv=C6N6aXoV{Ic->?9%2QcUFN5TdR9%{0rEr)fPOl|X(0h|vr2 z1oC4<4kbM+OW`r_*^v}vL%eaWq(v`!iS;5Dlmz8s6pdbjXZgj^t;~#vqYUL?XlE!7 zXWds+>mE@$uQX_!1w_Ol|x+(9ZaEvTj$kZg&k`azou( zPL%Llfr8O1Sv*cA(5XGh_?1O;Z58Wnb50I2lUo}7=0q1 zgx)BLlSs?TQf!j~?_@T0N@yws?^I@LgLfL*8NAb3x2IZnZ4F&=L!CNDb-arC79HFoYg(Wgh+YU{^hJ0QqP2wk$(EI+ z;3tLd4z_x6Xf;Il5@u?ndnwu(-8k!BR;`<;p-XP4tCtfcbZr!jPO^A}Zi<*u=+?L4 zm(WSWN#T%>G||@n>40-P)U^X1_+>zh9>A0E8)=m!ZDlE*g8}AXX=$n2WNDX`P#sN^ zSbMTz9rk~;?q?xj^iDkCGekGX%vf|0b{-A9P8C?mt5zybsAOfyK6P1fJFWQ|C8K@j zBaZTA+;*stUF{5%)*<7_9aC4QVNXYy!(f`BG&iV=%K>n@- zG5RVzfu+Q+$XSYa;+!$~h83<36+-Z@VWu_|*P@+su$y(StJb}~hAz3Ge%?ToQm_XF zqxZ6S1mlg&jQ2}!NOvDmO2K{29OrAQ`D0K@ubR(L2>2w{B-GqpSUFt^i=`mL<|wrb_K*H9)u)P;9& zJHh)-l#G5C^ASYvW@fx+@!$_ex4|y{sk0_{vwM< zx?dt@6zYrH+yZ_r%jG)pn|EhApYEiSF+L9K$>xAUB)^XmZS7x#9GnxH6js78?@EB&|N6d`RM0vJ(mfPvQ|1m57q+0o>HI&H@;qfz~l!~9DVDv9oJaYU? zVn(H6N!u{)8+2w|e3Xe2&>8)jJK01~jO6%NL|gfX${nz2vCZ;F+{mW>HH46c-+&nX zTRbTZ^n+<_mEVzFD@)y(I0?KWJjWJ)A6g7y{sS}PVJ;)}M{cL7=})Zue6{imHI&H@ z_4dz1DMf!l!RWuTcm(r{%#3$TZbIl zCz_$?`^IDwL=lqPmx#9Z9}2Y3tXQPY6WyF3i~41VAU*#AG5X(lQhE-g@E@{iWvL?* zCuhvOR5z6@Pr-9!G)!e?JX&R>r=gvZp3b`U)w&Hebjb~MxsfO#-GqYC%`6@v9V2EG z(y_L1(!k<7S!^jLa@0aJ{55L>FC4I;XP^>j&IB=f7M_GA{dQOpnN50DmcpA9eskE? z+|X9|n$KgVHhzboo$;H`x(ljx7uL`vH`J{|i4uN`P%wHii%0k^A!ZbQEx?by3ecCG z$pT10k*8Lo;noG8x+5d{Fw_FU!$FLG1)hW;ZC$Eljv!4dOA#In!igs7iRvm_dwdC@ z6S2hs92o`>!oHN5v9O~jZD`<`|0q^kR;_gOgi2PH>=O#da63&a?I;<2Eb|fI$1yY3 zqm?B;q&F7Mt8D!q}xTzsAN^P@v9HKji*S+d^gbp-4xQxA%SeI0KqSxcp_U8 z_kyw%(8Rf6bXT#$386xW?rLUg_jL`o)7*U`E1y)Yd~ywC@^vgT*7=b;OJUc?OLLd>k&Na3OGHNE`%kii%vVCmMd`!RubO zqBo!#DEERGeI}kXCg@X8l@Kte_$J1D%#?f<8`>Be3ei8CneiZ$0Xzro4B)w}+gGi7 zUJYGxL%rHWlmOg}g3;%*cm&`UVnzYj+@>Ah%i%-sWYMFL$j=2t!ym}EMke%D)B(C} zAVzP;lc1v?$jcJIjlwz@ZU>n&dibpt?B&AHONi@5%#6hq!S(R=RA5y-YC}qP&0l#drc%+*mW>hvRb4JgB=M0L3 z%%_P??qZ*IAdBQ=K=6Yno-}*l@?Mrgn>Ztkvt$J~R0wg-GE=+PJE^^V!D{5wZ}eq5 zrgLZpBzX{{3v4Tb#3M#D;etUDpLNsw%XeU9j|gw``nWJSykAVG+i3g8V$>L2N{H(s z+1V_g*{c;wo8{AcwdTT;d$o@O_IA=u2&dNf4L|3i<4VP~^^YOlTm1-oYWSE5xu zW!H>68wPyf0fuV{d_N_EQ(pz6MjJeFy&x{z;<6(ySI2QF0T-Wfrss zP8>1nvRoj&0$rBtPCL80A?$bSeIzvt-@~ij>}PYc=z=@8v2a9}oAgbnEsvS%OZOLr zV%u0Mrf-HA2G1=ZM&F93Xe!^7*SCS)?BfzW^!4pvehFX#4NW^ECsmagHsFbwC|$I=2DR9JgL)n2lU$M`_lj*$I8F!zSdt62!8F+x7!Wqb_SiCTT=wqvG<&|gy_wy!Bwzpo zHa5M56ha`RKzboPA-#tb0tpG}Jt2h@Qb_;a+dbV$y0i5!*3bLq&Ac|>yJ@>~-IR`$ zSCmd+sLL+wb+lW^+XX+eq2%P!=T=py$*!7W)YJ~ql+Id@)HxEZ^5ovgE_^0;3joh~{*uNP&B5QCu{oa+c?zd{kUCC#}>T zZD%~SI4-6-X-_SQi-tgSX}lzwQxYI)yP%Gat7FCnvcn!iXIuNHPntAo_xjBjMZ<_+ zvVWgC)~INQoIkGZIMG<-jif&|7wKRTTzZCZGX_V z3(?+n9I#bLM}28WgXrPO$v7#?cie(H8J#%AsAbfN|Gkw?8IvcVo3c%Ew<;+fuzmbu z1`?i+uG(qU#og*QYWYaFR@Cg)N_1;By0s}V5G@;6g@8{rYBdF1t9=bZ>8^ybs1i!5 zS zCZupa0$V>4SV=_EZr(z4=%Kp6s0%y9RL@VVKBF$egt6Dw9{p-I_tE$(xP_dRv~!-? zV${VLe|a|@bZo1bUL5W$vtrT#(L7)mg0@TKB~;Pq*_KX8wXIx2Wl1!K2DclvqeG50 zQ=X=BZpzBpk;D#d6}%jGeXDkdh9gRh5y=nJ50D4&PBCM%n=a+-=miY^t^@m2zuYNz z?N_@GByW-&mlSfRXb1!@g}`MHxOBg|oCLPXZ5W3nFnv469^H!RPQ@X11;pa}RRUrq zbX~gxZjpwUr(S9l2EUuk+9}^tNuyFFF*#*ax#03P*8vkXylbEt**Dktm5zhjTa9y(s0gJHy}1%G}Vn_ zuJrRcY3GWGq~-AvsP>EIUYa%0I}xGg1m;o9;s>yJ+8L{q^VLlvlD9l~OF&2+6yexD zBo?r|C*8qBux#a=!X9<=K`}F66J9BkafZ|_VpfoO6#+UIB| zmy2$9@@~Q1D`o~EIcYm-X;0l|)a_!*$tTCv9bzUAD*QycNJiah;kP5EF7H~Q?h-9| zs{lx8ZNEFN?&*++L<48Oe*wY_7n$DbnMmCmS1;?Iht~1otNX0J$-a8ICFWHSO_T@B zD~x(&2LiRNG~tzUbFNme64Tn2FJGhX7t^UBIS^F8S~Rs~*3h4NK+N)jZj~EfgT@t^ zm8(}K)q`SY3VRBg2Li>1MB{S&TeC*JHgHvGdKj+OtXidBCuV9p2bjwCUJrY#maoD; z^#(CB!(<=!M85Y5zsjEk+on?=Va8;NqPWzpCU z2OF2@7JD$d4Kr{dwk*mu%c7pGos4>mXsN*QR(Zde9Yj!Z_cr;cn6uaM94xaH(YI4~ zfZRL8bb_E9$U8-2CPjbhU1ClMTt(^KP)euM>M_w$vHu>?kj!BprQVDEl$##rF1$~y z-ihC*RiG~P+F2{QvxLxN8yw%mbYSJ9Xttu;F;An~1L+L<^Zt^U<=gopW^dc0;VRV! z;_8DUk{GE~AF{-3Y9FGJ#jBjBJ{(sc=?KS|XyLKh1qpetyiYU&w~~b+`M4$K1iy5e zhf;z0kH*!ieoUVFq!F`Ns^r-uf;Ib7 zhr~jz!uHZnl!{m>?Q|lO_tmFGOM5cfo?aGh-z}Q32+*9bKGWYgGDbv8po!%{eO64* zfv#M!ysKCk5E1+~?E)>Xp86biulO<9806~n@-ESU-FB&{zOV&5#^${3Tf91d(WozV z$k|4=8`)*#S|fW5Kn<7Zl(Y&oUY{^xHU@Q~P|7DT?P&*fUpDG1(CllH?R`^ZS6{PS z+c#DA^i3{_IeZ|%N|Deu?e^2^t44jTqkkd#P}xaU@7tfmTB5!#dn}vHFxa z?2%n^t!%duES+i5Y3TXd~x^6oK|*Bj$t) zD1HgN%6RH0M*URw#MRF__GrxHiwVxr&yAP{B~Sgrs9(a(*rP?Vl*`$E zBIkHGVf+fq*mFkxdSoy7o0@yU-;Omx+6j#Md_?^YCZ0Fy_ai3$Fy2H=K1aufKaQLh zt#mp#abas&v{F8Xi?*=T7iC2K2?k#<>dzwv|5D4~^JMU^W8=bsD>%$V)Zbv{MWg;c zV&)$mw0}%VSMy18l4yijB zbptm7dELmGP1TyswKcQkgp^x|0%RRQ!RYBM9vt`d3}(i8&5|3^okRBilJ)6Zt z-8saJf;iGPGKo$Q>@3AZj^+|=?QfxZtUM9xd8pjKPtON2dI6q5YmCT3(u-v&JO(~H zl7ei2H_nT+tc5>cy@&-RL3tF4MlZ&5BneBH84pJp%B5&$D34~{W2$vq>*$gj>fuX> z5|qcHV04tlLnx0UW(<^=m`i+2pD2_R6FG_z4WQg!wxQcl2`G;TF}fYkGL#jO6G$(X zrSR%PnXSU_M7Grt*y6Vb`XpxR<99OJ8NX9lcUiS=XB}N~L*42kO89l7VDxep5Aj<; z%qaX?+VXf~gmZ*9QTQk%^0Sg?YkxC-iJL(I{Nox!?iR_mTsN0;1Cr_Lry;GKhl(LF34g14TSQQ$SVc{u!H z_dZeVC?ayRfoN-g6R_JJSkN0$1?YM~j6N4ng05QNJkp6}DXIyMUSc z$X$qbMy`)_FRIqvTt}DOP?xq4CFCwf!RW0l9wK)MF{6-M&=#yXUMCJyomS4l{%XP~ zQgq~U8`0MO`9N_!uU}r2j%J}Xy&cU!bO(sh0#8D;p72hx70Xia6GC?vTkQ|52I%f) zrarotqMgybjCC)s){WQEB{$U7D~J-h2^5TeDT{~bTEvV(x1kMhI42Azg+o4)L|gl( z0nQyz*D3J8FAZX}jVIwZ(wZUZSeD{B5@0r#mg!a7D?PwUs1Bz|tUcMF4m&?u_ay|3 zcJPGH0NpGzW6?#}d(gn^RF0MM)k=k$O0g{2r!KqPPHTPme9G{)Rz}z7kJhDe-nVOYzpu z8H0ZnD_k8Y1mGKH>O*l2+BpZ;vhH=&y8G(rk{jyh^+YKJH=tnjjVvC*xSyHve#s5# z9w167xCsTL53+cudx)4(DOlP@`-RrKm^G;kX4VWoSkm0ng;DV8Psgvfo|PI-JeN=Cne`7jr+WM-_#SeE>d z@~ena9`8rN=vT9NsQUmhqw-i8N?nH^N)!p1e+|)^pD^@;XhMn}0x|lvc+w!jcZ)1V zQab?*>%*+@x_su97{TAj!h~CP~ zc+cdAl;1{_;C(v^M!$o_L)~{0GYa16ZFt8)ABs9l#gTDw1f(e_^7JmEt^E<&*n}U8 zN=5x{)B@zkK#YD5o-_`|$h?;{V_AyuFtERmO}sxa5y1WdX6kqTgWOKAe~6VoT&?_( zI?CjS`tvwZLj9vC82vF850U#gGvghT8`Av*Q9}KbC>Z@I77uklP0T3Nm$W$rybsIe zI`LM!Go4R&(#aT~fAvIjKp~Rf&k$|xUyK}F5SZi-j=h_Eqh*u&vyeeXJ_lm-=kcVB z99H8CWHpwhzSPc7WnSVbgbXi>hzOD z3GA<iU zb_o;E8NRQbXd);^a{M!*t^A5|H*7}PX8Gf6XjA_jLP*0eK#cw+o|Fc9Ra#%=S7bMq zrS8;D0 zL|glh0@~+REYjwQZbXnp{db5UJ^uhP`k#1GdJd=XFR~fSQb%ehXUx3xZ?^oOz;ckL zNmIzpc(lq$PewZ$c6w;BlVA8VVdi-*`RCT0|V(}5p-51?;169tfhB2P<*23r?= z%nps{rKkmhM}ruB44#A_ZC$ElT1hjOr3jA%VXaBJR$XOlk8dD!B7O-6aBL7j0DF{~ zv9O~j$Dx5|{unE@RVy7|Qz@1u`-DO}x6`z80!l`o$b1NR2Qyq9Rv4M1$`;__>#@==G=u${Rq8-iRlS z3Hk_BB?QbVzS@|NnUZ_i(7A!30R8ir84p4kz)fgp0MBRL3#xT5tfNbAs8@YN3BZd` zFnTkKhX8INW)y%eZQAzS96sev6g>)w{9H^lctO4`G@-Ym4$xf!V)QmV2|9W~UX}oE z6xNY&JHnjN!@uh7>}5ybCBRiMGZt3_yAusOXY697{%WP&HI-snvQHhol-ud&d>Kkc zU(S4pXq=g`9%EVZL&{eWrEDZnz?)4L4|OeKMrETiXY?F?&Y(!he3IzIF6`+PWRaXS z2wr&NNwWtos*#Vr;WzDw&Y~HR>;W-4$F@R9 z^2CT{Tp>u}gKqjz`EIN15y3584;KN44~c1X%k0otjGDr02XS2>J6q(l2egaQ7WvEp zUF5=(2ed)~dpqf*@xlF&m=S(r=j#Y@tw}TZ#BSpXgf)au^S9*RX6-$w92Qgx{+stfDb>wa3O(j zpoDPhD`C{=tMJ6dg1Bst%dWUw8^?77TxiCbp07aYt69nfQk&L4b@w9=?b46S_Mq7J z#7VL%C~kY~Y`HclUi|Q#vL`5R?s)>%!gn*CzJ{$`OV-4~6wb1H5;m@j<`VchVamey z6nz~U4~kaYG|4CEic$ghq;Q!eyb6%;aKpgX`yg}(7wT|XCy}%F+BtnaYWf<)Jdf^4 zmXdrsBQcb5bza}V!gFl=`qIIzJx|)UuW#h~8AUs|ua_w4oZgQ*aqOt;aK3a4bRDic zZSU=du-B~*kkl-E53hD}6Puew7b3BZg(JGYqz|IDJZ7q|)$a<#wzE`3AA%SL&&?o4 z--4%TF5j%ww}Rc`;hH@3^=)9}6fr|*QhdvhqrROKjt-;tT^D!Y9ox@v)O2I0Ti-zv zvz$V)%9DmIC-hOxg6Fc=WqWOt$xxe9l_#5a zM3Yq$dUBfcy?QdrCRkL4RLo8)tlL^;(9kTOIN)M!cj9Yu2ywds|1D)!fo5Czz!f zQ5j|6)P|+->gp!x&UE>j*FEhGnEF;H6RrOVUps4x?}6)!5^jt^^+u35!d4Wv_1*0j*n}rH_W3LnL5FQ2xgT0K4V00V z9o8;xImpKac>=E9v{afTzw(Jm?QuCgxv94L3S6P~yM)*jju@_zrB&}8mtZJ(7981F zQq14&2u%y21JHlL+0%{*W{2@lTZo1Z3g&xe5VS>FjaIAGY4wzoD+Qx5s5J$(r9rJZ z$lr?;&97>$L4Js)xvH(T_1)(Nca=~$8|OeE$_fm?LrQSgfV_Z1n|*J0PhsG0+UNA!R&0r>|8IvZ-AkJ zO6g;wn}|u>^l{2_)s479A8rz2pTN=Wrt878ZM6Jmhkc7+f6`$?$+m!e+6r|OmEoum zxz!N~yaKOpdug$IE_9q(aFN$fiGtVm7c_lZ=yU}Nuut&xp`SiFo%m;vj;?)H0N(~f z{gq{8Boo-}f_w*D(cd85DFP!V1@<|3q<=}(UARK+&kM0H;OGW+JG|Ln+kLmg{-R(X zbJ)TIcb^+EigA{~dxYq{B9rMe4BjU)`6UPOej)aNgDCdpJ@CLl8aDJ-!1Um4vqN}D zh<;fhe&r0r^KD2EJ-z5joX=6l@1QX{;vROl z$9Lh;;gj7@p)_XyqyTstN7}v_2tu9NzRw7eXC0A14;V#rv(4UkXl< z=jrRD%khD~fE0xMsZejZencJ}Ta?F#(A>|3%r7!B18~#M zXLmS1d;ffS@W$Wf*09=@z*9^dsCcPxr*Ny%GW+~GPUqJz;jXTx(yzN|dKsO-`2L?h zG_B;XpcTy7uSDFhI&q7=K$)1S{jUZ8Hx56r4D4NXO>~W-hPO1`T*ZHjyg91>8dcxl z)_2kk>vtsAd3;j> z>5}H+XIzVaLSd~7`U6Lo^FQMpP5edZ{}o5KMF?>w+`kF_-zCVq^l0TiaYO>U;hat7@Wf?(dZWdxYnHHCs)1SfYlczhlhJ7+;YacSEWLuIh0ssvZ4 zUMl3uaCGxf2-}0_75g1_xnNg#VBmskxI5^dc1+-AasE`g&nN{JSCeMU;0e4mEI^e( zr6^_?R?@Ioh_jf<7Ydw3I4XHaNU8~D@=8IhB4UX-nFt&4kgH|#Y9t4F4KYhq+cF#u z^zO;aT`X8jVEdk`&RQ{-Ni092TdGC31zsnp^*B<_l){M3IljL_aXrcSS#a~7%IO9n z(nyNvQOe*J`rd@gK_yR*hD=N47GH|%K1nH>alk^qn}uo%sTR35oiJOGHpQ0_rv%@B zI%g3pgh+TjHF=v*YbR!&na?Z>?>Z*$fOVnTU1uZJ;LCBG;^*MltdzN_2!++iK6HGa z$YDX9r3SQhvYsi3r1jK7DUl_4-y9zucpSaPHaDm z^Ij6mR*Et%#qlkKey)dmN1C>5K%P=UE}2Nzu!3=nk8dP$c9ezfQNBq4mas&aQ9UQ) z%+wgO_ytHmtSmNc3m=^D$jGADX41+bGZBklNQ)v9E0?qrp$Y10z6EKR_~NLYNQF)} zyUDjA9eX`$MD%3L$Ovz9gni>GPhyGDG-qmp_rWb{&B}g4&%@NWH!kmt@&Q_wvI*Uy zjXd^^0RRxBAp;-FFy!QY*IA(l|}cu0*#>57bL8HR>%gLV;$ z99HJB zz%*!gk5ArF)F~`ZMC-A)1&s%YJa~sJGtbKe$dZnKX2ar zj_>b$@6Fp+9}}MaiEuPNt9XHsmbNi&5nbGC*y4z)Y3!wpRhgn~5)Z4&oR`%ml0YKB zIx`z{MOBx{9wK{KLB<)SqAC;JQsXM2rWlhn4H^9zYVo^iCkfelBFN#61N(+MM~7E8 zD)Yi84Shmy$A6slM3%6cU7!C@W=zt>DBI>8%;QP$3`x`^<3I9#BxD#651Z{hJ0;^Q z3d|&J^Hz`FS9DxBa{-7pi6e>{Q>MU(+dF$UK=OucD=>T%!Z|iNd=G|mV)5}iOES}i zy7BQcwLlmipI=v+oe?u+!j?DP=1w+`w>DP_!r1txz+)MLIbPn%gjSu5h#L$^CbY4} zv9?!AYBfz_%+O7X+A+(ZO(IHdA*P}2CUg;db6Jh|992(fWQ`HClTgv|yyXuFMYkx; zO1e_kM_ZvmlwkPNHgU1Q)~*Z++u7*K{R!wca6z;bBKo@~ef0-C+lVM>rU6b9S(HS- z>$ty3jM|nMH>ju^BjN}V2W-<4WfGTc&1#+qSX8Zm2p|BhdstK3$`a9^AXeidznCPJ zV#uOpc-Y$=4eUr;y>RRJV{PxH7v(?|{Z1nN%ED2)i?w%D6-JyyWC4@&*s}J;1$po` z#d~&F`<&VtG^JwTR8X~}O4p)&G!D~InqV!bSF%+d4IE%f$V~6>hl&97W1-U|Xdc){ zbq-*_h#ho7(dib4xWX`7+%uPbzjF@zaFu7w1R4|-19dY>EuaCu&Bb@a2>78iz(N2! zDk;@UHv|z3<9axm^lQ+XyvEyEu&rgINJkutd$`5Dj>VHk$Kp1N(?dU>BVUk0&IZ3z z#mA~%$g4UEOo%BHc)TyzrmnIq9`^a{V8?s`o1?Cd?gKGM&Ltdhe+sY#l%}^)F#A$2 zaexInnQ$4qyUpjh%UwyAv)4Miy;nF$2f5sp?DW+=#i#?B-3sk-h?B2kH?D3Ft_BBv ztC5N8@H6-fhD*UF*&`)~G-589Xmf+o!@vg*ui*fnh0!hFAy(P7+&%>iU%WKBb{gY3!pn07WU06n`K60#36f zTWRXP*A4iKTww_y-w3l&`X&B8FV%J|e@%Azmr<=^04=9XwW6t;Fmu}`fWCt48SQ!m zXb|sL;W0|T1|!5fkb*;V(6JEKN-+L)E^@OY60Q>1lWRkMOG=1F9JUk_jxLF&*03Z} zlCbfe>=~lOG*v@q#@dR!CJ&y1u!mbsOh2oN?Krc)Xo}Nkpwr(#r;G1*qyHv17z{tm zo>;r}6Wa69TL2Bhy_LsuTPl`M0lKCb(*v2p&FOZIeg|$9!nd&dg2=?~yAz)?DsUIj zz@@vn(oq=Qj=P=Zu1k22IqZ8ldz@XgPMYtS!gj;D+{-!lIf~&A*$3-hZ^0vAN>_WJ zMD9);nBFHm<@fUycHB+*1FUMjZ^gGA!{6cX52oO8Q-*T@K5O_E1XyT3758y2`dwzM zuVrg`$`>FDqkagV!Eg!aO0s-5EIKu&TFmGVZp9x!7EHgv)!&2>_nQ;| zVovTif8-*6azw)IOx%2GZGV4t%+L(l-yfiV2F?kr{)Jn8#I^cYR=&BT^lu;wR^Q@~ zZ#$4|!R8fZ0DyL&f$`XQhx6ZMgDrD~zw;a-6I=K_d^$OFJfQyo3PApotNaT_w+r53 zRa<<)e{=eO9Qs5K9b1^g<6!Q6F7rW3W)VEu($GS7c+0UR|KB$#Y^|y9&p@cYbb2x# z!oBpr?8$TLOP_X=@gbOiC_bU3hTunl1F@&2!Nvj(P{n!k93CzN#7!*(kxNvwH+IwtH2_(b=df`p zEM(0)D=TV20-)-+U_Fd(PQ-LJziT0zzoW2_HaJ3!Txd}`>+h-nMu{+&y|A--%n#(= zP=4GnEZwk3gp#;P7jxMr7(+Qg(4{0XX)`AVkXUH$O-2nZ;%b?636T3}3o?r&+cI2^ zgSV7(PeE?!bk(+$#a1q{3?*{mSduLGSTX5xP7T6{xeU#Y*_6VqE~2SAp{KHA=gqA@ zjf<>6MR0Y_l%vWK(~_t~+t^#@m5rUwMbALdeAkBK-zuPu(stw&!v6v) zB{3@kn(!5E(hjcHiOd|6SQgywOu8Cg8)GtDGc8p!1958T@V|rX*(zx^F+H>k_y%1A z<0w57Wkbd6(!P?VYhm6kgi64ILFI@{hCqwxF%=Sg7VvsQvuQjQiApAk*i@tI*yDZG zjb{TVlxtBbMxs(|kgj)7yhCIN10ax;7yxv$qFrTU8#qk9Wgtv!5OOtW(jG*}gxt}+ zv=`_3nxrReDM2E59j6t~tB)d3W+)3j8{%q$ z#yEi2aVoM~HC6Zzg37F-zfvIVwEo(KagaC|nnm>8G{J=nWIH(&88V42gLg@dDr~IZ zH>PrCF-BzCQA@SJ9Ve^-j*w>>HjNSN^Fcbug}vAoQ);a__=au4KQR%gzac}cGzsKT zrftQWPop}{Jt-(`Cc{Be$MD~qNu42-%jG)FCd4_6?*$QAHKiyxmWrNoGNQ_sLM@S(so@Kg>n1fzgfz{s%7*MREWD diff --git a/doc/doctrees/tutorials/getting_started.doctree b/doc/doctrees/tutorials/getting_started.doctree index 57b121a1f75f659b52bc8c67a11a33436882b8ed..e213365de19674147a24343ba9f28962dbefe368 100644 GIT binary patch literal 32261 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 literal 31788 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� zT2GTmU)C6pyW}B_#~WDISi}N7V3@;xYYul@Uf#&u9d{)wcI>U*#N^m0;mvpl?QcO4 z$XoFnT0_#%Y7O6}d2TUz(nkQDc@b2IMg-(gI3jpE!9>>4A}#MgEU!*KR^ExHa6s@b zJS!J6ysSJn4mck;;CMthHpW2;41>AacXu^T-i@ljj`twI-U@a_lffX+|z1Y>OI&sH;eX3UY#b?YGU0R%eniCR|jRdW@gF;F_^ zse5!=4VKxWt=CUP+p4D;xP{(9T^w}j%)K*(bJlZuw+8WOE{X$~?$^QQX1i~#(nrpl9r8gGf%tAi5XgtLeBVx#hg>KL+loJ|P(EUz z@B+qpvztx$qbwM6YQR3UVh3QXQ`1vk@-YSunMMWW_v@srOWHnk8cCU@eg)tUJ$V!Y+*%vii5 zKl4iP;9swh@;P7#zI`4+AYZ^Q+xmS2w@49bAh>Pgi;CozERy_OiGJ-Qm*ozcs9oto z?3XoD_l4MG*tWicOi-Z~K=M^Yf+1f+5XjdRjG41%?M+|e8=C%2lb(J!aN#|o;l4gD zDbgyT`L`ODWMT^j_||;1Z0B1aU8mDwM>@^Mx3u0)vvEvF+P9Gbq=lD>-a~lFcTf$O z^<4ykd{2>TUaEQzRSLBr^NlE|7T?#}e_(6p04+I;=Gd+hKhzA}RpPjiZ$CmN@GSx& zKSl&7{0RbV`A`r>9aw8q9e%3mKQrlR?!UMoI^KbeQ9nmQ3?FsmexaE=Wq3k}%P(2T z+};)gCci>7F#0uuKz^e@%#}m2OyChQYVzo}n)`P)_fp^o4snl13@dFozt=3?xpZQP z*&mPzn8m=z9}xwt{)8ZqKPwQ!C)V8L(_b|GuO>ac6?inaDTOVCeQ9`*1`Q}_|Y6hR=%6oe5VtAqg2ahanVd!bw>-(|TepV0DqnDXiFd0R zQ7z)4S=_+JdwTO(o*~rF!Z`eF%|@r6oJy)B2Cbi0L zgP$;Nx%4B)SSpdjg=}1Xm8S8_gMR^KB|Q94Vu_ro!r5pX-tq!{FE8QU>FrVA5mIl(n77h{&RG!Cu~V-rj{H`M6JE83Hb?$Wegr9hTwMn5jK*lAv6}(qai0qYNNnEVVL163aa` zS*JJ+;y1Mn5k$2nM{DGIMy{#Nm8L4iiLg{nh7dh2NhV@NJw~*`8`jign7U6}(Fx6P ztY)}BGc1RIl!rArPGgV9FZCg{BIG)6ke3q>J(k)lq9y#kSxq)*u@mt-;Ne?mauS{b zd4RrCqR^d<`qEU{-Hpoj(9^|MPZw<-JNp7T8D*8Hr{F=A^He+pa+<=l6`Zaw9m-iC zE|kX^49#rDxo85S$2YB7_VW&*ey&OL%s%)7{luL&xulGs6jbzq2ypufe#7AaF=(o& zH&|fXgmESLn>6=XQErfbw!Z8n`Gtt^b5L9fKUYC-j)Q)X1>O4Xv9$$aLBdBFj-*e4 zUFsyf`xgPbvf@0z0V~c&5XcyQLsk%{UaYu4b6*(c1}h${FY{%^!A29Btau2DD=RKi z&|Bi5Qxb;NH-DaMfW9|`_d>k=zh4q z+-s~J!Um|EM8+DbezVgr0_wVT;id;iME!I z$05BUSK&91$1`tgudpYb;D;vJ8Pw!zq`*$s_Irrs_ABG za-9NS#T%-s6P)zpMZI#p#;&YaSY?RglL&D!(q&F=;PcAxi!LaLyI!BnxCL%mp2COa z+yj6M+)7n>D&9$e3TZ<9MtK_IAea>(6`wjaUvrhGYsQ3^Db{VaXE591)Jlt=`ADZc zlli>U#!`KH+uH;fg^AVj%!GOMuzZ7W$I6Y!mRdssYAEQT{vx;`&tmlAoIBN+k!KT9 zYK>c(a;Y+N_$Zp^x^;OD;;&7u#TIKE{^$k&xdg-yc;&Noc^+R@@`I!0MrmR@JuZ1Z z;vm)4xkjlv5jih4c>&_#hhf_)zo%w1ztCh}HH*F5qy=!@Oi5m(dH1E*cLTc6mL zujO&)vAkSk_s!z^{H+r%4p0;)aGe9LZpPHLyaI{Wq}GDeQsf9W)o4P$;3GF7)3vFE zZh4!$Qh^!5t2MWg1C^zsyh@|jz&EczkukT7tsuDgLtd@%dy#v%IZr=rYPoW=!ra67 z-VyhHpj8=(5zR zRwb3UG2`OYma~DWS`qE+sJ?;%HVA2M+(l`D~L|1g0!rc(R1k7M)`!156m(sizyd=$@t zdI#4S-g@dx|aEj$Pe6zRe6?K$W=try$^a`B9H-orCbpWVaI(6WuM{)`-(mCci=ncJLfwc6ZkZaEbKC zWunP0SgY-Vr=B}iFqtc>?1Is1s4f>RtPOG@#K+6aOVA3ohiB?+k7{lG>QZ&~pB)*3 zO$N1xUX-0(Ya4cZJgc>hcsv$=NWX$@h~SEq5v2G#J{BXtIPoM=b3P zzXKgDgy%!Y`4LG#JYQR71rjMpIfMf=sT@Z-^+(R4fO}L5z(B*R$6%xGHF>bHJn9Be z#XW1^0*C1Gx@nx?`t>T{G^>jv#=q=Y|1N>dPC2l$-M-0U6yb7=w&k3%7!<7D~ujH10uupm(!!dSCn! Wa=vE>1vv~7dS`s%LB1(|ll}&~)jx3n delta 940 zcmbV~TS(J!6vzEeozA8ik)~$;beX2x)Vvf{=*&b*d#JpWPB*u|PFT)eEPT+Y2nr&L zlTQ*_L6nuKhv;q(X+an&<%6k}Nr(kva9)gAPKY0)Ob{?cd3QJpwVay24QmFp;`*CN;NKFYh<60DU`){ zd3gz~Sb<<4Jaf|iqS^j3-V*`VOF<7BlAYjAyoa0|Pv}{Q@w^$1;0;FwF5;YG9m-v%g@H zvURnX1iG!B36C{_UqdR{UD1z#==0|KbKY#0IDa@cLW zQZJ{DBSW6d_HwsjC7r7ngOaQCF+d=ls+>k3o2xQ_AZj#h`c1S;0{Q^FUPVN8z diff --git a/doc/html/_sources/articles/spec_differences.txt b/doc/html/_sources/articles/spec_differences.txt index c864fb5..00ed069 100644 --- a/doc/html/_sources/articles/spec_differences.txt +++ b/doc/html/_sources/articles/spec_differences.txt @@ -9,7 +9,7 @@ are caused by difficulty of implementation of some features, such as multiple Unicode encodings within single stream, and some by unnecessary restrictions or ambiguities in the specification. -Still, D:YAML tries to be as close to the specification as possible. D:YAML should +Still, D:YAML tries to be as close to the specification as possible. It should never load documents with different meaning than according to the specification, and documents that fail to load should be very rare (for instance, very few files use multiple Unicode encodings). @@ -21,10 +21,6 @@ List of known differences: Differences that can cause valid YAML documents not to load: -* At the moment, all mappings in the internal representation are ordered, - and a comparison for equality between equal mappings with differing order - will return false. This will be fixed once Phobos has a usable map type or - D associative arrays work with variants. * No support for byte order marks and multiple Unicode encodings in a stream. * Plain scalars in flow context cannot contain ``,``, ``:`` and ``?``. This might change with ``:`` in the future. diff --git a/doc/html/_sources/tutorials/custom_types.txt b/doc/html/_sources/tutorials/custom_types.txt index ff6f3c8..1a22ebe 100644 --- a/doc/html/_sources/tutorials/custom_types.txt +++ b/doc/html/_sources/tutorials/custom_types.txt @@ -2,10 +2,10 @@ Custom YAML data types ====================== -Often you will want to serialize complex data types such as classes. You can use -functions to process nodes; e.g. a mapping containing class data members indexed -by name. Alternatively, YAML supports custom data types using identifiers called -*tags*. That is the topic of this tutorial. +Often you might want to serialize complex data types such as classes. You can +use functions to process nodes such as a mapping containing class data members +indexed by name. Alternatively, YAML supports custom data types using +identifiers called *tags*. That is the topic of this tutorial. Each YAML node has a tag specifying its type. For instance: strings use the tag ``tag:yaml.org,2002:str``. Tags of most default types are *implicitly resolved* @@ -19,9 +19,9 @@ Constructor D:YAML uses the *Constructor* class to process each node to hold data type corresponding to its tag. *Constructor* stores a function for each supported -tag to process it. These functions can be supplied by the user using the -*addConstructor()* method. *Constructor* is then passed to *Loader*, which will -parse YAML input. +tag to process it. These functions are supplied by the user using the +*addConstructor()* method. *Constructor* is then passed to *Loader*, which +parses YAML input. We will implement support for an RGB color type. It is implemented as the following struct: @@ -111,7 +111,7 @@ RRGGBB, or from a mapping, where we use the following format: return Color(cast(ubyte)r, cast(ubyte)g, cast(ubyte)b); } -Next, we need some YAML code using our new tag. Create a file called input.yaml +Next, we need some YAML data using our new tag. Create a file called input.yaml with the following contents: .. code-block:: yaml @@ -144,9 +144,10 @@ Finally, the code to put it all together: constructor.addConstructor("!color", &constructColorScalar); constructor.addConstructor("!color-mapping", &constructColorMapping); - auto loader = new Loader("input.yaml", constructor, new Resolver); + auto loader = Loader("input.yaml"); + loader.constructor = constructor; - auto root = loader.loadSingleDocument(); + auto root = loader.load(); if(root["scalar-red"].get!Color == red && root["mapping-red"].get!Color == red && @@ -166,10 +167,9 @@ Finally, the code to put it all together: } First, we create a *Constructor* and pass functions to handle the ``!color`` -and ``!color-mapping`` tag. We construct a *Loader* using the *Constructor*. -We also need a *Resolver*, but for now we just default-construct it. We then -load the YAML document, and finally, read the colors using *get()* method to -test if they were loaded as expected. +and ``!color-mapping`` tag. We construct a *Loader*m and pass the *Constructor* +to it. We then load the YAML document, and finally, read the colors using +*get()* method to test if they were loaded as expected. You can find the source code for what we've done so far in the ``examples/constructor`` directory in the D:YAML package. @@ -180,14 +180,13 @@ Resolver -------- Specifying tag for every color value can be tedious. D:YAML can implicitly -resolve tag of a scalar using a regular expression. This is how default types, -e.g. int, are resolved. We will use the *Resolver* class to add implicit tag +resolve scalar tags using regular expressions. This is how default types such as +int are resolved. We will use the *Resolver* class to add implicit tag resolution for the Color data type (in its scalar form). We use the *addImplicitResolver* method of *Resolver*, passing the tag, regular expression the value must match to resolve to this tag, and a string of possible -starting characters of the value. Then we pass the *Resolver* to the constructor -of *Loader*. +starting characters of the value. Then we pass the *Resolver* to *Loader*. Note that resolvers added first override ones added later. If no resolver matches a scalar, YAML string tag is used. Therefore our custom values must not @@ -203,11 +202,14 @@ Add this to your code to add implicit resolution of ``!color``. resolver.addImplicitResolver("!color", std.regex.regex("[0-9a-fA-F]{6}", "0123456789abcdefABCDEF")); - auto loader = new Loader("input.yaml", constructor, resolver); + auto loader = Loader("input.yaml"); + + loader.constructor = constructor; + loader.resolver = resolver; //code from the previous example... -Now, change contents of input.dyaml to this: +Now, change contents of input.yaml to this: .. code-block:: yaml diff --git a/doc/html/_sources/tutorials/getting_started.txt b/doc/html/_sources/tutorials/getting_started.txt index de07390..73bd3b0 100644 --- a/doc/html/_sources/tutorials/getting_started.txt +++ b/doc/html/_sources/tutorials/getting_started.txt @@ -26,10 +26,8 @@ Download the version of DMD for your operating system and install it. .. note:: Other D compilers exist, such as `GDC `_ and - `LDC `_. - Setting up with either one of them should be similar to DMD, - however, at the moment they are not as up to date as DMD. - + `LDC `_. Setting up with either one of + them should be similar to DMD, but they are not yet as stable as DMD. ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Download and compile D:YAML @@ -84,7 +82,7 @@ into the file: void main() { - yaml.Node root = yaml.load("input.yaml"); + Node root = Loader("input.yaml").load(); foreach(string word; root["Hello World"]) { writeln(word); @@ -100,22 +98,23 @@ Explanation of the code First, we import the *yaml* module. This is the only module you need to import to use D:YAML - it automatically imports all needed modules. -Next we load the file using the *yaml.load()* function - this loads the file as -**one** YAML document and throws *YAMLException*, D:YAML exception type, if the +Next we load the file using the *Loader.load()* method. *Loader* is the struct +used for parsing YAML documents, and *load()* is a method that loads the file as +**one** YAML document, or throws *YAMLException*, D:YAML exception type, if the file could not be parsed or does not contain exactly one document. Note that we don't do any error checking here in order to keep the example as simple as possible. -*yaml.Node* represents a node in a YAML document. It can be a sequence (array), +*Node* represents a node in a YAML document. It can be a sequence (array), mapping (associative array) or a scalar (value). Here the root node is a mapping, and we use the index operator to get subnodes with keys "Hello World" and "Answer". We iterate over the first, as it is a sequence, and use the -*yaml.Node.get()* method on the second to get its value as an integer. +*Node.get()* method on the second to get its value as an integer. You can iterate over a mapping or sequence as if it was an associative or normal array. If you try to iterate over a scalar, it will throw a *YAMLException*. -You can iterate over subnodes using yaml.Node as the iterated type, or specify +You can iterate over subnodes using *Node* as the iterated type, or specify the type subnodes are expected to have. D:YAML will automatically convert iterated subnodes to that type if possible. Here we specify the *string* type, so we iterate over the "Hello World" sequence as an array of strings. If it is @@ -123,8 +122,8 @@ not possible to convert to iterated type, a *YAMLException* is thrown. For instance, if we specified *int* here, we would get an error, as "Hello" cannot be converted to an integer. -The *yaml.Node.get()* method is used to get value of a scalar node as specified -type. D:YAML will try to return the scalar as specified type, converting if +The *Node.get()* method is used to get value of a scalar node, allowing to +specify type. D:YAML will try to return the scalar as this type, converting if needed, throwing *YAMLException* if not possible. @@ -135,16 +134,15 @@ Compiling To compile your project, you must give DMD the directories containing import modules and the library. You also need to tell it to link with D:YAML. The import directory should be the D:YAML package directory. You can specify it using the -``-I`` option of DMD. The library directory should point to where you put the -compiled D:YAML library. On Unix/Linux you can specify it using the ``-L-L`` -option, and link with D:YAML using the ``-L-l`` option. On Windows, the import -directory is used as the library directory. To link with the library on Windows, -just add the path to it relative to the current directory. +``-I`` option of DMD. The library directory should be where you put the compiled +D:YAML library. On Unix/Linux you can specify it using the ``-L-L`` option, and +link with D:YAML using the ``-L-l`` option. On Windows, the import directory is +used as the library directory. To link with the library on Windows, just add the +path to it relative to the current directory. -For example, if you extracted D:YAML to ``/home/xxx/dyaml`` and compiled it in -that directory, your project is in ``/home/xxx/dyaml-project``, and you are -currently in that directory, you can compile the project with the following -command on Unix/Linux:: +For example, if you extracted and compiled D:YAML in ``/home/xxx/dyaml``, your +project is in ``/home/xxx/dyaml-project``, and you are currently in that +directory, you can compile the project with the following command on Unix/Linux:: dmd -I../dyaml -L-L../dyaml -L-ldyaml main.d diff --git a/doc/html/_sources/tutorials/yaml_syntax.txt b/doc/html/_sources/tutorials/yaml_syntax.txt index 09fe3af..17eeb43 100644 --- a/doc/html/_sources/tutorials/yaml_syntax.txt +++ b/doc/html/_sources/tutorials/yaml_syntax.txt @@ -8,14 +8,14 @@ which this article is based on, `Chapter 2 of the YAML specification `_ or the `Wikipedia page `_. -YAML is a data serialization format designed to be as human readable as -possible. YAML is a recursive acronym for "YAML Ain't Markup Language". +YAML is a data serialization format designed for human readability. YAML is a +recursive acronym for "YAML Ain't Markup Language". YAML is similar to JSON, and in fact, JSON is a subset of YAML 1.2; but YAML has -some more advanced features and is easier to read. However, YAML is also more +some more advanced features and is easier to read. However, it is also more difficult to parse (and probably somewhat slower). Data is stored in mappings (associative arrays), sequences (lists) and scalars (single values). Data -structure hierarchy either depends on indentation (block context, similar to +structure hierarchy depends either on indentation (block context, similar to Python code), or nesting of brackets and braces (flow context, similar to JSON). YAML comments begin with ``#`` and continue until the end of line. @@ -25,8 +25,7 @@ Documents --------- A YAML stream consists of one or more documents starting with ``---`` and -optionally ending with ``...`` . If there is only one document, ``---`` can be -left out. +optionally ending with ``...`` . ``---`` can be left out for the first document. Single document with no explicit start or end: diff --git a/doc/html/_static/basic.css b/doc/html/_static/basic.css index 69f30d4..32630d5 100644 --- a/doc/html/_static/basic.css +++ b/doc/html/_static/basic.css @@ -4,7 +4,7 @@ * * Sphinx stylesheet -- basic theme. * - * :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ @@ -213,6 +213,24 @@ p.rubric { font-weight: bold; } +img.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + .align-left { text-align: left; } @@ -395,7 +413,7 @@ dl.glossary dt { } .footnote:target { - background-color: #ffa + background-color: #ffa; } .line-block { @@ -426,6 +444,7 @@ dl.glossary dt { pre { overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ } td.linenos pre { diff --git a/doc/html/_static/default.css b/doc/html/_static/default.css index 61edbc0..58facc6 100644 --- a/doc/html/_static/default.css +++ b/doc/html/_static/default.css @@ -4,7 +4,7 @@ * * Sphinx stylesheet -- default theme. * - * :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ @@ -114,6 +114,7 @@ div.sphinxsidebar input { } + /* -- hyperlink styles ------------------------------------------------------ */ a { diff --git a/doc/html/_static/doctools.js b/doc/html/_static/doctools.js index eeea95e..8b9bd2c 100644 --- a/doc/html/_static/doctools.js +++ b/doc/html/_static/doctools.js @@ -4,7 +4,7 @@ * * Sphinx JavaScript utilties for all documentation. * - * :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ diff --git a/doc/html/_static/file.png b/doc/html/_static/file.png index d18082e397e7e54f20721af768c4c2983258f1b4..4d6c7e7768fedd6d181e4eab4f3c32233834d64e 100644 GIT binary patch delta 296 zcmV+@0oVSB1GoZ^8Gi!+001a04^sdD0B=xCR7C&)0D*ylm6es5nVFT9m1uK>X>^8d zd5>*+l5TsFZhMn*pU;7TfrgBfiIk#=n5~JKu8Nwknz-1g!py+b#KgqJ#l^+O#>U6T z$Li|p>+9?6?CkCBW}0US|u z008`nFaa53ttH}+!91tw6?<><1lVO|pK|8hc61^ZT|eiCGF9(`)4f+1;qh67(fvDEhv1eJ8B5z|D(=6?jwT?@G*xx{!8|7v!a z`RAJ*84Ly&S(Y8pPKRL_o&yj?k!hWIP^Jc2 zYmy`>H54Tx^m@I@E>7_g1VJM~ot$D}kziJH5%|7eGw~f`7O*UGAGHtxw@&0P_ z3IJPcpX_XQxp8@XAxYJ=@cw!9I|0D(cF5_SAR>(4t^u$Ymtmj^o`nO-iXV{!3p~ Wt8{-jMt;Wt0000)[^>]*$|#([\w\-]+)$)/, + quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, // Check if a string has a non-whitespace character in it rnotwhite = /\S/, @@ -63,21 +65,23 @@ var jQuery = function( selector, context ) { rmsie = /(msie) ([\w.]+)/, rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/, + // Matches dashed string for camelizing + rdashAlpha = /-([a-z])/ig, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return letter.toUpperCase(); + }, + // Keep a UserAgent string for use with jQuery.browser userAgent = navigator.userAgent, // For matching the engine and version of the browser browserMatch, - // Has the ready events already been bound? - readyBound = false, - // The deferred used on DOM ready readyList, - // Promise methods - promiseMethods = "then done fail isResolved isRejected promise".split( " " ), - // The ready event handler DOMContentLoaded, @@ -113,7 +117,7 @@ jQuery.fn = jQuery.prototype = { if ( selector === "body" && !context && document.body ) { this.context = document; this[0] = document.body; - this.selector = "body"; + this.selector = selector; this.length = 1; return this; } @@ -121,7 +125,13 @@ jQuery.fn = jQuery.prototype = { // Handle HTML strings if ( typeof selector === "string" ) { // Are we dealing with HTML string or an ID? - match = quickExpr.exec( selector ); + if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = quickExpr.exec( selector ); + } // Verify a match, and that no context was specified for #id if ( match && (match[1] || !context) ) { @@ -202,7 +212,7 @@ jQuery.fn = jQuery.prototype = { selector: "", // The current version of jQuery being used - jquery: "1.5", + jquery: "1.6.2", // The default length of a jQuery object is 0 length: 0, @@ -313,7 +323,7 @@ jQuery.fn = jQuery.prototype = { jQuery.fn.init.prototype = jQuery.fn; jQuery.extend = jQuery.fn.extend = function() { - var options, name, src, copy, copyIsArray, clone, + var options, name, src, copy, copyIsArray, clone, target = arguments[0] || {}, i = 1, length = arguments.length, @@ -378,9 +388,11 @@ jQuery.extend = jQuery.fn.extend = function() { jQuery.extend({ noConflict: function( deep ) { - window.$ = _$; + if ( window.$ === jQuery ) { + window.$ = _$; + } - if ( deep ) { + if ( deep && window.jQuery === jQuery ) { window.jQuery = _jQuery; } @@ -394,15 +406,19 @@ jQuery.extend({ // the ready event fires. See #6781 readyWait: 1, + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + // Handle when the DOM is ready ready: function( wait ) { - // A third-party is pushing the ready event forwards - if ( wait === true ) { - jQuery.readyWait--; - } - - // Make sure that the DOM is not already loaded - if ( !jQuery.readyWait || (wait !== true && !jQuery.isReady) ) { + // Either a released hold or an DOMready/load event and not yet ready + if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) { // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). if ( !document.body ) { return setTimeout( jQuery.ready, 1 ); @@ -427,11 +443,11 @@ jQuery.extend({ }, bindReady: function() { - if ( readyBound ) { + if ( readyList ) { return; } - readyBound = true; + readyList = jQuery._Deferred(); // Catch cases where $(document).ready() is called after the // browser event has already occurred. @@ -452,7 +468,7 @@ jQuery.extend({ } else if ( document.attachEvent ) { // ensure firing before onload, // maybe late but safe also for iframes - document.attachEvent("onreadystatechange", DOMContentLoaded); + document.attachEvent( "onreadystatechange", DOMContentLoaded ); // A fallback to window.onload, that will always work window.attachEvent( "onload", jQuery.ready ); @@ -540,20 +556,21 @@ jQuery.extend({ // Make sure leading/trailing whitespace is removed (IE can't handle it) data = jQuery.trim( data ); + // Attempt to parse using the native JSON parser first + if ( window.JSON && window.JSON.parse ) { + return window.JSON.parse( data ); + } + // Make sure the incoming data is actual JSON // Logic borrowed from http://json.org/json2.js - if ( rvalidchars.test(data.replace(rvalidescape, "@") - .replace(rvalidtokens, "]") - .replace(rvalidbraces, "")) ) { + if ( rvalidchars.test( data.replace( rvalidescape, "@" ) + .replace( rvalidtokens, "]" ) + .replace( rvalidbraces, "")) ) { - // Try to use the native JSON parser first - return window.JSON && window.JSON.parse ? - window.JSON.parse( data ) : - (new Function("return " + data))(); + return (new Function( "return " + data ))(); - } else { - jQuery.error( "Invalid JSON: " + data ); } + jQuery.error( "Invalid JSON: " + data ); }, // Cross-browser xml parsing @@ -580,29 +597,26 @@ jQuery.extend({ noop: function() {}, - // Evalulates a script in a global context + // Evaluates a script in a global context + // Workarounds based on findings by Jim Driscoll + // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context globalEval: function( data ) { - if ( data && rnotwhite.test(data) ) { - // Inspired by code by Andrea Giammarchi - // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html - var head = document.getElementsByTagName("head")[0] || document.documentElement, - script = document.createElement("script"); - - script.type = "text/javascript"; - - if ( jQuery.support.scriptEval() ) { - script.appendChild( document.createTextNode( data ) ); - } else { - script.text = data; - } - - // Use insertBefore instead of appendChild to circumvent an IE6 bug. - // This arises when a base node is used (#2709). - head.insertBefore( script, head.firstChild ); - head.removeChild( script ); + if ( data && rnotwhite.test( data ) ) { + // We use execScript on Internet Explorer + // We use an anonymous function so that context is window + // rather than jQuery in Firefox + ( window.execScript || function( data ) { + window[ "eval" ].call( window, data ); + } )( data ); } }, + // Converts a dashed string to camelCased string; + // Used by both the css and data modules + camelCase: function( string ) { + return string.replace( rdashAlpha, fcamelCase ); + }, + nodeName: function( elem, name ) { return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); }, @@ -611,7 +625,7 @@ jQuery.extend({ each: function( object, callback, args ) { var name, i = 0, length = object.length, - isObj = length === undefined || jQuery.isFunction(object); + isObj = length === undefined || jQuery.isFunction( object ); if ( args ) { if ( isObj ) { @@ -637,8 +651,11 @@ jQuery.extend({ } } } else { - for ( var value = object[0]; - i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {} + for ( ; i < length; ) { + if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) { + break; + } + } } } @@ -669,7 +686,7 @@ jQuery.extend({ // The extra typeof function check is to prevent crashes // in Safari 2 (See: #3039) // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 - var type = jQuery.type(array); + var type = jQuery.type( array ); if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) { push.call( ret, array ); @@ -682,8 +699,9 @@ jQuery.extend({ }, inArray: function( elem, array ) { - if ( array.indexOf ) { - return array.indexOf( elem ); + + if ( indexOf ) { + return indexOf.call( array, elem ); } for ( var i = 0, length = array.length; i < length; i++ ) { @@ -733,15 +751,30 @@ jQuery.extend({ // arg is for internal usage only map: function( elems, callback, arg ) { - var ret = [], value; + var value, key, ret = [], + i = 0, + length = elems.length, + // jquery objects are treated as arrays + isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ; // Go through the array, translating each of the items to their - // new value (or values). - for ( var i = 0, length = elems.length; i < length; i++ ) { - value = callback( elems[ i ], i, arg ); + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); - if ( value != null ) { - ret[ ret.length ] = value; + if ( value != null ) { + ret[ ret.length ] = value; + } + } + + // Go through every key on the object, + } else { + for ( key in elems ) { + value = callback( elems[ key ], key, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } } } @@ -752,36 +785,35 @@ jQuery.extend({ // A global GUID counter for objects guid: 1, - proxy: function( fn, proxy, thisObject ) { - if ( arguments.length === 2 ) { - if ( typeof proxy === "string" ) { - thisObject = fn; - fn = thisObject[ proxy ]; - proxy = undefined; - - } else if ( proxy && !jQuery.isFunction( proxy ) ) { - thisObject = proxy; - proxy = undefined; - } + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + if ( typeof context === "string" ) { + var tmp = fn[ context ]; + context = fn; + fn = tmp; } - if ( !proxy && fn ) { + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + var args = slice.call( arguments, 2 ), proxy = function() { - return fn.apply( thisObject || this, arguments ); + return fn.apply( context, args.concat( slice.call( arguments ) ) ); }; - } // Set the guid of unique handler to the same of original handler, so it can be removed - if ( fn ) { - proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; - } + proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; - // So proxy can be declared as an argument return proxy; }, // Mutifunctional method to get and set values to a collection - // The value/s can be optionally by executed if its a function + // The value/s can optionally be executed if it's a function access: function( elems, key, value, exec, fn, pass ) { var length = elems.length; @@ -813,155 +845,6 @@ jQuery.extend({ return (new Date()).getTime(); }, - // Create a simple deferred (one callbacks list) - _Deferred: function() { - var // callbacks list - callbacks = [], - // stored [ context , args ] - fired, - // to avoid firing when already doing so - firing, - // flag to know if the deferred has been cancelled - cancelled, - // the deferred itself - deferred = { - - // done( f1, f2, ...) - done: function() { - if ( !cancelled ) { - var args = arguments, - i, - length, - elem, - type, - _fired; - if ( fired ) { - _fired = fired; - fired = 0; - } - for ( i = 0, length = args.length; i < length; i++ ) { - elem = args[ i ]; - type = jQuery.type( elem ); - if ( type === "array" ) { - deferred.done.apply( deferred, elem ); - } else if ( type === "function" ) { - callbacks.push( elem ); - } - } - if ( _fired ) { - deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] ); - } - } - return this; - }, - - // resolve with given context and args - resolveWith: function( context, args ) { - if ( !cancelled && !fired && !firing ) { - firing = 1; - try { - while( callbacks[ 0 ] ) { - callbacks.shift().apply( context, args ); - } - } - finally { - fired = [ context, args ]; - firing = 0; - } - } - return this; - }, - - // resolve with this as context and given arguments - resolve: function() { - deferred.resolveWith( jQuery.isFunction( this.promise ) ? this.promise() : this, arguments ); - return this; - }, - - // Has this deferred been resolved? - isResolved: function() { - return !!( firing || fired ); - }, - - // Cancel - cancel: function() { - cancelled = 1; - callbacks = []; - return this; - } - }; - - return deferred; - }, - - // Full fledged deferred (two callbacks list) - Deferred: function( func ) { - var deferred = jQuery._Deferred(), - failDeferred = jQuery._Deferred(), - promise; - // Add errorDeferred methods, then and promise - jQuery.extend( deferred, { - then: function( doneCallbacks, failCallbacks ) { - deferred.done( doneCallbacks ).fail( failCallbacks ); - return this; - }, - fail: failDeferred.done, - rejectWith: failDeferred.resolveWith, - reject: failDeferred.resolve, - isRejected: failDeferred.isResolved, - // Get a promise for this deferred - // If obj is provided, the promise aspect is added to the object - promise: function( obj , i /* internal */ ) { - if ( obj == null ) { - if ( promise ) { - return promise; - } - promise = obj = {}; - } - i = promiseMethods.length; - while( i-- ) { - obj[ promiseMethods[ i ] ] = deferred[ promiseMethods[ i ] ]; - } - return obj; - } - } ); - // Make sure only one callback list will be used - deferred.then( failDeferred.cancel, deferred.cancel ); - // Unexpose cancel - delete deferred.cancel; - // Call given func if any - if ( func ) { - func.call( deferred, deferred ); - } - return deferred; - }, - - // Deferred helper - when: function( object ) { - var args = arguments, - length = args.length, - deferred = length <= 1 && object && jQuery.isFunction( object.promise ) ? - object : - jQuery.Deferred(), - promise = deferred.promise(), - resolveArray; - - if ( length > 1 ) { - resolveArray = new Array( length ); - jQuery.each( args, function( index, element ) { - jQuery.when( element ).then( function( value ) { - resolveArray[ index ] = arguments.length > 1 ? slice.call( arguments, 0 ) : value; - if( ! --length ) { - deferred.resolveWith( promise, resolveArray ); - } - }, deferred.reject ); - } ); - } else if ( deferred !== object ) { - deferred.resolve( object ); - } - return promise; - }, - // Use of jQuery.browser is frowned upon. // More details: http://docs.jquery.com/Utilities/jQuery.browser uaMatch: function( ua ) { @@ -977,32 +860,29 @@ jQuery.extend({ }, sub: function() { - function jQuerySubclass( selector, context ) { - return new jQuerySubclass.fn.init( selector, context ); + function jQuerySub( selector, context ) { + return new jQuerySub.fn.init( selector, context ); } - jQuery.extend( true, jQuerySubclass, this ); - jQuerySubclass.superclass = this; - jQuerySubclass.fn = jQuerySubclass.prototype = this(); - jQuerySubclass.fn.constructor = jQuerySubclass; - jQuerySubclass.subclass = this.subclass; - jQuerySubclass.fn.init = function init( selector, context ) { - if ( context && context instanceof jQuery && !(context instanceof jQuerySubclass) ) { - context = jQuerySubclass(context); + jQuery.extend( true, jQuerySub, this ); + jQuerySub.superclass = this; + jQuerySub.fn = jQuerySub.prototype = this(); + jQuerySub.fn.constructor = jQuerySub; + jQuerySub.sub = this.sub; + jQuerySub.fn.init = function init( selector, context ) { + if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) { + context = jQuerySub( context ); } - return jQuery.fn.init.call( this, selector, context, rootjQuerySubclass ); + return jQuery.fn.init.call( this, selector, context, rootjQuerySub ); }; - jQuerySubclass.fn.init.prototype = jQuerySubclass.fn; - var rootjQuerySubclass = jQuerySubclass(document); - return jQuerySubclass; + jQuerySub.fn.init.prototype = jQuerySub.fn; + var rootjQuerySub = jQuerySub(document); + return jQuerySub; }, browser: {} }); -// Create readyList deferred -readyList = jQuery._Deferred(); - // Populate the class2type map jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { class2type[ "[object " + name + "]" ] = name.toLowerCase(); @@ -1019,12 +899,6 @@ if ( jQuery.browser.webkit ) { jQuery.browser.safari = true; } -if ( indexOf ) { - jQuery.inArray = function( elem, array ) { - return indexOf.call( array, elem ); - }; -} - // IE doesn't match non-breaking spaces with \s if ( rnotwhite.test( "\xA0" ) ) { trimLeft = /^[\s\xA0]+/; @@ -1070,50 +944,267 @@ function doScrollCheck() { jQuery.ready(); } -// Expose jQuery to the global object -return (window.jQuery = window.$ = jQuery); +return jQuery; })(); -(function() { +var // Promise methods + promiseMethods = "done fail isResolved isRejected promise then always pipe".split( " " ), + // Static reference to slice + sliceDeferred = [].slice; - jQuery.support = {}; +jQuery.extend({ + // Create a simple deferred (one callbacks list) + _Deferred: function() { + var // callbacks list + callbacks = [], + // stored [ context , args ] + fired, + // to avoid firing when already doing so + firing, + // flag to know if the deferred has been cancelled + cancelled, + // the deferred itself + deferred = { - var div = document.createElement("div"); + // done( f1, f2, ...) + done: function() { + if ( !cancelled ) { + var args = arguments, + i, + length, + elem, + type, + _fired; + if ( fired ) { + _fired = fired; + fired = 0; + } + for ( i = 0, length = args.length; i < length; i++ ) { + elem = args[ i ]; + type = jQuery.type( elem ); + if ( type === "array" ) { + deferred.done.apply( deferred, elem ); + } else if ( type === "function" ) { + callbacks.push( elem ); + } + } + if ( _fired ) { + deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] ); + } + } + return this; + }, - div.style.display = "none"; - div.innerHTML = "
a"; + // resolve with given context and args + resolveWith: function( context, args ) { + if ( !cancelled && !fired && !firing ) { + // make sure args are available (#8421) + args = args || []; + firing = 1; + try { + while( callbacks[ 0 ] ) { + callbacks.shift().apply( context, args ); + } + } + finally { + fired = [ context, args ]; + firing = 0; + } + } + return this; + }, - var all = div.getElementsByTagName("*"), - a = div.getElementsByTagName("a")[0], - select = document.createElement("select"), - opt = select.appendChild( document.createElement("option") ); + // resolve with this as context and given arguments + resolve: function() { + deferred.resolveWith( this, arguments ); + return this; + }, + + // Has this deferred been resolved? + isResolved: function() { + return !!( firing || fired ); + }, + + // Cancel + cancel: function() { + cancelled = 1; + callbacks = []; + return this; + } + }; + + return deferred; + }, + + // Full fledged deferred (two callbacks list) + Deferred: function( func ) { + var deferred = jQuery._Deferred(), + failDeferred = jQuery._Deferred(), + promise; + // Add errorDeferred methods, then and promise + jQuery.extend( deferred, { + then: function( doneCallbacks, failCallbacks ) { + deferred.done( doneCallbacks ).fail( failCallbacks ); + return this; + }, + always: function() { + return deferred.done.apply( deferred, arguments ).fail.apply( this, arguments ); + }, + fail: failDeferred.done, + rejectWith: failDeferred.resolveWith, + reject: failDeferred.resolve, + isRejected: failDeferred.isResolved, + pipe: function( fnDone, fnFail ) { + return jQuery.Deferred(function( newDefer ) { + jQuery.each( { + done: [ fnDone, "resolve" ], + fail: [ fnFail, "reject" ] + }, function( handler, data ) { + var fn = data[ 0 ], + action = data[ 1 ], + returned; + if ( jQuery.isFunction( fn ) ) { + deferred[ handler ](function() { + returned = fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise().then( newDefer.resolve, newDefer.reject ); + } else { + newDefer[ action ]( returned ); + } + }); + } else { + deferred[ handler ]( newDefer[ action ] ); + } + }); + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + if ( obj == null ) { + if ( promise ) { + return promise; + } + promise = obj = {}; + } + var i = promiseMethods.length; + while( i-- ) { + obj[ promiseMethods[i] ] = deferred[ promiseMethods[i] ]; + } + return obj; + } + }); + // Make sure only one callback list will be used + deferred.done( failDeferred.cancel ).fail( deferred.cancel ); + // Unexpose cancel + delete deferred.cancel; + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + return deferred; + }, + + // Deferred helper + when: function( firstParam ) { + var args = arguments, + i = 0, + length = args.length, + count = length, + deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ? + firstParam : + jQuery.Deferred(); + function resolveFunc( i ) { + return function( value ) { + args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; + if ( !( --count ) ) { + // Strange bug in FF4: + // Values changed onto the arguments object sometimes end up as undefined values + // outside the $.when method. Cloning the object into a fresh array solves the issue + deferred.resolveWith( deferred, sliceDeferred.call( args, 0 ) ); + } + }; + } + if ( length > 1 ) { + for( ; i < length; i++ ) { + if ( args[ i ] && jQuery.isFunction( args[ i ].promise ) ) { + args[ i ].promise().then( resolveFunc(i), deferred.reject ); + } else { + --count; + } + } + if ( !count ) { + deferred.resolveWith( deferred, args ); + } + } else if ( deferred !== firstParam ) { + deferred.resolveWith( deferred, length ? [ firstParam ] : [] ); + } + return deferred.promise(); + } +}); + + + +jQuery.support = (function() { + + var div = document.createElement( "div" ), + documentElement = document.documentElement, + all, + a, + select, + opt, + input, + marginDiv, + support, + fragment, + body, + testElementParent, + testElement, + testElementStyle, + tds, + events, + eventName, + i, + isSupported; + + // Preliminary tests + div.setAttribute("className", "t"); + div.innerHTML = "
a"; + + all = div.getElementsByTagName( "*" ); + a = div.getElementsByTagName( "a" )[ 0 ]; // Can't get basic test support if ( !all || !all.length || !a ) { - return; + return {}; } - jQuery.support = { + // First batch of supports tests + select = document.createElement( "select" ); + opt = select.appendChild( document.createElement("option") ); + input = div.getElementsByTagName( "input" )[ 0 ]; + + support = { // IE strips leading whitespace when .innerHTML is used - leadingWhitespace: div.firstChild.nodeType === 3, + leadingWhitespace: ( div.firstChild.nodeType === 3 ), // Make sure that tbody elements aren't automatically inserted // IE will insert them into empty tables - tbody: !div.getElementsByTagName("tbody").length, + tbody: !div.getElementsByTagName( "tbody" ).length, // Make sure that link elements get serialized correctly by innerHTML // This requires a wrapper element in IE - htmlSerialize: !!div.getElementsByTagName("link").length, + htmlSerialize: !!div.getElementsByTagName( "link" ).length, // Get the style information from getAttribute - // (IE uses .cssText insted) - style: /red/.test( a.getAttribute("style") ), + // (IE uses .cssText instead) + style: /top/.test( a.getAttribute("style") ), // Make sure that URLs aren't manipulated // (IE normalizes it by default) - hrefNormalized: a.getAttribute("href") === "/a", + hrefNormalized: ( a.getAttribute( "href" ) === "/a" ), // Make sure that element opacity exists // (IE uses filter instead) @@ -1127,177 +1218,193 @@ return (window.jQuery = window.$ = jQuery); // Make sure that if no value is specified for a checkbox // that it defaults to "on". // (WebKit defaults to "" instead) - checkOn: div.getElementsByTagName("input")[0].value === "on", + checkOn: ( input.value === "on" ), // Make sure that a selected-by-default option has a working selected property. // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) optSelected: opt.selected, + // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) + getSetAttribute: div.className !== "t", + // Will be defined later + submitBubbles: true, + changeBubbles: true, + focusinBubbles: false, deleteExpando: true, - optDisabled: false, - checkClone: false, - _scriptEval: null, noCloneEvent: true, - boxModel: null, inlineBlockNeedsLayout: false, shrinkWrapBlocks: false, - reliableHiddenOffsets: true + reliableMarginRight: true }; + // Make sure checked status is properly cloned + input.checked = true; + support.noCloneChecked = input.cloneNode( true ).checked; + // Make sure that the options inside disabled selects aren't marked as disabled - // (WebKit marks them as diabled) + // (WebKit marks them as disabled) select.disabled = true; - jQuery.support.optDisabled = !opt.disabled; - - jQuery.support.scriptEval = function() { - if ( jQuery.support._scriptEval === null ) { - var root = document.documentElement, - script = document.createElement("script"), - id = "script" + jQuery.now(); - - script.type = "text/javascript"; - try { - script.appendChild( document.createTextNode( "window." + id + "=1;" ) ); - } catch(e) {} - - root.insertBefore( script, root.firstChild ); - - // Make sure that the execution of code works by injecting a script - // tag with appendChild/createTextNode - // (IE doesn't support this, fails, and uses .text instead) - if ( window[ id ] ) { - jQuery.support._scriptEval = true; - delete window[ id ]; - } else { - jQuery.support._scriptEval = false; - } - - root.removeChild( script ); - // release memory in IE - root = script = id = null; - } - - return jQuery.support._scriptEval; - }; + support.optDisabled = !opt.disabled; // Test to see if it's possible to delete an expando from an element // Fails in Internet Explorer try { delete div.test; - - } catch(e) { - jQuery.support.deleteExpando = false; + } catch( e ) { + support.deleteExpando = false; } - if ( div.attachEvent && div.fireEvent ) { - div.attachEvent("onclick", function click() { + if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { + div.attachEvent( "onclick", function() { // Cloning a node shouldn't copy over any // bound event handlers (IE does this) - jQuery.support.noCloneEvent = false; - div.detachEvent("onclick", click); + support.noCloneEvent = false; }); - div.cloneNode(true).fireEvent("onclick"); + div.cloneNode( true ).fireEvent( "onclick" ); } - div = document.createElement("div"); - div.innerHTML = ""; + // Check if a radio maintains it's value + // after being appended to the DOM + input = document.createElement("input"); + input.value = "t"; + input.setAttribute("type", "radio"); + support.radioValue = input.value === "t"; - var fragment = document.createDocumentFragment(); + input.setAttribute("checked", "checked"); + div.appendChild( input ); + fragment = document.createDocumentFragment(); fragment.appendChild( div.firstChild ); // WebKit doesn't clone checked state correctly in fragments - jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked; + support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; + + div.innerHTML = ""; // Figure out if the W3C box model works as expected - // document.body must exist before we can do this - jQuery(function() { - var div = document.createElement("div"), - body = document.getElementsByTagName("body")[0]; + div.style.width = div.style.paddingLeft = "1px"; - // Frameset documents with no body should not run this code - if ( !body ) { - return; - } + body = document.getElementsByTagName( "body" )[ 0 ]; + // We use our own, invisible, body unless the body is already present + // in which case we use a div (#9239) + testElement = document.createElement( body ? "div" : "body" ); + testElementStyle = { + visibility: "hidden", + width: 0, + height: 0, + border: 0, + margin: 0 + }; + if ( body ) { + jQuery.extend( testElementStyle, { + position: "absolute", + left: -1000, + top: -1000 + }); + } + for ( i in testElementStyle ) { + testElement.style[ i ] = testElementStyle[ i ]; + } + testElement.appendChild( div ); + testElementParent = body || documentElement; + testElementParent.insertBefore( testElement, testElementParent.firstChild ); - div.style.width = div.style.paddingLeft = "1px"; - body.appendChild( div ); - jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2; + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + support.appendChecked = input.checked; - if ( "zoom" in div.style ) { - // Check if natively block-level elements act like inline-block - // elements when setting their display to 'inline' and giving - // them layout - // (IE < 8 does this) - div.style.display = "inline"; - div.style.zoom = 1; - jQuery.support.inlineBlockNeedsLayout = div.offsetWidth === 2; + support.boxModel = div.offsetWidth === 2; - // Check if elements with layout shrink-wrap their children - // (IE 6 does this) - div.style.display = ""; - div.innerHTML = "
"; - jQuery.support.shrinkWrapBlocks = div.offsetWidth !== 2; - } + if ( "zoom" in div.style ) { + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + // (IE < 8 does this) + div.style.display = "inline"; + div.style.zoom = 1; + support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 ); - div.innerHTML = "
t
"; - var tds = div.getElementsByTagName("td"); + // Check if elements with layout shrink-wrap their children + // (IE 6 does this) + div.style.display = ""; + div.innerHTML = "
"; + support.shrinkWrapBlocks = ( div.offsetWidth !== 2 ); + } - // Check if table cells still have offsetWidth/Height when they are set - // to display:none and there are still other visible table cells in a - // table row; if so, offsetWidth/Height are not reliable for use when - // determining if an element has been hidden directly using - // display:none (it is still safe to use offsets if a parent element is - // hidden; don safety goggles and see bug #4512 for more information). - // (only IE 8 fails this test) - jQuery.support.reliableHiddenOffsets = tds[0].offsetHeight === 0; + div.innerHTML = "
t
"; + tds = div.getElementsByTagName( "td" ); - tds[0].style.display = ""; - tds[1].style.display = "none"; + // Check if table cells still have offsetWidth/Height when they are set + // to display:none and there are still other visible table cells in a + // table row; if so, offsetWidth/Height are not reliable for use when + // determining if an element has been hidden directly using + // display:none (it is still safe to use offsets if a parent element is + // hidden; don safety goggles and see bug #4512 for more information). + // (only IE 8 fails this test) + isSupported = ( tds[ 0 ].offsetHeight === 0 ); - // Check if empty table cells still have offsetWidth/Height - // (IE < 8 fail this test) - jQuery.support.reliableHiddenOffsets = jQuery.support.reliableHiddenOffsets && tds[0].offsetHeight === 0; - div.innerHTML = ""; + tds[ 0 ].style.display = ""; + tds[ 1 ].style.display = "none"; - body.removeChild( div ).style.display = "none"; - div = tds = null; - }); + // Check if empty table cells still have offsetWidth/Height + // (IE < 8 fail this test) + support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); + div.innerHTML = ""; + + // Check if div with explicit width and no margin-right incorrectly + // gets computed margin-right based on width of container. For more + // info see bug #3333 + // Fails in WebKit before Feb 2011 nightlies + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + if ( document.defaultView && document.defaultView.getComputedStyle ) { + marginDiv = document.createElement( "div" ); + marginDiv.style.width = "0"; + marginDiv.style.marginRight = "0"; + div.appendChild( marginDiv ); + support.reliableMarginRight = + ( parseInt( ( document.defaultView.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0; + } + + // Remove the body element we added + testElement.innerHTML = ""; + testElementParent.removeChild( testElement ); // Technique from Juriy Zaytsev // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/ - var eventSupported = function( eventName ) { - var el = document.createElement("div"); - eventName = "on" + eventName; - - // We only care about the case where non-standard event systems - // are used, namely in IE. Short-circuiting here helps us to - // avoid an eval call (in setAttribute) which can cause CSP - // to go haywire. See: https://developer.mozilla.org/en/Security/CSP - if ( !el.attachEvent ) { - return true; + // We only care about the case where non-standard event systems + // are used, namely in IE. Short-circuiting here helps us to + // avoid an eval call (in setAttribute) which can cause CSP + // to go haywire. See: https://developer.mozilla.org/en/Security/CSP + if ( div.attachEvent ) { + for( i in { + submit: 1, + change: 1, + focusin: 1 + } ) { + eventName = "on" + i; + isSupported = ( eventName in div ); + if ( !isSupported ) { + div.setAttribute( eventName, "return;" ); + isSupported = ( typeof div[ eventName ] === "function" ); + } + support[ i + "Bubbles" ] = isSupported; } + } - var isSupported = (eventName in el); - if ( !isSupported ) { - el.setAttribute(eventName, "return;"); - isSupported = typeof el[eventName] === "function"; - } - el = null; + // Null connected elements to avoid leaks in IE + testElement = fragment = select = opt = body = marginDiv = div = input = null; - return isSupported; - }; - - jQuery.support.submitBubbles = eventSupported("submit"); - jQuery.support.changeBubbles = eventSupported("change"); - - // release memory in IE - div = all = a = null; + return support; })(); +// Keep track of boxModel +jQuery.boxModel = jQuery.support.boxModel; -var rbrace = /^(?:\{.*\}|\[.*\])$/; + + +var rbrace = /^(?:\{.*\}|\[.*\])$/, + rmultiDash = /([a-z])([A-Z])/g; jQuery.extend({ cache: {}, @@ -1321,7 +1428,7 @@ jQuery.extend({ hasData: function( elem ) { elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; - return !!elem && !jQuery.isEmptyObject(elem); + return !!elem && !isEmptyDataObject( elem ); }, data: function( elem, name, data, pvt /* Internal Use Only */ ) { @@ -1361,11 +1468,18 @@ jQuery.extend({ if ( !cache[ id ] ) { cache[ id ] = {}; + + // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery + // metadata on plain JS objects when the object is serialized using + // JSON.stringify + if ( !isNode ) { + cache[ id ].toJSON = jQuery.noop; + } } // An object can be passed to jQuery.data instead of a key/value pair; this gets // shallow copied over onto the existing cache - if ( typeof name === "object" ) { + if ( typeof name === "object" || typeof name === "function" ) { if ( pvt ) { cache[ id ][ internalKey ] = jQuery.extend(cache[ id ][ internalKey ], name); } else { @@ -1387,7 +1501,7 @@ jQuery.extend({ } if ( data !== undefined ) { - thisCache[ name ] = data; + thisCache[ jQuery.camelCase( name ) ] = data; } // TODO: This is a hack for 1.5 ONLY. It will be removed in 1.6. Users should @@ -1397,7 +1511,10 @@ jQuery.extend({ return thisCache[ internalKey ] && thisCache[ internalKey ].events; } - return getByName ? thisCache[ name ] : thisCache; + return getByName ? + // Check for both converted-to-camel and non-converted data property names + thisCache[ jQuery.camelCase( name ) ] || thisCache[ name ] : + thisCache; }, removeData: function( elem, name, pvt /* Internal Use Only */ ) { @@ -1427,7 +1544,7 @@ jQuery.extend({ // If there is no data left in the cache, we want to continue // and let the cache object itself get destroyed - if ( !jQuery.isEmptyObject(thisCache) ) { + if ( !isEmptyDataObject(thisCache) ) { return; } } @@ -1439,7 +1556,7 @@ jQuery.extend({ // Don't destroy the parent cache unless the internal data object // had been the only thing left in it - if ( !jQuery.isEmptyObject(cache[ id ]) ) { + if ( !isEmptyDataObject(cache[ id ]) ) { return; } } @@ -1460,6 +1577,13 @@ jQuery.extend({ // data if it existed if ( internalCache ) { cache[ id ] = {}; + // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery + // metadata on plain JS objects when the object is serialized using + // JSON.stringify + if ( !isNode ) { + cache[ id ].toJSON = jQuery.noop; + } + cache[ id ][ internalKey ] = internalCache; // Otherwise, we need to eliminate the expando on the node to avoid @@ -1506,12 +1630,13 @@ jQuery.fn.extend({ data = jQuery.data( this[0] ); if ( this[0].nodeType === 1 ) { - var attr = this[0].attributes, name; + var attr = this[0].attributes, name; for ( var i = 0, l = attr.length; i < l; i++ ) { name = attr[i].name; if ( name.indexOf( "data-" ) === 0 ) { - name = name.substr( 5 ); + name = jQuery.camelCase( name.substring(5) ); + dataAttr( this[0], name, data[ name ] ); } } @@ -1565,7 +1690,9 @@ function dataAttr( elem, key, data ) { // If nothing was found internally, try to fetch any // data from the HTML5 data-* attribute if ( data === undefined && elem.nodeType === 1 ) { - data = elem.getAttribute( "data-" + key ); + var name = "data-" + key.replace( rmultiDash, "$1-$2" ).toLowerCase(); + + data = elem.getAttribute( name ); if ( typeof data === "string" ) { try { @@ -1588,38 +1715,92 @@ function dataAttr( elem, key, data ) { return data; } +// TODO: This is a hack for 1.5 ONLY to allow objects with a single toJSON +// property to be considered empty objects; this property always exists in +// order to make sure JSON.stringify does not expose internal metadata +function isEmptyDataObject( obj ) { + for ( var name in obj ) { + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} + +function handleQueueMarkDefer( elem, type, src ) { + var deferDataKey = type + "defer", + queueDataKey = type + "queue", + markDataKey = type + "mark", + defer = jQuery.data( elem, deferDataKey, undefined, true ); + if ( defer && + ( src === "queue" || !jQuery.data( elem, queueDataKey, undefined, true ) ) && + ( src === "mark" || !jQuery.data( elem, markDataKey, undefined, true ) ) ) { + // Give room for hard-coded callbacks to fire first + // and eventually mark/queue something else on the element + setTimeout( function() { + if ( !jQuery.data( elem, queueDataKey, undefined, true ) && + !jQuery.data( elem, markDataKey, undefined, true ) ) { + jQuery.removeData( elem, deferDataKey, true ); + defer.resolve(); + } + }, 0 ); + } +} + jQuery.extend({ - queue: function( elem, type, data ) { - if ( !elem ) { - return; + + _mark: function( elem, type ) { + if ( elem ) { + type = (type || "fx") + "mark"; + jQuery.data( elem, type, (jQuery.data(elem,type,undefined,true) || 0) + 1, true ); } + }, - type = (type || "fx") + "queue"; - var q = jQuery._data( elem, type ); + _unmark: function( force, elem, type ) { + if ( force !== true ) { + type = elem; + elem = force; + force = false; + } + if ( elem ) { + type = type || "fx"; + var key = type + "mark", + count = force ? 0 : ( (jQuery.data( elem, key, undefined, true) || 1 ) - 1 ); + if ( count ) { + jQuery.data( elem, key, count, true ); + } else { + jQuery.removeData( elem, key, true ); + handleQueueMarkDefer( elem, type, "mark" ); + } + } + }, - // Speed up dequeue by getting out quickly if this is just a lookup - if ( !data ) { + queue: function( elem, type, data ) { + if ( elem ) { + type = (type || "fx") + "queue"; + var q = jQuery.data( elem, type, undefined, true ); + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !q || jQuery.isArray(data) ) { + q = jQuery.data( elem, type, jQuery.makeArray(data), true ); + } else { + q.push( data ); + } + } return q || []; } - - if ( !q || jQuery.isArray(data) ) { - q = jQuery._data( elem, type, jQuery.makeArray(data) ); - - } else { - q.push( data ); - } - - return q; }, dequeue: function( elem, type ) { type = type || "fx"; var queue = jQuery.queue( elem, type ), - fn = queue.shift(); + fn = queue.shift(), + defer; // If the fx queue is dequeued, always remove the progress sentinel if ( fn === "inprogress" ) { @@ -1640,6 +1821,7 @@ jQuery.extend({ if ( !queue.length ) { jQuery.removeData( elem, type + "queue", true ); + handleQueueMarkDefer( elem, type, "queue" ); } } }); @@ -1654,7 +1836,7 @@ jQuery.fn.extend({ if ( data === undefined ) { return jQuery.queue( this[0], type ); } - return this.each(function( i ) { + return this.each(function() { var queue = jQuery.queue( this, type, data ); if ( type === "fx" && queue[0] !== "inprogress" ) { @@ -1667,7 +1849,6 @@ jQuery.fn.extend({ jQuery.dequeue( this, type ); }); }, - // Based off of the plugin by Clint Helfers, with permission. // http://blindsignals.com/index.php/2009/07/jquery-delay/ delay: function( time, type ) { @@ -1681,9 +1862,41 @@ jQuery.fn.extend({ }, time ); }); }, - clearQueue: function( type ) { return this.queue( type || "fx", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, object ) { + if ( typeof type !== "string" ) { + object = type; + type = undefined; + } + type = type || "fx"; + var defer = jQuery.Deferred(), + elements = this, + i = elements.length, + count = 1, + deferDataKey = type + "defer", + queueDataKey = type + "queue", + markDataKey = type + "mark", + tmp; + function resolve() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + } + while( i-- ) { + if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) || + ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) || + jQuery.data( elements[ i ], markDataKey, undefined, true ) ) && + jQuery.data( elements[ i ], deferDataKey, jQuery._Deferred(), true ) )) { + count++; + tmp.done( resolve ); + } + } + resolve(); + return defer.promise(); } }); @@ -1691,66 +1904,67 @@ jQuery.fn.extend({ var rclass = /[\n\t\r]/g, - rspaces = /\s+/, + rspace = /\s+/, rreturn = /\r/g, - rspecialurl = /^(?:href|src|style)$/, rtype = /^(?:button|input)$/i, rfocusable = /^(?:button|input|object|select|textarea)$/i, rclickable = /^a(?:rea)?$/i, - rradiocheck = /^(?:radio|checkbox)$/i; - -jQuery.props = { - "for": "htmlFor", - "class": "className", - readonly: "readOnly", - maxlength: "maxLength", - cellspacing: "cellSpacing", - rowspan: "rowSpan", - colspan: "colSpan", - tabindex: "tabIndex", - usemap: "useMap", - frameborder: "frameBorder" -}; + rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, + rinvalidChar = /\:|^on/, + formHook, boolHook; jQuery.fn.extend({ attr: function( name, value ) { return jQuery.access( this, name, value, true, jQuery.attr ); }, - removeAttr: function( name, fn ) { - return this.each(function(){ - jQuery.attr( this, name, "" ); - if ( this.nodeType === 1 ) { - this.removeAttribute( name ); - } + removeAttr: function( name ) { + return this.each(function() { + jQuery.removeAttr( this, name ); + }); + }, + + prop: function( name, value ) { + return jQuery.access( this, name, value, true, jQuery.prop ); + }, + + removeProp: function( name ) { + name = jQuery.propFix[ name ] || name; + return this.each(function() { + // try/catch handles cases where IE balks (such as removing a property on window) + try { + this[ name ] = undefined; + delete this[ name ]; + } catch( e ) {} }); }, addClass: function( value ) { - if ( jQuery.isFunction(value) ) { - return this.each(function(i) { - var self = jQuery(this); - self.addClass( value.call(this, i, self.attr("class")) ); + var classNames, i, l, elem, + setClass, c, cl; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).addClass( value.call(this, j, this.className) ); }); } if ( value && typeof value === "string" ) { - var classNames = (value || "").split( rspaces ); + classNames = value.split( rspace ); - for ( var i = 0, l = this.length; i < l; i++ ) { - var elem = this[i]; + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; if ( elem.nodeType === 1 ) { - if ( !elem.className ) { + if ( !elem.className && classNames.length === 1 ) { elem.className = value; } else { - var className = " " + elem.className + " ", - setClass = elem.className; + setClass = " " + elem.className + " "; - for ( var c = 0, cl = classNames.length; c < cl; c++ ) { - if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) { - setClass += " " + classNames[c]; + for ( c = 0, cl = classNames.length; c < cl; c++ ) { + if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) { + setClass += classNames[ c ] + " "; } } elem.className = jQuery.trim( setClass ); @@ -1763,24 +1977,25 @@ jQuery.fn.extend({ }, removeClass: function( value ) { - if ( jQuery.isFunction(value) ) { - return this.each(function(i) { - var self = jQuery(this); - self.removeClass( value.call(this, i, self.attr("class")) ); + var classNames, i, l, elem, className, c, cl; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).removeClass( value.call(this, j, this.className) ); }); } if ( (value && typeof value === "string") || value === undefined ) { - var classNames = (value || "").split( rspaces ); + classNames = (value || "").split( rspace ); - for ( var i = 0, l = this.length; i < l; i++ ) { - var elem = this[i]; + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; if ( elem.nodeType === 1 && elem.className ) { if ( value ) { - var className = (" " + elem.className + " ").replace(rclass, " "); - for ( var c = 0, cl = classNames.length; c < cl; c++ ) { - className = className.replace(" " + classNames[c] + " ", " "); + className = (" " + elem.className + " ").replace( rclass, " " ); + for ( c = 0, cl = classNames.length; c < cl; c++ ) { + className = className.replace(" " + classNames[ c ] + " ", " "); } elem.className = jQuery.trim( className ); @@ -1799,9 +2014,8 @@ jQuery.fn.extend({ isBool = typeof stateVal === "boolean"; if ( jQuery.isFunction( value ) ) { - return this.each(function(i) { - var self = jQuery(this); - self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal ); + return this.each(function( i ) { + jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); }); } @@ -1812,7 +2026,7 @@ jQuery.fn.extend({ i = 0, self = jQuery( this ), state = stateVal, - classNames = value.split( rspaces ); + classNames = value.split( rspace ); while ( (className = classNames[ i++ ]) ) { // check each className given, space seperated list @@ -1844,77 +2058,42 @@ jQuery.fn.extend({ }, val: function( value ) { + var hooks, ret, + elem = this[0]; + if ( !arguments.length ) { - var elem = this[0]; - if ( elem ) { - if ( jQuery.nodeName( elem, "option" ) ) { - // attributes.value is undefined in Blackberry 4.7 but - // uses .value. See #6932 - var val = elem.attributes.value; - return !val || val.specified ? elem.value : elem.text; + hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ]; + + if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { + return ret; } - // We need to handle select boxes special - if ( jQuery.nodeName( elem, "select" ) ) { - var index = elem.selectedIndex, - values = [], - options = elem.options, - one = elem.type === "select-one"; - - // Nothing was selected - if ( index < 0 ) { - return null; - } - - // Loop through all the selected options - for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) { - var option = options[ i ]; - - // Don't return options that are disabled or in a disabled optgroup - if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && - (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) { - - // Get the specific value for the option - value = jQuery(option).val(); - - // We don't need an array for one selects - if ( one ) { - return value; - } - - // Multi-Selects return an array - values.push( value ); - } - } - - return values; - } - - // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified - if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) { - return elem.getAttribute("value") === null ? "on" : elem.value; - } - - // Everything else, we just grab the value - return (elem.value || "").replace(rreturn, ""); + ret = elem.value; + return typeof ret === "string" ? + // handle most common string cases + ret.replace(rreturn, "") : + // handle cases where value is null/undef or number + ret == null ? "" : ret; } return undefined; } - var isFunction = jQuery.isFunction(value); + var isFunction = jQuery.isFunction( value ); - return this.each(function(i) { - var self = jQuery(this), val = value; + return this.each(function( i ) { + var self = jQuery(this), val; if ( this.nodeType !== 1 ) { return; } if ( isFunction ) { - val = value.call(this, i, self.val()); + val = value.call( this, i, self.val() ); + } else { + val = value; } // Treat null/undefined as ""; convert numbers to string @@ -1922,27 +2101,16 @@ jQuery.fn.extend({ val = ""; } else if ( typeof val === "number" ) { val += ""; - } else if ( jQuery.isArray(val) ) { - val = jQuery.map(val, function (value) { + } else if ( jQuery.isArray( val ) ) { + val = jQuery.map(val, function ( value ) { return value == null ? "" : value + ""; }); } - if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) { - this.checked = jQuery.inArray( self.val(), val ) >= 0; + hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ]; - } else if ( jQuery.nodeName( this, "select" ) ) { - var values = jQuery.makeArray(val); - - jQuery( "option", this ).each(function() { - this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; - }); - - if ( !values.length ) { - this.selectedIndex = -1; - } - - } else { + // If set returns undefined, fall back to normal setting + if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { this.value = val; } }); @@ -1950,6 +2118,72 @@ jQuery.fn.extend({ }); jQuery.extend({ + valHooks: { + option: { + get: function( elem ) { + // attributes.value is undefined in Blackberry 4.7 but + // uses .value. See #6932 + var val = elem.attributes.value; + return !val || val.specified ? elem.value : elem.text; + } + }, + select: { + get: function( elem ) { + var value, + index = elem.selectedIndex, + values = [], + options = elem.options, + one = elem.type === "select-one"; + + // Nothing was selected + if ( index < 0 ) { + return null; + } + + // Loop through all the selected options + for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) { + var option = options[ i ]; + + // Don't return options that are disabled or in a disabled optgroup + if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && + (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + // Fixes Bug #2551 -- select.val() broken in IE after form.reset() + if ( one && !values.length && options.length ) { + return jQuery( options[ index ] ).val(); + } + + return values; + }, + + set: function( elem, value ) { + var values = jQuery.makeArray( value ); + + jQuery(elem).find("option").each(function() { + this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; + }); + + if ( !values.length ) { + elem.selectedIndex = -1; + } + return values; + } + } + }, + attrFn: { val: true, css: true, @@ -1960,115 +2194,340 @@ jQuery.extend({ height: true, offset: true }, - + + attrFix: { + // Always normalize to ensure hook usage + tabindex: "tabIndex" + }, + attr: function( elem, name, value, pass ) { + var nType = elem.nodeType; + // don't get/set attributes on text, comment and attribute nodes - if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || elem.nodeType === 2 ) { + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { return undefined; } if ( pass && name in jQuery.attrFn ) { - return jQuery(elem)[name](value); + return jQuery( elem )[ name ]( value ); } - var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ), - // Whether we are setting (or getting) - set = value !== undefined; + // Fallback to prop when attributes are not supported + if ( !("getAttribute" in elem) ) { + return jQuery.prop( elem, name, value ); + } - // Try to normalize/fix the name - name = notxml && jQuery.props[ name ] || name; + var ret, hooks, + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); - // Only do all the following if this is a node (faster for style) - if ( elem.nodeType === 1 ) { - // These attributes require special treatment - var special = rspecialurl.test( name ); + // Normalize the name if needed + if ( notxml ) { + name = jQuery.attrFix[ name ] || name; - // Safari mis-reports the default selected property of an option - // Accessing the parent's selectedIndex property fixes it - if ( name === "selected" && !jQuery.support.optSelected ) { - var parent = elem.parentNode; - if ( parent ) { - parent.selectedIndex; + hooks = jQuery.attrHooks[ name ]; - // Make sure that it also works with optgroups, see #5701 - if ( parent.parentNode ) { - parent.parentNode.selectedIndex; - } + if ( !hooks ) { + // Use boolHook for boolean attributes + if ( rboolean.test( name ) ) { + + hooks = boolHook; + + // Use formHook for forms and if the name contains certain characters + } else if ( formHook && name !== "className" && + (jQuery.nodeName( elem, "form" ) || rinvalidChar.test( name )) ) { + + hooks = formHook; } } + } - // If applicable, access the attribute via the DOM 0 way - // 'in' checks fail in Blackberry 4.7 #6931 - if ( (name in elem || elem[ name ] !== undefined) && notxml && !special ) { - if ( set ) { - // We can't allow the type property to be changed (since it causes problems in IE) - if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) { - jQuery.error( "type property can't be changed" ); - } + if ( value !== undefined ) { - if ( value === null ) { - if ( elem.nodeType === 1 ) { - elem.removeAttribute( name ); - } - - } else { - elem[ name ] = value; - } - } - - // browsers index elements by id/name on forms, give priority to attributes. - if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) { - return elem.getAttributeNode( name ).nodeValue; - } - - // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set - // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ - if ( name === "tabIndex" ) { - var attributeNode = elem.getAttributeNode( "tabIndex" ); - - return attributeNode && attributeNode.specified ? - attributeNode.value : - rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? - 0 : - undefined; - } - - return elem[ name ]; - } - - if ( !jQuery.support.style && notxml && name === "style" ) { - if ( set ) { - elem.style.cssText = "" + value; - } - - return elem.style.cssText; - } - - if ( set ) { - // convert the value to a string (all browsers do this but IE) see #1070 - elem.setAttribute( name, "" + value ); - } - - // Ensure that missing attributes return undefined - // Blackberry 4.7 returns "" from getAttribute #6938 - if ( !elem.attributes[ name ] && (elem.hasAttribute && !elem.hasAttribute( name )) ) { + if ( value === null ) { + jQuery.removeAttr( elem, name ); return undefined; + + } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + elem.setAttribute( name, "" + value ); + return value; } - var attr = !jQuery.support.hrefNormalized && notxml && special ? - // Some attributes require a special call on IE - elem.getAttribute( name, 2 ) : - elem.getAttribute( name ); + } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + + ret = elem.getAttribute( name ); // Non-existent attributes return null, we normalize to undefined - return attr === null ? undefined : attr; + return ret === null ? + undefined : + ret; } - // Handle everything which isn't a DOM element node - if ( set ) { - elem[ name ] = value; + }, + + removeAttr: function( elem, name ) { + var propName; + if ( elem.nodeType === 1 ) { + name = jQuery.attrFix[ name ] || name; + + if ( jQuery.support.getSetAttribute ) { + // Use removeAttribute in browsers that support it + elem.removeAttribute( name ); + } else { + jQuery.attr( elem, name, "" ); + elem.removeAttributeNode( elem.getAttributeNode( name ) ); + } + + // Set corresponding property to false for boolean attributes + if ( rboolean.test( name ) && (propName = jQuery.propFix[ name ] || name) in elem ) { + elem[ propName ] = false; + } } - return elem[ name ]; + }, + + attrHooks: { + type: { + set: function( elem, value ) { + // We can't allow the type property to be changed (since it causes problems in IE) + if ( rtype.test( elem.nodeName ) && elem.parentNode ) { + jQuery.error( "type property can't be changed" ); + } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { + // Setting the type on a radio button after the value resets the value in IE6-9 + // Reset value to it's default in case type is set after value + // This is for element creation + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + }, + tabIndex: { + get: function( elem ) { + // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set + // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + var attributeNode = elem.getAttributeNode("tabIndex"); + + return attributeNode && attributeNode.specified ? + parseInt( attributeNode.value, 10 ) : + rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? + 0 : + undefined; + } + }, + // Use the value property for back compat + // Use the formHook for button elements in IE6/7 (#1954) + value: { + get: function( elem, name ) { + if ( formHook && jQuery.nodeName( elem, "button" ) ) { + return formHook.get( elem, name ); + } + return name in elem ? + elem.value : + null; + }, + set: function( elem, value, name ) { + if ( formHook && jQuery.nodeName( elem, "button" ) ) { + return formHook.set( elem, value, name ); + } + // Does not return so that setAttribute is also used + elem.value = value; + } + } + }, + + propFix: { + tabindex: "tabIndex", + readonly: "readOnly", + "for": "htmlFor", + "class": "className", + maxlength: "maxLength", + cellspacing: "cellSpacing", + cellpadding: "cellPadding", + rowspan: "rowSpan", + colspan: "colSpan", + usemap: "useMap", + frameborder: "frameBorder", + contenteditable: "contentEditable" + }, + + prop: function( elem, name, value ) { + var nType = elem.nodeType; + + // don't get/set properties on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return undefined; + } + + var ret, hooks, + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + if ( notxml ) { + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + return (elem[ name ] = value); + } + + } else { + if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== undefined ) { + return ret; + + } else { + return elem[ name ]; + } + } + }, + + propHooks: {} +}); + +// Hook for boolean attributes +boolHook = { + get: function( elem, name ) { + // Align boolean attributes with corresponding properties + return jQuery.prop( elem, name ) ? + name.toLowerCase() : + undefined; + }, + set: function( elem, value, name ) { + var propName; + if ( value === false ) { + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + // value is true since we know at this point it's type boolean and not false + // Set boolean attributes to the same name and set the DOM property + propName = jQuery.propFix[ name ] || name; + if ( propName in elem ) { + // Only set the IDL specifically if it already exists on the element + elem[ propName ] = true; + } + + elem.setAttribute( name, name.toLowerCase() ); + } + return name; } +}; + +// IE6/7 do not support getting/setting some attributes with get/setAttribute +if ( !jQuery.support.getSetAttribute ) { + + // propFix is more comprehensive and contains all fixes + jQuery.attrFix = jQuery.propFix; + + // Use this for any attribute on a form in IE6/7 + formHook = jQuery.attrHooks.name = jQuery.attrHooks.title = jQuery.valHooks.button = { + get: function( elem, name ) { + var ret; + ret = elem.getAttributeNode( name ); + // Return undefined if nodeValue is empty string + return ret && ret.nodeValue !== "" ? + ret.nodeValue : + undefined; + }, + set: function( elem, value, name ) { + // Check form objects in IE (multiple bugs related) + // Only use nodeValue if the attribute node exists on the form + var ret = elem.getAttributeNode( name ); + if ( ret ) { + ret.nodeValue = value; + return value; + } + } + }; + + // Set width and height to auto instead of 0 on empty string( Bug #8150 ) + // This is for removals + jQuery.each([ "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + set: function( elem, value ) { + if ( value === "" ) { + elem.setAttribute( name, "auto" ); + return value; + } + } + }); + }); +} + + +// Some attributes require a special call on IE +if ( !jQuery.support.hrefNormalized ) { + jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + get: function( elem ) { + var ret = elem.getAttribute( name, 2 ); + return ret === null ? undefined : ret; + } + }); + }); +} + +if ( !jQuery.support.style ) { + jQuery.attrHooks.style = { + get: function( elem ) { + // Return undefined in the case of empty string + // Normalize to lowercase since IE uppercases css property names + return elem.style.cssText.toLowerCase() || undefined; + }, + set: function( elem, value ) { + return (elem.style.cssText = "" + value); + } + }; +} + +// Safari mis-reports the default selected property of an option +// Accessing the parent's selectedIndex property fixes it +if ( !jQuery.support.optSelected ) { + jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, { + get: function( elem ) { + var parent = elem.parentNode; + + if ( parent ) { + parent.selectedIndex; + + // Make sure that it also works with optgroups, see #5701 + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + } + }); +} + +// Radios and checkboxes getter/setter +if ( !jQuery.support.checkOn ) { + jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + get: function( elem ) { + // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified + return elem.getAttribute("value") === null ? "on" : elem.value; + } + }; + }); +} +jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], { + set: function( elem, value ) { + if ( jQuery.isArray( value ) ) { + return (elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0); + } + } + }); }); @@ -2077,12 +2536,11 @@ jQuery.extend({ var rnamespaces = /\.(.*)$/, rformElems = /^(?:textarea|input|select)$/i, rperiod = /\./g, - rspace = / /g, + rspaces = / /g, rescape = /[^\w\s.|`]/g, fcleanup = function( nm ) { return nm.replace(rescape, "\\$&"); - }, - eventKey = "events"; + }; /* * A number of helper functions used for managing events. @@ -2098,17 +2556,11 @@ jQuery.event = { return; } - // For whatever reason, IE has trouble passing the window object - // around, causing it to be cloned in the process - if ( jQuery.isWindow( elem ) && ( elem !== window && !elem.frameElement ) ) { - elem = window; - } - if ( handler === false ) { handler = returnFalse; } else if ( !handler ) { // Fixes bug #7229. Fix recommended by jdalton - return; + return; } var handleObjIn, handleObj; @@ -2132,31 +2584,18 @@ jQuery.event = { return; } - var events = elemData[ eventKey ], + var events = elemData.events, eventHandle = elemData.handle; - if ( typeof events === "function" ) { - // On plain objects events is a fn that holds the the data - // which prevents this data from being JSON serialized - // the function does not need to be called, it just contains the data - eventHandle = events.handle; - events = events.events; - - } else if ( !events ) { - if ( !elem.nodeType ) { - // On plain objects, create a fn that acts as the holder - // of the values to avoid JSON serialization of event data - elemData[ eventKey ] = elemData = function(){}; - } - + if ( !events ) { elemData.events = events = {}; } if ( !eventHandle ) { - elemData.handle = eventHandle = function() { - // Handle the second event of a trigger and when - // an event is called after a page has unloaded - return typeof jQuery !== "undefined" && !jQuery.event.triggered ? + elemData.handle = eventHandle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? jQuery.event.handle.apply( eventHandle.elem, arguments ) : undefined; }; @@ -2226,7 +2665,7 @@ jQuery.event = { // Add the function to the element's handler list handlers.push( handleObj ); - // Keep track of which events have been used, for global triggering + // Keep track of which events have been used, for event optimization jQuery.event.global[ type ] = true; } @@ -2249,17 +2688,12 @@ jQuery.event = { var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType, elemData = jQuery.hasData( elem ) && jQuery._data( elem ), - events = elemData && elemData[ eventKey ]; + events = elemData && elemData.events; if ( !elemData || !events ) { return; } - if ( typeof events === "function" ) { - elemData = events; - events = events.events; - } - // types is actually an event object here if ( types && types.type ) { handler = types.handler; @@ -2359,196 +2793,190 @@ jQuery.event = { delete elemData.events; delete elemData.handle; - if ( typeof elemData === "function" ) { - jQuery.removeData( elem, eventKey, true ); - - } else if ( jQuery.isEmptyObject( elemData ) ) { + if ( jQuery.isEmptyObject( elemData ) ) { jQuery.removeData( elem, undefined, true ); } } }, + + // Events that are safe to short-circuit if no handlers are attached. + // Native DOM events should not be added, they may have inline handlers. + customEvent: { + "getData": true, + "setData": true, + "changeData": true + }, - // bubbling is internal - trigger: function( event, data, elem /*, bubbling */ ) { + trigger: function( event, data, elem, onlyHandlers ) { // Event object or event type var type = event.type || event, - bubbling = arguments[3]; + namespaces = [], + exclusive; - if ( !bubbling ) { - event = typeof event === "object" ? - // jQuery.Event object - event[ jQuery.expando ] ? event : - // Object literal - jQuery.extend( jQuery.Event(type), event ) : - // Just the event type (string) - jQuery.Event(type); - - if ( type.indexOf("!") >= 0 ) { - event.type = type = type.slice(0, -1); - event.exclusive = true; - } - - // Handle a global trigger - if ( !elem ) { - // Don't bubble custom events when global (to avoid too much overhead) - event.stopPropagation(); - - // Only trigger if we've ever bound an event for it - if ( jQuery.event.global[ type ] ) { - // XXX This code smells terrible. event.js should not be directly - // inspecting the data cache - jQuery.each( jQuery.cache, function() { - // internalKey variable is just used to make it easier to find - // and potentially change this stuff later; currently it just - // points to jQuery.expando - var internalKey = jQuery.expando, - internalCache = this[ internalKey ]; - if ( internalCache && internalCache.events && internalCache.events[type] ) { - jQuery.event.trigger( event, data, internalCache.handle.elem ); - } - }); - } - } - - // Handle triggering a single element - - // don't do events on text and comment nodes - if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) { - return undefined; - } - - // Clean up in case it is reused - event.result = undefined; - event.target = elem; - - // Clone the incoming data, if any - data = jQuery.makeArray( data ); - data.unshift( event ); + if ( type.indexOf("!") >= 0 ) { + // Exclusive events trigger only for the exact event (no namespaces) + type = type.slice(0, -1); + exclusive = true; } - event.currentTarget = elem; - - // Trigger the event, it is assumed that "handle" is a function - var handle = elem.nodeType ? - jQuery._data( elem, "handle" ) : - (jQuery._data( elem, eventKey ) || {}).handle; - - if ( handle ) { - handle.apply( elem, data ); + if ( type.indexOf(".") >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); } - var parent = elem.parentNode || elem.ownerDocument; + if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) { + // No jQuery handlers for this event type, and it can't have inline handlers + return; + } - // Trigger an inline bound script - try { - if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) { - if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) { - event.result = false; - event.preventDefault(); + // Caller can pass in an Event, Object, or just an event type string + event = typeof event === "object" ? + // jQuery.Event object + event[ jQuery.expando ] ? event : + // Object literal + new jQuery.Event( type, event ) : + // Just the event type (string) + new jQuery.Event( type ); + + event.type = type; + event.exclusive = exclusive; + event.namespace = namespaces.join("."); + event.namespace_re = new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)"); + + // triggerHandler() and global events don't bubble or run the default action + if ( onlyHandlers || !elem ) { + event.preventDefault(); + event.stopPropagation(); + } + + // Handle a global trigger + if ( !elem ) { + // TODO: Stop taunting the data cache; remove global events and always attach to document + jQuery.each( jQuery.cache, function() { + // internalKey variable is just used to make it easier to find + // and potentially change this stuff later; currently it just + // points to jQuery.expando + var internalKey = jQuery.expando, + internalCache = this[ internalKey ]; + if ( internalCache && internalCache.events && internalCache.events[ type ] ) { + jQuery.event.trigger( event, data, internalCache.handle.elem ); } + }); + return; + } + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // Clean up the event in case it is being reused + event.result = undefined; + event.target = elem; + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data != null ? jQuery.makeArray( data ) : []; + data.unshift( event ); + + var cur = elem, + // IE doesn't like method names with a colon (#3533, #8272) + ontype = type.indexOf(":") < 0 ? "on" + type : ""; + + // Fire event on the current element, then bubble up the DOM tree + do { + var handle = jQuery._data( cur, "handle" ); + + event.currentTarget = cur; + if ( handle ) { + handle.apply( cur, data ); } - // prevent IE from throwing an error for some elements with some event types, see #3533 - } catch (inlineError) {} + // Trigger an inline bound script + if ( ontype && jQuery.acceptData( cur ) && cur[ ontype ] && cur[ ontype ].apply( cur, data ) === false ) { + event.result = false; + event.preventDefault(); + } - if ( !event.isPropagationStopped() && parent ) { - jQuery.event.trigger( event, data, parent, true ); + // Bubble up to document, then to window + cur = cur.parentNode || cur.ownerDocument || cur === event.target.ownerDocument && window; + } while ( cur && !event.isPropagationStopped() ); - } else if ( !event.isDefaultPrevented() ) { + // If nobody prevented the default action, do it now + if ( !event.isDefaultPrevented() ) { var old, - target = event.target, - targetType = type.replace( rnamespaces, "" ), - isClick = jQuery.nodeName( target, "a" ) && targetType === "click", - special = jQuery.event.special[ targetType ] || {}; + special = jQuery.event.special[ type ] || {}; - if ( (!special._default || special._default.call( elem, event ) === false) && - !isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) { + if ( (!special._default || special._default.call( elem.ownerDocument, event ) === false) && + !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) { + // Call a native DOM method on the target with the same name name as the event. + // Can't use an .isFunction)() check here because IE6/7 fails that test. + // IE<9 dies on focus to hidden element (#1486), may want to revisit a try/catch. try { - if ( target[ targetType ] ) { - // Make sure that we don't accidentally re-trigger the onFOO events - old = target[ "on" + targetType ]; + if ( ontype && elem[ type ] ) { + // Don't re-trigger an onFOO event when we call its FOO() method + old = elem[ ontype ]; if ( old ) { - target[ "on" + targetType ] = null; + elem[ ontype ] = null; } - jQuery.event.triggered = true; - target[ targetType ](); + jQuery.event.triggered = type; + elem[ type ](); } - - // prevent IE from throwing an error for some elements with some event types, see #3533 - } catch (triggerError) {} + } catch ( ieError ) {} if ( old ) { - target[ "on" + targetType ] = old; + elem[ ontype ] = old; } - jQuery.event.triggered = false; + jQuery.event.triggered = undefined; } } + + return event.result; }, handle: function( event ) { - var all, handlers, namespaces, namespace_re, events, - namespace_sort = [], - args = jQuery.makeArray( arguments ); + event = jQuery.event.fix( event || window.event ); + // Snapshot the handlers list since a called handler may add/remove events. + var handlers = ((jQuery._data( this, "events" ) || {})[ event.type ] || []).slice(0), + run_all = !event.exclusive && !event.namespace, + args = Array.prototype.slice.call( arguments, 0 ); - event = args[0] = jQuery.event.fix( event || window.event ); + // Use the fix-ed Event rather than the (read-only) native event + args[0] = event; event.currentTarget = this; - // Namespaced event handlers - all = event.type.indexOf(".") < 0 && !event.exclusive; + for ( var j = 0, l = handlers.length; j < l; j++ ) { + var handleObj = handlers[ j ]; - if ( !all ) { - namespaces = event.type.split("."); - event.type = namespaces.shift(); - namespace_sort = namespaces.slice(0).sort(); - namespace_re = new RegExp("(^|\\.)" + namespace_sort.join("\\.(?:.*\\.)?") + "(\\.|$)"); - } + // Triggered event must 1) be non-exclusive and have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event. + if ( run_all || event.namespace_re.test( handleObj.namespace ) ) { + // Pass in a reference to the handler function itself + // So that we can later remove it + event.handler = handleObj.handler; + event.data = handleObj.data; + event.handleObj = handleObj; - event.namespace = event.namespace || namespace_sort.join("."); + var ret = handleObj.handler.apply( this, args ); - events = jQuery._data(this, eventKey); - - if ( typeof events === "function" ) { - events = events.events; - } - - handlers = (events || {})[ event.type ]; - - if ( events && handlers ) { - // Clone the handlers to prevent manipulation - handlers = handlers.slice(0); - - for ( var j = 0, l = handlers.length; j < l; j++ ) { - var handleObj = handlers[ j ]; - - // Filter the functions by class - if ( all || namespace_re.test( handleObj.namespace ) ) { - // Pass in a reference to the handler function itself - // So that we can later remove it - event.handler = handleObj.handler; - event.data = handleObj.data; - event.handleObj = handleObj; - - var ret = handleObj.handler.apply( this, args ); - - if ( ret !== undefined ) { - event.result = ret; - if ( ret === false ) { - event.preventDefault(); - event.stopPropagation(); - } + if ( ret !== undefined ) { + event.result = ret; + if ( ret === false ) { + event.preventDefault(); + event.stopPropagation(); } + } - if ( event.isImmediatePropagationStopped() ) { - break; - } + if ( event.isImmediatePropagationStopped() ) { + break; } } } - return event.result; }, @@ -2587,8 +3015,9 @@ jQuery.event = { // Calculate pageX/Y if missing and clientX/Y available if ( event.pageX == null && event.clientX != null ) { - var doc = document.documentElement, - body = document.body; + var eventDocument = event.target.ownerDocument || document, + doc = eventDocument.documentElement, + body = eventDocument.body; event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0); event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0); @@ -2667,10 +3096,10 @@ jQuery.removeEvent = document.removeEventListener ? } }; -jQuery.Event = function( src ) { +jQuery.Event = function( src, props ) { // Allow instantiation without the 'new' keyword if ( !this.preventDefault ) { - return new jQuery.Event( src ); + return new jQuery.Event( src, props ); } // Event object @@ -2680,7 +3109,7 @@ jQuery.Event = function( src ) { // Events bubbling up the document may have been marked as prevented // by a handler lower down the tree; reflect the correct value. - this.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false || + this.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false || src.getPreventDefault && src.getPreventDefault()) ? returnTrue : returnFalse; // Event type @@ -2688,6 +3117,11 @@ jQuery.Event = function( src ) { this.type = src; } + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + // timeStamp is buggy for some events on Firefox(#3843) // So we won't rely on the native value this.timeStamp = jQuery.now(); @@ -2749,27 +3183,27 @@ jQuery.Event.prototype = { // Checks if an event happened on an element within another element // Used in jQuery.event.special.mouseenter and mouseleave handlers var withinElement = function( event ) { + // Check if mouse(over|out) are still within the same parent element - var parent = event.relatedTarget; + var related = event.relatedTarget, + inside = false, + eventType = event.type; - // Firefox sometimes assigns relatedTarget a XUL element - // which we cannot access the parentNode property of - try { - // Traverse up the tree - while ( parent && parent !== this ) { - parent = parent.parentNode; + event.type = event.data; + + if ( related !== this ) { + + if ( related ) { + inside = jQuery.contains( this, related ); } - if ( parent !== this ) { - // set the correct event type - event.type = event.data; + if ( !inside ) { - // handle event if we actually just moused on to a non sub-element jQuery.event.handle.apply( this, arguments ); - } - // assuming we've left the element since we most likely mousedover a xul element - } catch(e) { } + event.type = eventType; + } + } }, // In case of event delegation, we only need to rename the event.type, @@ -2799,14 +3233,13 @@ if ( !jQuery.support.submitBubbles ) { jQuery.event.special.submit = { setup: function( data, namespaces ) { - if ( this.nodeName && this.nodeName.toLowerCase() !== "form" ) { + if ( !jQuery.nodeName( this, "form" ) ) { jQuery.event.add(this, "click.specialSubmit", function( e ) { var elem = e.target, type = elem.type; if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) { - e.liveFired = undefined; - return trigger( "submit", this, arguments ); + trigger( "submit", this, arguments ); } }); @@ -2815,8 +3248,7 @@ if ( !jQuery.support.submitBubbles ) { type = elem.type; if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) { - e.liveFired = undefined; - return trigger( "submit", this, arguments ); + trigger( "submit", this, arguments ); } }); @@ -2850,7 +3282,7 @@ if ( !jQuery.support.changeBubbles ) { }).join("-") : ""; - } else if ( elem.nodeName.toLowerCase() === "select" ) { + } else if ( jQuery.nodeName( elem, "select" ) ) { val = elem.selectedIndex; } @@ -2879,7 +3311,7 @@ if ( !jQuery.support.changeBubbles ) { if ( data != null || val ) { e.type = "change"; e.liveFired = undefined; - return jQuery.event.trigger( e, arguments[1], elem ); + jQuery.event.trigger( e, arguments[1], elem ); } }; @@ -2890,22 +3322,22 @@ if ( !jQuery.support.changeBubbles ) { beforedeactivate: testChange, click: function( e ) { - var elem = e.target, type = elem.type; + var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : ""; - if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) { - return testChange.call( this, e ); + if ( type === "radio" || type === "checkbox" || jQuery.nodeName( elem, "select" ) ) { + testChange.call( this, e ); } }, // Change has to be called before submit // Keydown will be called before keypress, which is used in submit-event delegation keydown: function( e ) { - var elem = e.target, type = elem.type; + var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : ""; - if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") || + if ( (e.keyCode === 13 && !jQuery.nodeName( elem, "textarea" ) ) || (e.keyCode === 32 && (type === "checkbox" || type === "radio")) || type === "select-multiple" ) { - return testChange.call( this, e ); + testChange.call( this, e ); } }, @@ -2944,32 +3376,58 @@ if ( !jQuery.support.changeBubbles ) { } function trigger( type, elem, args ) { - args[0].type = type; - return jQuery.event.handle.apply( elem, args ); + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + // Don't pass args or remember liveFired; they apply to the donor event. + var event = jQuery.extend( {}, args[ 0 ] ); + event.type = type; + event.originalEvent = {}; + event.liveFired = undefined; + jQuery.event.handle.call( elem, event ); + if ( event.isDefaultPrevented() ) { + args[ 0 ].preventDefault(); + } } // Create "bubbling" focus and blur events -if ( document.addEventListener ) { +if ( !jQuery.support.focusinBubbles ) { jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler while someone wants focusin/focusout + var attaches = 0; + jQuery.event.special[ fix ] = { setup: function() { - this.addEventListener( orig, handler, true ); - }, - teardown: function() { - this.removeEventListener( orig, handler, true ); + if ( attaches++ === 0 ) { + document.addEventListener( orig, handler, true ); + } + }, + teardown: function() { + if ( --attaches === 0 ) { + document.removeEventListener( orig, handler, true ); + } } }; - function handler( e ) { - e = jQuery.event.fix( e ); + function handler( donor ) { + // Donor event is always a native one; fix it and switch its type. + // Let focusin/out handler cancel the donor focus/blur event. + var e = jQuery.event.fix( donor ); e.type = fix; - return jQuery.event.handle.call( this, e ); + e.originalEvent = {}; + jQuery.event.trigger( e, null, e.target ); + if ( e.isDefaultPrevented() ) { + donor.preventDefault(); + } } }); } jQuery.each(["bind", "one"], function( i, name ) { jQuery.fn[ name ] = function( type, data, fn ) { + var handler; + // Handle object literals if ( typeof type === "object" ) { for ( var key in type ) { @@ -2978,15 +3436,20 @@ jQuery.each(["bind", "one"], function( i, name ) { return this; } - if ( jQuery.isFunction( data ) || data === false ) { + if ( arguments.length === 2 || data === false ) { fn = data; data = undefined; } - var handler = name === "one" ? jQuery.proxy( fn, function( event ) { - jQuery( this ).unbind( event, handler ); - return fn.apply( this, arguments ); - }) : fn; + if ( name === "one" ) { + handler = function( event ) { + jQuery( this ).unbind( event, handler ); + return fn.apply( this, arguments ); + }; + handler.guid = fn.guid || jQuery.guid++; + } else { + handler = fn; + } if ( type === "unload" && name !== "one" ) { this.one( type, data, fn ); @@ -3024,7 +3487,7 @@ jQuery.fn.extend({ undelegate: function( selector, types, fn ) { if ( arguments.length === 0 ) { - return this.unbind( "live" ); + return this.unbind( "live" ); } else { return this.die( types, null, fn, selector ); @@ -3039,35 +3502,34 @@ jQuery.fn.extend({ triggerHandler: function( type, data ) { if ( this[0] ) { - var event = jQuery.Event( type ); - event.preventDefault(); - event.stopPropagation(); - jQuery.event.trigger( event, data, this[0] ); - return event.result; + return jQuery.event.trigger( type, data, this[0], true ); } }, toggle: function( fn ) { // Save reference to arguments for access in closure var args = arguments, - i = 1; + guid = fn.guid || jQuery.guid++, + i = 0, + toggler = function( event ) { + // Figure out which function to execute + var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i; + jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 ); + + // Make sure that clicks stop + event.preventDefault(); + + // and execute the function + return args[ lastToggle ].apply( this, arguments ) || false; + }; // link all the functions, so any of them can unbind this click handler + toggler.guid = guid; while ( i < args.length ) { - jQuery.proxy( fn, args[ i++ ] ); + args[ i++ ].guid = guid; } - return this.click( jQuery.proxy( fn, function( event ) { - // Figure out which function to execute - var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i; - jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 ); - - // Make sure that clicks stop - event.preventDefault(); - - // and execute the function - return args[ lastToggle ].apply( this, arguments ) || false; - })); + return this.click( toggler ); }, hover: function( fnOver, fnOut ) { @@ -3096,8 +3558,16 @@ jQuery.each(["live", "die"], function( i, name ) { return this; } - if ( jQuery.isFunction( data ) ) { - fn = data; + if ( name === "die" && !types && + origSelector && origSelector.charAt(0) === "." ) { + + context.unbind( origSelector ); + + return this; + } + + if ( data === false || jQuery.isFunction( data ) ) { + fn = data || returnFalse; data = undefined; } @@ -3119,7 +3589,7 @@ jQuery.each(["live", "die"], function( i, name ) { preType = type; - if ( type === "focus" || type === "blur" ) { + if ( liveMap[ type ] ) { types.push( liveMap[ type ] + namespaces ); type = type + namespaces; @@ -3148,11 +3618,7 @@ function liveHandler( event ) { var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret, elems = [], selectors = [], - events = jQuery._data( this, eventKey ); - - if ( typeof events === "function" ) { - events = events.events; - } + events = jQuery._data( this, "events" ); // Make sure we avoid non-left-click bubbling in Firefox (#3861) and disabled elements in IE (#6911) if ( event.liveFired === this || !events || !events.live || event.target.disabled || event.button && event.type === "click" ) { @@ -3186,7 +3652,7 @@ function liveHandler( event ) { for ( j = 0; j < live.length; j++ ) { handleObj = live[j]; - if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) ) { + if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) && !close.elem.disabled ) { elem = close.elem; related = null; @@ -3194,6 +3660,11 @@ function liveHandler( event ) { if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) { event.type = handleObj.preType; related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0]; + + // Make sure not to accidentally match a child element with the same selector + if ( related && jQuery.contains( elem, related ) ) { + related = elem; + } } if ( !related || related !== elem ) { @@ -3232,7 +3703,7 @@ function liveHandler( event ) { } function liveConvert( type, selector ) { - return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspace, "&"); + return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspaces, "&"); } jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + @@ -3257,6 +3728,7 @@ jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblcl }); + /*! * Sizzle CSS Selector Engine * Copyright 2011, The Dojo Foundation @@ -3269,7 +3741,9 @@ var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[ done = 0, toString = Object.prototype.toString, hasDuplicate = false, - baseHasDuplicate = true; + baseHasDuplicate = true, + rBackslash = /\\/g, + rNonWord = /\W/; // Here we check if the JavaScript engine is using some sort of // optimization where it does not always call our comparision @@ -3468,7 +3942,7 @@ Sizzle.find = function( expr, context, isXML ) { match.splice( 1, 1 ); if ( left.substr( left.length - 1 ) !== "\\" ) { - match[1] = (match[1] || "").replace(/\\/g, ""); + match[1] = (match[1] || "").replace( rBackslash, "" ); set = Expr.find[ type ]( match, context, isXML ); if ( set != null ) { @@ -3607,13 +4081,16 @@ var Expr = Sizzle.selectors = { attrHandle: { href: function( elem ) { return elem.getAttribute( "href" ); + }, + type: function( elem ) { + return elem.getAttribute( "type" ); } }, relative: { "+": function(checkSet, part){ var isPartStr = typeof part === "string", - isTag = isPartStr && !/\W/.test( part ), + isTag = isPartStr && !rNonWord.test( part ), isPartStrNotTag = isPartStr && !isTag; if ( isTag ) { @@ -3641,7 +4118,7 @@ var Expr = Sizzle.selectors = { i = 0, l = checkSet.length; - if ( isPartStr && !/\W/.test( part ) ) { + if ( isPartStr && !rNonWord.test( part ) ) { part = part.toLowerCase(); for ( ; i < l; i++ ) { @@ -3675,7 +4152,7 @@ var Expr = Sizzle.selectors = { doneName = done++, checkFn = dirCheck; - if ( typeof part === "string" && !/\W/.test(part) ) { + if ( typeof part === "string" && !rNonWord.test( part ) ) { part = part.toLowerCase(); nodeCheck = part; checkFn = dirNodeCheck; @@ -3689,7 +4166,7 @@ var Expr = Sizzle.selectors = { doneName = done++, checkFn = dirCheck; - if ( typeof part === "string" && !/\W/.test( part ) ) { + if ( typeof part === "string" && !rNonWord.test( part ) ) { part = part.toLowerCase(); nodeCheck = part; checkFn = dirNodeCheck; @@ -3732,7 +4209,7 @@ var Expr = Sizzle.selectors = { }, preFilter: { CLASS: function( match, curLoop, inplace, result, not, isXML ) { - match = " " + match[1].replace(/\\/g, "") + " "; + match = " " + match[1].replace( rBackslash, "" ) + " "; if ( isXML ) { return match; @@ -3755,11 +4232,11 @@ var Expr = Sizzle.selectors = { }, ID: function( match ) { - return match[1].replace(/\\/g, ""); + return match[1].replace( rBackslash, "" ); }, TAG: function( match, curLoop ) { - return match[1].toLowerCase(); + return match[1].replace( rBackslash, "" ).toLowerCase(); }, CHILD: function( match ) { @@ -3790,14 +4267,14 @@ var Expr = Sizzle.selectors = { }, ATTR: function( match, curLoop, inplace, result, not, isXML ) { - var name = match[1] = match[1].replace(/\\/g, ""); + var name = match[1] = match[1].replace( rBackslash, "" ); if ( !isXML && Expr.attrMap[name] ) { match[1] = Expr.attrMap[name]; } // Handle if an un-quoted value was used - match[4] = ( match[4] || match[5] || "" ).replace(/\\/g, ""); + match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" ); if ( match[2] === "~=" ) { match[4] = " " + match[4] + " "; @@ -3852,7 +4329,9 @@ var Expr = Sizzle.selectors = { selected: function( elem ) { // Accessing this property makes selected-by-default // options in Safari work properly - elem.parentNode.selectedIndex; + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } return elem.selected === true; }, @@ -3874,41 +4353,53 @@ var Expr = Sizzle.selectors = { }, text: function( elem ) { - return "text" === elem.type; + var attr = elem.getAttribute( "type" ), type = elem.type; + // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) + // use getAttribute instead to test this case + return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null ); }, + radio: function( elem ) { - return "radio" === elem.type; + return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type; }, checkbox: function( elem ) { - return "checkbox" === elem.type; + return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type; }, file: function( elem ) { - return "file" === elem.type; + return elem.nodeName.toLowerCase() === "input" && "file" === elem.type; }, + password: function( elem ) { - return "password" === elem.type; + return elem.nodeName.toLowerCase() === "input" && "password" === elem.type; }, submit: function( elem ) { - return "submit" === elem.type; + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && "submit" === elem.type; }, image: function( elem ) { - return "image" === elem.type; + return elem.nodeName.toLowerCase() === "input" && "image" === elem.type; }, reset: function( elem ) { - return "reset" === elem.type; + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && "reset" === elem.type; }, button: function( elem ) { - return "button" === elem.type || elem.nodeName.toLowerCase() === "button"; + var name = elem.nodeName.toLowerCase(); + return name === "input" && "button" === elem.type || name === "button"; }, input: function( elem ) { return (/input|select|textarea|button/i).test( elem.nodeName ); + }, + + focus: function( elem ) { + return elem === elem.ownerDocument.activeElement; } }, setFilters: { @@ -4161,6 +4652,16 @@ if ( document.documentElement.compareDocumentPosition ) { } else { sortOrder = function( a, b ) { + // The nodes are identical, we can exit early + if ( a === b ) { + hasDuplicate = true; + return 0; + + // Fallback to using sourceIndex (in IE) if it's available on both nodes + } else if ( a.sourceIndex && b.sourceIndex ) { + return a.sourceIndex - b.sourceIndex; + } + var al, bl, ap = [], bp = [], @@ -4168,13 +4669,8 @@ if ( document.documentElement.compareDocumentPosition ) { bup = b.parentNode, cur = aup; - // The nodes are identical, we can exit early - if ( a === b ) { - hasDuplicate = true; - return 0; - // If the nodes are siblings (or identical) we can do a quick check - } else if ( aup === bup ) { + if ( aup === bup ) { return siblingCheck( a, b ); // If no parents were found then the nodes are disconnected @@ -4407,7 +4903,8 @@ if ( document.querySelectorAll ) { // and working up from there (Thanks to Andrew Dupont for the technique) // IE 8 doesn't work on object elements } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { - var old = context.getAttribute( "id" ), + var oldContext = context, + old = context.getAttribute( "id" ), nid = old || id, hasParent = context.parentNode, relativeHierarchySelector = /^\s*[+~]/.test( query ); @@ -4429,7 +4926,7 @@ if ( document.querySelectorAll ) { } catch(pseudoError) { } finally { if ( !old ) { - context.removeAttribute( "id" ); + oldContext.removeAttribute( "id" ); } } } @@ -4449,19 +4946,23 @@ if ( document.querySelectorAll ) { (function(){ var html = document.documentElement, - matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector, - pseudoWorks = false; - - try { - // This should fail with an exception - // Gecko does not error, returns false instead - matches.call( document.documentElement, "[test!='']:sizzle" ); - - } catch( pseudoError ) { - pseudoWorks = true; - } + matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector; if ( matches ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9 fails this) + var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ), + pseudoWorks = false; + + try { + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( document.documentElement, "[test!='']:sizzle" ); + + } catch( pseudoError ) { + pseudoWorks = true; + } + Sizzle.matchesSelector = function( node, expr ) { // Make sure that attribute selectors are quoted expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']"); @@ -4469,7 +4970,15 @@ if ( document.querySelectorAll ) { if ( !Sizzle.isXML( node ) ) { try { if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) { - return matches.call( node, expr ); + var ret = matches.call( node, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || !disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9, so check for that + node.document && node.document.nodeType !== 11 ) { + return ret; + } } } catch(e) {} } @@ -4658,17 +5167,30 @@ var runtil = /Until$/, jQuery.fn.extend({ find: function( selector ) { - var ret = this.pushStack( "", "find", selector ), - length = 0; + var self = this, + i, l; - for ( var i = 0, l = this.length; i < l; i++ ) { + if ( typeof selector !== "string" ) { + return jQuery( selector ).filter(function() { + for ( i = 0, l = self.length; i < l; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }); + } + + var ret = this.pushStack( "", "find", selector ), + length, n, r; + + for ( i = 0, l = this.length; i < l; i++ ) { length = ret.length; jQuery.find( selector, this[i], ret ); if ( i > 0 ) { // Make sure that the results are unique - for ( var n = length; n < ret.length; n++ ) { - for ( var r = 0; r < length; r++ ) { + for ( n = length; n < ret.length; n++ ) { + for ( r = 0; r < length; r++ ) { if ( ret[r] === ret[n] ) { ret.splice(n--, 1); break; @@ -4701,12 +5223,15 @@ jQuery.fn.extend({ }, is: function( selector ) { - return !!selector && jQuery.filter( selector, this ).length > 0; + return !!selector && ( typeof selector === "string" ? + jQuery.filter( selector, this ).length > 0 : + this.filter( selector ).length > 0 ); }, closest: function( selectors, context ) { var ret = [], i, l, cur = this[0]; - + + // Array if ( jQuery.isArray( selectors ) ) { var match, selector, matches = {}, @@ -4716,8 +5241,8 @@ jQuery.fn.extend({ for ( i = 0, l = selectors.length; i < l; i++ ) { selector = selectors[i]; - if ( !matches[selector] ) { - matches[selector] = jQuery.expr.match.POS.test( selector ) ? + if ( !matches[ selector ] ) { + matches[ selector ] = POS.test( selector ) ? jQuery( selector, context || this.context ) : selector; } @@ -4725,9 +5250,9 @@ jQuery.fn.extend({ while ( cur && cur.ownerDocument && cur !== context ) { for ( selector in matches ) { - match = matches[selector]; + match = matches[ selector ]; - if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) { + if ( match.jquery ? match.index( cur ) > -1 : jQuery( cur ).is( match ) ) { ret.push({ selector: selector, elem: cur, level: level }); } } @@ -4740,8 +5265,10 @@ jQuery.fn.extend({ return ret; } - var pos = POS.test( selectors ) ? - jQuery( selectors, context || this.context ) : null; + // String + var pos = POS.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; for ( i = 0, l = this.length; i < l; i++ ) { cur = this[i]; @@ -4753,14 +5280,14 @@ jQuery.fn.extend({ } else { cur = cur.parentNode; - if ( !cur || !cur.ownerDocument || cur === context ) { + if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) { break; } } } } - ret = ret.length > 1 ? jQuery.unique(ret) : ret; + ret = ret.length > 1 ? jQuery.unique( ret ) : ret; return this.pushStack( ret, "closest", selectors ); }, @@ -4783,7 +5310,7 @@ jQuery.fn.extend({ add: function( selector, context ) { var set = typeof selector === "string" ? jQuery( selector, context ) : - jQuery.makeArray( selector ), + jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), all = jQuery.merge( this.get(), set ); return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? @@ -4845,11 +5372,11 @@ jQuery.each({ }, function( name, fn ) { jQuery.fn[ name ] = function( until, selector ) { var ret = jQuery.map( this, fn, until ), - // The variable 'args' was introduced in - // https://github.com/jquery/jquery/commit/52a0238 - // to work around a bug in Chrome 10 (Dev) and should be removed when the bug is fixed. - // http://code.google.com/p/v8/issues/detail?id=1050 - args = slice.call(arguments); + // The variable 'args' was introduced in + // https://github.com/jquery/jquery/commit/52a0238 + // to work around a bug in Chrome 10 (Dev) and should be removed when the bug is fixed. + // http://code.google.com/p/v8/issues/detail?id=1050 + args = slice.call(arguments); if ( !runtil.test( name ) ) { selector = until; @@ -4921,6 +5448,11 @@ jQuery.extend({ // Implement the identical functionality for filter and not function winnow( elements, qualifier, keep ) { + + // Can't pass null or undefined to indexOf in Firefox 4 + // Set to 0 to skip string check + qualifier = qualifier || 0; + if ( jQuery.isFunction( qualifier ) ) { return jQuery.grep(elements, function( elem, i ) { var retVal = !!qualifier.call( elem, i, elem ); @@ -4959,8 +5491,10 @@ var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g, rtbody = /", "" ], legend: [ 1, "
", "
" ], @@ -5021,7 +5555,7 @@ jQuery.fn.extend({ } return elem; - }).append(this); + }).append( this ); } return this; @@ -5111,7 +5645,7 @@ jQuery.fn.extend({ } if ( elem.parentNode ) { - elem.parentNode.removeChild( elem ); + elem.parentNode.removeChild( elem ); } } } @@ -5136,7 +5670,7 @@ jQuery.fn.extend({ }, clone: function( dataAndEvents, deepDataAndEvents ) { - dataAndEvents = dataAndEvents == null ? true : dataAndEvents; + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; return this.map( function () { @@ -5213,7 +5747,9 @@ jQuery.fn.extend({ } }); } else { - return this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ); + return this.length ? + this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) : + this; } }, @@ -5305,8 +5841,8 @@ function cloneCopyEvent( src, dest ) { } var internalKey = jQuery.expando, - oldData = jQuery.data( src ), - curData = jQuery.data( dest, oldData ); + oldData = jQuery.data( src ), + curData = jQuery.data( dest, oldData ); // Switch to use the internal data object, if it exists, for the next // stage of data copying @@ -5320,28 +5856,34 @@ function cloneCopyEvent( src, dest ) { for ( var type in events ) { for ( var i = 0, l = events[ type ].length; i < l; i++ ) { - jQuery.event.add( dest, type, events[ type ][ i ], events[ type ][ i ].data ); + jQuery.event.add( dest, type + ( events[ type ][ i ].namespace ? "." : "" ) + events[ type ][ i ].namespace, events[ type ][ i ], events[ type ][ i ].data ); } } } } } -function cloneFixAttributes(src, dest) { +function cloneFixAttributes( src, dest ) { + var nodeName; + // We do not need to do anything for non-Elements if ( dest.nodeType !== 1 ) { return; } - var nodeName = dest.nodeName.toLowerCase(); - // clearAttributes removes the attributes, which we don't want, // but also removes the attachEvent events, which we *do* want - dest.clearAttributes(); + if ( dest.clearAttributes ) { + dest.clearAttributes(); + } // mergeAttributes, in contrast, only merges back on the // original attributes, not the events - dest.mergeAttributes(src); + if ( dest.mergeAttributes ) { + dest.mergeAttributes( src ); + } + + nodeName = dest.nodeName.toLowerCase(); // IE6-8 fail to clone children inside object elements that use // the proprietary classid attribute value (rather than the type @@ -5380,8 +5922,21 @@ function cloneFixAttributes(src, dest) { } jQuery.buildFragment = function( args, nodes, scripts ) { - var fragment, cacheable, cacheresults, - doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document); + var fragment, cacheable, cacheresults, doc; + + // nodes may contain either an explicit document object, + // a jQuery collection or context object. + // If nodes[0] contains a valid object to assign to doc + if ( nodes && nodes[0] ) { + doc = nodes[0].ownerDocument || nodes[0]; + } + + // Ensure that an attr object doesn't incorrectly stand in as a document object + // Chrome and Firefox seem to allow this to occur and will throw exception + // Fixes #8950 + if ( !doc.createDocumentFragment ) { + doc = document; + } // Only cache "small" (1/2 KB) HTML strings that are associated with the main document // Cloning options loses the selected state, so don't cache them @@ -5391,11 +5946,10 @@ jQuery.buildFragment = function( args, nodes, scripts ) { args[0].charAt(0) === "<" && !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) { cacheable = true; + cacheresults = jQuery.fragments[ args[0] ]; - if ( cacheresults ) { - if ( cacheresults !== 1 ) { - fragment = cacheresults; - } + if ( cacheresults && cacheresults !== 1 ) { + fragment = cacheresults; } } @@ -5441,6 +5995,33 @@ jQuery.each({ }; }); +function getAll( elem ) { + if ( "getElementsByTagName" in elem ) { + return elem.getElementsByTagName( "*" ); + + } else if ( "querySelectorAll" in elem ) { + return elem.querySelectorAll( "*" ); + + } else { + return []; + } +} + +// Used in clean, fixes the defaultChecked property +function fixDefaultChecked( elem ) { + if ( elem.type === "checkbox" || elem.type === "radio" ) { + elem.defaultChecked = elem.checked; + } +} +// Finds all inputs and passes them to fixDefaultChecked +function findInputs( elem ) { + if ( jQuery.nodeName( elem, "input" ) ) { + fixDefaultChecked( elem ); + } else if ( "getElementsByTagName" in elem ) { + jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked ); + } +} + jQuery.extend({ clone: function( elem, dataAndEvents, deepDataAndEvents ) { var clone = elem.cloneNode(true), @@ -5448,17 +6029,20 @@ jQuery.extend({ destElements, i; - if ( !jQuery.support.noCloneEvent && (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { + if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) && + (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { // IE copies events bound via attachEvent when using cloneNode. // Calling detachEvent on the clone will also remove the events // from the original. In order to get around this, we use some // proprietary methods to clear the events. Thanks to MooTools // guys for this hotness. + cloneFixAttributes( elem, clone ); + // Using Sizzle here is crazy slow, so we use getElementsByTagName // instead - srcElements = elem.getElementsByTagName("*"); - destElements = clone.getElementsByTagName("*"); + srcElements = getAll( elem ); + destElements = getAll( clone ); // Weird iteration because IE will replace the length property // with an element if you are cloning the body and one of the @@ -5466,31 +6050,31 @@ jQuery.extend({ for ( i = 0; srcElements[i]; ++i ) { cloneFixAttributes( srcElements[i], destElements[i] ); } - - cloneFixAttributes( elem, clone ); } // Copy the events from the original to the clone if ( dataAndEvents ) { - cloneCopyEvent( elem, clone ); - if ( deepDataAndEvents && "getElementsByTagName" in elem ) { + if ( deepDataAndEvents ) { + srcElements = getAll( elem ); + destElements = getAll( clone ); - srcElements = elem.getElementsByTagName("*"); - destElements = clone.getElementsByTagName("*"); - - if ( srcElements.length ) { - for ( i = 0; srcElements[i]; ++i ) { - cloneCopyEvent( srcElements[i], destElements[i] ); - } + for ( i = 0; srcElements[i]; ++i ) { + cloneCopyEvent( srcElements[i], destElements[i] ); } } } + + srcElements = destElements = null; + // Return the cloned set return clone; - }, + }, + clean: function( elems, context, fragment, scripts ) { + var checkScriptType; + context = context || document; // !context.createElement fails in IE with an error but returns typeof 'object' @@ -5498,7 +6082,7 @@ jQuery.extend({ context = context.ownerDocument || context[0] && context[0].ownerDocument || document; } - var ret = []; + var ret = [], j; for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { if ( typeof elem === "number" ) { @@ -5510,54 +6094,67 @@ jQuery.extend({ } // Convert html string into DOM nodes - if ( typeof elem === "string" && !rhtml.test( elem ) ) { - elem = context.createTextNode( elem ); + if ( typeof elem === "string" ) { + if ( !rhtml.test( elem ) ) { + elem = context.createTextNode( elem ); + } else { + // Fix "XHTML"-style tags in all browsers + elem = elem.replace(rxhtmlTag, "<$1>"); - } else if ( typeof elem === "string" ) { - // Fix "XHTML"-style tags in all browsers - elem = elem.replace(rxhtmlTag, "<$1>"); + // Trim whitespace, otherwise indexOf won't work as expected + var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(), + wrap = wrapMap[ tag ] || wrapMap._default, + depth = wrap[0], + div = context.createElement("div"); - // Trim whitespace, otherwise indexOf won't work as expected - var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(), - wrap = wrapMap[ tag ] || wrapMap._default, - depth = wrap[0], - div = context.createElement("div"); + // Go to html and back, then peel off extra wrappers + div.innerHTML = wrap[1] + elem + wrap[2]; - // Go to html and back, then peel off extra wrappers - div.innerHTML = wrap[1] + elem + wrap[2]; + // Move to the right depth + while ( depth-- ) { + div = div.lastChild; + } - // Move to the right depth - while ( depth-- ) { - div = div.lastChild; - } + // Remove IE's autoinserted from table fragments + if ( !jQuery.support.tbody ) { - // Remove IE's autoinserted from table fragments - if ( !jQuery.support.tbody ) { + // String was a , *may* have spurious + var hasBody = rtbody.test(elem), + tbody = tag === "table" && !hasBody ? + div.firstChild && div.firstChild.childNodes : - // String was a
, *may* have spurious - var hasBody = rtbody.test(elem), - tbody = tag === "table" && !hasBody ? - div.firstChild && div.firstChild.childNodes : + // String was a bare or + wrap[1] === "
" && !hasBody ? + div.childNodes : + []; - // String was a bare or - wrap[1] === "
" && !hasBody ? - div.childNodes : - []; - - for ( var j = tbody.length - 1; j >= 0 ; --j ) { - if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) { - tbody[ j ].parentNode.removeChild( tbody[ j ] ); + for ( j = tbody.length - 1; j >= 0 ; --j ) { + if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) { + tbody[ j ].parentNode.removeChild( tbody[ j ] ); + } } } - } + // IE completely kills leading whitespace when innerHTML is used + if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { + div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild ); + } - // IE completely kills leading whitespace when innerHTML is used - if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { - div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild ); + elem = div.childNodes; } + } - elem = div.childNodes; + // Resets defaultChecked for any radios and checkboxes + // about to be appended to the DOM in IE 6/7 (#8060) + var len; + if ( !jQuery.support.appendChecked ) { + if ( elem[0] && typeof (len = elem.length) === "number" ) { + for ( j = 0; j < len; j++ ) { + findInputs( elem[j] ); + } + } else { + findInputs( elem ); + } } if ( elem.nodeType ) { @@ -5568,13 +6165,18 @@ jQuery.extend({ } if ( fragment ) { + checkScriptType = function( elem ) { + return !elem.type || rscriptType.test( elem.type ); + }; for ( i = 0; ret[i]; i++ ) { if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) { scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] ); } else { if ( ret[i].nodeType === 1 ) { - ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) ); + var jsTags = jQuery.grep( ret[i].getElementsByTagName( "script" ), checkScriptType ); + + ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) ); } fragment.appendChild( ret[i] ); } @@ -5636,7 +6238,7 @@ function evalScript( i, elem ) { dataType: "script" }); } else { - jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" ); + jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "/*$0*/" ) ); } if ( elem.parentNode ) { @@ -5646,13 +6248,14 @@ function evalScript( i, elem ) { - var ralpha = /alpha\([^)]*\)/i, ropacity = /opacity=([^)]*)/, - rdashAlpha = /-([a-z])/ig, - rupper = /([A-Z])/g, + // fixed for IE9, see #8346 + rupper = /([A-Z]|^ms)/g, rnumpx = /^-?\d+(?:px)?$/i, rnum = /^-?\d/, + rrelNum = /^[+\-]=/, + rrelNumFilter = /[^+\-\.\de]+/g, cssShow = { position: "absolute", visibility: "hidden", display: "block" }, cssWidth = [ "Left", "Right" ], @@ -5660,11 +6263,7 @@ var ralpha = /alpha\([^)]*\)/i, curCSS, getComputedStyle, - currentStyle, - - fcamelCase = function( all, letter ) { - return letter.toUpperCase(); - }; + currentStyle; jQuery.fn.css = function( name, value ) { // Setting 'undefined' is a no-op @@ -5699,11 +6298,14 @@ jQuery.extend({ // Exclude the following css properties to add px cssNumber: { - "zIndex": true, + "fillOpacity": true, "fontWeight": true, + "lineHeight": true, "opacity": true, - "zoom": true, - "lineHeight": true + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true }, // Add in properties whose names you wish to fix before @@ -5721,20 +6323,29 @@ jQuery.extend({ } // Make sure that we're working with the right name - var ret, origName = jQuery.camelCase( name ), + var ret, type, origName = jQuery.camelCase( name ), style = elem.style, hooks = jQuery.cssHooks[ origName ]; name = jQuery.cssProps[ origName ] || origName; // Check if we're setting a value if ( value !== undefined ) { + type = typeof value; + // Make sure that NaN and null values aren't set. See: #7116 - if ( typeof value === "number" && isNaN( value ) || value == null ) { + if ( type === "number" && isNaN( value ) || value == null ) { return; } + // convert relative number strings (+= or -=) to relative numbers. #7345 + if ( type === "string" && rrelNum.test( value ) ) { + value = +value.replace( rrelNumFilter, "" ) + parseFloat( jQuery.css( elem, name ) ); + // Fixes bug #9237 + type = "number"; + } + // If a number was passed in, add 'px' to the (except for certain CSS properties) - if ( typeof value === "number" && !jQuery.cssNumber[ origName ] ) { + if ( type === "number" && !jQuery.cssNumber[ origName ] ) { value += "px"; } @@ -5759,11 +6370,17 @@ jQuery.extend({ }, css: function( elem, name, extra ) { - // Make sure that we're working with the right name - var ret, origName = jQuery.camelCase( name ), - hooks = jQuery.cssHooks[ origName ]; + var ret, hooks; - name = jQuery.cssProps[ origName ] || origName; + // Make sure that we're working with the right name + name = jQuery.camelCase( name ); + hooks = jQuery.cssHooks[ name ]; + name = jQuery.cssProps[ name ] || name; + + // cssFloat needs a special treatment + if ( name === "cssFloat" ) { + name = "float"; + } // If a hook was provided get the computed value from there if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) { @@ -5771,7 +6388,7 @@ jQuery.extend({ // Otherwise, if a way to get the computed value exists, use that } else if ( curCSS ) { - return curCSS( elem, name, origName ); + return curCSS( elem, name ); } }, @@ -5791,10 +6408,6 @@ jQuery.extend({ for ( name in options ) { elem.style[ name ] = old[ name ]; } - }, - - camelCase: function( string ) { - return string.replace( rdashAlpha, fcamelCase ); } }); @@ -5808,44 +6421,21 @@ jQuery.each(["height", "width"], function( i, name ) { if ( computed ) { if ( elem.offsetWidth !== 0 ) { - val = getWH( elem, name, extra ); - + return getWH( elem, name, extra ); } else { jQuery.swap( elem, cssShow, function() { val = getWH( elem, name, extra ); }); } - if ( val <= 0 ) { - val = curCSS( elem, name, name ); - - if ( val === "0px" && currentStyle ) { - val = currentStyle( elem, name, name ); - } - - if ( val != null ) { - // Should return "auto" instead of 0, use 0 for - // temporary backwards-compat - return val === "" || val === "auto" ? "0px" : val; - } - } - - if ( val < 0 || val == null ) { - val = elem.style[ name ]; - - // Should return "auto" instead of 0, use 0 for - // temporary backwards-compat - return val === "" || val === "auto" ? "0px" : val; - } - - return typeof val === "string" ? val : val + "px"; + return val; } }, set: function( elem, value ) { if ( rnumpx.test( value ) ) { // ignore negative width and height values #1599 - value = parseFloat(value); + value = parseFloat( value ); if ( value >= 0 ) { return value + "px"; @@ -5862,33 +6452,56 @@ if ( !jQuery.support.opacity ) { jQuery.cssHooks.opacity = { get: function( elem, computed ) { // IE uses filters for opacity - return ropacity.test((computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "") ? - (parseFloat(RegExp.$1) / 100) + "" : + return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ? + ( parseFloat( RegExp.$1 ) / 100 ) + "" : computed ? "1" : ""; }, set: function( elem, value ) { - var style = elem.style; + var style = elem.style, + currentStyle = elem.currentStyle; // IE has trouble with opacity if it does not have layout // Force it by setting the zoom level style.zoom = 1; // Set the alpha filter to set the opacity - var opacity = jQuery.isNaN(value) ? + var opacity = jQuery.isNaN( value ) ? "" : "alpha(opacity=" + value * 100 + ")", - filter = style.filter || ""; + filter = currentStyle && currentStyle.filter || style.filter || ""; - style.filter = ralpha.test(filter) ? - filter.replace(ralpha, opacity) : - style.filter + ' ' + opacity; + style.filter = ralpha.test( filter ) ? + filter.replace( ralpha, opacity ) : + filter + " " + opacity; } }; } +jQuery(function() { + // This hook cannot be added until DOM ready because the support test + // for it is not run until after DOM ready + if ( !jQuery.support.reliableMarginRight ) { + jQuery.cssHooks.marginRight = { + get: function( elem, computed ) { + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + // Work around by temporarily setting element display to inline-block + var ret; + jQuery.swap( elem, { "display": "inline-block" }, function() { + if ( computed ) { + ret = curCSS( elem, "margin-right", "marginRight" ); + } else { + ret = elem.style.marginRight; + } + }); + return ret; + } + }; + } +}); + if ( document.defaultView && document.defaultView.getComputedStyle ) { - getComputedStyle = function( elem, newName, name ) { + getComputedStyle = function( elem, name ) { var ret, defaultView, computedStyle; name = name.replace( rupper, "-$1" ).toLowerCase(); @@ -5910,7 +6523,7 @@ if ( document.defaultView && document.defaultView.getComputedStyle ) { if ( document.documentElement.currentStyle ) { currentStyle = function( elem, name ) { - var left, + var left, ret = elem.currentStyle && elem.currentStyle[ name ], rsLeft = elem.runtimeStyle && elem.runtimeStyle[ name ], style = elem.style; @@ -5945,27 +6558,50 @@ if ( document.documentElement.currentStyle ) { curCSS = getComputedStyle || currentStyle; function getWH( elem, name, extra ) { - var which = name === "width" ? cssWidth : cssHeight, - val = name === "width" ? elem.offsetWidth : elem.offsetHeight; - if ( extra === "border" ) { - return val; + // Start with offset property + var val = name === "width" ? elem.offsetWidth : elem.offsetHeight, + which = name === "width" ? cssWidth : cssHeight; + + if ( val > 0 ) { + if ( extra !== "border" ) { + jQuery.each( which, function() { + if ( !extra ) { + val -= parseFloat( jQuery.css( elem, "padding" + this ) ) || 0; + } + if ( extra === "margin" ) { + val += parseFloat( jQuery.css( elem, extra + this ) ) || 0; + } else { + val -= parseFloat( jQuery.css( elem, "border" + this + "Width" ) ) || 0; + } + }); + } + + return val + "px"; } - jQuery.each( which, function() { - if ( !extra ) { - val -= parseFloat(jQuery.css( elem, "padding" + this )) || 0; - } + // Fall back to computed then uncomputed css if necessary + val = curCSS( elem, name, name ); + if ( val < 0 || val == null ) { + val = elem.style[ name ] || 0; + } + // Normalize "", auto, and prepare for extra + val = parseFloat( val ) || 0; - if ( extra === "margin" ) { - val += parseFloat(jQuery.css( elem, "margin" + this )) || 0; + // Add padding, border, margin + if ( extra ) { + jQuery.each( which, function() { + val += parseFloat( jQuery.css( elem, "padding" + this ) ) || 0; + if ( extra !== "padding" ) { + val += parseFloat( jQuery.css( elem, "border" + this + "Width" ) ) || 0; + } + if ( extra === "margin" ) { + val += parseFloat( jQuery.css( elem, extra + this ) ) || 0; + } + }); + } - } else { - val -= parseFloat(jQuery.css( elem, "border" + this + "Width" )) || 0; - } - }); - - return val; + return val + "px"; } if ( jQuery.expr && jQuery.expr.filters ) { @@ -5988,8 +6624,10 @@ var r20 = /%20/g, rbracket = /\[\]$/, rCRLF = /\r?\n/g, rhash = /#.*$/, - rheaders = /^(.*?):\s*(.*?)\r?$/mg, // IE leaves an \r character at EOL + rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL rinput = /^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i, + // #7653, #8125, #8152: local protocol detection + rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|widget):$/, rnoContent = /^(?:GET|HEAD)$/, rprotocol = /^\/\//, rquery = /\?/, @@ -5997,7 +6635,7 @@ var r20 = /%20/g, rselectTextarea = /^(?:select|textarea)/i, rspacesAjax = /\s+/, rts = /([?&])_=[^&]*/, - rurl = /^(\w+:)\/\/([^\/?#:]+)(?::(\d+))?/, + rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/, // Keep a copy of the old load method _load = jQuery.fn.load, @@ -6018,7 +6656,28 @@ var r20 = /%20/g, * 2) the catchall symbol "*" can be used * 3) selection will start with transport dataType and THEN go to "*" if needed */ - transports = {}; + transports = {}, + + // Document location + ajaxLocation, + + // Document location segments + ajaxLocParts; + +// #8138, IE may throw an exception when accessing +// a field from window.location if document.domain has been set +try { + ajaxLocation = location.href; +} catch( e ) { + // Use the href attribute of an A element + // since IE will modify it given document.location + ajaxLocation = document.createElement( "a" ); + ajaxLocation.href = ""; + ajaxLocation = ajaxLocation.href; +} + +// Segment location into parts +ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || []; // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport function addToPrefiltersOrTransports( structure ) { @@ -6056,8 +6715,8 @@ function addToPrefiltersOrTransports( structure ) { }; } -//Base inspection function for prefilters and transports -function inspectPrefiltersOrTransports( structure, options, originalOptions, jXHR, +// Base inspection function for prefilters and transports +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR, dataType /* internal */, inspected /* internal */ ) { dataType = dataType || options.dataTypes[ 0 ]; @@ -6072,16 +6731,16 @@ function inspectPrefiltersOrTransports( structure, options, originalOptions, jXH selection; for(; i < length && ( executeOnly || !selection ); i++ ) { - selection = list[ i ]( options, originalOptions, jXHR ); + selection = list[ i ]( options, originalOptions, jqXHR ); // If we got redirected to another dataType - // we try there if not done already + // we try there if executing only and not done already if ( typeof selection === "string" ) { - if ( inspected[ selection ] ) { + if ( !executeOnly || inspected[ selection ] ) { selection = undefined; } else { options.dataTypes.unshift( selection ); selection = inspectPrefiltersOrTransports( - structure, options, originalOptions, jXHR, selection, inspected ); + structure, options, originalOptions, jqXHR, selection, inspected ); } } } @@ -6089,7 +6748,7 @@ function inspectPrefiltersOrTransports( structure, options, originalOptions, jXH // we try the catchall dataType if not done already if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) { selection = inspectPrefiltersOrTransports( - structure, options, originalOptions, jXHR, "*", inspected ); + structure, options, originalOptions, jqXHR, "*", inspected ); } // unnecessary when only executing (prefilters) // but it'll be ignored by the caller in that case @@ -6121,7 +6780,7 @@ jQuery.fn.extend({ if ( jQuery.isFunction( params ) ) { // We assume that it's the callback callback = params; - params = null; + params = undefined; // Otherwise, build a param string } else if ( typeof params === "object" ) { @@ -6139,14 +6798,14 @@ jQuery.fn.extend({ dataType: "html", data: params, // Complete callback (responseText is used internally) - complete: function( jXHR, status, responseText ) { - // Store the response as specified by the jXHR object - responseText = jXHR.responseText; + complete: function( jqXHR, status, responseText ) { + // Store the response as specified by the jqXHR object + responseText = jqXHR.responseText; // If successful, inject the HTML into all the matched elements - if ( jXHR.isResolved() ) { + if ( jqXHR.isResolved() ) { // #4825: Get the actual response in case // a dataFilter is present in ajaxSettings - jXHR.done(function( r ) { + jqXHR.done(function( r ) { responseText = r; }); // See if a selector was specified @@ -6165,7 +6824,7 @@ jQuery.fn.extend({ } if ( callback ) { - self.each( callback, [ responseText, status, jXHR ] ); + self.each( callback, [ responseText, status, jqXHR ] ); } } }); @@ -6205,7 +6864,7 @@ jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".sp jQuery.fn[ o ] = function( f ){ return this.bind( o, f ); }; -} ); +}); jQuery.each( [ "get", "post" ], function( i, method ) { jQuery[ method ] = function( url, data, callback, type ) { @@ -6213,7 +6872,7 @@ jQuery.each( [ "get", "post" ], function( i, method ) { if ( jQuery.isFunction( data ) ) { type = type || callback; callback = data; - data = null; + data = undefined; } return jQuery.ajax({ @@ -6224,27 +6883,44 @@ jQuery.each( [ "get", "post" ], function( i, method ) { dataType: type }); }; -} ); +}); jQuery.extend({ getScript: function( url, callback ) { - return jQuery.get( url, null, callback, "script" ); + return jQuery.get( url, undefined, callback, "script" ); }, getJSON: function( url, data, callback ) { return jQuery.get( url, data, callback, "json" ); }, - ajaxSetup: function( settings ) { - jQuery.extend( true, jQuery.ajaxSettings, settings ); - if ( settings.context ) { - jQuery.ajaxSettings.context = settings.context; + // Creates a full fledged settings object into target + // with both ajaxSettings and settings fields. + // If target is omitted, writes into ajaxSettings. + ajaxSetup: function ( target, settings ) { + if ( !settings ) { + // Only one parameter, we extend ajaxSettings + settings = target; + target = jQuery.extend( true, jQuery.ajaxSettings, settings ); + } else { + // target was provided, we extend into it + jQuery.extend( true, target, jQuery.ajaxSettings, settings ); } + // Flatten fields we don't want deep extended + for( var field in { context: 1, url: 1 } ) { + if ( field in settings ) { + target[ field ] = settings[ field ]; + } else if( field in jQuery.ajaxSettings ) { + target[ field ] = jQuery.ajaxSettings[ field ]; + } + } + return target; }, ajaxSettings: { - url: location.href, + url: ajaxLocation, + isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ), global: true, type: "GET", contentType: "application/x-www-form-urlencoded", @@ -6259,7 +6935,6 @@ jQuery.extend({ cache: null, traditional: false, headers: {}, - crossDomain: null, */ accepts: { @@ -6306,9 +6981,8 @@ jQuery.extend({ // Main method ajax: function( url, options ) { - // If options is not an object, - // we simulate pre-1.5 signature - if ( typeof options !== "object" ) { + // If url is an object, simulate pre-1.5 signature + if ( typeof url === "object" ) { options = url; url = undefined; } @@ -6317,21 +6991,25 @@ jQuery.extend({ options = options || {}; var // Create the final options object - s = jQuery.extend( true, {}, jQuery.ajaxSettings, options ), - // Callbacks contexts - // We force the original context if it exists - // or take it from jQuery.ajaxSettings otherwise - // (plain objects used as context get extended) - callbackContext = - ( s.context = ( "context" in options ? options : jQuery.ajaxSettings ).context ) || s, - globalEventContext = callbackContext === s ? jQuery.event : jQuery( callbackContext ), + s = jQuery.ajaxSetup( {}, options ), + // Callbacks context + callbackContext = s.context || s, + // Context for global events + // It's the callbackContext if one was provided in the options + // and if it's a DOM node or a jQuery collection + globalEventContext = callbackContext !== s && + ( callbackContext.nodeType || callbackContext instanceof jQuery ) ? + jQuery( callbackContext ) : jQuery.event, // Deferreds deferred = jQuery.Deferred(), completeDeferred = jQuery._Deferred(), // Status-dependent callbacks statusCode = s.statusCode || {}, + // ifModified key + ifModifiedKey, // Headers (they are sent all at once) requestHeaders = {}, + requestHeadersNames = {}, // Response headers responseHeadersString, responseHeaders, @@ -6340,22 +7018,24 @@ jQuery.extend({ // timeout handle timeoutTimer, // Cross-domain detection vars - loc = document.location, - protocol = loc.protocol || "http:", parts, - // The jXHR state + // The jqXHR state state = 0, + // To know if global events are to be dispatched + fireGlobals, // Loop variable i, // Fake xhr - jXHR = { + jqXHR = { readyState: 0, // Caches the header setRequestHeader: function( name, value ) { - if ( state === 0 ) { - requestHeaders[ name.toLowerCase() ] = value; + if ( !state ) { + var lname = name.toLowerCase(); + name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name; + requestHeaders[ name ] = value; } return this; }, @@ -6377,7 +7057,15 @@ jQuery.extend({ } match = responseHeaders[ key.toLowerCase() ]; } - return match || null; + return match === undefined ? null : match; + }, + + // Overrides response content-type header + overrideMimeType: function( type ) { + if ( !state ) { + s.mimeType = type; + } + return this; }, // Cancel the request @@ -6394,7 +7082,7 @@ jQuery.extend({ // Callback for when everything is done // It is defined here because jslint complains if it is declared // at the end of the function (which would be more logical and readable) - function done( status, statusText, responses, headers) { + function done( status, statusText, responses, headers ) { // Called once if ( state === 2 ) { @@ -6410,19 +7098,19 @@ jQuery.extend({ } // Dereference transport for early garbage collection - // (no matter how long the jXHR object will be used) + // (no matter how long the jqXHR object will be used) transport = undefined; // Cache response headers responseHeadersString = headers || ""; // Set readyState - jXHR.readyState = status ? 4 : 0; + jqXHR.readyState = status ? 4 : 0; var isSuccess, success, error, - response = responses ? ajaxHandleResponses( s, jXHR, responses ) : undefined, + response = responses ? ajaxHandleResponses( s, jqXHR, responses ) : undefined, lastModified, etag; @@ -6432,11 +7120,11 @@ jQuery.extend({ // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. if ( s.ifModified ) { - if ( ( lastModified = jXHR.getResponseHeader( "Last-Modified" ) ) ) { - jQuery.lastModified[ s.url ] = lastModified; + if ( ( lastModified = jqXHR.getResponseHeader( "Last-Modified" ) ) ) { + jQuery.lastModified[ ifModifiedKey ] = lastModified; } - if ( ( etag = jXHR.getResponseHeader( "Etag" ) ) ) { - jQuery.etag[ s.url ] = etag; + if ( ( etag = jqXHR.getResponseHeader( "Etag" ) ) ) { + jQuery.etag[ ifModifiedKey ] = etag; } } @@ -6463,7 +7151,7 @@ jQuery.extend({ // We extract error from statusText // then normalize statusText and status for non-aborts error = statusText; - if( status ) { + if( !statusText || status ) { statusText = "error"; if ( status < 0 ) { status = 0; @@ -6472,30 +7160,30 @@ jQuery.extend({ } // Set data for the fake xhr object - jXHR.status = status; - jXHR.statusText = statusText; + jqXHR.status = status; + jqXHR.statusText = statusText; // Success/Error if ( isSuccess ) { - deferred.resolveWith( callbackContext, [ success, statusText, jXHR ] ); + deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); } else { - deferred.rejectWith( callbackContext, [ jXHR, statusText, error ] ); + deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); } // Status-dependent callbacks - jXHR.statusCode( statusCode ); + jqXHR.statusCode( statusCode ); statusCode = undefined; - if ( s.global ) { + if ( fireGlobals ) { globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ), - [ jXHR, s, isSuccess ? success : error ] ); + [ jqXHR, s, isSuccess ? success : error ] ); } // Complete - completeDeferred.resolveWith( callbackContext, [ jXHR, statusText ] ); + completeDeferred.resolveWith( callbackContext, [ jqXHR, statusText ] ); - if ( s.global ) { - globalEventContext.trigger( "ajaxComplete", [ jXHR, s] ); + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxComplete", [ jqXHR, s] ); // Handle the global AJAX counter if ( !( --jQuery.active ) ) { jQuery.event.trigger( "ajaxStop" ); @@ -6504,13 +7192,13 @@ jQuery.extend({ } // Attach deferreds - deferred.promise( jXHR ); - jXHR.success = jXHR.done; - jXHR.error = jXHR.fail; - jXHR.complete = completeDeferred.done; + deferred.promise( jqXHR ); + jqXHR.success = jqXHR.done; + jqXHR.error = jqXHR.fail; + jqXHR.complete = completeDeferred.done; // Status-dependent callbacks - jXHR.statusCode = function( map ) { + jqXHR.statusCode = function( map ) { if ( map ) { var tmp; if ( state < 2 ) { @@ -6518,8 +7206,8 @@ jQuery.extend({ statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ]; } } else { - tmp = map[ jXHR.status ]; - jXHR.then( tmp, tmp ); + tmp = map[ jqXHR.status ]; + jqXHR.then( tmp, tmp ); } } return this; @@ -6528,18 +7216,18 @@ jQuery.extend({ // Remove hash character (#7531: and string promotion) // Add protocol if not provided (#5866: IE7 issue with protocol-less urls) // We also use the url parameter if available - s.url = ( "" + ( url || s.url ) ).replace( rhash, "" ).replace( rprotocol, protocol + "//" ); + s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" ); // Extract dataTypes list s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( rspacesAjax ); // Determine if a cross-domain request is in order - if ( !s.crossDomain ) { + if ( s.crossDomain == null ) { parts = rurl.exec( s.url.toLowerCase() ); s.crossDomain = !!( parts && - ( parts[ 1 ] != protocol || parts[ 2 ] != loc.hostname || + ( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] || ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) != - ( loc.port || ( protocol === "http:" ? 80 : 443 ) ) ) + ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) ) ); } @@ -6549,7 +7237,15 @@ jQuery.extend({ } // Apply prefilters - inspectPrefiltersOrTransports( prefilters, s, options, jXHR ); + inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); + + // If request was aborted inside a prefiler, stop there + if ( state === 2 ) { + return false; + } + + // We can fire global events as of now if asked to + fireGlobals = s.global; // Uppercase the type s.type = s.type.toUpperCase(); @@ -6558,7 +7254,7 @@ jQuery.extend({ s.hasContent = !rnoContent.test( s.type ); // Watch for a new set of requests - if ( s.global && jQuery.active++ === 0 ) { + if ( fireGlobals && jQuery.active++ === 0 ) { jQuery.event.trigger( "ajaxStart" ); } @@ -6570,6 +7266,9 @@ jQuery.extend({ s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data; } + // Get ifModifiedKey before adding the anti-cache parameter + ifModifiedKey = s.url; + // Add anti-cache in url if needed if ( s.cache === false ) { @@ -6584,77 +7283,80 @@ jQuery.extend({ // Set the correct header, if data is being sent if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { - requestHeaders[ "content-type" ] = s.contentType; + jqXHR.setRequestHeader( "Content-Type", s.contentType ); } // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. if ( s.ifModified ) { - if ( jQuery.lastModified[ s.url ] ) { - requestHeaders[ "if-modified-since" ] = jQuery.lastModified[ s.url ]; + ifModifiedKey = ifModifiedKey || s.url; + if ( jQuery.lastModified[ ifModifiedKey ] ) { + jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] ); } - if ( jQuery.etag[ s.url ] ) { - requestHeaders[ "if-none-match" ] = jQuery.etag[ s.url ]; + if ( jQuery.etag[ ifModifiedKey ] ) { + jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] ); } } // Set the Accepts header for the server, depending on the dataType - requestHeaders.accept = s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ? - s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", */*; q=0.01" : "" ) : - s.accepts[ "*" ]; + jqXHR.setRequestHeader( + "Accept", + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ? + s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", */*; q=0.01" : "" ) : + s.accepts[ "*" ] + ); // Check for headers option for ( i in s.headers ) { - requestHeaders[ i.toLowerCase() ] = s.headers[ i ]; + jqXHR.setRequestHeader( i, s.headers[ i ] ); } // Allow custom headers/mimetypes and early abort - if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jXHR, s ) === false || state === 2 ) ) { + if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) { // Abort if not done already - done( 0, "abort" ); - // Return false - jXHR = false; + jqXHR.abort(); + return false; + } + + // Install callbacks on deferreds + for ( i in { success: 1, error: 1, complete: 1 } ) { + jqXHR[ i ]( s[ i ] ); + } + + // Get transport + transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); + + // If no transport, we auto-abort + if ( !transport ) { + done( -1, "No Transport" ); } else { - - // Install callbacks on deferreds - for ( i in { success: 1, error: 1, complete: 1 } ) { - jXHR[ i ]( s[ i ] ); + jqXHR.readyState = 1; + // Send global event + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); + } + // Timeout + if ( s.async && s.timeout > 0 ) { + timeoutTimer = setTimeout( function(){ + jqXHR.abort( "timeout" ); + }, s.timeout ); } - // Get transport - transport = inspectPrefiltersOrTransports( transports, s, options, jXHR ); - - // If no transport, we auto-abort - if ( !transport ) { - done( -1, "No Transport" ); - } else { - // Set state as sending - state = jXHR.readyState = 1; - // Send global event - if ( s.global ) { - globalEventContext.trigger( "ajaxSend", [ jXHR, s ] ); - } - // Timeout - if ( s.async && s.timeout > 0 ) { - timeoutTimer = setTimeout( function(){ - jXHR.abort( "timeout" ); - }, s.timeout ); - } - - try { - transport.send( requestHeaders, done ); - } catch (e) { - // Propagate exception as error if not done - if ( status < 2 ) { - done( -1, e ); - // Simply rethrow otherwise - } else { - jQuery.error( e ); - } + try { + state = 1; + transport.send( requestHeaders, done ); + } catch (e) { + // Propagate exception as error if not done + if ( status < 2 ) { + done( -1, e ); + // Simply rethrow otherwise + } else { + jQuery.error( e ); } } } - return jXHR; + + return jqXHR; }, // Serialize an array of form elements or a set of @@ -6673,11 +7375,11 @@ jQuery.extend({ } // If an array was passed in, assume that it is an array of form elements. - if ( jQuery.isArray( a ) || a.jquery ) { + if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { // Serialize the form elements jQuery.each( a, function() { add( this.name, this.value ); - } ); + }); } else { // If traditional, encode the "old" way (the way 1.3.2 or older @@ -6693,7 +7395,7 @@ jQuery.extend({ }); function buildParams( prefix, obj, traditional, add ) { - if ( jQuery.isArray( obj ) && obj.length ) { + if ( jQuery.isArray( obj ) ) { // Serialize array item. jQuery.each( obj, function( i, v ) { if ( traditional || rbracket.test( prefix ) ) { @@ -6713,16 +7415,9 @@ function buildParams( prefix, obj, traditional, add ) { }); } else if ( !traditional && obj != null && typeof obj === "object" ) { - // If we see an array here, it is empty and should be treated as an empty - // object - if ( jQuery.isArray( obj ) || jQuery.isEmptyObject( obj ) ) { - add( prefix, "" ); - // Serialize object item. - } else { - jQuery.each( obj, function( k, v ) { - buildParams( prefix + "[" + k + "]", v, traditional, add ); - }); + for ( var name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); } } else { @@ -6749,7 +7444,7 @@ jQuery.extend({ * - finds the right dataType (mediates between content-type and expected dataType) * - returns the corresponding response */ -function ajaxHandleResponses( s, jXHR, responses ) { +function ajaxHandleResponses( s, jqXHR, responses ) { var contents = s.contents, dataTypes = s.dataTypes, @@ -6762,7 +7457,7 @@ function ajaxHandleResponses( s, jXHR, responses ) { // Fill responseXXX fields for( type in responseFields ) { if ( type in responses ) { - jXHR[ responseFields[type] ] = responses[ type ]; + jqXHR[ responseFields[type] ] = responses[ type ]; } } @@ -6770,7 +7465,7 @@ function ajaxHandleResponses( s, jXHR, responses ) { while( dataTypes[ 0 ] === "*" ) { dataTypes.shift(); if ( ct === undefined ) { - ct = jXHR.getResponseHeader( "content-type" ); + ct = s.mimeType || jqXHR.getResponseHeader( "content-type" ); } } @@ -6822,8 +7517,9 @@ function ajaxConvert( s, response ) { } var dataTypes = s.dataTypes, - converters = s.converters, + converters = {}, i, + key, length = dataTypes.length, tmp, // Current and previous dataTypes @@ -6840,6 +7536,16 @@ function ajaxConvert( s, response ) { // For each dataType in the chain for( i = 1; i < length; i++ ) { + // Create converters map + // with lowercased keys + if ( i === 1 ) { + for( key in s.converters ) { + if( typeof key === "string" ) { + converters[ key.toLowerCase() ] = s.converters[ key ]; + } + } + } + // Get the dataTypes prev = current; current = dataTypes[ i ]; @@ -6891,7 +7597,7 @@ function ajaxConvert( s, response ) { var jsc = jQuery.now(), - jsre = /(\=)\?(&|$)|()\?\?()/i; + jsre = /(\=)\?(&|$)|\?\?/i; // Default jsonp settings jQuery.ajaxSetup({ @@ -6902,15 +7608,14 @@ jQuery.ajaxSetup({ }); // Detect, normalize options and install callbacks for jsonp requests -jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, dataIsString /* internal */ ) { +jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { - dataIsString = ( typeof s.data === "string" ); + var inspectData = s.contentType === "application/x-www-form-urlencoded" && + ( typeof s.data === "string" ); if ( s.dataTypes[ 0 ] === "jsonp" || - originalSettings.jsonpCallback || - originalSettings.jsonp != null || s.jsonp !== false && ( jsre.test( s.url ) || - dataIsString && jsre.test( s.data ) ) ) { + inspectData && jsre.test( s.data ) ) ) { var responseContainer, jsonpCallback = s.jsonpCallback = @@ -6923,7 +7628,7 @@ jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, dataIsString if ( s.jsonp !== false ) { url = url.replace( jsre, replace ); if ( s.url === url ) { - if ( dataIsString ) { + if ( inspectData ) { data = data.replace( jsre, replace ); } if ( s.data === data ) { @@ -6936,32 +7641,24 @@ jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, dataIsString s.url = url; s.data = data; + // Install callback window[ jsonpCallback ] = function( response ) { responseContainer = [ response ]; }; - s.complete = [ function() { - + // Clean-up function + jqXHR.always(function() { // Set callback back to previous value window[ jsonpCallback ] = previous; - // Call if it was a function and we have a response - if ( previous) { - if ( responseContainer && jQuery.isFunction( previous ) ) { - window[ jsonpCallback ] ( responseContainer[ 0 ] ); - } - } else { - // else, more memory leak avoidance - try{ - delete window[ jsonpCallback ]; - } catch( e ) {} + if ( responseContainer && jQuery.isFunction( previous ) ) { + window[ jsonpCallback ]( responseContainer[ 0 ] ); } - - }, s.complete ]; + }); // Use data converter to retrieve json after script execution s.converters["script json"] = function() { - if ( ! responseContainer ) { + if ( !responseContainer ) { jQuery.error( jsonpCallback + " was not called" ); } return responseContainer[ 0 ]; @@ -6973,7 +7670,7 @@ jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, dataIsString // Delegate to script return "script"; } -} ); +}); @@ -6981,10 +7678,10 @@ jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, dataIsString // Install script dataType jQuery.ajaxSetup({ accepts: { - script: "text/javascript, application/javascript" + script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript" }, contents: { - script: /javascript/ + script: /javascript|ecmascript/ }, converters: { "text script": function( text ) { @@ -7003,7 +7700,7 @@ jQuery.ajaxPrefilter( "script", function( s ) { s.type = "GET"; s.global = false; } -} ); +}); // Bind script tag hack transport jQuery.ajaxTransport( "script", function(s) { @@ -7012,7 +7709,7 @@ jQuery.ajaxTransport( "script", function(s) { if ( s.crossDomain ) { var script, - head = document.getElementsByTagName( "head" )[ 0 ] || document.documentElement; + head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement; return { @@ -7031,7 +7728,7 @@ jQuery.ajaxTransport( "script", function(s) { // Attach handlers for all browsers script.onload = script.onreadystatechange = function( _, isAbort ) { - if ( !script.readyState || /loaded|complete/.test( script.readyState ) ) { + if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) { // Handle memory leak in IE script.onload = script.onreadystatechange = null; @@ -7062,22 +7759,33 @@ jQuery.ajaxTransport( "script", function(s) { } }; } -} ); +}); -var // Next active xhr id - xhrId = jQuery.now(), +var // #5280: Internet Explorer will keep connections alive if we don't abort on unload + xhrOnUnloadAbort = window.ActiveXObject ? function() { + // Abort all pending requests + for ( var key in xhrCallbacks ) { + xhrCallbacks[ key ]( 0, 1 ); + } + } : false, + xhrId = 0, + xhrCallbacks; - // active xhrs - xhrs = {}, +// Functions to create xhrs +function createStandardXHR() { + try { + return new window.XMLHttpRequest(); + } catch( e ) {} +} - // #5280: see below - xhrUnloadAbortInstalled, - - // XHR used to determine supports properties - testXHR; +function createActiveXHR() { + try { + return new window.ActiveXObject( "Microsoft.XMLHTTP" ); + } catch( e ) {} +} // Create the request object // (This is still attached to ajaxSettings for backward compatibility) @@ -7089,34 +7797,18 @@ jQuery.ajaxSettings.xhr = window.ActiveXObject ? * we need a fallback. */ function() { - if ( window.location.protocol !== "file:" ) { - try { - return new window.XMLHttpRequest(); - } catch( xhrError ) {} - } - - try { - return new window.ActiveXObject("Microsoft.XMLHTTP"); - } catch( activeError ) {} + return !this.isLocal && createStandardXHR() || createActiveXHR(); } : // For all other browsers, use the standard XMLHttpRequest object - function() { - return new window.XMLHttpRequest(); - }; + createStandardXHR; -// Test if we can create an xhr object -try { - testXHR = jQuery.ajaxSettings.xhr(); -} catch( xhrCreationException ) {} - -//Does this browser support XHR requests? -jQuery.support.ajax = !!testXHR; - -// Does this browser support crossDomain XHR requests -jQuery.support.cors = testXHR && ( "withCredentials" in testXHR ); - -// No need for the temporary xhr anymore -testXHR = undefined; +// Determine support properties +(function( xhr ) { + jQuery.extend( jQuery.support, { + ajax: !!xhr, + cors: !!xhr && ( "withCredentials" in xhr ) + }); +})( jQuery.ajaxSettings.xhr() ); // Create transport if the browser can provide an xhr if ( jQuery.support.ajax ) { @@ -7130,26 +7822,10 @@ if ( jQuery.support.ajax ) { return { send: function( headers, complete ) { - // #5280: we need to abort on unload or IE will keep connections alive - if ( !xhrUnloadAbortInstalled ) { - - xhrUnloadAbortInstalled = 1; - - jQuery(window).bind( "unload", function() { - - // Abort all pending requests - jQuery.each( xhrs, function( _, xhr ) { - if ( xhr.onreadystatechange ) { - xhr.onreadystatechange( 1 ); - } - } ); - - } ); - } - // Get a new xhr var xhr = s.xhr(), - handle; + handle, + i; // Open the socket // Passing null username, generates a login popup on Opera (#2865) @@ -7159,19 +7835,32 @@ if ( jQuery.support.ajax ) { xhr.open( s.type, s.url, s.async ); } - // Requested-With header - // Not set for crossDomain requests with no content - // (see why at http://trac.dojotoolkit.org/ticket/9486) - // Won't change header if already provided - if ( !( s.crossDomain && !s.hasContent ) && !headers["x-requested-with"] ) { - headers[ "x-requested-with" ] = "XMLHttpRequest"; + // Apply custom fields if provided + if ( s.xhrFields ) { + for ( i in s.xhrFields ) { + xhr[ i ] = s.xhrFields[ i ]; + } + } + + // Override mime type if needed + if ( s.mimeType && xhr.overrideMimeType ) { + xhr.overrideMimeType( s.mimeType ); + } + + // X-Requested-With header + // For cross-domain requests, seeing as conditions for a preflight are + // akin to a jigsaw puzzle, we simply never set it to be sure. + // (it can always be set on a per-request basis or even using ajaxSetup) + // For same-domain requests, won't change header if already provided. + if ( !s.crossDomain && !headers["X-Requested-With"] ) { + headers[ "X-Requested-With" ] = "XMLHttpRequest"; } // Need an extra try/catch for cross domain requests in Firefox 3 try { - jQuery.each( headers, function( key, value ) { - xhr.setRequestHeader( key, value ); - } ); + for ( i in headers ) { + xhr.setRequestHeader( i, headers[ i ] ); + } } catch( _ ) {} // Do send the request @@ -7182,74 +7871,80 @@ if ( jQuery.support.ajax ) { // Listener callback = function( _, isAbort ) { - // Was never called and is aborted or complete - if ( callback && ( isAbort || xhr.readyState === 4 ) ) { + var status, + statusText, + responseHeaders, + responses, + xml; - // Only called once - callback = 0; + // Firefox throws exceptions when accessing properties + // of an xhr when a network error occured + // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE) + try { - // Do not keep as active anymore - if ( handle ) { - xhr.onreadystatechange = jQuery.noop; - delete xhrs[ handle ]; - } + // Was never called and is aborted or complete + if ( callback && ( isAbort || xhr.readyState === 4 ) ) { - // If it's an abort - if ( isAbort ) { - // Abort it manually if needed - if ( xhr.readyState !== 4 ) { - xhr.abort(); + // Only called once + callback = undefined; + + // Do not keep as active anymore + if ( handle ) { + xhr.onreadystatechange = jQuery.noop; + if ( xhrOnUnloadAbort ) { + delete xhrCallbacks[ handle ]; + } } - } else { - // Get info - var status = xhr.status, - statusText, - responseHeaders = xhr.getAllResponseHeaders(), - responses = {}, + + // If it's an abort + if ( isAbort ) { + // Abort it manually if needed + if ( xhr.readyState !== 4 ) { + xhr.abort(); + } + } else { + status = xhr.status; + responseHeaders = xhr.getAllResponseHeaders(); + responses = {}; xml = xhr.responseXML; - // Construct response list - if ( xml && xml.documentElement /* #4958 */ ) { - responses.xml = xml; + // Construct response list + if ( xml && xml.documentElement /* #4958 */ ) { + responses.xml = xml; + } + responses.text = xhr.responseText; + + // Firefox throws an exception when accessing + // statusText for faulty cross-domain requests + try { + statusText = xhr.statusText; + } catch( e ) { + // We normalize with Webkit giving an empty statusText + statusText = ""; + } + + // Filter status for non standard behaviors + + // If the request is local and we have data: assume a success + // (success with no data won't get notified, that's the best we + // can do given current implementations) + if ( !status && s.isLocal && !s.crossDomain ) { + status = responses.text ? 200 : 404; + // IE - #1450: sometimes returns 1223 when it should be 204 + } else if ( status === 1223 ) { + status = 204; + } } - responses.text = xhr.responseText; - - // Firefox throws an exception when accessing - // statusText for faulty cross-domain requests - try { - statusText = xhr.statusText; - } catch( e ) { - // We normalize with Webkit giving an empty statusText - statusText = ""; - } - - // Filter status for non standard behaviours - status = - // Opera returns 0 when it should be 304 - // Webkit returns 0 for failing cross-domain no matter the real status - status === 0 ? - ( - // Webkit, Firefox: filter out faulty cross-domain requests - !s.crossDomain || statusText ? - ( - // Opera: filter out real aborts #6060 - responseHeaders ? - 304 : - 0 - ) : - // We assume 302 but could be anything cross-domain related - 302 - ) : - ( - // IE sometimes returns 1223 when it should be 204 (see #1450) - status == 1223 ? - 204 : - status - ); - - // Call complete - complete( status, statusText, responses, responseHeaders ); } + } catch( firefoxAccessException ) { + if ( !isAbort ) { + complete( -1, firefoxAccessException ); + } + } + + // Call complete if needed + if ( responses ) { + complete( status, statusText, responses, responseHeaders ); } }; @@ -7259,9 +7954,17 @@ if ( jQuery.support.ajax ) { if ( !s.async || xhr.readyState === 4 ) { callback(); } else { - // Add to list of active xhrs - handle = xhrId++; - xhrs[ handle ] = xhr; + handle = ++xhrId; + if ( xhrOnUnloadAbort ) { + // Create the active xhrs callbacks list if needed + // and attach the unload handler + if ( !xhrCallbacks ) { + xhrCallbacks = {}; + jQuery( window ).unload( xhrOnUnloadAbort ); + } + // Add to list of active xhrs callbacks + xhrCallbacks[ handle ] = callback; + } xhr.onreadystatechange = callback; } }, @@ -7280,6 +7983,7 @@ if ( jQuery.support.ajax ) { var elemdisplay = {}, + iframe, iframeDoc, rfxtypes = /^(?:toggle|show|hide)$/, rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i, timerId, @@ -7290,7 +7994,11 @@ var elemdisplay = {}, [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ], // opacity animations [ "opacity" ] - ]; + ], + fxNow, + requestAnimationFrame = window.webkitRequestAnimationFrame || + window.mozRequestAnimationFrame || + window.oRequestAnimationFrame; jQuery.fn.extend({ show: function( speed, easing, callback ) { @@ -7302,19 +8010,22 @@ jQuery.fn.extend({ } else { for ( var i = 0, j = this.length; i < j; i++ ) { elem = this[i]; - display = elem.style.display; - // Reset the inline display of this element to learn if it is - // being hidden by cascaded rules or not - if ( !jQuery._data(elem, "olddisplay") && display === "none" ) { - display = elem.style.display = ""; - } + if ( elem.style ) { + display = elem.style.display; - // Set elements which have been overridden with display: none - // in a stylesheet to whatever the default browser style is - // for such an element - if ( display === "" && jQuery.css( elem, "display" ) === "none" ) { - jQuery._data(elem, "olddisplay", defaultDisplay(elem.nodeName)); + // Reset the inline display of this element to learn if it is + // being hidden by cascaded rules or not + if ( !jQuery._data(elem, "olddisplay") && display === "none" ) { + display = elem.style.display = ""; + } + + // Set elements which have been overridden with display: none + // in a stylesheet to whatever the default browser style is + // for such an element + if ( display === "" && jQuery.css( elem, "display" ) === "none" ) { + jQuery._data(elem, "olddisplay", defaultDisplay(elem.nodeName)); + } } } @@ -7322,10 +8033,13 @@ jQuery.fn.extend({ // to avoid the constant reflow for ( i = 0; i < j; i++ ) { elem = this[i]; - display = elem.style.display; - if ( display === "" || display === "none" ) { - elem.style.display = jQuery._data(elem, "olddisplay") || ""; + if ( elem.style ) { + display = elem.style.display; + + if ( display === "" || display === "none" ) { + elem.style.display = jQuery._data(elem, "olddisplay") || ""; + } } } @@ -7339,17 +8053,21 @@ jQuery.fn.extend({ } else { for ( var i = 0, j = this.length; i < j; i++ ) { - var display = jQuery.css( this[i], "display" ); + if ( this[i].style ) { + var display = jQuery.css( this[i], "display" ); - if ( display !== "none" && !jQuery._data( this[i], "olddisplay" ) ) { - jQuery._data( this[i], "olddisplay", display ); + if ( display !== "none" && !jQuery._data( this[i], "olddisplay" ) ) { + jQuery._data( this[i], "olddisplay", display ); + } } } // Set the display of the elements in a second loop // to avoid the constant reflow for ( i = 0; i < j; i++ ) { - this[i].style.display = "none"; + if ( this[i].style ) { + this[i].style.display = "none"; + } } return this; @@ -7387,32 +8105,54 @@ jQuery.fn.extend({ var optall = jQuery.speed(speed, easing, callback); if ( jQuery.isEmptyObject( prop ) ) { - return this.each( optall.complete ); + return this.each( optall.complete, [ false ] ); } + // Do not change referenced properties as per-property easing will be lost + prop = jQuery.extend( {}, prop ); + return this[ optall.queue === false ? "each" : "queue" ](function() { // XXX 'this' does not always have a nodeName when running the // test suite - var opt = jQuery.extend({}, optall), p, + if ( optall.queue === false ) { + jQuery._mark( this ); + } + + var opt = jQuery.extend( {}, optall ), isElement = this.nodeType === 1, hidden = isElement && jQuery(this).is(":hidden"), - self = this; + name, val, p, + display, e, + parts, start, end, unit; + + // will store per property easing and be used to determine when an animation is complete + opt.animatedProperties = {}; for ( p in prop ) { - var name = jQuery.camelCase( p ); + // property name normalization + name = jQuery.camelCase( p ); if ( p !== name ) { prop[ name ] = prop[ p ]; delete prop[ p ]; - p = name; } - if ( prop[p] === "hide" && hidden || prop[p] === "show" && !hidden ) { - return opt.complete.call(this); + val = prop[ name ]; + + // easing resolution: per property > opt.specialEasing > opt.easing > 'swing' (default) + if ( jQuery.isArray( val ) ) { + opt.animatedProperties[ name ] = val[ 1 ]; + val = prop[ name ] = val[ 0 ]; + } else { + opt.animatedProperties[ name ] = opt.specialEasing && opt.specialEasing[ name ] || opt.easing || 'swing'; } - if ( isElement && ( p === "height" || p === "width" ) ) { + if ( val === "hide" && hidden || val === "show" && !hidden ) { + return opt.complete.call( this ); + } + + if ( isElement && ( name === "height" || name === "width" ) ) { // Make sure that nothing sneaks out // Record all 3 overflow attributes because IE does not // change the overflow attribute when overflowX and @@ -7428,7 +8168,7 @@ jQuery.fn.extend({ this.style.display = "inline-block"; } else { - var display = defaultDisplay(this.nodeName); + display = defaultDisplay( this.nodeName ); // inline-level elements accept inline-block; // block-level elements need to be inline with layout @@ -7442,44 +8182,37 @@ jQuery.fn.extend({ } } } - - if ( jQuery.isArray( prop[p] ) ) { - // Create (if needed) and add to specialEasing - (opt.specialEasing = opt.specialEasing || {})[p] = prop[p][1]; - prop[p] = prop[p][0]; - } } if ( opt.overflow != null ) { this.style.overflow = "hidden"; } - opt.curAnim = jQuery.extend({}, prop); - - jQuery.each( prop, function( name, val ) { - var e = new jQuery.fx( self, opt, name ); + for ( p in prop ) { + e = new jQuery.fx( this, opt, p ); + val = prop[ p ]; if ( rfxtypes.test(val) ) { - e[ val === "toggle" ? hidden ? "show" : "hide" : val ]( prop ); + e[ val === "toggle" ? hidden ? "show" : "hide" : val ](); } else { - var parts = rfxnum.exec(val), - start = e.cur() || 0; + parts = rfxnum.exec( val ); + start = e.cur(); if ( parts ) { - var end = parseFloat( parts[2] ), - unit = parts[3] || "px"; + end = parseFloat( parts[2] ); + unit = parts[3] || ( jQuery.cssNumber[ p ] ? "" : "px" ); // We need to compute starting value if ( unit !== "px" ) { - jQuery.style( self, name, (end || 1) + unit); + jQuery.style( this, p, (end || 1) + unit); start = ((end || 1) / e.cur()) * start; - jQuery.style( self, name, start + unit); + jQuery.style( this, p, start + unit); } // If a +=/-= token was provided, we're doing a relative animation if ( parts[1] ) { - end = ((parts[1] === "-=" ? -1 : 1) * end) + start; + end = ( (parts[ 1 ] === "-=" ? -1 : 1) * end ) + start; } e.custom( start, end, unit ); @@ -7488,7 +8221,7 @@ jQuery.fn.extend({ e.custom( start, val, "" ); } } - }); + } // For JS strict compliance return true; @@ -7496,15 +8229,18 @@ jQuery.fn.extend({ }, stop: function( clearQueue, gotoEnd ) { - var timers = jQuery.timers; - if ( clearQueue ) { this.queue([]); } this.each(function() { - // go in reverse order so anything added to the queue during the loop is ignored - for ( var i = timers.length - 1; i >= 0; i-- ) { + var timers = jQuery.timers, + i = timers.length; + // clear marker counters if we know they won't be + if ( !gotoEnd ) { + jQuery._unmark( true, this ); + } + while ( i-- ) { if ( timers[i].elem === this ) { if (gotoEnd) { // force the next step to be the last @@ -7526,6 +8262,17 @@ jQuery.fn.extend({ }); +// Animations created synchronously will run synchronously +function createFxNow() { + setTimeout( clearFxNow, 0 ); + return ( fxNow = jQuery.now() ); +} + +function clearFxNow() { + fxNow = undefined; +} + +// Generate parameters to create a standard animation function genFx( type, num ) { var obj = {}; @@ -7564,13 +8311,16 @@ jQuery.extend({ // Queueing opt.old = opt.complete; - opt.complete = function() { - if ( opt.queue !== false ) { - jQuery(this).dequeue(); - } + opt.complete = function( noUnmark ) { if ( jQuery.isFunction( opt.old ) ) { opt.old.call( this ); } + + if ( opt.queue !== false ) { + jQuery.dequeue( this ); + } else if ( noUnmark !== false ) { + jQuery._unmark( this ); + } }; return opt; @@ -7592,9 +8342,7 @@ jQuery.extend({ this.elem = elem; this.prop = prop; - if ( !options.orig ) { - options.orig = {}; - } + options.orig = options.orig || {}; } }); @@ -7615,19 +8363,24 @@ jQuery.fx.prototype = { return this.elem[ this.prop ]; } - var r = parseFloat( jQuery.css( this.elem, this.prop ) ); - return r || 0; + var parsed, + r = jQuery.css( this.elem, this.prop ); + // Empty strings, null, undefined and "auto" are converted to 0, + // complex values such as "rotate(1rad)" are returned as is, + // simple values such as "10px" are parsed to Float. + return isNaN( parsed = parseFloat( r ) ) ? !r || r === "auto" ? 0 : r : parsed; }, // Start an animation from one number to another custom: function( from, to, unit ) { var self = this, - fx = jQuery.fx; + fx = jQuery.fx, + raf; - this.startTime = jQuery.now(); + this.startTime = fxNow || createFxNow(); this.start = from; this.end = to; - this.unit = unit || this.unit || "px"; + this.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? "" : "px" ); this.now = this.start; this.pos = this.state = 0; @@ -7638,7 +8391,20 @@ jQuery.fx.prototype = { t.elem = this.elem; if ( t() && jQuery.timers.push(t) && !timerId ) { - timerId = setInterval(fx.tick, fx.interval); + // Use requestAnimationFrame instead of setInterval if available + if ( requestAnimationFrame ) { + timerId = true; + raf = function() { + // When timerId gets set to null at any point, this stops + if ( timerId ) { + requestAnimationFrame( raf ); + fx.tick(); + } + }; + requestAnimationFrame( raf ); + } else { + timerId = setInterval( fx.tick, fx.interval ); + } } }, @@ -7669,60 +8435,64 @@ jQuery.fx.prototype = { // Each step of an animation step: function( gotoEnd ) { - var t = jQuery.now(), done = true; + var t = fxNow || createFxNow(), + done = true, + elem = this.elem, + options = this.options, + i, n; - if ( gotoEnd || t >= this.options.duration + this.startTime ) { + if ( gotoEnd || t >= options.duration + this.startTime ) { this.now = this.end; this.pos = this.state = 1; this.update(); - this.options.curAnim[ this.prop ] = true; + options.animatedProperties[ this.prop ] = true; - for ( var i in this.options.curAnim ) { - if ( this.options.curAnim[i] !== true ) { + for ( i in options.animatedProperties ) { + if ( options.animatedProperties[i] !== true ) { done = false; } } if ( done ) { // Reset the overflow - if ( this.options.overflow != null && !jQuery.support.shrinkWrapBlocks ) { - var elem = this.elem, - options = this.options; + if ( options.overflow != null && !jQuery.support.shrinkWrapBlocks ) { jQuery.each( [ "", "X", "Y" ], function (index, value) { elem.style[ "overflow" + value ] = options.overflow[index]; - } ); + }); } // Hide the element if the "hide" operation was done - if ( this.options.hide ) { - jQuery(this.elem).hide(); + if ( options.hide ) { + jQuery(elem).hide(); } // Reset the properties, if the item has been hidden or shown - if ( this.options.hide || this.options.show ) { - for ( var p in this.options.curAnim ) { - jQuery.style( this.elem, p, this.options.orig[p] ); + if ( options.hide || options.show ) { + for ( var p in options.animatedProperties ) { + jQuery.style( elem, p, options.orig[p] ); } } // Execute the complete function - this.options.complete.call( this.elem ); + options.complete.call( elem ); } return false; } else { - var n = t - this.startTime; - this.state = n / this.options.duration; - - // Perform the easing function, defaults to swing - var specialEasing = this.options.specialEasing && this.options.specialEasing[this.prop]; - var defaultEasing = this.options.easing || (jQuery.easing.swing ? "swing" : "linear"); - this.pos = jQuery.easing[specialEasing || defaultEasing](this.state, n, 0, 1, this.options.duration); - this.now = this.start + ((this.end - this.start) * this.pos); + // classical easing cannot be used with an Infinity duration + if ( options.duration == Infinity ) { + this.now = t; + } else { + n = t - this.startTime; + this.state = n / options.duration; + // Perform the easing function, defaults to swing + this.pos = jQuery.easing[ options.animatedProperties[ this.prop ] ]( this.state, n, 0, 1, options.duration ); + this.now = this.start + ((this.end - this.start) * this.pos); + } // Perform the next step of the animation this.update(); } @@ -7733,9 +8503,7 @@ jQuery.fx.prototype = { jQuery.extend( jQuery.fx, { tick: function() { - var timers = jQuery.timers; - - for ( var i = 0; i < timers.length; i++ ) { + for ( var timers = jQuery.timers, i = 0 ; i < timers.length ; ++i ) { if ( !timers[i]() ) { timers.splice(i--, 1); } @@ -7783,17 +8551,47 @@ if ( jQuery.expr && jQuery.expr.filters ) { }; } +// Try to restore the default display value of an element function defaultDisplay( nodeName ) { + if ( !elemdisplay[ nodeName ] ) { - var elem = jQuery("<" + nodeName + ">").appendTo("body"), - display = elem.css("display"); + + var body = document.body, + elem = jQuery( "<" + nodeName + ">" ).appendTo( body ), + display = elem.css( "display" ); elem.remove(); + // If the simple way fails, + // get element's real default display by attaching it to a temp iframe if ( display === "none" || display === "" ) { - display = "block"; + // No iframe to use yet, so create it + if ( !iframe ) { + iframe = document.createElement( "iframe" ); + iframe.frameBorder = iframe.width = iframe.height = 0; + } + + body.appendChild( iframe ); + + // Create a cacheable copy of the iframe document on first call. + // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML + // document to it; WebKit & Firefox won't allow reusing the iframe document. + if ( !iframeDoc || !iframe.createElement ) { + iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document; + iframeDoc.write( ( document.compatMode === "CSS1Compat" ? "" : "" ) + "" ); + iframeDoc.close(); + } + + elem = iframeDoc.createElement( nodeName ); + + iframeDoc.body.appendChild( elem ); + + display = jQuery.css( elem, "display" ); + + body.removeChild( iframe ); } + // Store the correct default display elemdisplay[ nodeName ] = display; } @@ -7840,8 +8638,8 @@ if ( "getBoundingClientRect" in document.documentElement ) { win = getWindow(doc), clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0, - scrollTop = (win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop ), - scrollLeft = (win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft), + scrollTop = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop, + scrollLeft = win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft, top = box.top + scrollTop - clientTop, left = box.left + scrollLeft - clientLeft; @@ -7954,7 +8752,6 @@ jQuery.offset = { this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop); body.removeChild( container ); - body = container = innerDiv = checkDiv = table = td = null; jQuery.offset.initialize = jQuery.noop; }, @@ -7984,17 +8781,19 @@ jQuery.offset = { curOffset = curElem.offset(), curCSSTop = jQuery.css( elem, "top" ), curCSSLeft = jQuery.css( elem, "left" ), - calculatePosition = (position === "absolute" && jQuery.inArray('auto', [curCSSTop, curCSSLeft]) > -1), + calculatePosition = (position === "absolute" || position === "fixed") && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1, props = {}, curPosition = {}, curTop, curLeft; - // need to be able to calculate position if either top or left is auto and position is absolute + // need to be able to calculate position if either top or left is auto and position is either absolute or fixed if ( calculatePosition ) { curPosition = curElem.position(); + curTop = curPosition.top; + curLeft = curPosition.left; + } else { + curTop = parseFloat( curCSSTop ) || 0; + curLeft = parseFloat( curCSSLeft ) || 0; } - curTop = calculatePosition ? curPosition.top : parseInt( curCSSTop, 10 ) || 0; - curLeft = calculatePosition ? curPosition.left : parseInt( curCSSLeft, 10 ) || 0; - if ( jQuery.isFunction( options ) ) { options = options.call( elem, i, curOffset ); } @@ -8063,29 +8862,16 @@ jQuery.fn.extend({ jQuery.each( ["Left", "Top"], function( i, name ) { var method = "scroll" + name; - jQuery.fn[ method ] = function(val) { - var elem = this[0], win; + jQuery.fn[ method ] = function( val ) { + var elem, win; - if ( !elem ) { - return null; - } + if ( val === undefined ) { + elem = this[ 0 ]; - if ( val !== undefined ) { - // Set the scroll offset - return this.each(function() { - win = getWindow( this ); + if ( !elem ) { + return null; + } - if ( win ) { - win.scrollTo( - !i ? val : jQuery(win).scrollLeft(), - i ? val : jQuery(win).scrollTop() - ); - - } else { - this[ method ] = val; - } - }); - } else { win = getWindow( elem ); // Return the scroll offset @@ -8094,6 +8880,21 @@ jQuery.each( ["Left", "Top"], function( i, name ) { win.document.body[ method ] : elem[ method ]; } + + // Set the scroll offset + return this.each(function() { + win = getWindow( this ); + + if ( win ) { + win.scrollTo( + !i ? val : jQuery( win ).scrollLeft(), + i ? val : jQuery( win ).scrollTop() + ); + + } else { + this[ method ] = val; + } + }); }; }); @@ -8108,22 +8909,24 @@ function getWindow( elem ) { -// Create innerHeight, innerWidth, outerHeight and outerWidth methods +// Create width, height, innerHeight, innerWidth, outerHeight and outerWidth methods jQuery.each([ "Height", "Width" ], function( i, name ) { var type = name.toLowerCase(); // innerHeight and innerWidth - jQuery.fn["inner" + name] = function() { - return this[0] ? - parseFloat( jQuery.css( this[0], type, "padding" ) ) : + jQuery.fn[ "inner" + name ] = function() { + var elem = this[0]; + return elem && elem.style ? + parseFloat( jQuery.css( elem, type, "padding" ) ) : null; }; // outerHeight and outerWidth - jQuery.fn["outer" + name] = function( margin ) { - return this[0] ? - parseFloat( jQuery.css( this[0], type, margin ? "margin" : "border" ) ) : + jQuery.fn[ "outer" + name ] = function( margin ) { + var elem = this[0]; + return elem && elem.style ? + parseFloat( jQuery.css( elem, type, margin ? "margin" : "border" ) ) : null; }; @@ -8173,4 +8976,6 @@ jQuery.each([ "Height", "Width" ], function( i, name ) { }); +// Expose jQuery to the global object +window.jQuery = window.$ = jQuery; })(window); diff --git a/doc/html/_static/minus.png b/doc/html/_static/minus.png index da1c5620d10c047525a467a425abe9ff5269cfc2..bce9f779b45c1e474deca9a5f9e874bfd199b41f 100644 GIT binary patch delta 99 zcmX@kST;d2mYIQpVO~+Y2$13l@Ck9%)YLq4=FGcy?>>C^AfDhG1r%5Hba4!+xYc{g zkdJ|ZdL6GdVguxwighiHZFoh7V610u_K77(8A5T-G@yGywny C;3SR! delta 181 zcmXRr&NxA`o{52hLG9dwLLkLi;1OBOz`!jG!i)^F=12eq*-JcqUD>a*a|m!V+N`s9 z3KZffag8W(&d<$F%`0K}c4pdspjeQni(`nyV(FCY15|7D01(Yb6sIkr~k*|j;xQ5&xyQ6)2uJlbR0`fOi0*K d{$5VbnBju0eCX!rK0ToE44$rjF6*2UngEKoK!X4P diff --git a/doc/html/_static/plus.png b/doc/html/_static/plus.png index b3cb37425ea68b39ffa7b2e5fb69161275a87541..4c677f139df529fbb84ad12ba59ec7e1f918f0c4 100644 GIT binary patch delta 99 zcmX@kST;d2mYIQpVO~+Y2$13l@Ck9%)YLq4=FGcy?>>C^AfDhG1r%5Hba4!+xYc{g zkdJ|ZdL6Gg&%3xwighiHXfBh9|Q+*lza*a|m!5GUr%w z0EIY8Tq8=H^K)}k^GX=Lotd^DC>G@D;us=vIoYQ884q*ZfkOulELgOtDfHd_{q^79 z-A#59-nwOri*RC+0t?6Lgo7qB=j^J!XgD4HsQ>u*!%GF<_SgSk@q(`-vtakcodKdi d9fy«' ); var sidebarbutton = $('#sidebarbutton'); + light_color = sidebarbutton.css('background-color'); // find the height of the viewport to center the '<<' in the page var viewport_height; if (window.innerHeight) @@ -144,4 +145,4 @@ $(function() { add_sidebar_button(); var sidebarbutton = $('#sidebarbutton'); set_position_from_cookie(); -}); \ No newline at end of file +}); diff --git a/doc/html/_static/underscore.js b/doc/html/_static/underscore.js index 9146e08..eaba008 100644 --- a/doc/html/_static/underscore.js +++ b/doc/html/_static/underscore.js @@ -1,16 +1,807 @@ -(function(){var j=this,n=j._,i=function(a){this._wrapped=a},m=typeof StopIteration!=="undefined"?StopIteration:"__break__",b=j._=function(a){return new i(a)};if(typeof exports!=="undefined")exports._=b;var k=Array.prototype.slice,o=Array.prototype.unshift,p=Object.prototype.toString,q=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;b.VERSION="0.5.5";b.each=function(a,c,d){try{if(a.forEach)a.forEach(c,d);else if(b.isArray(a)||b.isArguments(a))for(var e=0,f=a.length;e=e.computed&&(e={value:f,computed:g})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);var e={computed:Infinity};b.each(a,function(f,g,h){g=c?c.call(d,f,g,h):f;gf?1:0}),"value")};b.sortedIndex=function(a,c,d){d=d||b.identity;for(var e=0,f=a.length;e>1;d(a[g])=0})})};b.zip=function(){for(var a=b.toArray(arguments),c=b.max(b.pluck(a,"length")),d=new Array(c),e=0;e0?f-c:c-f)>=0)return e;e[g++]=f}};b.bind=function(a,c){var d=b.rest(arguments,2);return function(){return a.apply(c||j,d.concat(b.toArray(arguments)))}};b.bindAll=function(a){var c=b.rest(arguments);if(c.length==0)c=b.functions(a);b.each(c,function(d){a[d]=b.bind(a[d],a)}); -return a};b.delay=function(a,c){var d=b.rest(arguments,2);return setTimeout(function(){return a.apply(a,d)},c)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(b.rest(arguments)))};b.wrap=function(a,c){return function(){var d=[a].concat(b.toArray(arguments));return c.apply(c,d)}};b.compose=function(){var a=b.toArray(arguments);return function(){for(var c=b.toArray(arguments),d=a.length-1;d>=0;d--)c=[a[d].apply(this,c)];return c[0]}};b.keys=function(a){if(b.isArray(a))return b.range(0,a.length); -var c=[];for(var d in a)q.call(a,d)&&c.push(d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=function(a){return b.select(b.keys(a),function(c){return b.isFunction(a[c])}).sort()};b.extend=function(a,c){for(var d in c)a[d]=c[d];return a};b.clone=function(a){if(b.isArray(a))return a.slice(0);return b.extend({},a)};b.tap=function(a,c){c(a);return a};b.isEqual=function(a,c){if(a===c)return true;var d=typeof a;if(d!=typeof c)return false;if(a==c)return true;if(!a&&c||a&&!c)return false; -if(a.isEqual)return a.isEqual(c);if(b.isDate(a)&&b.isDate(c))return a.getTime()===c.getTime();if(b.isNaN(a)&&b.isNaN(c))return true;if(b.isRegExp(a)&&b.isRegExp(c))return a.source===c.source&&a.global===c.global&&a.ignoreCase===c.ignoreCase&&a.multiline===c.multiline;if(d!=="object")return false;if(a.length&&a.length!==c.length)return false;d=b.keys(a);var e=b.keys(c);if(d.length!=e.length)return false;for(var f in a)if(!b.isEqual(a[f],c[f]))return false;return true};b.isEmpty=function(a){return b.keys(a).length== -0};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=function(a){return!!(a&&a.concat&&a.unshift)};b.isArguments=function(a){return a&&b.isNumber(a.length)&&!b.isArray(a)&&!r.call(a,"length")};b.isFunction=function(a){return!!(a&&a.constructor&&a.call&&a.apply)};b.isString=function(a){return!!(a===""||a&&a.charCodeAt&&a.substr)};b.isNumber=function(a){return p.call(a)==="[object Number]"};b.isDate=function(a){return!!(a&&a.getTimezoneOffset&&a.setUTCFullYear)};b.isRegExp=function(a){return!!(a&& -a.test&&a.exec&&(a.ignoreCase||a.ignoreCase===false))};b.isNaN=function(a){return b.isNumber(a)&&isNaN(a)};b.isNull=function(a){return a===null};b.isUndefined=function(a){return typeof a=="undefined"};b.noConflict=function(){j._=n;return this};b.identity=function(a){return a};b.breakLoop=function(){throw m;};var s=0;b.uniqueId=function(a){var c=s++;return a?a+c:c};b.template=function(a,c){a=new Function("obj","var p=[],print=function(){p.push.apply(p,arguments);};with(obj){p.push('"+a.replace(/[\r\t\n]/g, -" ").replace(/'(?=[^%]*%>)/g,"\t").split("'").join("\\'").split("\t").join("'").replace(/<%=(.+?)%>/g,"',$1,'").split("<%").join("');").split("%>").join("p.push('")+"');}return p.join('');");return c?a(c):a};b.forEach=b.each;b.foldl=b.inject=b.reduce;b.foldr=b.reduceRight;b.filter=b.select;b.every=b.all;b.some=b.any;b.head=b.first;b.tail=b.rest;b.methods=b.functions;var l=function(a,c){return c?b(a).chain():a};b.each(b.functions(b),function(a){var c=b[a];i.prototype[a]=function(){var d=b.toArray(arguments); -o.call(d,this._wrapped);return l(c.apply(b,d),this._chain)}});b.each(["pop","push","reverse","shift","sort","splice","unshift"],function(a){var c=Array.prototype[a];i.prototype[a]=function(){c.apply(this._wrapped,arguments);return l(this._wrapped,this._chain)}});b.each(["concat","join","slice"],function(a){var c=Array.prototype[a];i.prototype[a]=function(){return l(c.apply(this._wrapped,arguments),this._chain)}});i.prototype.chain=function(){this._chain=true;return this};i.prototype.value=function(){return this._wrapped}})(); +// Underscore.js 1.1.6 +// (c) 2011 Jeremy Ashkenas, DocumentCloud Inc. +// Underscore is freely distributable under the MIT license. +// Portions of Underscore are inspired or borrowed from Prototype, +// Oliver Steele's Functional, and John Resig's Micro-Templating. +// For all details and documentation: +// http://documentcloud.github.com/underscore + +(function() { + + // Baseline setup + // -------------- + + // Establish the root object, `window` in the browser, or `global` on the server. + var root = this; + + // Save the previous value of the `_` variable. + var previousUnderscore = root._; + + // Establish the object that gets returned to break out of a loop iteration. + var breaker = {}; + + // Save bytes in the minified (but not gzipped) version: + var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype; + + // Create quick reference variables for speed access to core prototypes. + var slice = ArrayProto.slice, + unshift = ArrayProto.unshift, + toString = ObjProto.toString, + hasOwnProperty = ObjProto.hasOwnProperty; + + // All **ECMAScript 5** native function implementations that we hope to use + // are declared here. + var + nativeForEach = ArrayProto.forEach, + nativeMap = ArrayProto.map, + nativeReduce = ArrayProto.reduce, + nativeReduceRight = ArrayProto.reduceRight, + nativeFilter = ArrayProto.filter, + nativeEvery = ArrayProto.every, + nativeSome = ArrayProto.some, + nativeIndexOf = ArrayProto.indexOf, + nativeLastIndexOf = ArrayProto.lastIndexOf, + nativeIsArray = Array.isArray, + nativeKeys = Object.keys, + nativeBind = FuncProto.bind; + + // Create a safe reference to the Underscore object for use below. + var _ = function(obj) { return new wrapper(obj); }; + + // Export the Underscore object for **CommonJS**, with backwards-compatibility + // for the old `require()` API. If we're not in CommonJS, add `_` to the + // global object. + if (typeof module !== 'undefined' && module.exports) { + module.exports = _; + _._ = _; + } else { + root._ = _; + } + + // Current version. + _.VERSION = '1.1.6'; + + // Collection Functions + // -------------------- + + // The cornerstone, an `each` implementation, aka `forEach`. + // Handles objects implementing `forEach`, arrays, and raw objects. + // Delegates to **ECMAScript 5**'s native `forEach` if available. + var each = _.each = _.forEach = function(obj, iterator, context) { + if (obj == null) return; + if (nativeForEach && obj.forEach === nativeForEach) { + obj.forEach(iterator, context); + } else if (_.isNumber(obj.length)) { + for (var i = 0, l = obj.length; i < l; i++) { + if (iterator.call(context, obj[i], i, obj) === breaker) return; + } + } else { + for (var key in obj) { + if (hasOwnProperty.call(obj, key)) { + if (iterator.call(context, obj[key], key, obj) === breaker) return; + } + } + } + }; + + // Return the results of applying the iterator to each element. + // Delegates to **ECMAScript 5**'s native `map` if available. + _.map = function(obj, iterator, context) { + var results = []; + if (obj == null) return results; + if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context); + each(obj, function(value, index, list) { + results[results.length] = iterator.call(context, value, index, list); + }); + return results; + }; + + // **Reduce** builds up a single result from a list of values, aka `inject`, + // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available. + _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) { + var initial = memo !== void 0; + if (obj == null) obj = []; + if (nativeReduce && obj.reduce === nativeReduce) { + if (context) iterator = _.bind(iterator, context); + return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator); + } + each(obj, function(value, index, list) { + if (!initial && index === 0) { + memo = value; + initial = true; + } else { + memo = iterator.call(context, memo, value, index, list); + } + }); + if (!initial) throw new TypeError("Reduce of empty array with no initial value"); + return memo; + }; + + // The right-associative version of reduce, also known as `foldr`. + // Delegates to **ECMAScript 5**'s native `reduceRight` if available. + _.reduceRight = _.foldr = function(obj, iterator, memo, context) { + if (obj == null) obj = []; + if (nativeReduceRight && obj.reduceRight === nativeReduceRight) { + if (context) iterator = _.bind(iterator, context); + return memo !== void 0 ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator); + } + var reversed = (_.isArray(obj) ? obj.slice() : _.toArray(obj)).reverse(); + return _.reduce(reversed, iterator, memo, context); + }; + + // Return the first value which passes a truth test. Aliased as `detect`. + _.find = _.detect = function(obj, iterator, context) { + var result; + any(obj, function(value, index, list) { + if (iterator.call(context, value, index, list)) { + result = value; + return true; + } + }); + return result; + }; + + // Return all the elements that pass a truth test. + // Delegates to **ECMAScript 5**'s native `filter` if available. + // Aliased as `select`. + _.filter = _.select = function(obj, iterator, context) { + var results = []; + if (obj == null) return results; + if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context); + each(obj, function(value, index, list) { + if (iterator.call(context, value, index, list)) results[results.length] = value; + }); + return results; + }; + + // Return all the elements for which a truth test fails. + _.reject = function(obj, iterator, context) { + var results = []; + if (obj == null) return results; + each(obj, function(value, index, list) { + if (!iterator.call(context, value, index, list)) results[results.length] = value; + }); + return results; + }; + + // Determine whether all of the elements match a truth test. + // Delegates to **ECMAScript 5**'s native `every` if available. + // Aliased as `all`. + _.every = _.all = function(obj, iterator, context) { + var result = true; + if (obj == null) return result; + if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context); + each(obj, function(value, index, list) { + if (!(result = result && iterator.call(context, value, index, list))) return breaker; + }); + return result; + }; + + // Determine if at least one element in the object matches a truth test. + // Delegates to **ECMAScript 5**'s native `some` if available. + // Aliased as `any`. + var any = _.some = _.any = function(obj, iterator, context) { + iterator || (iterator = _.identity); + var result = false; + if (obj == null) return result; + if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context); + each(obj, function(value, index, list) { + if (result = iterator.call(context, value, index, list)) return breaker; + }); + return result; + }; + + // Determine if a given value is included in the array or object using `===`. + // Aliased as `contains`. + _.include = _.contains = function(obj, target) { + var found = false; + if (obj == null) return found; + if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1; + any(obj, function(value) { + if (found = value === target) return true; + }); + return found; + }; + + // Invoke a method (with arguments) on every item in a collection. + _.invoke = function(obj, method) { + var args = slice.call(arguments, 2); + return _.map(obj, function(value) { + return (method.call ? method || value : value[method]).apply(value, args); + }); + }; + + // Convenience version of a common use case of `map`: fetching a property. + _.pluck = function(obj, key) { + return _.map(obj, function(value){ return value[key]; }); + }; + + // Return the maximum element or (element-based computation). + _.max = function(obj, iterator, context) { + if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj); + var result = {computed : -Infinity}; + each(obj, function(value, index, list) { + var computed = iterator ? iterator.call(context, value, index, list) : value; + computed >= result.computed && (result = {value : value, computed : computed}); + }); + return result.value; + }; + + // Return the minimum element (or element-based computation). + _.min = function(obj, iterator, context) { + if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj); + var result = {computed : Infinity}; + each(obj, function(value, index, list) { + var computed = iterator ? iterator.call(context, value, index, list) : value; + computed < result.computed && (result = {value : value, computed : computed}); + }); + return result.value; + }; + + // Sort the object's values by a criterion produced by an iterator. + _.sortBy = function(obj, iterator, context) { + return _.pluck(_.map(obj, function(value, index, list) { + return { + value : value, + criteria : iterator.call(context, value, index, list) + }; + }).sort(function(left, right) { + var a = left.criteria, b = right.criteria; + return a < b ? -1 : a > b ? 1 : 0; + }), 'value'); + }; + + // Use a comparator function to figure out at what index an object should + // be inserted so as to maintain order. Uses binary search. + _.sortedIndex = function(array, obj, iterator) { + iterator || (iterator = _.identity); + var low = 0, high = array.length; + while (low < high) { + var mid = (low + high) >> 1; + iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid; + } + return low; + }; + + // Safely convert anything iterable into a real, live array. + _.toArray = function(iterable) { + if (!iterable) return []; + if (iterable.toArray) return iterable.toArray(); + if (_.isArray(iterable)) return iterable; + if (_.isArguments(iterable)) return slice.call(iterable); + return _.values(iterable); + }; + + // Return the number of elements in an object. + _.size = function(obj) { + return _.toArray(obj).length; + }; + + // Array Functions + // --------------- + + // Get the first element of an array. Passing **n** will return the first N + // values in the array. Aliased as `head`. The **guard** check allows it to work + // with `_.map`. + _.first = _.head = function(array, n, guard) { + return (n != null) && !guard ? slice.call(array, 0, n) : array[0]; + }; + + // Returns everything but the first entry of the array. Aliased as `tail`. + // Especially useful on the arguments object. Passing an **index** will return + // the rest of the values in the array from that index onward. The **guard** + // check allows it to work with `_.map`. + _.rest = _.tail = function(array, index, guard) { + return slice.call(array, (index == null) || guard ? 1 : index); + }; + + // Get the last element of an array. + _.last = function(array) { + return array[array.length - 1]; + }; + + // Trim out all falsy values from an array. + _.compact = function(array) { + return _.filter(array, function(value){ return !!value; }); + }; + + // Return a completely flattened version of an array. + _.flatten = function(array) { + return _.reduce(array, function(memo, value) { + if (_.isArray(value)) return memo.concat(_.flatten(value)); + memo[memo.length] = value; + return memo; + }, []); + }; + + // Return a version of the array that does not contain the specified value(s). + _.without = function(array) { + var values = slice.call(arguments, 1); + return _.filter(array, function(value){ return !_.include(values, value); }); + }; + + // Produce a duplicate-free version of the array. If the array has already + // been sorted, you have the option of using a faster algorithm. + // Aliased as `unique`. + _.uniq = _.unique = function(array, isSorted) { + return _.reduce(array, function(memo, el, i) { + if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) memo[memo.length] = el; + return memo; + }, []); + }; + + // Produce an array that contains every item shared between all the + // passed-in arrays. + _.intersect = function(array) { + var rest = slice.call(arguments, 1); + return _.filter(_.uniq(array), function(item) { + return _.every(rest, function(other) { + return _.indexOf(other, item) >= 0; + }); + }); + }; + + // Zip together multiple lists into a single array -- elements that share + // an index go together. + _.zip = function() { + var args = slice.call(arguments); + var length = _.max(_.pluck(args, 'length')); + var results = new Array(length); + for (var i = 0; i < length; i++) results[i] = _.pluck(args, "" + i); + return results; + }; + + // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**), + // we need this function. Return the position of the first occurrence of an + // item in an array, or -1 if the item is not included in the array. + // Delegates to **ECMAScript 5**'s native `indexOf` if available. + // If the array is large and already in sort order, pass `true` + // for **isSorted** to use binary search. + _.indexOf = function(array, item, isSorted) { + if (array == null) return -1; + var i, l; + if (isSorted) { + i = _.sortedIndex(array, item); + return array[i] === item ? i : -1; + } + if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item); + for (i = 0, l = array.length; i < l; i++) if (array[i] === item) return i; + return -1; + }; + + + // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available. + _.lastIndexOf = function(array, item) { + if (array == null) return -1; + if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item); + var i = array.length; + while (i--) if (array[i] === item) return i; + return -1; + }; + + // Generate an integer Array containing an arithmetic progression. A port of + // the native Python `range()` function. See + // [the Python documentation](http://docs.python.org/library/functions.html#range). + _.range = function(start, stop, step) { + if (arguments.length <= 1) { + stop = start || 0; + start = 0; + } + step = arguments[2] || 1; + + var len = Math.max(Math.ceil((stop - start) / step), 0); + var idx = 0; + var range = new Array(len); + + while(idx < len) { + range[idx++] = start; + start += step; + } + + return range; + }; + + // Function (ahem) Functions + // ------------------ + + // Create a function bound to a given object (assigning `this`, and arguments, + // optionally). Binding with arguments is also known as `curry`. + // Delegates to **ECMAScript 5**'s native `Function.bind` if available. + // We check for `func.bind` first, to fail fast when `func` is undefined. + _.bind = function(func, obj) { + if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); + var args = slice.call(arguments, 2); + return function() { + return func.apply(obj, args.concat(slice.call(arguments))); + }; + }; + + // Bind all of an object's methods to that object. Useful for ensuring that + // all callbacks defined on an object belong to it. + _.bindAll = function(obj) { + var funcs = slice.call(arguments, 1); + if (funcs.length == 0) funcs = _.functions(obj); + each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); }); + return obj; + }; + + // Memoize an expensive function by storing its results. + _.memoize = function(func, hasher) { + var memo = {}; + hasher || (hasher = _.identity); + return function() { + var key = hasher.apply(this, arguments); + return hasOwnProperty.call(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments)); + }; + }; + + // Delays a function for the given number of milliseconds, and then calls + // it with the arguments supplied. + _.delay = function(func, wait) { + var args = slice.call(arguments, 2); + return setTimeout(function(){ return func.apply(func, args); }, wait); + }; + + // Defers a function, scheduling it to run after the current call stack has + // cleared. + _.defer = function(func) { + return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1))); + }; + + // Internal function used to implement `_.throttle` and `_.debounce`. + var limit = function(func, wait, debounce) { + var timeout; + return function() { + var context = this, args = arguments; + var throttler = function() { + timeout = null; + func.apply(context, args); + }; + if (debounce) clearTimeout(timeout); + if (debounce || !timeout) timeout = setTimeout(throttler, wait); + }; + }; + + // Returns a function, that, when invoked, will only be triggered at most once + // during a given window of time. + _.throttle = function(func, wait) { + return limit(func, wait, false); + }; + + // Returns a function, that, as long as it continues to be invoked, will not + // be triggered. The function will be called after it stops being called for + // N milliseconds. + _.debounce = function(func, wait) { + return limit(func, wait, true); + }; + + // Returns a function that will be executed at most one time, no matter how + // often you call it. Useful for lazy initialization. + _.once = function(func) { + var ran = false, memo; + return function() { + if (ran) return memo; + ran = true; + return memo = func.apply(this, arguments); + }; + }; + + // Returns the first function passed as an argument to the second, + // allowing you to adjust arguments, run code before and after, and + // conditionally execute the original function. + _.wrap = function(func, wrapper) { + return function() { + var args = [func].concat(slice.call(arguments)); + return wrapper.apply(this, args); + }; + }; + + // Returns a function that is the composition of a list of functions, each + // consuming the return value of the function that follows. + _.compose = function() { + var funcs = slice.call(arguments); + return function() { + var args = slice.call(arguments); + for (var i=funcs.length-1; i >= 0; i--) { + args = [funcs[i].apply(this, args)]; + } + return args[0]; + }; + }; + + // Returns a function that will only be executed after being called N times. + _.after = function(times, func) { + return function() { + if (--times < 1) { return func.apply(this, arguments); } + }; + }; + + + // Object Functions + // ---------------- + + // Retrieve the names of an object's properties. + // Delegates to **ECMAScript 5**'s native `Object.keys` + _.keys = nativeKeys || function(obj) { + if (obj !== Object(obj)) throw new TypeError('Invalid object'); + var keys = []; + for (var key in obj) if (hasOwnProperty.call(obj, key)) keys[keys.length] = key; + return keys; + }; + + // Retrieve the values of an object's properties. + _.values = function(obj) { + return _.map(obj, _.identity); + }; + + // Return a sorted list of the function names available on the object. + // Aliased as `methods` + _.functions = _.methods = function(obj) { + return _.filter(_.keys(obj), function(key){ return _.isFunction(obj[key]); }).sort(); + }; + + // Extend a given object with all the properties in passed-in object(s). + _.extend = function(obj) { + each(slice.call(arguments, 1), function(source) { + for (var prop in source) { + if (source[prop] !== void 0) obj[prop] = source[prop]; + } + }); + return obj; + }; + + // Fill in a given object with default properties. + _.defaults = function(obj) { + each(slice.call(arguments, 1), function(source) { + for (var prop in source) { + if (obj[prop] == null) obj[prop] = source[prop]; + } + }); + return obj; + }; + + // Create a (shallow-cloned) duplicate of an object. + _.clone = function(obj) { + return _.isArray(obj) ? obj.slice() : _.extend({}, obj); + }; + + // Invokes interceptor with the obj, and then returns obj. + // The primary purpose of this method is to "tap into" a method chain, in + // order to perform operations on intermediate results within the chain. + _.tap = function(obj, interceptor) { + interceptor(obj); + return obj; + }; + + // Perform a deep comparison to check if two objects are equal. + _.isEqual = function(a, b) { + // Check object identity. + if (a === b) return true; + // Different types? + var atype = typeof(a), btype = typeof(b); + if (atype != btype) return false; + // Basic equality test (watch out for coercions). + if (a == b) return true; + // One is falsy and the other truthy. + if ((!a && b) || (a && !b)) return false; + // Unwrap any wrapped objects. + if (a._chain) a = a._wrapped; + if (b._chain) b = b._wrapped; + // One of them implements an isEqual()? + if (a.isEqual) return a.isEqual(b); + // Check dates' integer values. + if (_.isDate(a) && _.isDate(b)) return a.getTime() === b.getTime(); + // Both are NaN? + if (_.isNaN(a) && _.isNaN(b)) return false; + // Compare regular expressions. + if (_.isRegExp(a) && _.isRegExp(b)) + return a.source === b.source && + a.global === b.global && + a.ignoreCase === b.ignoreCase && + a.multiline === b.multiline; + // If a is not an object by this point, we can't handle it. + if (atype !== 'object') return false; + // Check for different array lengths before comparing contents. + if (a.length && (a.length !== b.length)) return false; + // Nothing else worked, deep compare the contents. + var aKeys = _.keys(a), bKeys = _.keys(b); + // Different object sizes? + if (aKeys.length != bKeys.length) return false; + // Recursive comparison of contents. + for (var key in a) if (!(key in b) || !_.isEqual(a[key], b[key])) return false; + return true; + }; + + // Is a given array or object empty? + _.isEmpty = function(obj) { + if (_.isArray(obj) || _.isString(obj)) return obj.length === 0; + for (var key in obj) if (hasOwnProperty.call(obj, key)) return false; + return true; + }; + + // Is a given value a DOM element? + _.isElement = function(obj) { + return !!(obj && obj.nodeType == 1); + }; + + // Is a given value an array? + // Delegates to ECMA5's native Array.isArray + _.isArray = nativeIsArray || function(obj) { + return toString.call(obj) === '[object Array]'; + }; + + // Is a given variable an arguments object? + _.isArguments = function(obj) { + return !!(obj && hasOwnProperty.call(obj, 'callee')); + }; + + // Is a given value a function? + _.isFunction = function(obj) { + return !!(obj && obj.constructor && obj.call && obj.apply); + }; + + // Is a given value a string? + _.isString = function(obj) { + return !!(obj === '' || (obj && obj.charCodeAt && obj.substr)); + }; + + // Is a given value a number? + _.isNumber = function(obj) { + return !!(obj === 0 || (obj && obj.toExponential && obj.toFixed)); + }; + + // Is the given value `NaN`? `NaN` happens to be the only value in JavaScript + // that does not equal itself. + _.isNaN = function(obj) { + return obj !== obj; + }; + + // Is a given value a boolean? + _.isBoolean = function(obj) { + return obj === true || obj === false; + }; + + // Is a given value a date? + _.isDate = function(obj) { + return !!(obj && obj.getTimezoneOffset && obj.setUTCFullYear); + }; + + // Is the given value a regular expression? + _.isRegExp = function(obj) { + return !!(obj && obj.test && obj.exec && (obj.ignoreCase || obj.ignoreCase === false)); + }; + + // Is a given value equal to null? + _.isNull = function(obj) { + return obj === null; + }; + + // Is a given variable undefined? + _.isUndefined = function(obj) { + return obj === void 0; + }; + + // Utility Functions + // ----------------- + + // Run Underscore.js in *noConflict* mode, returning the `_` variable to its + // previous owner. Returns a reference to the Underscore object. + _.noConflict = function() { + root._ = previousUnderscore; + return this; + }; + + // Keep the identity function around for default iterators. + _.identity = function(value) { + return value; + }; + + // Run a function **n** times. + _.times = function (n, iterator, context) { + for (var i = 0; i < n; i++) iterator.call(context, i); + }; + + // Add your own custom functions to the Underscore object, ensuring that + // they're correctly added to the OOP wrapper as well. + _.mixin = function(obj) { + each(_.functions(obj), function(name){ + addToWrapper(name, _[name] = obj[name]); + }); + }; + + // Generate a unique integer id (unique within the entire client session). + // Useful for temporary DOM ids. + var idCounter = 0; + _.uniqueId = function(prefix) { + var id = idCounter++; + return prefix ? prefix + id : id; + }; + + // By default, Underscore uses ERB-style template delimiters, change the + // following template settings to use alternative delimiters. + _.templateSettings = { + evaluate : /<%([\s\S]+?)%>/g, + interpolate : /<%=([\s\S]+?)%>/g + }; + + // JavaScript micro-templating, similar to John Resig's implementation. + // Underscore templating handles arbitrary delimiters, preserves whitespace, + // and correctly escapes quotes within interpolated code. + _.template = function(str, data) { + var c = _.templateSettings; + var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' + + 'with(obj||{}){__p.push(\'' + + str.replace(/\\/g, '\\\\') + .replace(/'/g, "\\'") + .replace(c.interpolate, function(match, code) { + return "'," + code.replace(/\\'/g, "'") + ",'"; + }) + .replace(c.evaluate || null, function(match, code) { + return "');" + code.replace(/\\'/g, "'") + .replace(/[\r\n\t]/g, ' ') + "__p.push('"; + }) + .replace(/\r/g, '\\r') + .replace(/\n/g, '\\n') + .replace(/\t/g, '\\t') + + "');}return __p.join('');"; + var func = new Function('obj', tmpl); + return data ? func(data) : func; + }; + + // The OOP Wrapper + // --------------- + + // If Underscore is called as a function, it returns a wrapped object that + // can be used OO-style. This wrapper holds altered versions of all the + // underscore functions. Wrapped objects may be chained. + var wrapper = function(obj) { this._wrapped = obj; }; + + // Expose `wrapper.prototype` as `_.prototype` + _.prototype = wrapper.prototype; + + // Helper function to continue chaining intermediate results. + var result = function(obj, chain) { + return chain ? _(obj).chain() : obj; + }; + + // A method to easily add functions to the OOP wrapper. + var addToWrapper = function(name, func) { + wrapper.prototype[name] = function() { + var args = slice.call(arguments); + unshift.call(args, this._wrapped); + return result(func.apply(_, args), this._chain); + }; + }; + + // Add all of the Underscore functions to the wrapper object. + _.mixin(_); + + // Add all mutator Array functions to the wrapper. + each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { + var method = ArrayProto[name]; + wrapper.prototype[name] = function() { + method.apply(this._wrapped, arguments); + return result(this._wrapped, this._chain); + }; + }); + + // Add all accessor Array functions to the wrapper. + each(['concat', 'join', 'slice'], function(name) { + var method = ArrayProto[name]; + wrapper.prototype[name] = function() { + return result(method.apply(this._wrapped, arguments), this._chain); + }; + }); + + // Start chaining a wrapped Underscore object. + wrapper.prototype.chain = function() { + this._chain = true; + return this; + }; + + // Extracts the result from a wrapped and chained object. + wrapper.prototype.value = function() { + return this._wrapped; + }; + +})(); diff --git a/doc/html/api/dyaml.constructor.html b/doc/html/api/dyaml.constructor.html index ac826e6..697ca19 100644 --- a/doc/html/api/dyaml.constructor.html +++ b/doc/html/api/dyaml.constructor.html @@ -24,9 +24,13 @@ @@ -45,7 +49,7 @@

Can be thrown by custom constructor functions.

-
this(string msg, Mark start, Mark end); +
this(string msg, Mark start, Mark end, string file = __FILE__, int line = __LINE__);

Construct a ConstructorException.

@@ -98,6 +102,9 @@ the node in file) and either a string (if constructing from scalar), an array of Nodes (from sequence) or an array of Node.Pair (from mapping). The value returned by this function will be stored in the resulring node. +
+ + Only one constructor function can be set for one tag.

Parameters:
diff --git a/doc/html/api/dyaml.dumper.html b/doc/html/api/dyaml.dumper.html new file mode 100644 index 0000000..8113df9 --- /dev/null +++ b/doc/html/api/dyaml.dumper.html @@ -0,0 +1,223 @@ + + + + + +dyaml.dumper - D:YAML 0.1 API documentation + + + + + + + +
+

dyaml.dumper

+ +

YAML dumper. +

+

Code based on PyYAML.

+ +
struct Dumper; +
+

Dumps YAML documents to files or streams. +

+

User specified Representer and/or Resolver can be used to support new + tags / data types. +
+ + Setters are provided to affect output details (style, encoding, etc.). + +

+Examples:
Write to a file: +
 auto node = Node([1, 2, 3, 4, 5]);
+ Dumper("file.yaml").dump(node);
+
+ + Write multiple YAML documents to a file: +
 auto node1 = Node([1, 2, 3, 4, 5]);
+ auto node2 = Node("This document contains only one string");
+ Dumper("file.yaml").dump(node1, node2);
+
+ //Or with an array:
+ //Dumper("file.yaml").dump([node1, node2]);
+
+
+
+ + Write to memory: +
 import std.stream;
+ auto stream = new MemoryStream();
+ auto node = Node([1, 2, 3, 4, 5]);
+ Dumper(stream).dump(node);
+
+ + Use a custom representer/resolver to support custom data types and/or implicit tags: +
 auto node = Node([1, 2, 3, 4, 5]);
+ auto representer = new Representer();
+ auto resolver = new Resolver();
+
+ //Add representer functions / resolver expressions here...
+
+ auto dumper = Dumper("file.yaml");
+ dumper.representer = representer;
+ dumper.resolver = resolver;
+ dumper.dump(node);
+
+
+ +
this(string filename); +
+

Construct a Dumper writing to a file. +

+Parameters:
tag
+ +
string filenameFile name to write to.
+Throws:
YAMLException if the file can not be dumped to (e.g. cannot be opened).
+ + +
this(Stream stream); +
+

Construct a Dumper writing to a stream. This is useful to e.g. write to memory.

+ +
+
void resolver(Resolver resolver); +
+

Specify custom Resolver to use.

+ +
+
void representer(Representer representer); +
+

Specify custom Representer to use.

+ +
+
void canonical(in bool canonical); +
+

Write scalars in canonical form?

+ +
+
void indent(in uint indent); +
+

Set indentation width. 2 by default. Must not be zero.

+ +
+
void textWidth(in uint width); +
+

Set preferred text width.

+ +
+
void lineBreak(in LineBreak lineBreak); +
+

Set line break to use. Unix by default.

+ +
+
void encoding(in Encoding encoding); +
+

Set character encoding to use. UTF-8 by default.

+ +
+
void explicitStart(in bool explicit); +
+

Always explicitly write document start?

+ +
+
void explicitEnd(in bool explicit); +
+

Always explicitly write document end?

+ +
+
void YAMLVersion(in string YAMLVersion); +
+

Specify YAML version string. "1.1" by default.

+ +
+
void tagDirectives(string[string] tags); +
+

Specify tag directives. +

+

A tag directive specifies a shorthand notation for specifying tags. + Each tag directive associates a handle with a prefix. This allows for + compact tag notation. +
+ + Each handle specified MUST start and end with a '!' character + (a single character "!" handle is allowed as well). +
+ + Only alphanumeric characters, '-', and '_' may be used in handles. +
+ + Each prefix MUST not be empty. +
+ + The "!!" handle is used for default YAML tags with prefix + "tag:yaml.org,2002:". This can be overridden. + +

+Parameters:
+ +
string[string] tagsTag directives (keys are handles, values are prefixes).
+

Example:
+

 Dumper dumper = Dumper("file.yaml");
+ //This will emit tags starting with "tag:long.org,2011"
+ //with a "!short!" prefix instead.
+ dumper.tags("short", "tag:long.org,2011:");
+ dumper.dump(Node("foo"));
+
+

+ +
+
void dump(Node[] documents...); +
+

Dump one or more YAML documents to the file/stream. +

+

Note that while you can call dump() multiple times on the same + dumper, you will end up writing multiple YAML "files" to the same + file/stream. + +

+Parameters:
+ +
Node[] documentsDocuments to dump (root nodes of the documents).
+Throws:
YAMLException on error (e.g. invalid nodes, + unable to write to file/stream).
+ +
+ + + + + + + + + + diff --git a/doc/html/api/dyaml.encoding.html b/doc/html/api/dyaml.encoding.html new file mode 100644 index 0000000..3d226d9 --- /dev/null +++ b/doc/html/api/dyaml.encoding.html @@ -0,0 +1,71 @@ + + + + + +dyaml.encoding - D:YAML 0.1 API documentation + + + + + + + +
+

dyaml.encoding

+ +
+
enum Encoding; +
+

Text encodings supported by D:YAML.

+ +
UTF_8
+

Unicode UTF-8

+ +
+
UTF_16
+

Unicode UTF-16

+ +
+
UTF_32
+

Unicode UTF-32

+ +
+
+
+
+ +
+ + + + + diff --git a/doc/html/api/dyaml.exception.html b/doc/html/api/dyaml.exception.html index b2c7dd8..dfaf5b7 100644 --- a/doc/html/api/dyaml.exception.html +++ b/doc/html/api/dyaml.exception.html @@ -24,9 +24,13 @@ @@ -35,16 +39,15 @@

dyaml.exception

-

D:
-YAML exceptions and exception related code.

+

Exceptions thrown by D:YAML and exception related code.

class YAMLException: object.Exception;

Base class for all exceptions thrown by D:YAML.

-
this(string msg); +
this(string msg, string file = __FILE__, int line = __LINE__);
-

Construct a YAMLException with specified message.

+

Construct a YAMLException with specified message, and position where it was thrown.

diff --git a/doc/html/api/dyaml.linebreak.html b/doc/html/api/dyaml.linebreak.html new file mode 100644 index 0000000..18b1151 --- /dev/null +++ b/doc/html/api/dyaml.linebreak.html @@ -0,0 +1,71 @@ + + + + + +dyaml.linebreak - D:YAML 0.1 API documentation + + + + + + + +
+

dyaml.linebreak

+ +
+
enum LineBreak; +
+

Enumerates platform specific line breaks.

+ +
Unix
+

Unix line break ("\n").

+ +
+
Windows
+

Windows line break ("\r\n").

+ +
+
Macintosh
+

Macintosh line break ("\r").

+ +
+
+
+
+ +
+ + + + + diff --git a/doc/html/api/dyaml.loader.html b/doc/html/api/dyaml.loader.html index 2660fff..8be8ea2 100644 --- a/doc/html/api/dyaml.loader.html +++ b/doc/html/api/dyaml.loader.html @@ -24,9 +24,13 @@ @@ -35,50 +39,36 @@

dyaml.loader

-

Class and convenience functions used to load YAML documents.

+

Class used to load YAML documents.

-
Node load(in string filename); +
struct Loader;
-

Load single YAML document from a file. +

Loads YAML documents from files or streams.

-

If there is no or more than one YAML document in the file, this will throw. - Use loadAll for such files. +

User specified Constructor and/or Resolver can be used to support new + tags / data types.

-Parameters:
- -
string filenameName of the file to load from.
-Returns:
Root node of the document. +Examples:
Load single YAML document from a file: +
 auto rootNode = Loader("file.yaml").load();
+ ...
+
-
-Throws:
YAMLException if there wasn't exactly one document in the file, - the file could not be opened or on a YAML parsing error.
+ Load all YAML documents from a file: +
 auto nodes = Loader("file.yaml").loadAll();
+ ...
+
-
-
Node load(Stream input, in string name = "<unknown>"); -
-

Load single YAML document from a stream. -

-

You can use this to e.g load YAML from memory. -
+ Iterate over YAML documents in a file, lazily loading them: +

 auto loader = Loader("file.yaml");
 
- If there is no or more than one YAML document in the stream, this will throw.
- Use loadAll for such files.
+ foreach(ref node; loader)
+ {
+     ...
+ }
+
-

-Parameters:
- - - -
Stream inputStream to read from. Must be readable.
string nameName of the stream, used in error messages.
-Returns:
Root node of the document. - -
-Throws:
YAMLException if there wasn't exactly one document in the stream, - the stream could not be read from or on a YAML parsing error. - -
-Examples:
Loading YAML from memory: + Load YAML from memory:
 import std.stream;
  import std.stdio;
 
@@ -86,50 +76,27 @@
                      "green: '#00ff00'\n"
                      "blue:  '#0000ff'";
 
- auto colors = yaml.load(new MemoryStream(cast(char[])yaml_input));
+ auto colors = Loader(new MemoryStream(cast(char[])yaml_input)).load();
 
  foreach(string color, string value; colors)
  {
      writeln(color, " is ", value, " in HTML/CSS");
  }
 
+ + Use a custom constructor/resolver to support custom data types and/or implicit tags: +
 auto constructor = new Constructor();
+ auto resolver = new Resolver();
+
+ //Add constructor functions / resolver expressions here...
+
+ auto loader = Loader("file.yaml");
+ loader.constructor = constructor;
+ loader.resolver = resolver;
+ auto rootNode = loader.load(node);
+
-
-
Node[] loadAll(in string filename); -
-

Load all YAML documents from a file. -

-Parameters:
- -
string filenameName of the file to load from.
-Returns:
Array of root nodes of documents in the stream. - If the stream is empty, empty array will be returned. - -
-Throws:
YAMLException if the file could not be opened or on a YAML parsing error.
- -
-
Node[] loadAll(Stream input, in string name = "<unknown>"); -
-

Load all YAML documents from a stream. -

-Parameters:
- - - -
Stream inputStream to read from. Must be readable.
string nameName of the stream, used in error messages.
-Returns:
Array of root nodes of documents in the file. - If the file is empty, empty array will be returned. - -
-Throws:
YAMLException if the stream could not be read from or on a YAML parsing error.
- -
-
struct Loader; -
-

Loads YAML documents from files or streams.

-
this(in string filename);

Construct a Loader to load YAML from a file. @@ -140,48 +107,36 @@ Throws:

YAMLException if the file could not be opened or read from.
-
this(in string filename, Constructor constructor, Resolver resolver); +
this(Stream stream);
-

Construct a Loader to load YAML from a file, with provided constructor and resolver. +

Construct a Loader to load YAML from a stream.

-

Constructor and resolver can be used to implement custom data types in YAML. - -

-Parameters:
- - - - - -
string filenameName of the file to load from.
Constructor constructorConstructor to use.
Resolver resolverResolver to use.
-Throws:
YAMLException if the file could not be opened or read from.
- -
-
this(Stream input, in string name, Constructor constructor, Resolver resolver); -
-

Construct a Loader to load YAML from a stream with provided constructor and resolver. -

-

Stream can be used to load YAML from memory and other sources. - Constructor and resolver can be used to implement custom data types in YAML. - -

-Parameters:
+Parameters:
Stream input
- - - - - -
Stream stream Stream to read from. Must be readable.
string nameName of the stream. Used in error messages.
Constructor constructorConstructor to use.
Resolver resolverResolver to use.
-Throws:
YAMLException if the stream could not be read from.
+Throws:
YAMLException if stream could not be read from.
-
Node loadSingleDocument(); +
@property void name(string name); +
+

Set stream name. Used in debugging messages.

+ +
+
@property void resolver(Resolver resolver); +
+

Specify custom Resolver to use.

+ +
+
@property void constructor(Constructor constructor); +
+

Specify custom Constructor to use.

+ +
+
Node load();

Load single YAML document.

-

If no or more than one YAML document is found, this will throw a YAMLException. +

If none or more than one YAML document is found, this will throw a YAMLException.

Returns:
Root node of the document. @@ -190,12 +145,22 @@ Throws:
YAMLException if there wasn't exactly one document or on a YAML parsing error.
+
+
Node[] loadAll(); +
+

Load all YAML documents. +

+Returns:
Array of root nodes of all documents in the file/stream. + +
+Throws:
YAMLException on a YAML parsing error.
+
int opApply(int delegate(ref Node) dg);

Foreach over YAML documents.

-

Parses documents lazily, as they are needed. +

Parses documents lazily, when they are needed.

Throws:
YAMLException on a parsing error.
diff --git a/doc/html/api/dyaml.node.html b/doc/html/api/dyaml.node.html index e4d9ac3..d0f90a3 100644 --- a/doc/html/api/dyaml.node.html +++ b/doc/html/api/dyaml.node.html @@ -24,9 +24,13 @@ @@ -35,7 +39,8 @@

dyaml.node

-

Node of a YAML document. Used to read YAML data once it's loaded.

+

Node of a YAML document. Used to read YAML data once it's loaded, + and to prepare data to emit.

class NodeException: dyaml.exception.YAMLException;
@@ -51,13 +56,13 @@

YAML node.

-

This is a pseudo-dynamic type that can store any YAML value, including sequence - or a mapping of nodes. You can get data from a Node directly or iterate over it - if it's a sequence or a mapping.

+

This is a pseudo-dynamic type that can store any YAML value, including a + sequence or mapping of nodes. You can get data from a Node directly or + iterate over it if it's a collection.

struct Pair;
-

Pair of YAML nodes, used in mappings.

+

Key-value pair of YAML nodes, used in mappings.

Node key;
@@ -68,13 +73,154 @@

Value node.

+
+
auto this(K, V)(K key, V value); +
+

Construct a Pair from two values. Will be converted to Nodes if needed.

+
bool equals(ref Pair rhs);
-

Test for equality with another Pair.

+

Equality test with another Pair.

+
+
auto this(T)(T value, in string tag = null); +
+

Construct a Node from a value. +

+

Any type except of Node can be stored in a Node, but default YAML + types (integers, floats, strings, timestamps, etc.) will be stored + more efficiently. +
+ +
+ + Note that to emit any non-default types you store + in a node, you need a Representer to represent them in YAML - + otherwise emitting will fail. + +

+Parameters:
+ + + +
valueValue to store in the node.
tagOverrides tag of the node when emitted, regardless + of tag determined by Representer. Representer uses + this to determine YAML data type when a D data type + maps to multiple different YAML data types. Tag must + be in full form, e.g. "tag:yaml.org,2002:int", not + a shortcut, like "!!int".
+ +
+
auto this(T)(T[] array, in string tag = null); +
+

Construct a node from an array. +

+

If array is an array of nodes or pairs, it is stored directly. + Otherwise, every value in the array is converted to a node, and + those nodes are stored. + +

+Parameters:
+ + + +
arrayValues to store in the node.
tagOverrides tag of the node when emitted, regardless + of tag determined by Representer. Representer uses + this to determine YAML data type when a D data type + maps to multiple different YAML data types. + This is used to differentiate between YAML sequences + ("!!seq") and sets ("!!set"), which both are + internally represented as an array_ of nodes. Tag + must be in full form, e.g. "tag:yaml.org,2002:set", + not a shortcut, like "!!set".
+Examples:
 //Will be emitted as a sequence (default for arrays)
+ auto seq = Node([1, 2, 3, 4, 5]);
+ //Will be emitted as a set (overriden tag)
+ auto set = Node([1, 2, 3, 4, 5], "tag:yaml.org,2002:set");
+
+
+ +
+
auto this(K, V)(V[K] array, in string tag = null); +
+

Construct a node from an associative array. +

+

If keys and/or values of array are nodes, they stored directly. + Otherwise they are converted to nodes and then stored. + +

+Parameters:
+ + + +
arrayValues to store in the node.
tagOverrides tag of the node when emitted, regardless + of tag determined by Representer. Representer uses + this to determine YAML data type when a D data type + maps to multiple different YAML data types. + This is used to differentiate between YAML unordered + mappings ("!!map"), ordered mappings ("!!omap"), and + pairs ("!!pairs") which are all internally + represented as an array of node pairs. Tag must be + in full form, e.g. "tag:yaml.org,2002:omap", not a + shortcut, like "!!omap".
+Examples:
 //Will be emitted as an unordered mapping (default for mappings)
+ auto map   = Node([1 : "a", 2 : "b"]);
+ //Will be emitted as an ordered map (overriden tag)
+ auto omap  = Node([1 : "a", 2 : "b"], "tag:yaml.org,2002:omap");
+ //Will be emitted as pairs (overriden tag)
+ auto pairs = Node([1 : "a", 2 : "b"], "tag:yaml.org,2002:pairs");
+
+
+ +
+
auto this(K, V)(K[] keys, V[] values, in string tag = null); +
+

Construct a node from arrays of keys and values. +

+

Constructs a mapping node with key-value pairs from + keys and values, keeping their order. Useful when order + is important (ordered maps, pairs). +
+ +
+ + keys and values must have equal length. +
+ +
+ + If keys and/or values are nodes, they are stored directly/ + Otherwise they are converted to nodes and then stored. + +

+Parameters:
+ + + + + +
keysKeys of the mapping, from first to last pair.
valuesValues of the mapping, from first to last pair.
tagOverrides tag of the node when emitted, regardless + of tag determined by Representer. Representer uses + this to determine YAML data type when a D data type + maps to multiple different YAML data types. + This is used to differentiate between YAML unordered + mappings ("!!map"), ordered mappings ("!!omap"), and + pairs ("!!pairs") which are all internally + represented as an array of node pairs. Tag must be + in full form, e.g. "tag:yaml.org,2002:omap", not a + shortcut, like "!!omap".
+Examples:
 //Will be emitted as an unordered mapping (default for mappings)
+ auto map   = Node([1, 2], ["a", "b"]);
+ //Will be emitted as an ordered map (overriden tag)
+ auto omap  = Node([1, 2], ["a", "b"], "tag:yaml.org,2002:omap");
+ //Will be emitted as pairs (overriden tag)
+ auto pairs = Node([1, 2], ["a", "b"], "tag:yaml.org,2002:pairs");
+
+
+
const @property bool isValid();
@@ -88,12 +234,12 @@
const @property bool isSequence();
-

Is this node a sequence of nodes?

+

Is this node a sequence?

const @property bool isMapping();
-

Is this node a mapping of nodes?

+

Is this node a mapping?

const @property bool isUserType(); @@ -105,15 +251,16 @@

Equality test.

-

If T is Node, recursively compare all - subnodes and might be quite expensive if testing entire documents. +

If T is Node, recursively compare all subnodes. + This might be quite expensive if testing entire documents.
If T is not Node, convert the node to T and test equality with that.

-Examples:
 //node is a Node that contains integer 42
- assert(node == 42);
+Examples:
 auto node = Node(42);
+
+ assert(node == 42);
  assert(node == "42");
  assert(node != "43");
 
@@ -130,7 +277,7 @@

Get the value of the node as specified type.

If the specifed type does not match type in the node, - conversion is attempted if possible. + conversion is attempted.
Timestamps are stored as std.datetime.SysTime. @@ -145,13 +292,14 @@ but is replaced by a mapping later. Even if the node is a mapping, the get method can be used as if it was a scalar if it has a default value. This way, new YAML files where the node is a mapping can still be read - by old versions of the program, which expects the node to be a scalar. + by old versions of the program, which expect the node to be a scalar.

Examples:
Automatic type conversion: -
 //node is a node that contains integer 42
- assert(node.get!int == 42);
+
 auto node = Node(42);
+
+ assert(node.get!int == 42);
  assert(node.get!string == "42");
  assert(node.get!double == 42.0);
 
@@ -167,8 +315,8 @@

Write the value of the node to target.

-

If the type of target does not match type of the node, - conversion is attempted, if possible. +

If the target type does not match node type, + conversion is attempted.

Parameters:
@@ -179,7 +327,7 @@
@property size_t length();
-

If this is a sequence or a mapping, return its length. +

If this is a collection, return its length.

Otherwise, throw NodeException. @@ -190,11 +338,13 @@ Throws:

NodeException if this is not a sequence nor a mapping.
-
Node opIndex(T)(in T index); +
Node opIndex(T)(T index);
-

Get the element with specified index. +

Get the element at specified index.

If the node is a sequence, index must be integral. +
+
If the node is a mapping, return the value corresponding to the first @@ -208,7 +358,36 @@ Returns:

Value corresponding to the index.
-Throws:
NodeException if the index could not be found.
+Throws:
NodeException if the index could not be found, + non-integral index is used with a sequence or the node is + not a collection.
+ +
+
void opIndexAssign(K, V)(V value, K index); +
+

Set element at specified index in a collection. +

+

This method can only be called on collection nodes. +
+ + If the node is a sequence, index must be integral. +
+ + If the node is a mapping, sets the value corresponding to the first + key matching index (including conversion, so e.g. "42" matches 42). +
+ + If the node is a mapping and no key matches index, a new key-value + pair is added to the mapping. In sequences the index must be in + range. This ensures behavior siilar to D arrays and associative + arrays. + +

+Parameters:
target
+ +
indexIndex of the value to set.
+Throws:
NodeException if the node is not a collection, index is out + of range or if a non-integral index is used on a sequence node.
int opApply(T)(int delegate(ref T) dg); @@ -235,14 +414,95 @@ element could not be converted to specified type.
-
alias isInt; +
void add(T)(T value);
-

Is the value an integer of some kind?

+

Add an element to a sequence. +

+

This method can only be called on sequence nodes. +
+ + If value is a node, it is copied to the sequence directly. Otherwise + value is converted to a node and then stored in the sequence. +
+ +

When emitting, all values in the sequence will be emitted. When + using the !!set tag, the user needs to ensure that all elements in + the sequence are unique, otherwise invalid YAML code will be + emitted.

+ +

+Parameters:
+ +
valueValue to add to the sequence.
-
alias isFloat; +
void add(K, V)(K key, V value);
-

Is the value a floating point number of some kind?

+

Add a key-value pair to a mapping. +

+

This method can only be called on mapping nodes. +
+ + If key and/or value is a node, it is copied to the mapping directly. + Otherwise it is converted to a node and then stored in the mapping. +
+ +

It is possible for the same key to be present more than once in a + mapping. When emitting, all key-value pairs will be emitted. + This is useful with the "!!pairs" tag, but will result in + invalid YAML with "!!map" and "!!omap" tags.

+ +

+Parameters:
+ + + +
keyKey to add.
valueValue to add.
+ +
+
void remove(T)(T value); +
+

Remove first (if any) occurence of a value in a collection. +

+

This method can only be called on collection nodes. +
+ + If the node is a sequence, the first node matching value (including + conversion, so e.g. "42" matches 42) is removed. + If the node is a mapping, the first key-value pair where value + matches specified value is removed. + +

+Parameters:
+ +
valueValue to remove.
+Throws:
NodeException if the node is not a collection.
+ +
+
void removeAt(T)(T index); +
+

Remove element at the specified index of a collection. +

+

This method can only be called on collection nodes. +
+ + If the node is a sequence, index must be integral. +
+ + If the node is a mapping, remove the first key-value pair where + key matches index (including conversion, so e.g. "42" matches 42). +
+ + If the node is a mapping and no key matches index, nothing is removed + and no exception is thrown. This ensures behavior siilar to D arrays + and associative arrays. + +

+Parameters:
+ +
indexIndex to remove at.
+Throws:
NodeException if the node is not a collection, index is out + of range or if a non-integral index is used on a sequence node.
diff --git a/doc/html/api/dyaml.representer.html b/doc/html/api/dyaml.representer.html new file mode 100644 index 0000000..593dcd0 --- /dev/null +++ b/doc/html/api/dyaml.representer.html @@ -0,0 +1,326 @@ + + + + + +dyaml.representer - D:YAML 0.1 API documentation + + + + + + + +
+

dyaml.representer

+ +

YAML node representer. +

+

Code based on PyYAML.

+ +
class RepresenterException: dyaml.exception.YAMLException; +
+

Exception thrown on Representer errors.

+ +
+
class Representer; +
+

Used to represent YAML nodes various data types into scalar, sequence and mapping nodes ready for output.

+ +
this(bool useDefaultRepresenters = true); +
+

Construct a Representer. +

+Parameters:
+ +
bool useDefaultRepresentersUse default representer functions + for default YAML types? This can be + disabled to use custom representer + functions for default types.
+ +
+
void addRepresenter(T)(Node function(ref Node, Representer) representer); +
+

Add a function to represent nodes with a specific data type. +

+

The representer function takes a reference to a Node storing the data + type and to the Representer. It returns the represented node and may + throw a RepresenterException. See the example for more information. +
+ + Only one function may be specified for one data type. Default data + types already have representer functions unless disabled in these + Representer constructor. + +

+Parameters:
+ +
representerRepresenter function to add.
+Examples:
Representing a simple struct: +
 import std.string;
+
+ import yaml;
+
+ struct MyStruct
+ {
+     int x, y, z;
+ }
+
+ Node representMyStruct(ref Node node, Representer representer)
+ {
+     //The node is guaranteed to be MyStruct as we add representer for MyStruct.
+     auto value = node.get!MyStruct;
+     //Using custom scalar format, x:y:z.
+     auto scalar = format(value.x, ":", value.y, ":", value.z);
+     //Representing as a scalar, with custom tag to specify this data type.
+     return representer.representScalar("!mystruct.tag", scalar);
+ }
+
+ void main()
+ {
+     auto dumper = Dumper("file.txt");
+     auto representer = new Representer;
+     representer.addRepresenter!MyStruct(&representMyStruct);
+     dumper.representer = representer;
+     dumper.dump(Node(MyStruct(1,2,3)));
+ }
+
+ + Representing a class: +
 import std.string;
+
+ import yaml;
+
+ class MyClass
+ {
+     int x, y, z;
+
+     this(int x, int y, int z)
+     {
+         this.x = x;
+         this.y = y;
+         this.z = z;
+     }
+
+     ///We need custom opEquals for node equality, as default opEquals compares references.
+     override bool opEquals(Object rhs)
+     {
+         if(typeid(rhs) != typeid(MyClass)){return false;}
+         auto t = cast(MyClass)rhs;
+         return x == t.x && y == t.y && z == t.z;
+     }
+
+     ///Useful for Node.get!string .
+     override string toString()
+     {
+         return format("MyClass("), x, ", ", y, ", ", z, "");
+     }
+ }
+
+ //Same as representMyStruct.
+ Node representMyClass(ref Node node, Representer representer)
+ {
+     //The node is guaranteed to be MyClass as we add representer for MyClass.
+     auto value = node.get!MyClass;
+     //Using custom scalar format, x:y:z.
+     auto scalar = format(value.x, ":", value.y, ":", value.z);
+     //Representing as a scalar, with custom tag to specify this data type.
+     return representer.representScalar("!myclass.tag", scalar);
+ }
+
+ void main()
+ {
+     auto dumper = Dumper("file.txt");
+     auto representer = new Representer;
+     representer.addRepresenter!MyClass(&representMyClass);
+     dumper.representer = representer;
+     dumper.dump(Node(new MyClass(1,2,3)));
+ }
+
+
+ +
+
Node representScalar(in string tag, string scalar); +
+

Represent a scalar with specified tag. +

+

This is used by representer functions that produce scalars. + +

+Parameters:
+ + + +
string tagTag of the scalar.
string scalarScalar value.
+Returns:
The represented node. + +
+

Example:
+

 struct MyStruct
+ {
+     int x, y, z;
+ }
+
+ Node representMyStruct(ref Node node, Representer representer)
+ {
+     auto value = node.get!MyStruct;
+     auto scalar = format(value.x, ":", value.y, ":", value.z);
+     return representer.representScalar("!mystruct.tag", scalar);
+ }
+
+

+ +
+
Node representSequence(in string tag, Node[] sequence); +
+

Represent a sequence with specified tag, representing children first. +

+

This is used by representer functions that produce sequences. + +

+Parameters:
+ + + +
string tagTag of the sequence.
Node[] sequenceSequence of nodes.
+Returns:
The represented node. + +
+Throws:
RepresenterException if a child could not be represented. + +
+

Example:
+

 struct MyStruct
+ {
+     int x, y, z;
+ }
+
+ Node representMyStruct(ref Node node, Representer representer)
+ {
+     auto value = node.get!MyStruct;
+     auto nodes = [Node(value.x), Node(value.y), Node(value.z)];
+     return representer.representSequence("!mystruct.tag", nodes);
+ }
+
+

+ +
+
Node representMapping(in string tag, Pair[] pairs); +
+

Represent a mapping with specified tag, representing children first. +

+

This is used by representer functions that produce mappings. + +

+Parameters:
+ + + +
string tagTag of the mapping.
Pair[] pairsKey-value pairs of the mapping.
+Returns:
The represented node. + +
+Throws:
RepresenterException if a child could not be represented. + +
+

Example:
+

 struct MyStruct
+ {
+     int x, y, z;
+ }
+
+ Node representMyStruct(ref Node node, Representer representer)
+ {
+     auto value = node.get!MyStruct;
+     auto pairs = [Node.Pair("x", value.x),
+                   Node.Pair("y", value.y),
+                   Node.Pair("z", value.z)];
+     return representer.representMapping("!mystruct.tag", pairs);
+ }
+
+

+ +
+
+
+
Node representNull(ref Node node, Representer representer); +
+

Represent a null node as a null YAML value.

+ +
+
Node representString(ref Node node, Representer representer); +
+

Represent a string node as a string scalar.

+ +
+
Node representBytes(ref Node node, Representer representer); +
+

Represent a bytes node as a binary scalar.

+ +
+
Node representBool(ref Node node, Representer representer); +
+

Represent a bool node as a bool scalar.

+ +
+
Node representLong(ref Node node, Representer representer); +
+

Represent a long node as an integer scalar.

+ +
+
Node representReal(ref Node node, Representer representer); +
+

Represent a real node as a floating point scalar.

+ +
+
Node representSysTime(ref Node node, Representer representer); +
+

Represent a SysTime node as a timestamp.

+ +
+
Node representNodes(ref Node node, Representer representer); +
+

Represent a sequence node as sequence/set.

+ +
+
Node representPairs(ref Node node, Representer representer); +
+

Represent a mapping node as map/ordered map/pairs.

+ +
+
+ +
+ + + + + diff --git a/doc/html/api/dyaml.resolver.html b/doc/html/api/dyaml.resolver.html index a735edc..4dc9533 100644 --- a/doc/html/api/dyaml.resolver.html +++ b/doc/html/api/dyaml.resolver.html @@ -24,9 +24,13 @@ @@ -83,6 +87,21 @@ String of possible starting characters of the scalar.
+ +
package const @property Tag defaultScalarTag(); +
+

Return default scalar tag.

+ +
+
package const @property Tag defaultSequenceTag(); +
+

Return default sequence tag.

+ +
+
package const @property Tag defaultMappingTag(); +
+

Return default mapping tag.

+
diff --git a/doc/html/api/index.html b/doc/html/api/index.html index e956f72..347afc7 100644 --- a/doc/html/api/index.html +++ b/doc/html/api/index.html @@ -24,9 +24,13 @@ diff --git a/doc/html/articles/spec_differences.html b/doc/html/articles/spec_differences.html index 432edea..d8947b6 100644 --- a/doc/html/articles/spec_differences.html +++ b/doc/html/articles/spec_differences.html @@ -47,7 +47,7 @@ are caused by difficulty of implementation of some features, such as multiple Unicode encodings within single stream, and some by unnecessary restrictions or ambiguities in the specification.

-

Still, D:YAML tries to be as close to the specification as possible. D:YAML should +

Still, D:YAML tries to be as close to the specification as possible. It should never load documents with different meaning than according to the specification, and documents that fail to load should be very rare (for instance, very few files use multiple Unicode encodings).

@@ -55,11 +55,6 @@ files use multiple Unicode encodings).

List of known differences:

Differences that can cause valid YAML documents not to load:

    -
  • At the moment, all mappings in the internal representation are ordered, -and a comparison for equality between equal mappings with differing order -will return false. This will be fixed once Phobos has a usable map type or -D associative arrays work with variants.

    -
  • No support for byte order marks and multiple Unicode encodings in a stream.

  • Plain scalars in flow context cannot contain ,, : and ?. @@ -143,8 +138,8 @@ struct appears in Phobos.

    \ No newline at end of file diff --git a/doc/html/index.html b/doc/html/index.html index 4d5cd6f..1d94b8c 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -103,8 +103,8 @@ \ No newline at end of file diff --git a/doc/html/search.html b/doc/html/search.html index 2c4a917..f28945f 100644 --- a/doc/html/search.html +++ b/doc/html/search.html @@ -87,8 +87,8 @@ \ No newline at end of file diff --git a/doc/html/searchindex.js b/doc/html/searchindex.js index 2150163..3d6710f 100644 --- a/doc/html/searchindex.js +++ b/doc/html/searchindex.js @@ -1 +1 @@ -Search.setIndex({objects:{},terms:{represent:1,all:[1,3,4],code:[0,1,3,4],scalar:[0,1,2,3,4],follow:[3,4],depend:[0,3],show:[0,3],readabl:0,specif:[0,1,2],articl:[0,2],program:4,digit:[3,4],sourc:[3,4],everi:3,string:[0,3,4],powervr:0,"void":[3,4],phobo:1,failur:3,yamlexcept:[3,4],implicitli:[0,3],tri:1,gender:0,list:[0,1,2],iter:4,"try":[3,4],item:0,slower:0,past:4,fold:0,second:[0,4],design:0,pass:3,download:4,rrr:3,even:1,index:[3,4],what:3,appear:1,defin:0,current:4,version:4,"new":3,method:[3,4],usag:4,never:1,here:4,ggg:3,ldyaml:4,path:4,modifi:4,implicit:[0,3],valu:[0,1,3,4],convert:[0,4],anchor:[0,1,2],datetim:0,omap:0,chang:[0,1,3],loadsingledocu:3,commonli:4,modul:4,unix:4,subnod:4,instal:4,regex:3,from:3,would:4,doubl:0,two:[0,1,3],next:[3,4],few:1,call:[3,4],msg:3,type:[0,1,2,3,4],tell:4,more:[0,4],python:0,phone:0,known:[1,2,4],hold:3,must:[3,4],word:4,alia:[0,1],work:1,paragraph:0,can:[0,1,3,4],learn:4,male:0,root:[3,4],overrid:3,want:3,stream:[0,1],give:4,process:3,topic:3,tag:[0,1,3,2],tab:1,serial:[0,3],multipl:[0,1],newlin:0,quot:[0,1],getting_start:4,how:[3,4],foreach:[3,4],answer:[0,4],instead:0,simpl:[0,4],map:[0,1,2,3,4],mar:4,clone:0,variant:1,usabl:1,ff0000:3,uint:3,mai:1,end:[0,1,3],associ:[0,1,4],read:[0,3],stdio:4,explicit:0,correspond:3,ambigu:1,caus:1,alias:[0,1,2],"switch":3,green:[0,3],allow:[0,1],first:[0,2,3,4],order:[1,4],over:4,move:4,orang:3,becaus:1,veri:1,hierarchi:0,still:[0,1],style:0,fix:1,complex:[0,3],yaml:[0,1,2,3,4],window:4,html:3,therefor:[1,3],might:[0,1,3,4],easier:0,them:[0,1,4],"float":[0,3],"return":[1,3,4],thei:[0,1,3,4],handl:[1,3],auto:3,"break":3,now:[1,3,4],introduct:[0,4],name:[0,3],separ:0,each:[0,3],found:4,went:3,complet:3,mean:1,compil:[3,4],unequ:1,idea:4,expect:[3,4],our:[3,4],extract:4,out:0,space:0,content:[1,3,4],rel:4,"0123456789abcdefabcdef":3,ref:3,red:[0,3],difficulti:1,advanc:0,base:0,dictionari:0,put:[3,4],org:[1,3],"byte":1,thrown:4,pyyaml:[0,1],indent:[0,1],could:4,keep:4,length:3,yamlcoloninflowcontext:1,confus:1,assign:0,radeon:0,oper:[0,4],onc:[0,1],arrai:[0,1,3,4],restrict:1,date:4,unlik:0,alreadi:4,done:3,size:0,differ:[1,2],script:4,data:[0,1,3,2],addimplicitresolv:3,system:[0,4],construct:[0,3],nodeexcept:3,gpu:0,conveni:0,"final":3,store:[0,3],adher:1,consol:4,option:[0,4],especi:0,ishexdigit:3,specifi:[0,3,4],pars:[0,3,4],somewhat:0,exactli:4,than:1,serv:4,remov:0,structur:[0,1],charact:[0,1,3],project:[2,4],str:[0,3],were:3,posit:3,clearli:1,packag:[3,4],have:[0,3,4],tabl:0,need:[0,1,3,4],"null":0,lib:4,inform:[0,4],constructcolormap:3,note:[3,4],also:[0,3,4],take:3,which:[0,1,3],brace:0,singl:[0,1],uppercas:3,blue:[0,3],begin:[0,1],normal:4,previou:3,most:[0,3,4],regular:3,pair:[0,3],"class":[1,3],don:[1,3,4],later:3,cover:4,doe:[0,1,4],bracket:0,cortex:0,fact:0,ldc:4,cdc:4,alphanumer:1,syntax:[0,2],identifi:[0,3],find:[3,4],onli:[0,4],explicitli:0,just:[3,4],explain:4,should:[1,3,4],meant:4,std:[3,4],get:[2,3,4],express:3,cannot:[1,4],report:3,whether:3,common:0,contain:[0,1,3,4],where:[0,3,4],wiki:1,set:[0,2,4],seq:0,see:[0,1,3],result:3,fail:1,close:1,athlon:0,wikipedia:0,between:[0,1,2],"import":4,altern:3,accord:1,kei:[0,1,3,4],both:3,last:0,howev:[0,4],equal:1,comment:0,etc:3,tutori:[2,3,4],context:[0,1],load:[1,3,4],point:4,color:[0,3],hyphen:0,loader:3,colon:0,addconstructor:3,suppli:3,respect:3,rgb:3,empti:0,mark:[0,1,3],json:0,basic:4,resolut:[0,3],ani:[0,3,4],togeth:3,input:[3,4],"catch":3,"case":3,multi:0,main:[3,4],look:4,plain:[0,1],ffff00:3,cast:3,ain:0,error:[3,4],loos:1,non:[0,3],archiv:4,tediou:3,ascii:[1,3],welcom:[2,4],same:[0,1,3],member:3,binari:0,instanc:[1,3,4],timestamp:0,android:0,document:[0,1,2,3,4],difficult:0,http:1,nest:0,moment:[1,4],user:[0,3],implement:[1,3],markup:0,constructorexcept:3,person:0,exampl:[3,4],command:4,thi:[0,1,3,4],everyth:3,left:0,explan:4,systim:0,newest:4,execut:4,less:1,gdc:4,human:0,languag:[0,4],struct:[1,3],libdyaml:4,interptet:1,except:4,constructcolorscalar:3,add:[3,4],other:[1,4],els:0,match:3,build:4,real:0,format:[0,3],preserv:0,world:4,recurs:[0,1],tolow:3,like:3,success:3,resolv:[0,2,3],integ:[0,3,4],arthur:0,api:[2,4],either:[0,3,4],output:4,unnecessari:1,right:1,often:3,linux:[0,4],some:[0,1,3,4],intern:1,home:4,ubyt:[0,3],librari:4,lead:1,unord:1,refer:0,run:4,acronym:0,dyaml:[1,3,4],unicod:1,chapter:0,comparison:1,about:[1,4],simplest:4,rare:1,page:0,constructor:[2,3],fals:1,produc:4,block:0,subset:0,within:1,encod:1,automat:4,bbb:3,bsd:0,bool:[0,3],your:[2,3,4],wai:[1,3],support:[0,1,3],question:0,"long":0,custom:[0,2,3],writeln:[3,4],start:[0,2,3,4],"function":[3,4],form:3,continu:0,link:4,line:0,"true":3,conclus:4,"throw":[3,4],dmd:4,consist:0,possibl:[0,1,3,4],"default":[0,3],until:0,directori:[3,4],problem:1,similar:[0,4],featur:[0,1],creat:[0,3,4],"int":[0,3,4],flow:[0,1],dure:3,parser:[0,4],repres:[0,4],"char":3,exist:4,file:[1,3,4],yamlnul:0,isdigit:3,dent:0,check:[3,4],probabl:0,hex:3,when:4,detail:[0,1],invalid:3,valid:1,rrggbb:3,futur:[0,1],test:3,you:[0,3,4],node:[0,3,4],xxx:4,sequenc:[0,2,3,4],consid:1,debian:0,reduc:0,longer:3,anywher:0,rule:1,hello:4,ignor:1,far:3,escap:0,cpu:0},objtypes:{},titles:["YAML syntax","Differences between D:YAML and the YAML specification","Welcome to D:YAML documentation!","Custom YAML data types","Getting started"],objnames:{},filenames:["tutorials/yaml_syntax","articles/spec_differences","index","tutorials/custom_types","tutorials/getting_started"]}) \ No newline at end of file +Search.setIndex({objects:{},terms:{all:[1,3,4],code:[0,1,3,4],scalar:[0,1,2,3,4],follow:[3,4],depend:[0,3],show:[0,3],readabl:0,specif:[0,1,2],articl:[0,2],program:4,digit:[3,4],sourc:[3,4],everi:3,string:[0,3,4],powervr:0,"void":[3,4],phobo:1,failur:3,yamlexcept:[3,4],implicitli:[0,3],tri:1,gender:0,list:[0,1,2],iter:4,"try":[3,4],item:0,slower:0,past:4,fold:0,second:[0,4],design:0,pass:3,download:4,rrr:3,even:1,index:[3,4],what:3,appear:1,defin:0,current:4,version:4,"new":3,method:[3,4],usag:4,never:1,here:4,ggg:3,ldyaml:4,path:4,modifi:4,implicit:[0,3],valu:[0,1,3,4],convert:[0,4],anchor:[0,1,2],datetim:0,omap:0,implement:[1,3],commonli:4,modul:4,unix:4,subnod:4,instal:4,regex:3,from:3,would:4,doubl:0,two:[0,1,3],next:[3,4],few:1,call:[3,4],handl:[1,3],msg:3,type:[0,1,2,3,4],tell:4,more:[0,4],phone:0,known:[1,2,4],hold:3,must:[3,4],word:4,alia:[0,1],work:1,paragraph:0,can:[0,1,3,4],learn:4,male:0,root:[3,4],overrid:3,want:3,stream:[0,1],give:4,process:3,topic:3,tag:[0,1,3,2],tab:1,serial:[0,3],multipl:[0,1],newlin:0,quot:[0,1],getting_start:4,how:[3,4],foreach:[3,4],answer:[0,4],instead:0,simpl:[0,4],map:[0,1,2,3,4],mar:4,clone:0,variant:1,ff0000:3,uint:3,mai:1,end:[0,1,3],data:[0,1,3,2],read:[0,3],stdio:4,explicit:0,correspond:3,ambigu:1,caus:1,alias:[0,1,2],"switch":3,green:[0,3],allow:[0,1,4],first:[0,2,3,4],order:[1,4],over:4,move:4,orang:3,becaus:1,veri:1,hierarchi:0,still:[0,1],style:0,yaml:[0,1,2,3,4],window:4,html:3,therefor:[1,3],might:[0,1,3,4],easier:0,them:[0,1,4],"float":[0,3],"return":[3,4],thei:[0,1,3,4],python:0,auto:3,"break":3,now:[1,3,4],introduct:[0,4],name:[0,3],separ:0,each:[0,3],found:4,went:3,complet:3,mean:1,compil:[3,4],unequ:1,idea:4,expect:[3,4],our:[3,4],extract:4,out:0,space:0,content:[1,3,4],rel:4,"0123456789abcdefabcdef":3,ref:3,red:[0,3],difficulti:1,advanc:0,base:0,dictionari:0,put:[3,4],org:[1,3],"byte":1,thrown:4,pyyaml:[0,1],indent:[0,1],could:4,keep:4,length:3,yamlcoloninflowcontext:1,confus:1,assign:0,radeon:0,oper:[0,4],onc:[0,1],arrai:[0,1,3,4],restrict:1,unlik:0,alreadi:4,done:3,stabl:4,size:0,differ:[1,2],script:4,associ:[0,1,4],addimplicitresolv:3,system:[0,4],construct:[0,3],nodeexcept:3,gpu:0,conveni:0,"final":3,store:[0,3],adher:1,consol:4,option:[0,4],especi:0,ishexdigit:3,specifi:[0,3,4],pars:[0,3,4],somewhat:0,exactli:4,than:1,std:[3,4],instanc:[1,3,4],remov:0,structur:[0,1],charact:[0,1,3],project:[2,4],str:[0,3],were:3,posit:3,clearli:1,packag:[3,4],have:[0,3,4],tabl:0,need:[0,1,3,4],"null":0,lib:4,inform:[0,4],constructcolormap:3,note:[3,4],also:[0,3,4],take:3,which:[0,1,3],brace:0,singl:[0,1],uppercas:3,blue:[0,3],begin:[0,1],normal:4,previou:3,most:[0,3,4],regular:3,pair:[0,3],"class":[1,3],don:[1,3,4],later:3,cover:4,doe:[0,1,4],bracket:0,cortex:0,fact:0,ldc:4,cdc:4,alphanumer:1,syntax:[0,2],identifi:[0,3],find:[3,4],onli:4,explicitli:0,just:4,explain:4,should:[1,3,4],meant:4,serv:4,get:[2,3,4],express:3,cannot:[1,4],report:3,whether:3,common:0,contain:[0,1,3,4],where:[0,3,4],wiki:1,set:[0,2,4],seq:0,see:[0,1,3],result:3,fail:1,close:1,athlon:0,wikipedia:0,between:[0,1,2],"import":4,altern:3,accord:1,kei:[0,1,3,4],both:3,last:0,howev:0,comment:0,etc:3,tutori:[2,3,4],context:[0,1],load:[1,3,4],color:[0,3],hyphen:0,loader:[3,4],colon:0,addconstructor:3,linux:[0,4],respect:3,rgb:3,empti:0,mark:[0,1,3],json:0,basic:4,resolut:[0,3],ani:[0,3,4],togeth:3,input:[3,4],"catch":3,"case":3,multi:0,main:[3,4],look:4,plain:[0,1],ffff00:3,cast:3,ain:0,error:[3,4],loos:1,non:[0,3],archiv:4,tediou:3,ascii:[1,3],welcom:[2,4],same:[0,1,3],member:3,binari:0,complex:[0,3],timestamp:0,android:0,document:[0,1,2,3,4],difficult:0,http:1,nest:0,user:[0,3],chang:[0,1,3],markup:0,constructorexcept:3,person:0,exampl:[3,4],command:4,thi:[0,1,3,4],everyth:3,left:0,explan:4,systim:0,newest:4,execut:4,less:1,gdc:4,human:0,yet:4,languag:[0,4],struct:[1,3,4],libdyaml:4,interptet:1,except:4,constructcolorscalar:3,add:[3,4],other:[1,4],els:0,match:3,build:4,real:0,format:[0,3],preserv:0,world:4,recurs:[0,1],tolow:3,like:3,success:3,resolv:[0,2,3],integ:[0,3,4],arthur:0,api:[2,4],either:[0,3,4],output:4,unnecessari:1,right:1,often:3,suppli:3,some:[0,1,3,4],home:4,ubyt:[0,3],librari:4,lead:1,unord:1,refer:0,run:4,acronym:0,dyaml:[1,4],unicod:1,chapter:0,about:[1,4],simplest:4,rare:1,page:0,constructor:[2,3],produc:4,block:0,subset:0,within:1,encod:1,automat:4,bbb:3,bsd:0,bool:[0,3],your:[2,3,4],wai:[1,3],support:[0,1,3],question:0,"long":0,custom:[0,2,3],writeln:[3,4],start:[0,2,3,4],"function":3,form:3,continu:0,link:4,line:0,"true":3,conclus:4,"throw":[3,4],dmd:4,consist:0,possibl:[0,1,3,4],"default":[0,3],until:0,directori:[3,4],problem:1,similar:[0,4],featur:[0,1],creat:[0,3,4],"int":[0,3,4],flow:[0,1],dure:3,parser:[0,4],repres:[0,4],"char":3,exist:4,file:[1,3,4],yamlnul:0,isdigit:3,dent:0,check:[3,4],probabl:0,hex:3,when:4,detail:[0,1],invalid:3,valid:1,rrggbb:3,futur:[0,1],test:3,you:[0,3,4],node:[0,3,4],xxx:4,sequenc:[0,2,3,4],consid:1,debian:0,reduc:0,longer:3,anywher:0,rule:1,hello:4,ignor:1,far:3,escap:0,cpu:0},objtypes:{},titles:["YAML syntax","Differences between D:YAML and the YAML specification","Welcome to D:YAML documentation!","Custom YAML data types","Getting started"],objnames:{},filenames:["tutorials/yaml_syntax","articles/spec_differences","index","tutorials/custom_types","tutorials/getting_started"]}) \ No newline at end of file diff --git a/doc/html/tutorials/custom_types.html b/doc/html/tutorials/custom_types.html index da8d4b0..64ff2b8 100644 --- a/doc/html/tutorials/custom_types.html +++ b/doc/html/tutorials/custom_types.html @@ -47,10 +47,10 @@

    Custom YAML data types

    -

    Often you will want to serialize complex data types such as classes. You can use -functions to process nodes; e.g. a mapping containing class data members indexed -by name. Alternatively, YAML supports custom data types using identifiers called -tags. That is the topic of this tutorial.

    +

    Often you might want to serialize complex data types such as classes. You can +use functions to process nodes such as a mapping containing class data members +indexed by name. Alternatively, YAML supports custom data types using +identifiers called tags. That is the topic of this tutorial.

    Each YAML node has a tag specifying its type. For instance: strings use the tag tag:yaml.org,2002:str. Tags of most default types are implicitly resolved during parsing, so you don’t need to specify tag for each float, integer, etc. @@ -59,9 +59,9 @@ It is also possible to implicitly resolve custom tags, as we will show later.

    Constructor

    D:YAML uses the Constructor class to process each node to hold data type corresponding to its tag. Constructor stores a function for each supported -tag to process it. These functions can be supplied by the user using the -addConstructor() method. Constructor is then passed to Loader, which will -parse YAML input.

    +tag to process it. These functions are supplied by the user using the +addConstructor() method. Constructor is then passed to Loader, which +parses YAML input.

    We will implement support for an RGB color type. It is implemented as the following struct:

    struct Color
    @@ -146,7 +146,7 @@ RRGGBB, or from a mapping, where we use the following format:
     }
     
    -

    Next, we need some YAML code using our new tag. Create a file called input.yaml +

    Next, we need some YAML data using our new tag. Create a file called input.yaml with the following contents:

    scalar-red: !color FF0000
     scalar-orange: !color FFFF00
    @@ -173,9 +173,10 @@ with the following contents:

    constructor.addConstructor("!color", &constructColorScalar); constructor.addConstructor("!color-mapping", &constructColorMapping); - auto loader = new Loader("input.yaml", constructor, new Resolver); + auto loader = Loader("input.yaml"); + loader.constructor = constructor; - auto root = loader.loadSingleDocument(); + auto root = loader.load(); if(root["scalar-red"].get!Color == red && root["mapping-red"].get!Color == red && @@ -196,23 +197,21 @@ with the following contents:

    First, we create a Constructor and pass functions to handle the !color -and !color-mapping tag. We construct a Loader using the Constructor. -We also need a Resolver, but for now we just default-construct it. We then -load the YAML document, and finally, read the colors using get() method to -test if they were loaded as expected.

    +and !color-mapping tag. We construct a Loader*m and pass the *Constructor +to it. We then load the YAML document, and finally, read the colors using +get() method to test if they were loaded as expected.

    You can find the source code for what we’ve done so far in the examples/constructor directory in the D:YAML package.

    Resolver

    Specifying tag for every color value can be tedious. D:YAML can implicitly -resolve tag of a scalar using a regular expression. This is how default types, -e.g. int, are resolved. We will use the Resolver class to add implicit tag +resolve scalar tags using regular expressions. This is how default types such as +int are resolved. We will use the Resolver class to add implicit tag resolution for the Color data type (in its scalar form).

    We use the addImplicitResolver method of Resolver, passing the tag, regular expression the value must match to resolve to this tag, and a string of possible -starting characters of the value. Then we pass the Resolver to the constructor -of Loader.

    +starting characters of the value. Then we pass the Resolver to Loader.

    Note that resolvers added first override ones added later. If no resolver matches a scalar, YAML string tag is used. Therefore our custom values must not be resolvable as any non-string YAML data type.

    @@ -223,12 +222,15 @@ be resolvable as any non-string YAML data type.

    resolver.addImplicitResolver("!color", std.regex.regex("[0-9a-fA-F]{6}", "0123456789abcdefABCDEF")); -auto loader = new Loader("input.yaml", constructor, resolver); +auto loader = Loader("input.yaml"); + +loader.constructor = constructor; +loader.resolver = resolver; //code from the previous example...
    -

    Now, change contents of input.dyaml to this:

    +

    Now, change contents of input.yaml to this:

    scalar-red: FF0000
     scalar-orange: FFFF00
     mapping-red: !color-mapping {r: 255, g: 0, b: 0}
    @@ -282,8 +284,8 @@ D:YAML package.

    \ No newline at end of file diff --git a/doc/html/tutorials/getting_started.html b/doc/html/tutorials/getting_started.html index 2b573ce..5b8b649 100644 --- a/doc/html/tutorials/getting_started.html +++ b/doc/html/tutorials/getting_started.html @@ -64,9 +64,8 @@ Download the version of DMD for your operating system and install it.

    Note

    Other D compilers exist, such as GDC and -LDC. -Setting up with either one of them should be similar to DMD, -however, at the moment they are not as up to date as DMD.

    +LDC. Setting up with either one of +them should be similar to DMD, but they are not yet as stable as DMD.

    @@ -109,7 +108,7 @@ into the file:

    void main() { - yaml.Node root = yaml.load("input.yaml"); + Node root = Loader("input.yaml").load(); foreach(string word; root["Hello World"]) { writeln(word); @@ -122,27 +121,28 @@ into the file:

    Explanation of the code

    First, we import the yaml module. This is the only module you need to import to use D:YAML - it automatically imports all needed modules.

    -

    Next we load the file using the yaml.load() function - this loads the file as -one YAML document and throws YAMLException, D:YAML exception type, if the +

    Next we load the file using the Loader.load() method. Loader is the struct +used for parsing YAML documents, and load() is a method that loads the file as +one YAML document, or throws YAMLException, D:YAML exception type, if the file could not be parsed or does not contain exactly one document. Note that we don’t do any error checking here in order to keep the example as simple as possible.

    -

    yaml.Node represents a node in a YAML document. It can be a sequence (array), +

    Node represents a node in a YAML document. It can be a sequence (array), mapping (associative array) or a scalar (value). Here the root node is a mapping, and we use the index operator to get subnodes with keys “Hello World” and “Answer”. We iterate over the first, as it is a sequence, and use the -yaml.Node.get() method on the second to get its value as an integer.

    +Node.get() method on the second to get its value as an integer.

    You can iterate over a mapping or sequence as if it was an associative or normal array. If you try to iterate over a scalar, it will throw a YAMLException.

    -

    You can iterate over subnodes using yaml.Node as the iterated type, or specify +

    You can iterate over subnodes using Node as the iterated type, or specify the type subnodes are expected to have. D:YAML will automatically convert iterated subnodes to that type if possible. Here we specify the string type, so we iterate over the “Hello World” sequence as an array of strings. If it is not possible to convert to iterated type, a YAMLException is thrown. For instance, if we specified int here, we would get an error, as “Hello” cannot be converted to an integer.

    -

    The yaml.Node.get() method is used to get value of a scalar node as specified -type. D:YAML will try to return the scalar as specified type, converting if +

    The Node.get() method is used to get value of a scalar node, allowing to +specify type. D:YAML will try to return the scalar as this type, converting if needed, throwing YAMLException if not possible.

    @@ -150,15 +150,14 @@ needed, throwing YAMLException if not possible.

    To compile your project, you must give DMD the directories containing import modules and the library. You also need to tell it to link with D:YAML. The import directory should be the D:YAML package directory. You can specify it using the --I option of DMD. The library directory should point to where you put the -compiled D:YAML library. On Unix/Linux you can specify it using the -L-L -option, and link with D:YAML using the -L-l option. On Windows, the import -directory is used as the library directory. To link with the library on Windows, -just add the path to it relative to the current directory.

    -

    For example, if you extracted D:YAML to /home/xxx/dyaml and compiled it in -that directory, your project is in /home/xxx/dyaml-project, and you are -currently in that directory, you can compile the project with the following -command on Unix/Linux:

    +-I option of DMD. The library directory should be where you put the compiled +D:YAML library. On Unix/Linux you can specify it using the -L-L option, and +link with D:YAML using the -L-l option. On Windows, the import directory is +used as the library directory. To link with the library on Windows, just add the +path to it relative to the current directory.

    +

    For example, if you extracted and compiled D:YAML in /home/xxx/dyaml, your +project is in /home/xxx/dyaml-project, and you are currently in that +directory, you can compile the project with the following command on Unix/Linux:

    dmd -I../dyaml -L-L../dyaml -L-ldyaml main.d

    And the following on Windows:

    @@ -225,8 +224,8 @@ example in the example/getting_st
    \ No newline at end of file diff --git a/doc/html/tutorials/yaml_syntax.html b/doc/html/tutorials/yaml_syntax.html index 507eba6..98bc68f 100644 --- a/doc/html/tutorials/yaml_syntax.html +++ b/doc/html/tutorials/yaml_syntax.html @@ -52,20 +52,19 @@ information, see Chapter 2 of the YAML specification or the Wikipedia page.

    -

    YAML is a data serialization format designed to be as human readable as -possible. YAML is a recursive acronym for “YAML Ain’t Markup Language”.

    +

    YAML is a data serialization format designed for human readability. YAML is a +recursive acronym for “YAML Ain’t Markup Language”.

    YAML is similar to JSON, and in fact, JSON is a subset of YAML 1.2; but YAML has -some more advanced features and is easier to read. However, YAML is also more +some more advanced features and is easier to read. However, it is also more difficult to parse (and probably somewhat slower). Data is stored in mappings (associative arrays), sequences (lists) and scalars (single values). Data -structure hierarchy either depends on indentation (block context, similar to +structure hierarchy depends either on indentation (block context, similar to Python code), or nesting of brackets and braces (flow context, similar to JSON). YAML comments begin with # and continue until the end of line.

    Documents

    A YAML stream consists of one or more documents starting with --- and -optionally ending with ... . If there is only one document, --- can be -left out.

    +optionally ending with ... . --- can be left out for the first document.

    Single document with no explicit start or end:

    - Red
     - Green
    @@ -96,7 +95,7 @@ left out.

    Sequences

    Sequences are arrays of nodes of any type, similar e.g. to Python lists. -In block context, each item begins with hyphen+space “- “. In flow context, +In block context, each item begins with hyphen+space “- ”. In flow context, sequences have syntax similar to D arrays.

    #Block context
     - Red
    @@ -137,7 +136,7 @@ sequences have syntax similar to D arrays.

    Mappings

    Mappings are associative arrays where each key and value can be of any type, similar e.g. to Python dictionaries. In block context, keys and values are -separated by colon+space “: “. In flow context, mappings have syntax similar +separated by colon+space ”: ”. In flow context, mappings have syntax similar to D associative arrays, but with braces instead of brackets:

    #Block context
     CPU: Athlon
    @@ -174,7 +173,7 @@ to D associative arrays, but with braces instead of brackets:

    OS: Android
    -

    Complex keys start with question mark+space “? “.

    +

    Complex keys start with question mark+space ”? ”.

    #Nested in a sequence
     ? [CPU, GPU]: [Athlon, Radeon]
     OS: Debian
    @@ -331,8 +330,8 @@ Some of these might change in the future (especially !!map and !!set).

    \ No newline at end of file diff --git a/docsrc/tutorials/custom_types.rst b/docsrc/tutorials/custom_types.rst index a5fcf26..1a22ebe 100644 --- a/docsrc/tutorials/custom_types.rst +++ b/docsrc/tutorials/custom_types.rst @@ -186,8 +186,7 @@ resolution for the Color data type (in its scalar form). We use the *addImplicitResolver* method of *Resolver*, passing the tag, regular expression the value must match to resolve to this tag, and a string of possible -starting characters of the value. Then we pass the *Resolver* to the constructor -of *Loader*. +starting characters of the value. Then we pass the *Resolver* to *Loader*. Note that resolvers added first override ones added later. If no resolver matches a scalar, YAML string tag is used. Therefore our custom values must not diff --git a/docsrc/tutorials/getting_started.rst b/docsrc/tutorials/getting_started.rst index c19b89d..73bd3b0 100644 --- a/docsrc/tutorials/getting_started.rst +++ b/docsrc/tutorials/getting_started.rst @@ -100,7 +100,7 @@ to use D:YAML - it automatically imports all needed modules. Next we load the file using the *Loader.load()* method. *Loader* is the struct used for parsing YAML documents, and *load()* is a method that loads the file as -**one** YAML document and throws *YAMLException*, D:YAML exception type, if the +**one** YAML document, or throws *YAMLException*, D:YAML exception type, if the file could not be parsed or does not contain exactly one document. Note that we don't do any error checking here in order to keep the example as simple as possible. diff --git a/dyaml/dumper.d b/dyaml/dumper.d index 727f45a..bfd59e1 100644 --- a/dyaml/dumper.d +++ b/dyaml/dumper.d @@ -5,8 +5,9 @@ // http://www.boost.org/LICENSE_1_0.txt) /** - * YAML dumper. - * Code based on PyYAML: http://www.pyyaml.org + * YAML _dumper. + * + * Code based on $(LINK2 http://www.pyyaml.org, PyYAML). */ module dyaml.dumper; @@ -33,7 +34,7 @@ import dyaml.tagdirectives; * User specified Representer and/or Resolver can be used to support new * tags / data types. * - * Setters are provided to affect the output (style, encoding).. + * Setters are provided to affect output details (style, encoding, etc.). * * Examples: * @@ -48,6 +49,11 @@ import dyaml.tagdirectives; * auto node1 = Node([1, 2, 3, 4, 5]); * auto node2 = Node("This document contains only one string"); * Dumper("file.yaml").dump(node1, node2); + * + * //Or with an array: + * //Dumper("file.yaml").dump([node1, node2]); + * + * * -------------------- * * Write to memory: @@ -142,7 +148,7 @@ struct Dumper * * Params: filename = File name to write to. * - * Throws: YAMLException if the file can not be dumped to (e.g. cannot be read). + * Throws: YAMLException if the file can not be dumped to (e.g. cannot be opened). */ this(string filename) { @@ -153,7 +159,7 @@ struct Dumper } } - ///Construct a Dumper writing to a stream. This is useful to e.g. write to memory. + ///Construct a Dumper writing to a _stream. This is useful to e.g. write to memory. this(Stream stream) { resolver_ = new Resolver(); @@ -185,7 +191,7 @@ struct Dumper representer_ = representer; } - ///Write scalars in canonical form? + ///Write scalars in _canonical form? void canonical(in bool canonical) { canonical_ = canonical; @@ -202,7 +208,7 @@ struct Dumper indent_ = indent; } - ///Set preferred text width. + ///Set preferred text _width. void textWidth(in uint width) { textWidth_ = width; @@ -214,7 +220,7 @@ struct Dumper lineBreak_ = lineBreak; } - ///Set character encoding to use. UTF-8 by default. + ///Set character _encoding to use. UTF-8 by default. void encoding(in Encoding encoding) { encoding_ = encoding; @@ -241,18 +247,18 @@ struct Dumper /** * Specify tag directives. * - * A tag directive specifies a shorthand notation for specifying tags. + * A tag directive specifies a shorthand notation for specifying _tags. * Each tag directive associates a handle with a prefix. This allows for * compact tag notation. * * Each handle specified MUST start and end with a '!' character * (a single character "!" handle is allowed as well). * - * Only alphanumeric characters, '-', and '_' may be used in handles. + * Only alphanumeric characters, '-', and '__' may be used in handles. * * Each prefix MUST not be empty. * - * The "!!" handle is used for default YAML tags with prefix + * The "!!" handle is used for default YAML _tags with prefix * "tag:yaml.org,2002:". This can be overridden. * * Params: tags = Tag directives (keys are handles, values are prefixes). @@ -281,13 +287,13 @@ struct Dumper } /** - * Dump one or more YAML documents to the file/stream. + * Dump one or more YAML _documents to the file/stream. * * Note that while you can call dump() multiple times on the same * dumper, you will end up writing multiple YAML "files" to the same * file/stream. * - * Params: documents = Documents to dump (root nodes of the documents). + * Params: documents = Documents to _dump (root nodes of the _documents). * * Throws: YAMLException on error (e.g. invalid nodes, * unable to write to file/stream). diff --git a/dyaml/encoding.d b/dyaml/encoding.d index bb96d2c..bb7fddc 100644 --- a/dyaml/encoding.d +++ b/dyaml/encoding.d @@ -7,10 +7,13 @@ module dyaml.encoding; -///Text encodings. +///Text encodings supported by D:YAML. enum Encoding : ubyte { + ///Unicode UTF-8 UTF_8, + ///Unicode UTF-16 UTF_16, + ///Unicode UTF-32 UTF_32 } diff --git a/dyaml/exception.d b/dyaml/exception.d index bdd6a8f..8a965c0 100644 --- a/dyaml/exception.d +++ b/dyaml/exception.d @@ -4,7 +4,7 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -///D:YAML exceptions and exception related code. +///Exceptions thrown by D:YAML and _exception related code. module dyaml.exception; @@ -78,7 +78,7 @@ abstract class MarkedYAMLException : YAMLException } } -///Constructors of YAML exceptions are mostly the same, so we use a mixin. +//Constructors of YAML exceptions are mostly the same, so we use a mixin. template ExceptionCtors() { public: @@ -88,7 +88,7 @@ template ExceptionCtors() } } -///Constructors of marked YAML exceptions are mostly the same, so we use a mixin. +//Constructors of marked YAML exceptions are mostly the same, so we use a mixin. template MarkedExceptionCtors() { public: diff --git a/dyaml/linebreak.d b/dyaml/linebreak.d index d9b763b..6e54af3 100644 --- a/dyaml/linebreak.d +++ b/dyaml/linebreak.d @@ -4,19 +4,23 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -///Line break enum. module dyaml.linebreak; ///Enumerates platform specific line breaks. enum LineBreak { + ///Unix line break ("\n"). Unix, + ///Windows line break ("\r\n"). Windows, + ///Macintosh line break ("\r"). Macintosh } -///Get line break string for specified line break. +package: + +//Get line break string for specified line break. string lineBreak(in LineBreak b) pure { final switch(b) diff --git a/dyaml/loader.d b/dyaml/loader.d index 657dd1e..bb9e9de 100644 --- a/dyaml/loader.d +++ b/dyaml/loader.d @@ -5,7 +5,7 @@ // http://www.boost.org/LICENSE_1_0.txt) /** - * Class and convenience functions used to load YAML documents. + * Class used to load YAML documents. */ module dyaml.loader; @@ -125,11 +125,11 @@ struct Loader } /** - * Construct a Loader to load YAML from a stream. + * Construct a Loader to load YAML from a _stream. * * Params: stream = Stream to read from. Must be readable. * - * Throws: YAMLException if the stream could not be read from. + * Throws: YAMLException if stream could not be read from. */ this(Stream stream) { @@ -160,19 +160,19 @@ struct Loader clear(parser_); } - ///Set stream name. Used in debugging messages. + ///Set stream _name. Used in debugging messages. @property void name(string name) { name_ = name; } - ///Set Resolver to use. + ///Specify custom Resolver to use. @property void resolver(Resolver resolver) { resolver_ = resolver; } - ///Set Constructor to use. + ///Specify custom Constructor to use. @property void constructor(Constructor constructor) { constructor_ = constructor; @@ -181,7 +181,7 @@ struct Loader /** * Load single YAML document. * - * If no or more than one YAML document is found, this will throw a YAMLException. + * If none or more than one YAML document is found, this will throw a YAMLException. * * Returns: Root node of the document. * @@ -208,8 +208,7 @@ struct Loader * * Returns: Array of root nodes of all documents in the file/stream. * - * Throws: YAMLException if there wasn't exactly one document - * or on a YAML parsing error. + * Throws: YAMLException on a YAML parsing error. */ Node[] loadAll() { @@ -224,7 +223,7 @@ struct Loader /** * Foreach over YAML documents. * - * Parses documents lazily, as they are needed. + * Parses documents lazily, when they are needed. * * Throws: YAMLException on a parsing error. */ diff --git a/dyaml/node.d b/dyaml/node.d index 8e7f6c7..f88edc4 100644 --- a/dyaml/node.d +++ b/dyaml/node.d @@ -57,7 +57,7 @@ struct YAMLNull{} //Merge YAML type, used to support "tag:yaml.org,2002:merge". package struct YAMLMerge{} -///Base class for YAMLContainer - used for user defined YAML types. +//Base class for YAMLContainer - used for user defined YAML types. package abstract class YAMLObject { public: @@ -110,14 +110,14 @@ package class YAMLContainer(T) : YAMLObject /** * YAML node. * - * This is a pseudo-dynamic type that can store any YAML value, including sequence - * or a mapping of nodes. You can get data from a Node directly or iterate over it - * if it's a sequence or a mapping. + * This is a pseudo-dynamic type that can store any YAML value, including a + * sequence or mapping of nodes. You can get data from a Node directly or + * iterate over it if it's a collection. */ struct Node { public: - ///Pair of YAML nodes, used in mappings. + ///Key-value pair of YAML nodes, used in mappings. struct Pair { public: @@ -174,10 +174,11 @@ struct Node * Construct a Node from a value. * * Any type except of Node can be stored in a Node, but default YAML - * types (integers, floats, strings, timestamp, etc.) will be stored + * types (integers, floats, strings, timestamps, etc.) will be stored * more efficiently. * - * Note that for any non-default types you store + * + * Note that to emit any non-default types you store * in a node, you need a Representer to represent them in YAML - * otherwise emitting will fail. * @@ -186,8 +187,8 @@ struct Node * of tag determined by Representer. Representer uses * this to determine YAML data type when a D data type * maps to multiple different YAML data types. Tag must - * be in full form, e.g. "tag:yaml.org,2002:omap", not - * a shortcut, like "!!omap". + * be in full form, e.g. "tag:yaml.org,2002:int", not + * a shortcut, like "!!int". */ this(T)(T value, in string tag = null) if (isSomeString!T || (!isArray!T && !isAssociativeArray!T)) @@ -221,11 +222,11 @@ struct Node } /** - * Construct a node from an array_. + * Construct a node from an _array. * - * If array is an array_ of nodes or node pairs, it is stored in the - * node directly. Otherwise, every value in the array is converted to a - * node, and those nodes are stored. + * If _array is an _array of nodes or pairs, it is stored directly. + * Otherwise, every value in the array is converted to a node, and + * those nodes are stored. * * Params: array = Values to store in the node. * tag = Overrides tag of the node when emitted, regardless @@ -233,10 +234,10 @@ struct Node * this to determine YAML data type when a D data type * maps to multiple different YAML data types. * This is used to differentiate between YAML sequences - * (!!seq) and sets (!!set), which both are internally - * represented as an array_ of nodes. Tag must be in - * full form, e.g. "tag:yaml.org,2002:set", not a - * shortcut, like "!!set". + * ("!!seq") and sets ("!!set"), which both are + * internally represented as an array_ of nodes. Tag + * must be in full form, e.g. "tag:yaml.org,2002:set", + * not a shortcut, like "!!set". * * Examples: * -------------------- @@ -282,10 +283,10 @@ struct Node } /** - * Construct a node from an associative array_. + * Construct a node from an associative _array. * - * If keys and/or values of array are nodes, they are copied to the node - * directly. Otherwise they are converted to nodes and then stored. + * If keys and/or values of _array are nodes, they stored directly. + * Otherwise they are converted to nodes and then stored. * * Params: array = Values to store in the node. * tag = Overrides tag of the node when emitted, regardless @@ -293,11 +294,11 @@ struct Node * this to determine YAML data type when a D data type * maps to multiple different YAML data types. * This is used to differentiate between YAML unordered - * mappings (!!map), ordered mappings (!!omap), and - * pairs (!!pairs) which are all internally represented - * as an array_ of node pairs. Tag must be in full - * form, e.g. "tag:yaml.org,2002:omap", not a shortcut, - * like "!!omap". + * mappings ("!!map"), ordered mappings ("!!omap"), and + * pairs ("!!pairs") which are all internally + * represented as an _array of node pairs. Tag must be + * in full form, e.g. "tag:yaml.org,2002:omap", not a + * shortcut, like "!!omap". * * Examples: * -------------------- @@ -338,16 +339,18 @@ struct Node } /** - * Construct a node from arrays of keys_ and values_. + * Construct a node from arrays of _keys and _values. * * Constructs a mapping node with key-value pairs from - * keys_ and values_, keeping their order. Useful when order + * _keys and _values, keeping their order. Useful when order * is important (ordered maps, pairs). * + * * keys and values must have equal length. * - * If keys_ and/or values_ of are nodes, they are copied to the node - * directly. Otherwise they are converted to nodes and then stored. + * + * If _keys and/or _values are nodes, they are stored directly/ + * Otherwise they are converted to nodes and then stored. * * Params: keys = Keys of the mapping, from first to last pair. * values = Values of the mapping, from first to last pair. @@ -356,11 +359,11 @@ struct Node * this to determine YAML data type when a D data type * maps to multiple different YAML data types. * This is used to differentiate between YAML unordered - * mappings (!!map), ordered mappings (!!omap), and - * pairs (!!pairs) which are all internally represented - * as an array_ of node pairs. Tag must be in full - * form, e.g. "tag:yaml.org,2002:omap", not a shortcut, - * like "!!omap". + * mappings ("!!map"), ordered mappings ("!!omap"), and + * pairs ("!!pairs") which are all internally + * represented as an array of node pairs. Tag must be + * in full form, e.g. "tag:yaml.org,2002:omap", not a + * shortcut, like "!!omap". * * Examples: * -------------------- @@ -411,10 +414,10 @@ struct Node ///Is this node a scalar value? @property bool isScalar() const {return !(isMapping || isSequence);} - ///Is this node a sequence of nodes? + ///Is this node a sequence? @property bool isSequence() const {return isType!(Node[]);} - ///Is this node a mapping of nodes? + ///Is this node a mapping? @property bool isMapping() const {return isType!(Pair[]);} ///Is this node a user defined type? @@ -423,14 +426,15 @@ struct Node /** * Equality test. * - * If T is Node, recursively compare all - * subnodes and might be quite expensive if testing entire documents. + * If T is Node, recursively compare all subnodes. + * This might be quite expensive if testing entire documents. * * If T is not Node, convert the node to T and test equality with that. * * Examples: * -------------------- - * //node is a Node that contains integer 42 + * auto node = Node(42); + * * assert(node == 42); * assert(node == "42"); * assert(node != "43"); @@ -449,7 +453,7 @@ struct Node * Get the value of the node as specified type. * * If the specifed type does not match type in the node, - * conversion is attempted if possible. + * conversion is attempted. * * Timestamps are stored as std.datetime.SysTime. * Binary values are decoded and stored as ubyte[]. @@ -462,14 +466,15 @@ struct Node * but is replaced by a mapping later. Even if the node is a mapping, the * get method can be used as if it was a scalar if it has a default value. * This way, new YAML files where the node is a mapping can still be read - * by old versions of the program, which expects the node to be a scalar. + * by old versions of the program, which expect the node to be a scalar. * ) * * Examples: * * Automatic type conversion: * -------------------- - * //node is a node that contains integer 42 + * auto node = Node(42); + * * assert(node.get!int == 42); * assert(node.get!string == "42"); * assert(node.get!double == 42.0); @@ -489,8 +494,8 @@ struct Node /** * Write the value of the node to target. * - * If the type of target does not match type of the node, - * conversion is attempted, if possible. + * If the target type does not match node type, + * conversion is attempted. * * Params: target = Variable to write to. * @@ -580,7 +585,7 @@ struct Node } /** - * If this is a sequence or a mapping, return its length. + * If this is a collection, return its _length. * * Otherwise, throw NodeException. * @@ -597,10 +602,11 @@ struct Node } /** - * Get the element with specified index. + * Get the element at specified index. * * If the node is a sequence, index must be integral. * + * * If the node is a mapping, return the value corresponding to the first * key equal to index, even after conversion. I.e; node["12"] will * return value of the first key that equals "12", even if it's an integer. @@ -663,17 +669,17 @@ struct Node } /** - * Set element at the specified index of a collection. + * Set element at specified index in a collection. * * This method can only be called on collection nodes. * * If the node is a sequence, index must be integral. * - * If the node is a mapping, set the value_ corresponding to the first + * If the node is a mapping, sets the _value corresponding to the first * key matching index (including conversion, so e.g. "42" matches 42). * * If the node is a mapping and no key matches index, a new key-value - * pair is added to the mapping. With sequences the index must be in + * pair is added to the mapping. In sequences the index must be in * range. This ensures behavior siilar to D arrays and associative * arrays. * @@ -887,18 +893,19 @@ struct Node } /** - * Add an element to a sequence node. + * Add an element to a sequence. * * This method can only be called on sequence nodes. * * If value is a node, it is copied to the sequence directly. Otherwise * value is converted to a node and then stored in the sequence. * - * When emitting, all values in the sequence will be emitted. If using - * the !!set tag, the user needs to ensure that all elements in the - * sequence are unique, otherwise invalid YAML code will be emitted. + * $(P When emitting, all values in the sequence will be emitted. When + * using the !!set tag, the user needs to ensure that all elements in + * the sequence are unique, otherwise $(B invalid) YAML code will be + * emitted.) * - * Params: value = Value to add to the sequence. + * Params: value = Value to _add to the sequence. */ void add(T)(T value) { @@ -923,20 +930,20 @@ struct Node } /** - * Add a key-value pair to a mapping node. + * Add a key-value pair to a mapping. * * This method can only be called on mapping nodes. * * If key and/or value is a node, it is copied to the mapping directly. * Otherwise it is converted to a node and then stored in the mapping. * - * It is possible to for the same key to be present more than once in a + * $(P It is possible for the same key to be present more than once in a * mapping. When emitting, all key-value pairs will be emitted. - * This is useful with the !!pairs tag, but will result in invalid YAML - * with !!map and !!omap tags. + * This is useful with the "!!pairs" tag, but will result in + * $(B invalid) YAML with "!!map" and "!!omap" tags.) * - * Params: key = Key to add. - * value = Value to add. + * Params: key = Key to _add. + * value = Value to _add. */ void add(K, V)(K key, V value) { @@ -965,10 +972,10 @@ struct Node * * If the node is a sequence, the first node matching value (including * conversion, so e.g. "42" matches 42) is removed. - * If the node is a mapping, the first key-value pair where value_ - * matches value is removed. + * If the node is a mapping, the first key-value pair where _value + * matches specified value is removed. * - * Params: value = Value to remove. + * Params: value = Value to _remove. * * Throws: NodeException if the node is not a collection. */ diff --git a/dyaml/representer.d b/dyaml/representer.d index e90aee8..0defeb4 100644 --- a/dyaml/representer.d +++ b/dyaml/representer.d @@ -5,8 +5,9 @@ // http://www.boost.org/LICENSE_1_0.txt) /** - * YAML representer. - * Code based on PyYAML: http://www.pyyaml.org + * YAML node _representer. + * + * Code based on $(LINK2 http://www.pyyaml.org, PyYAML). */ module dyaml.representer; @@ -33,7 +34,7 @@ class RepresenterException : YAMLException mixin ExceptionCtors; } -///Used to represent YAML nodes various data types into scalar/sequence/mapping nodes ready for output. +///Used to represent YAML nodes various data types into scalar, sequence and mapping nodes ready for output. final class Representer { private: @@ -43,7 +44,7 @@ final class Representer /** * Construct a Representer. * - * Params: useDefaultRepresenters = Use defualt representer functions + * Params: useDefaultRepresenters = Use default representer functions * for default YAML types? This can be * disabled to use custom representer * functions for default types. @@ -180,11 +181,11 @@ final class Representer //user code. /** - * Represent a scalar with specified tag. + * Represent a _scalar with specified _tag. * * This is used by representer functions that produce scalars. * - * Params: tag = Tag of the scalar. + * Params: tag = Tag of the _scalar. * scalar = Scalar value. * * Returns: The represented node. @@ -210,7 +211,7 @@ final class Representer } /** - * Represent a sequence with specified tag, representing children first. + * Represent a _sequence with specified _tag, representing children first. * * This is used by representer functions that produce sequences. * @@ -248,12 +249,12 @@ final class Representer } /** - * Represent a mapping with specified tag, representing children first. + * Represent a mapping with specified _tag, representing children first. * * This is used by representer functions that produce mappings. * * Params: tag = Tag of the mapping. - * pairs = Key-value pairs of the mapping. + * pairs = Key-value _pairs of the mapping. * * Returns: The represented node. * @@ -288,7 +289,7 @@ final class Representer } package: - ///Represent a node based on its type, and return the represented result. + //Represent a node based on its type, and return the represented result. Node representData(ref Node data) { //User types are wrapped in YAMLObject. @@ -302,7 +303,7 @@ final class Representer return result; } - ///Represent a node, serializing with specified Serializer. + //Represent a node, serializing with specified Serializer. void represent(ref Serializer serializer, ref Node node) { auto data = representData(node); @@ -310,13 +311,14 @@ final class Representer } } -///Represent a null node as a null. + +///Represent a _null _node as a _null YAML value. Node representNull(ref Node node, Representer representer) { return representer.representScalar("tag:yaml.org,2002:null", "null"); } -///Represent a string node as a string scalar. +///Represent a string _node as a string scalar. Node representString(ref Node node, Representer representer) { string value = node.get!string; @@ -324,7 +326,7 @@ Node representString(ref Node node, Representer representer) : representer.representScalar("tag:yaml.org,2002:str", value); } -///Represent a bytes node as a binary scalar. +///Represent a bytes _node as a binary scalar. Node representBytes(ref Node node, Representer representer) { const ubyte[] value = node.get!(ubyte[]); @@ -333,21 +335,21 @@ Node representBytes(ref Node node, Representer representer) cast(string)Base64.encode(value)); } -///Represent a bool node as a bool scalar. +///Represent a bool _node as a bool scalar. Node representBool(ref Node node, Representer representer) { return representer.representScalar("tag:yaml.org,2002:bool", node.get!bool ? "true" : "false"); } -///Represent a long node as an integer scalar. +///Represent a long _node as an integer scalar. Node representLong(ref Node node, Representer representer) { return representer.representScalar("tag:yaml.org,2002:int", to!string(node.get!long)); } -///Represent a real node as a floating point scalar. +///Represent a real _node as a floating point scalar. Node representReal(ref Node node, Representer representer) { real f = node.get!real; @@ -361,7 +363,14 @@ Node representReal(ref Node node, Representer representer) return representer.representScalar("tag:yaml.org,2002:float", value); } -///Represent a sequence node as sequence/set. +///Represent a SysTime _node as a timestamp. +Node representSysTime(ref Node node, Representer representer) +{ + return representer.representScalar("tag:yaml.org,2002:timestamp", + node.get!SysTime.toISOExtString()); +} + +///Represent a sequence _node as sequence/set. Node representNodes(ref Node node, Representer representer) { auto nodes = node.get!(Node[]); @@ -383,7 +392,7 @@ Node representNodes(ref Node node, Representer representer) } } -///Represent a mapping node as map/ordered map/pairs. +///Represent a mapping _node as map/ordered map/pairs. Node representPairs(ref Node node, Representer representer) { auto pairs = node.get!(Node.Pair[]); @@ -433,13 +442,6 @@ Node representPairs(ref Node node, Representer representer) } } -///Represent a SysTime node as a timestamp. -Node representSysTime(ref Node node, Representer representer) -{ - return representer.representScalar("tag:yaml.org,2002:timestamp", - node.get!SysTime.toISOExtString()); -} - //Unittests private: