tinycon-0.6.5/000077500000000000000000000000001270223647400132145ustar00rootroot00000000000000tinycon-0.6.5/.gitignore000066400000000000000000000000301270223647400151750ustar00rootroot00000000000000.DS_Store node_modules/ tinycon-0.6.5/Gruntfile.js000066400000000000000000000004431270223647400155120ustar00rootroot00000000000000module.exports = function(grunt) { grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.initConfig({ uglify: { all: { options: { preserveComments: 'some' }, files: { 'tinycon.min.js': ['tinycon.js'] } }, }, }); };tinycon-0.6.5/LICENSE000066400000000000000000000020341270223647400142200ustar00rootroot00000000000000Copyright (c) 2015 Tom Moor Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. tinycon-0.6.5/README.md000066400000000000000000000050261270223647400144760ustar00rootroot00000000000000# Tinycon A small library for manipulating the favicon, in particular adding alert bubbles and changing images. Tinycon gracefully falls back to a number in title approach for browsers that don't support canvas or dynamic favicons. See the Live Demo here. ## Documentation Tinycon adds a single object to the global namespace and does not require initialisation. ### Installation There are several versions of Tinycon published on NPM, unfortunately they are not controlled by me and do not track HEAD. The best idea is to install from github directly and cut out the middleman! ``` npm install tommoor/tinycon --save ``` ### Basic Usage ```javascript Tinycon.setBubble(6); ``` ### Options Tinycon can take a range of options to customise the look * width: the width of the alert bubble * height: the height of the alert bubble * font: a css string to use for the fontface (recommended to leave this) * color: the foreground font color * background: the alert bubble background color * fallback: should we fallback to a number in brackets for browsers that don't support canvas/dynamic favicons? Boolean, or use the string 'force' to ensure a title update even in supported browsers. * abbreviate: should tinycon shrink large numbers such as 1000 to an abbreviated version (1k). Boolean, defaults to true ```javascript Tinycon.setOptions({ width: 7, height: 9, font: '10px arial', color: '#ffffff', background: '#549A2F', fallback: true }); ``` ### AMD support Tinycon can also be used as an asynchronous module. ```javascript require([ 'tinycon.js' ], function (T) { T.setOptions({ width: 7, height: 9, font: '10px arial', color: '#ffffff', background: '#549A2F', fallback: true }); T.setBubble(7); }); ``` ## Browser Support Tinycon has been tested to work completely in the following browsers. Older versions may be supported, but haven't been tested: * Chrome 15+ * Firefox 9+ * Opera 11+ Currently the library degrades to title update: * Internet Explorer 9 * Safari 5 ## License / Credits Tinycon is released under the MIT license. It is simple and easy to understand and places almost no restrictions on what you can do with Tinycon. [More Information](http://en.wikipedia.org/wiki/MIT_License) Tinycon was inspired by [Notificon](https://github.com/makeable/Notificon) ## Download Releases are available for download from [GitHub](http://github.com/tommoor/tinycon/downloads). tinycon-0.6.5/examples/000077500000000000000000000000001270223647400150325ustar00rootroot00000000000000tinycon-0.6.5/examples/favicon.ico000066400000000000000000000021761270223647400171610ustar00rootroot00000000000000 h(  @  33]] li 9ZZ`]x<` ] < <<0<< * ccZZQ$E o'$o ZZ33?   # 1       ? tinycon-0.6.5/examples/index-amd.html000066400000000000000000000004021270223647400175620ustar00rootroot00000000000000 Tinycon tinycon-0.6.5/examples/index.html000066400000000000000000000004661270223647400170350ustar00rootroot00000000000000 Tinycon tinycon-0.6.5/examples/screenshot.png000066400000000000000000000641341270223647400177250ustar00rootroot00000000000000PNG  IHDR7kEj CiCCPICC profilexڝSwX>eVBl"#Ya@Ņ VHUĂ H(gAZU\8ܧ}zy&j9R<:OHɽH gyx~t?op.$P&W " R.TSd ly|B" I>ةآ(G$@`UR,@".Y2GvX@`B, 8C L0ҿ_pH˕͗K3w!lBa)f "#HL 8?flŢko">!N_puk[Vh]3 Z zy8@P< %b0>3o~@zq@qanvRB1n#Dž)4\,XP"MyRD!ɕ2 w ONl~Xv@~- g42y@+͗\LD*A aD@ $<B AT:18 \p` Aa!:b""aH4 Q"rBj]H#-r9\@ 2G1Qu@Ơst4]k=Kut}c1fa\E`X&cX5V5cX7va$^lGXLXC%#W 1'"O%zxb:XF&!!%^'_H$ɒN !%2I IkHH-S>iL&m O:ňL $RJ5e?2BQͩ:ZImvP/S4u%͛Cˤ-Кigih/t ݃EЗkw Hb(k{/LӗT02goUX**|:V~TUsU?y TU^V}FUP թU6RwRPQ__c FHTc!2eXBrV,kMb[Lvv/{LSCsfffqƱ9ٜJ! {--?-jf~7zھbrup@,:m:u 6Qu>cy Gm7046l18c̐ckihhI'&g5x>fob4ekVyVV׬I\,mWlPW :˶vm))Sn1 9a%m;t;|rtuvlp4éĩWggs5KvSmnz˕ҵܭm=}M.]=AXq㝧/^v^Y^O&0m[{`:>=e>>z"=#~~~;yN`k5/ >B Yroc3g,Z0&L~oL̶Gli})*2.QStqt,֬Yg񏩌;jrvgjlRlc웸xEt$ =sl3Ttcܢ˞w|/9%bKGD pHYs  tIME1a~ IDATxwř7;a6IڠrB2H#`>l8׆ߝq` &KcI!0BBBq%$6ٝ1S=56av O}뉄RJ!I$I$I!Ev$I$I$II$I$I$ n$I$I$I$$I$I$IF$I$I$$I$I$I7$I$I$IH$I$I$Ip#I$I$I$$I$I$II$I$I$ n$I$I$I$$I$I$IF$I$I$II$I$I7$I$I$IH$I$I$Ip#I$I$I$$I$I$I7$I$I/YeTv$I$I:o";n$8$I$IG/J$I$I}00I$I/+ 1 n>PlI"I$I$ OsN@.$I$I@ל@眀5z$$I$I_&3P |9n NI$IE8قwি?@wi’$I$I_ 5+S roiG$I$/%ppWRﯹI$I$IP Hsn}T%I$IL`5ix $p3ښ\AM5;KH$I ${ 9WfC.&3e$I$Ik7Vs '4pmM&[Ns$p$I$I;M.lA@hq>wp_`PZ p$I$I_̤ݬ@s p n}t]/ n$I$I nr՞d(lR:8}7 l%~@$I$iKmkJtDMN \7}.mYhur=H$I *dpݠDj5S7 <$I$\\4l5mH@\5fɑZI$Itkk2iJVCc7鋏M_5@N6g;US$I$Iꏶ?t`t\8󹃛6ـlN48,%I$I'Ӱd9p),`cI1:H~~p8(W`#57$I$|p //6--1&8Y642hsߡPmmmbC^^v;(B)(PUU4֖,6^|PEמ6Ln?~g|<BŴޟR Ţt!>l&9rFۋBPRRÑdp̀Թ8nr1 \@ ގ^t 4(*6ZB ?mmv]6B2{2[wSU%ec*-_9r? yyy(,, 'dnF䗒so&`鷮.n TE\"x 4xI$&NS<;_STSEW-1:eo+ 9~>_9rnG^^RlJiC־lOBcOD0& BƟnpޝ`XLN\Di-#8TYb?QIdvcmDaB6:$_9rsӉ~Ȭ dkJ34L}Ktߋ{#÷WUfimd'J4Mt hB0O mw ?DÞ%_b1CF ͟;EȟD/> ݮֆ СC9rvbm'IsMtl̾ m\ǜٌ8y:;#5tnDDm&Q_HETǟ\D#.9r㯿~زeK3x_$^;$jĹ7 Ka6Pڛ>;F. .iLТӕR\fJl#.ٽd/l&x׽8b X|/ :}be .jQSX,:C9/>x0bĈS8XLhgiҁlOM_eS]{?si o ͆@ J)l6{xJlv/@&5־l<3#؈ js؄$ŷEխhEo~SѩBx&.JP-ah"k81y;7SͲxJ?FsQޓpUf9rnfCww7(/A86ʃ=Qgp26`+5Ie:霒^3fh›ݗSB3♷FSwUwj3ѨF@S~?7<#F8/b6Zre.={6@_|̙3GNjKFK& N:H,Hd&O83R6ZFۘE5ˮD":pq򓝵 , ΐ9O^HgΜAKK `֙9KFf3Ğ)ch6z{{QUUe:L ŏ?F~6MYd;cV*ESMܤ2٘LMFE`c#>F6SBNٍ/;0W  JN`뮝8s.6L.hߊBLO?mř[1Q=vFM_ǚ Psq%(UqIQߋބq',H^ j46h۶mÅЀ @?2 ֔ R[8$%Z"?TWW#b=4il`60ȴE Q%Qui@̪Z%&Lf+iV7 Fb&qƎ B ϟAY(O8L)d0@im29M`~G ߉ϟkK :<{2..FayMQUUtŎρځ{z d!쾫D:>@'o]]D %N&yqwݳs-Yv]/=gЏU\|u6lևǏGuu5Frc;S+ ͳ@hKhinѣGQSSv]hVkFl1Z&+FZ\׿Q@QÞmn12#!1(d+\4ZneN"k^"U0>in4٘}g}%2Z|$ هnNa>az8^0ۅCmEK&u};xX_0:PsPK ћRU;P:}o&)N96>AX ams?!܇&(]Sd?3MK &`ڵ:t(GoooGgg'"HcxJfBaa#jMM6}YAl5%32*x̓Y5›" 7I6*`$y@@dP(l_ +W… z3m @M&QΡgp);1ԘEL9iuؠ+mvLw,At^錷A;QF0!ω;Ku'~2@8<|AmH1'L#v@QE"j,yӡ}(S|=Q- ;Gׅ8԰M~2+f$N:ښC@ T5ɨ fؐ'6?M6h"̟7^'%6Bĩ7Fy2SR)>T@ T (N4kAUi;jHS磶O2OAss3ƌ͂m(yA 8z(xLO#+oiT/݋=SLW"Y{bx'd^@7rUUUWDҨo?bnc~S%v[[[Rx}} n;}n6fFNf\*g@MC:%XlTnH[cdRChcFO<'==quzA{za<;NL{HT# H*{q:)< 4rB  zUH$n"$IQQ5g5ra)3g΄&Ƅ2!OATŅ~4~W^yw=x㦛n tȐC4;&NPJӽ~W# ̀Jw: sQ,a_B%U/1T%5j֬Y*Ff@im"XOhvEEEp:8z((|\q7+^F㭙D ΔOQԔQA>pOȃQѤ&v?o~灢}v7ܷUUEGG"=(p&GbB}F;Cq&ɹwd211,F„}g›g.<q J|ވ6`ZC;:`-Bq#P`U(AB:hTvʃa5 M,>OM'?1[[[QRR׋H4 /Й3 rJ8q"|9s x <3gNTЀIA(&,jr'f(L 1UдǏOTiҹTj,)}AA%_Bc$׋={r^WjD@ٳgχr\Bcc#^9#i/_71X,h(拱Z:ĴbxQDx4+7+ .f;E#9<755:򵳲1py͗I|kɔ]8ۂDT̃)1I?xFDW[ @ } P>]mm@GwY:S\NUy(.7|/+ b  NʴbVN y77GghjPVPb`}Ѐӧ'*_6(PDBa4-EKdF8}4B0TJAza+?x`< 'PsT@% $~JIlpd?\;!)e;+禡m OΔZJ5o-?o#S '鴃RP8={1qdlVc)Qn [n|ڨRss3z`ӦM(**Jq2χnGkk+|>_)[yMhJx_ Ĉ&1zI 6Jο#-Vpt*q?{>Qb1f@sy%?bA#_##ߕIg Cq6&lEOT*p@t'wT4n#Jˠ|P*+ۚZP.4vKFSܾ!< (Hn4Ղ@GEQP]2GڶڐGg  # Ȳ;"> BOt5 3(Oo G/%O&R]F%&>bHX5 i 4׉@@2sBYQ+]p#;<2VU3 ă/6Fv._ 7H3eOw&R0M#GL4|o2:iE 3g"XS (ECP<>(EP˰;F]h4P>b},45/JU#1>҄^#gQ2q5#84DĬP%/f  b\͌6xޙ3gPQQ70R*(U`ٲex#`̘1#`AANb~1r(PBM^R_n>lD3|W`Ie)|>/=hf,u|;}]9 5܀?۝z}ﶂR35V\Tx+^O9W?P+7PUMlߙO 6MDoU瀪}TğRMIS]]]bL~ck:eY)^|]$IEq.)uCJMV3^G>OzhMgqqBLw|BÊ qm~pe%&5?ޠ8s4}=^C˖aEXh֭[F,X g:r!Z9T ((Ssuu4M`fZ \/oWg!t|>q w|Ww c:A'񣫖뗣q㳘> Jʂ'Z{X65&G-'BXȳiJlHt68aǕ\h\sR! #%v3@zԜN'ƍw,6?a1dGWWJJJt6`޼yډ;r-,Zvfbr'NoT9/5_(S ? NKXGͨ8k|8MEi7ψ_ ;;/_s1ZT&ji");]Dՠ$ԗq#- %ѦZy1?jxJKV'޲rL@\Z6Mwƃd;vf;ۍw((]aCCyu'~" ž:>sP1l6j+&arl*_Ѷ-qߞFsR$P8V;v uuuXf .byםkE+{z"} \?oN*ԸB5CX mXY c%|,ſ~iw&0~ OӇwe@T[rpR5߆G/|om>+PtGcx常B' Tr#6{m$mrZh2JOF!3I؅mM!4 _R ͆`0^8MYV~2 g"E"b&lֿj\F5b$щF.t~F͹n)?}ID#og_L(X%6#\C|կ<7ИؘKav]]vBv'^zF^{΋= ߟЙ}TV /oflp===kIOlG<^ٓDQtvv'%^ .NfTWWb  #F(a7TWW{>xUx嗱alذSLRCoپpfc)T,'츁Y ^ħOe&(=`L>0 BX-"gfaH^tTZ^Vχ}JI8&e7!;f 聀zW/ mVaSO /0?pOFmmn{^={Æ mnO<F˗/fń R+@II ZZZPVVa ۨym ,<(7 DbVR }Dg|}of})[ϛx^yߧ?@{.{rBW +.L6-n?W 2}A7o|+Ws=۷Ls,X|%ߍ~U47Q#q͍ 'F<wax Jqmў;X؅]w$t~^߈|(=g$TKHBysNIMnMSh"?;wqb6l@CCv؁f]H$Z8q"e{<9reeep8EII B4P[[ &n)˃GqqqJqE^Sї/n8)E-Q(z\&@86t7iG*oщNgtE?=*--E0L)䉓xӛ°ao} 7|3nf;`-*?#xڞY/D_ U(P|B)'CX|F?&\Pj,ѿ,w𻻧o=_3%^뱠+BPj4wlSkqx͎bk9GeSP.-wUYk$~b>l"1RfH"T@#2 #al];2ن6uKdՇ2ըnډ;vU/f[Y1x !"ë0cttww#r'r~đ#Gb Kf.÷-\{5Vq/.* طnû|%W_(Ű0%#Dt;(;w=1l{D{Zw4)9pؠD.Ynkr 3f)AxuV:y Æ KY I1d /C͛1n89 0o;o#jXxӢXKeK_3rM)ʬT5%yCԼ@43tljY1b:'l!^"߃@;ݯ׌p8e}eraai>Om}7 />|iӧšv! &B" pf.$=I)dkΧ@c]q3Ͽ3/X(ri斨3 O1D3h_χp8ѣF~oa4űcP[[՛bUWW ???gex<>|8ń6h&xm!D*x(`&~ya9`Ċv)3- /{&_P[ľ6Pbecʕ,?+IWf![gLڝtZvMMM>|y|e9ٗE"/X$40KbՑ<Fb+^T;h1R3gΠƍCoooM3&Q+3.[oÆɓ'k.|P[ApԎF볿B1iժDXp~+ha%PHn' upt(*Y(wKK Z[[5d OmLv\.\.Cyk ZZZPPP0 _a<1r FcxiSFբM$݇/qc??}4$xd7Hc1?Rfa͘e6ҴDS۷_|qzQ=꫘f|.#/^WԈls=3]bbܹ(**BooO !,ʞ}b(֮]g1UwۡF"iz >I">4C(G?gB.H%yhkok\`>@0Դl4,n>V^^_ YM]a}Ib5#&7\0bDD$e7Ngj22=YVSӔh{g3SU& 5:̤IMupSL*T aL+0!A>Rᎅl65*xbݏUO8'54yj3SsDAw,VaQ,XpaoMʩZ7I9#K@(mJ8D>oM+C$` !ѣGQSSv$wdEak j,~F2[၉,&3L%~e}q?M(,DYY|*M\ mX*_a3!:FasZPŸ\xh6{I;NsϷ{vL> pX4!bNOOg9h33Ph$qIZ T'uBޒ_E1utcǎ^fZ6;1vh*oZB=%gW,f)nkɦT:T>9ژit:۬?y-bpqaMD[/0gÆMxT|*~'v{67oF4W^<\}BpabW- @4y|2<ޑ{weMFİ< ɿs? ?/s΁(سgz{{ϻu@|M!f:k yYg2w]XQ3ͺvèV_ˉs#@6ʋ\}vKl仓d>ө ńKbWIl6$#O)· *JQ)v]޶mf3?󨾰|;uTTcH:vΖIK3;ˇ޲\]8~3 K?G)QEEEXx1>={e'}fżA4 E4Z F1 AXVwfo0bDT:ML:ΠԖ!jrrw]wAb1z!%R,,Ԭm4Ca+y+Ĩ'kk+\.F $IkO3F.*F n=*Sl@OKkkƞpR$TW/MH}Ds_$e"3hOh910s#ѹG&iv_mWy~I*]ƭ'LO.zm?l@L_*f쥲9hstm1ᰘrBԝ(7_(RrrZo+6F"<[/_߹?%g?^az@lAN&֊/t-ILIUd&1Hr2?&͊&s5DGK*Or$ g@R8gRme〜)YhI5jRL+Y CWy*h*#UYPhH^/r%+?!O?3Ee h|j-a&ɥ].@@tA ƚOL$ƩCH&YՂQo4Ecc#BP<@.}ZE_hVHC*fj.9ց-}1We/q]c5!U9z/G9/I,VBF^T,S&\3QnɿjLő#G0n8ˈI_RU]8t jGj*P6y_{x&@䤹 \.U[ rB$Q/\ ԃI HDWk&T _ jvָg;K̭{矪ELCƌ%/y^X'O@С)'YA !'׽:v\PL/f&S'd+F2UsPφC*b3,^LYxJ dDZTҟwH|w4ߌP0#/$BPZV&, RHlsٳ(m'd^W4qWҼE;x+oOSmPr GH? Fc$ݍTTTd}fާd7 O?4V^kw;p8r҄Cx$M=;ǒd& S0X`5~e_8` 芴!*Mκ-'g-. kA4ayVF=zGĉQZZ2oΙ;;;wvǛn .soǎظq#9ۍ#FK.i+iHUU7z}OW)+G7^/ldݡU.\A9?uut魆zj^>,ꪜ'BM[B0Bl?^Ggg |>,^rA+m۶!C/Ǎ7˨T7==u12tj,k$i"99W{s*CEyyBH^Є3Ԅ49lNEI¡0N8b|>5IFeCxwPk֬A8Ƙ1cQ_ 3gn3g}j(ů~k|ؿ? (--M_kŊ/K̛73gD0ĨQp+x7@ĒN8nL2v‰'jo n{(USE~b=] & |pvUEo69>=׿5+5{ꫯ+I~=@lv%8 UpхN bC,F( ]vj@ JQ rw}vZ mmmZwyV’%K0c =b: ÇGccV1Î;G\F{w ܤ3Y\8ݺ /BD"l#|͉9{2m6vq;j@p8a1|ף>'pF_?t oXуG@vM`E# aLyf+ V6ç; [|^sIysk\cAQ|HU`5.8D>d wD!@ݞ^;5yd!?y{~֟k MٳX|9N'ϟ = tq}رcv|>ϫWc-K3W{@ hsn5bЄǺfuuË/28N(\eLRX$tdU5W` PB J) |Y{/>p8Kq%ظq#>c|>tvt6]2&yK'Į]P^^˅]v_:ڍa t&W曝,)ă}[p̙EV{Xmg.8nB1~ wtᢋKhɟgGKIDAT}}Qs+WBSS3~?@(--׿u׿Dqq16l؀[n%L 9/f9.7-*xkQ6uK/!Crt@^+ƣ{QIt30 nG[k@4Q_a/2rp]waE,CII n6477p݈D"PEK 6'|uuu:t:QVV]ݎz(ECW:GGG/^O>'555Cooo:ݻ&L) 7߄׾bƸqƍ޽{Obhn7nF8NeEkd#RԔrՂ d~縒_8WƳ WphTŢn P,` {'1~B^"b&sAI}݇/+V@}}}1~x,]'O6];kfͷ& p.+;i7ݿf!r4eʂȓLIѣx70dnl6<w# |ɒTNT_DL0tP6 mmmp9]LhjjӧQTTYfa hooFx'g*e?`S {GӉBlݺp7Mz4yf̝;hM(BYY."UU1tPꫯƖ-[$':vQ]] 5.Fm6FѣGFQFn4E}}=&O . /h,BueN`8E ٖ 8k:~Ӑ8;c5dƎu@8u**;`%cF?^EQ FCe "0i$L4 n:|)_y啸k1yv"Ki;X~=:ƍH<?uhNˈ)",8 Y)Ԕc4l{1nx<(n?#:;;DRxp:xG0Bz&&IG@0SOqYv(ZlP , Tep)xyثhkkSMGsLbc„ l  oUhuyS)SOFp[nE =w!NpcpkN'E6 4+cJڵ >OS;NƮ0&:>^9?fgX-lV{Z18 Vj#-m*@мN$pZ`魷B+Ӗ?#x,SO-ݻQTT6HDCq8vc'6v$@)R6uz&L͛QUU͖ѣE~~>zzz.-OT^^e˖^o[,XӧO7m}vYv˖-Cyyy:a*@K8"!h5ߜ'[R`DM5ڎVk#^1%Bj,=#ܳj,3ȷح)sƁ?c?b7_qA~*:5GWw*CT\0`0Tذana*˭P UdF7O<׽3gbɒ_۶o~O?T{?˿nf;Zժ3uaMZeW QS#(شq#$|(UA ˯`߾};0rHCA3&ڶMg΋D"rpEaÆ [$䙞)=ƮSL  ˅K.EEEl4i~mZRvcٲexkئ~{FUMnvBAg=\F+?mHʝP@wbn}#N~+I Om]vnٳGrh|D*N (n4n'=ҁ;?[zn_xDi(L:SMmڷ;ocǎرcfy?of̘%$?ή.̚5 s@Aqq1z-lٲEӈ[,Zǿ_Zs_n Gp:Xx1^~eXVACyםx؈ }`С8}4/_,\0Y~f.tuuH3E-]b֭p8z `ŊطoT% nT{Kp'Nߎ^lV+zc1)L'֥$3>98^U[}^.7!F[>+Vq饗aHi aލRDriG24i&#jjYR E?R2ǣ,PXXfMh1믣@FJqDKmpZ-s}cǢ V±cPSS%K`ر `߾}Ypaz[&& JφX}&$|8x̾mi&bPs G_a҂瓱YO3? X|9^+ʇ? Z1z6XF?9֬Yxqe_:~#Z}S ݋'Yl? j[o(֭[aw:vaZg(-J +5Oy8 "{[PPuj,V ,xTQQ1N;T5yћ9j=<N (..m6DQXV$˖tH)‘pNu&g\ O?xᇡ( -ZBL1,**Bmm-^u_>D49N8XSN_G,å^O?˗/ŋQSS5F_3e(p*vsW1V "vt[aɸdRB q CK4lFugKɀM.?VP6  T( rk!(|>@"8x@^e56=1~xWPAA}Q'|y .@ I|A\.YzAҀQ4ESS|>^z%TVV_*0c K/٩.imx?Oʟ҅_m>a;^,a `@ N>w {&oMzϠ4OD] ?ܦ=W4M$iՈE eC3W όf#F),xR B!]D,>̣i(μ;lSx7駟ꢣ-ZEn̙i }|p)466pf`ذcIps~Ŀݍu]qݙJX:36ѦJ Q-*pEEi 0t〉kS0Q)x/]lUC Իn]Ԕ⑩R{B<,͓<#ٮ|?h{wλstIÇK*6݈>_1zk6;Rh/C7Ol:W-?yfu3iibb_㧵;CEY퐵QatŚrg zȈFFFtuڵuaBs+&''uUU*YkuYy|v1ΚI7iNw}5VkU]Q5qmTE$0ST9]Vc1ƫ"?[YQH|9lWT-l9~c7^-ş$1xe5>>\>ؘZŒB}GJU~@ sƟΩX,뒤/z>}Zy,oUϙq\PNGs`>H;~nu=}TT*듑T[Er͓7$2a#XwYWU`[ș2$' Q$c,X4j L<%juWV"/8r,A5˳DB>F* f{ow0V+AX%y.߯)MMMy{;wFmZoVVrm4j~ҒB$76q F+Vju}rw>_Uu/w?/>oNgSL)*$M2j1^m3Imizߟ׏?/X߿{DD6J߽lxt6㦱A"us r&[a=_>_PX[o P6?9{hm9?N?Coœ9{In̍wSqSr&a?=Xr`=4xzYdCNĿ~2ҡCoujggFI=8\4g YkoR7u[w/2%-..WOO~kj%IK$qGWWW~2ӴgoOrM ia2?IOd&޸& Lmfq3%A4IύaaQ r ohN :j_^uiN'_fo/+Οv߷gl)Ѥ{_<(55nI2X*&uu_;o,u.q`zu}^a#?Nv_髍Z9NƹڳY铜[6E4'M,[KĿL~T,ߍ'ol:Ϙ f]&6^DqO/9]&~hc襦沍6shM:?=&]Dw0&c_b>??'~fn7ngU˗9Bh}7'$7$7$7$7@r@r@r@r@rHnHnHnHnHn    $7$7$7$7`uIENDB`tinycon-0.6.5/package.json000066400000000000000000000005261270223647400155050ustar00rootroot00000000000000{ "name": "tinycon", "version": "0.6.4", "description": "Add notification bubbles in the favicon", "author": "Tom Moor (http://tommoor.com)", "main" : "./tinycon.js", "repository" : { "type": "git", "url": "git://github.com/tommoor/tinycon.git" }, "devDependencies": { "grunt": "~0.4.5" } } tinycon-0.6.5/tinycon.js000066400000000000000000000167101270223647400152420ustar00rootroot00000000000000/*! * Tinycon - A small library for manipulating the Favicon * Tom Moor, http://tommoor.com * Copyright (c) 2015 Tom Moor * @license MIT Licensed * @version 0.6.4 */ (function(){ var Tinycon = {}; var currentFavicon = null; var originalFavicon = null; var faviconImage = null; var canvas = null; var options = {}; var r = window.devicePixelRatio || 1; var size = 16 * r; var defaults = { width: 7, height: 9, font: 10 * r + 'px arial', color: '#ffffff', background: '#F03D25', fallback: true, crossOrigin: true, abbreviate: true }; var ua = (function () { var agent = navigator.userAgent.toLowerCase(); // New function has access to 'agent' via closure return function (browser) { return agent.indexOf(browser) !== -1; }; }()); var browser = { ie: ua('trident'), chrome: ua('chrome'), webkit: ua('chrome') || ua('safari'), safari: ua('safari') && !ua('chrome'), mozilla: ua('mozilla') && !ua('chrome') && !ua('safari') }; // private methods var getFaviconTag = function(){ var links = document.getElementsByTagName('link'); for(var i=0, len=links.length; i < len; i++) { if ((links[i].getAttribute('rel') || '').match(/\bicon\b/i)) { return links[i]; } } return false; }; var removeFaviconTag = function(){ var links = document.getElementsByTagName('link'); var head = document.getElementsByTagName('head')[0]; for(var i=0, len=links.length; i < len; i++) { var exists = (typeof(links[i]) !== 'undefined'); if (exists && (links[i].getAttribute('rel') || '').match(/\bicon\b/i)) { head.removeChild(links[i]); } } }; var getCurrentFavicon = function(){ if (!originalFavicon || !currentFavicon) { var tag = getFaviconTag(); currentFavicon = tag ? tag.getAttribute('href') : '/favicon.ico'; if (!originalFavicon) { originalFavicon = currentFavicon; } } return currentFavicon; }; var getCanvas = function (){ if (!canvas) { canvas = document.createElement("canvas"); canvas.width = size; canvas.height = size; } return canvas; }; var setFaviconTag = function(url){ if(url){ removeFaviconTag(); var link = document.createElement('link'); link.type = 'image/x-icon'; link.rel = 'icon'; link.href = url; document.getElementsByTagName('head')[0].appendChild(link); } }; var log = function(message){ if (window.console) window.console.log(message); }; var drawFavicon = function(label, color) { // fallback to updating the browser title if unsupported if (!getCanvas().getContext || browser.ie || browser.safari || options.fallback === 'force') { return updateTitle(label); } var context = getCanvas().getContext("2d"); var color = color || '#000000'; var src = getCurrentFavicon(); faviconImage = document.createElement('img'); faviconImage.onload = function() { // clear canvas context.clearRect(0, 0, size, size); // draw the favicon context.drawImage(faviconImage, 0, 0, faviconImage.width, faviconImage.height, 0, 0, size, size); // draw bubble over the top if ((label + '').length > 0) drawBubble(context, label, color); // refresh tag in page refreshFavicon(); }; // allow cross origin resource requests if the image is not a data:uri // as detailed here: https://github.com/mrdoob/three.js/issues/1305 if (!src.match(/^data/) && options.crossOrigin) { faviconImage.crossOrigin = 'anonymous'; } faviconImage.src = src; }; var updateTitle = function(label) { if (options.fallback) { // Grab the current title that we can prefix with the label var originalTitle = document.title; // Strip out the old label if there is one if (originalTitle[0] === '(') { originalTitle = originalTitle.slice(originalTitle.indexOf(' ')); } if ((label + '').length > 0) { document.title = '(' + label + ') ' + originalTitle; } else { document.title = originalTitle; } } }; var drawBubble = function(context, label, color) { // automatic abbreviation for long (>2 digits) numbers if (typeof label == 'number' && label > 99 && options.abbreviate) { label = abbreviateNumber(label); } // bubble needs to be larger for double digits var len = (label + '').length-1; var width = options.width * r + (6 * r * len), height = options.height * r; var top = size - height, left = size - width - r, bottom = 16 * r, right = 16 * r, radius = 2 * r; // webkit seems to render fonts lighter than firefox context.font = (browser.webkit ? 'bold ' : '') + options.font; context.fillStyle = options.background; context.strokeStyle = options.background; context.lineWidth = r; // bubble context.beginPath(); context.moveTo(left + radius, top); context.quadraticCurveTo(left, top, left, top + radius); context.lineTo(left, bottom - radius); context.quadraticCurveTo(left, bottom, left + radius, bottom); context.lineTo(right - radius, bottom); context.quadraticCurveTo(right, bottom, right, bottom - radius); context.lineTo(right, top + radius); context.quadraticCurveTo(right, top, right - radius, top); context.closePath(); context.fill(); // bottom shadow context.beginPath(); context.strokeStyle = "rgba(0,0,0,0.3)"; context.moveTo(left + radius / 2.0, bottom); context.lineTo(right - radius / 2.0, bottom); context.stroke(); // label context.fillStyle = options.color; context.textAlign = "right"; context.textBaseline = "top"; // unfortunately webkit/mozilla are a pixel different in text positioning context.fillText(label, r === 2 ? 29 : 15, browser.mozilla ? 7*r : 6*r); }; var refreshFavicon = function(){ // check support if (!getCanvas().getContext) return; setFaviconTag(getCanvas().toDataURL()); }; var abbreviateNumber = function(label) { var metricPrefixes = [ ['G', 1000000000], ['M', 1000000], ['k', 1000] ]; for(var i = 0; i < metricPrefixes.length; ++i) { if (label >= metricPrefixes[i][1]) { label = round(label / metricPrefixes[i][1]) + metricPrefixes[i][0]; break; } } return label; }; var round = function (value, precision) { var number = new Number(value); return number.toFixed(precision); }; // public methods Tinycon.setOptions = function(custom){ options = {}; // account for deprecated UK English spelling if (custom.colour) { custom.color = custom.colour; } for(var key in defaults){ options[key] = custom.hasOwnProperty(key) ? custom[key] : defaults[key]; } return this; }; Tinycon.setImage = function(url){ currentFavicon = url; refreshFavicon(); return this; }; Tinycon.setBubble = function(label, color) { label = label || ''; drawFavicon(label, color); return this; }; Tinycon.reset = function(){ currentFavicon = originalFavicon; setFaviconTag(originalFavicon); }; Tinycon.setOptions(defaults); if(typeof define === 'function' && define.amd) { define(Tinycon); } else if (typeof module !== 'undefined') { module.exports = Tinycon; } else { window.Tinycon = Tinycon; } })();