diff --git a/.bowerrc b/.bowerrc new file mode 100644 index 00000000..67a2bf07 --- /dev/null +++ b/.bowerrc @@ -0,0 +1,3 @@ +{ + "directory": "client/components" +} diff --git a/Gruntfile.js b/Gruntfile.js index 5ecefaed..e57541e8 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -5,9 +5,11 @@ module.exports = function(grunt) { uglify: { js: { files: { - "client/grunt/test.min.js": [ - "client/grunt/test-1.js", - "client/grunt/test-2.js" + "client/js/libs.js": [ + "client/components/jquery/dist/jquery.js", + "client/components/stickyscroll/stickyscroll.js", + "client/components/jquery-cookie/jquery.cookie.js", + "client/components/favico.js/favico.js" ] } } diff --git a/bower.json b/bower.json new file mode 100644 index 00000000..921578c9 --- /dev/null +++ b/bower.json @@ -0,0 +1,9 @@ +{ + "name": "shout", + "dependencies": { + "jquery": "~2.1.1", + "favico.js": "~0.3.4", + "stickyscroll": "~1.3.1", + "jquery-cookie": "~1.4.1" + } +} diff --git a/client/components/favico.js/.bower.json b/client/components/favico.js/.bower.json new file mode 100644 index 00000000..7a96a91d --- /dev/null +++ b/client/components/favico.js/.bower.json @@ -0,0 +1,34 @@ +{ + "name": "favico.js", + "version": "0.3.4", + "homepage": "http://lab.ejci.net/favico.js/", + "authors": [ + "Miroslav Magda " + ], + "description": "Favico.js is a library to manipulate the favicon, adding alert badges, render images or videos.", + "main": "favico.js", + "keywords": [ + "favicon", + "badge" + ], + "license": "MIT", + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "page", + "example-simple", + "example-angular", + "tests" + ], + "_release": "0.3.4", + "_resolution": { + "type": "version", + "tag": "0.3.4", + "commit": "fe580b81a240fba23cf324b018402cec96618cd1" + }, + "_source": "git://github.com/ejci/favico.js.git", + "_target": "~0.3.4", + "_originalSource": "favico.js" +} \ No newline at end of file diff --git a/client/components/favico.js/GPL-LICENSE.txt b/client/components/favico.js/GPL-LICENSE.txt new file mode 100644 index 00000000..76927f58 --- /dev/null +++ b/client/components/favico.js/GPL-LICENSE.txt @@ -0,0 +1,278 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. \ No newline at end of file diff --git a/client/components/favico.js/MIT-LICENSE.txt b/client/components/favico.js/MIT-LICENSE.txt new file mode 100644 index 00000000..83e1702a --- /dev/null +++ b/client/components/favico.js/MIT-LICENSE.txt @@ -0,0 +1,20 @@ +Copyright (c) 2011 Miroslav Magda, http://ejci.net/ + +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. \ No newline at end of file diff --git a/client/components/favico.js/Makefile b/client/components/favico.js/Makefile new file mode 100644 index 00000000..1ab19831 --- /dev/null +++ b/client/components/favico.js/Makefile @@ -0,0 +1,51 @@ + +BIN = ./node_modules/.bin + +CWD := $(shell pwd) +UGLIFY = $(CWD)/node_modules/.bin/uglifyjs +JSHINT = $(CWD)/node_modules/.bin/jshint + +clean: + @rm -f favico-*.min.js + +lint: + $(JSHINT) ./favico.js + +build: + make clean + make lint + VERSION=`node -pe "require('./package.json').version"` && \ + $(UGLIFY) -c -m --comments 'license' favico.js > "favico-$$VERSION.min.js" + +define release + VERSION=`node -pe "require('./bower.json').version"` && \ + NEXT_VERSION=`node -pe "require('semver').inc(\"$$VERSION\", '$(1)')"` && \ + node -e "\ + ['./bower.json', './package.json'].forEach(function (file) {\ + var j = require(file);\ + j.version = \"$$NEXT_VERSION\";\ + var s = JSON.stringify(j, null, 2);\ + require('fs').writeFileSync(file, s);\ + });\ + " && \ + git rm favico-*.min.js && \ + make build && \ + git add favico-*.min.js bower.json package.json && \ + git commit -m "release $$NEXT_VERSION" && \ + git tag "$$NEXT_VERSION" -m "release $$NEXT_VERSION" +endef + +release-patch: lint + @$(call release,patch) + +release-minor: lint + @$(call release,minor) + +release-major: lint + @$(call release,major) + +publish: + git push --tags origin HEAD:master + # todo: bower/npm publish + +.PHONY: clean lint build diff --git a/client/components/favico.js/bower.json b/client/components/favico.js/bower.json new file mode 100644 index 00000000..6b0148f6 --- /dev/null +++ b/client/components/favico.js/bower.json @@ -0,0 +1,11 @@ +{ + "name": "favico.js", + "version": "0.3.4", + "homepage": "http://lab.ejci.net/favico.js/", + "authors": ["Miroslav Magda "], + "description": "Favico.js is a library to manipulate the favicon, adding alert badges, render images or videos.", + "main": "favico.js", + "keywords": ["favicon", "badge"], + "license": "MIT", + "ignore": ["**/.*", "node_modules", "bower_components", "test", "page", "example-simple", "example-angular", "tests"] +} \ No newline at end of file diff --git a/client/components/favico.js/favico-0.3.4.min.js b/client/components/favico.js/favico-0.3.4.min.js new file mode 100644 index 00000000..7e7a0c7a --- /dev/null +++ b/client/components/favico.js/favico-0.3.4.min.js @@ -0,0 +1,7 @@ +/** + * @license MIT + * @fileOverview Favico animations + * @author Miroslav Magda, http://blog.ejci.net + * @version 0.3.4 + */ +!function(){var e=function(e){"use strict";function t(e){if(e.paused||e.ended||w)return!1;try{d.clearRect(0,0,h,s),d.drawImage(e,0,0,h,s)}catch(o){}setTimeout(t,U.duration,e),L.setIcon(c)}function o(e){var t=/^#?([a-f\d])([a-f\d])([a-f\d])$/i;e=e.replace(t,function(e,t,o,n){return t+t+o+o+n+n});var o=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);return o?{r:parseInt(o[1],16),g:parseInt(o[2],16),b:parseInt(o[3],16)}:!1}function n(e,t){var o,n={};for(o in e)n[o]=e[o];for(o in t)n[o]=t[o];return n}function r(){return document.hidden||document.msHidden||document.webkitHidden||document.mozHidden}e=e?e:{};var i,a,s,h,c,d,f,l,u,g,y,w,x,m={bgColor:"#d00",textColor:"#fff",fontFamily:"sans-serif",fontStyle:"bold",type:"circle",position:"down",animation:"slide",elementId:!1};x={},x.ff=/firefox/i.test(navigator.userAgent.toLowerCase()),x.chrome=/chrome/i.test(navigator.userAgent.toLowerCase()),x.opera=/opera/i.test(navigator.userAgent.toLowerCase()),x.ie=/msie/i.test(navigator.userAgent.toLowerCase())||/trident/i.test(navigator.userAgent.toLowerCase()),x.supported=x.chrome||x.ff||x.opera;var p=[];y=function(){},l=w=!1;var v=function(){i=n(m,e),i.bgColor=o(i.bgColor),i.textColor=o(i.textColor),i.position=i.position.toLowerCase(),i.animation=U.types[""+i.animation]?i.animation:m.animation;var t=i.position.indexOf("up")>-1,r=i.position.indexOf("left")>-1;if(t||r)for(var l=0;l0?f.height:32,h=f.width>0?f.width:32,c.height=s,c.width=h,d=c.getContext("2d"),b.ready()}):(f.setAttribute("src",""),s=32,h=32,f.height=s,f.width=h,c.height=s,c.width=h,d=c.getContext("2d"),b.ready())}catch(g){throw"Error initializing favico. Message: "+g.message}},b={};b.ready=function(){l=!0,b.reset(),y()},b.reset=function(){p=[],u=!1,d.clearRect(0,0,h,s),d.drawImage(f,0,0,h,s),L.setIcon(c)},b.start=function(){if(l&&!g){var e=function(){u=p[0],g=!1,p.length>0&&(p.shift(),b.start())};p.length>0&&(g=!0,u?U.run(u.options,function(){U.run(p[0].options,function(){e()},!1)},!0):U.run(p[0].options,function(){e()},!1))}};var C={},M=function(e){return e.n=Math.abs(e.n),e.x=h*e.x,e.y=s*e.y,e.w=h*e.w,e.h=s*e.h,e};C.circle=function(e){e=M(e);var t=!1;e.n>9&&e.n<100?(e.x=e.x-.4*e.w,e.w=1.4*e.w,t=!0):e.n>=100&&(e.x=e.x-.65*e.w,e.w=1.65*e.w,t=!0),d.clearRect(0,0,h,s),d.drawImage(f,0,0,h,s),d.beginPath(),d.font=i.fontStyle+" "+Math.floor(e.h*(e.n>99?.85:1))+"px "+i.fontFamily,d.textAlign="center",t?(d.moveTo(e.x+e.w/2,e.y),d.lineTo(e.x+e.w-e.h/2,e.y),d.quadraticCurveTo(e.x+e.w,e.y,e.x+e.w,e.y+e.h/2),d.lineTo(e.x+e.w,e.y+e.h-e.h/2),d.quadraticCurveTo(e.x+e.w,e.y+e.h,e.x+e.w-e.h/2,e.y+e.h),d.lineTo(e.x+e.h/2,e.y+e.h),d.quadraticCurveTo(e.x,e.y+e.h,e.x,e.y+e.h-e.h/2),d.lineTo(e.x,e.y+e.h/2),d.quadraticCurveTo(e.x,e.y,e.x+e.h/2,e.y)):d.arc(e.x+e.w/2,e.y+e.h/2,e.h/2,0,2*Math.PI),d.fillStyle="rgba("+i.bgColor.r+","+i.bgColor.g+","+i.bgColor.b+","+e.o+")",d.fill(),d.closePath(),d.beginPath(),d.stroke(),d.fillStyle="rgba("+i.textColor.r+","+i.textColor.g+","+i.textColor.b+","+e.o+")",e.n>999?d.fillText((e.n>9999?9:Math.floor(e.n/1e3))+"k+",Math.floor(e.x+e.w/2),Math.floor(e.y+e.h-.2*e.h)):d.fillText(e.n,Math.floor(e.x+e.w/2),Math.floor(e.y+e.h-.15*e.h)),d.closePath()},C.rectangle=function(e){e=M(e);var t=!1;e.n>9&&e.n<100?(e.x=e.x-.4*e.w,e.w=1.4*e.w,t=!0):e.n>=100&&(e.x=e.x-.65*e.w,e.w=1.65*e.w,t=!0),d.clearRect(0,0,h,s),d.drawImage(f,0,0,h,s),d.beginPath(),d.font="bold "+Math.floor(e.h*(e.n>99?.9:1))+"px sans-serif",d.textAlign="center",d.fillStyle="rgba("+i.bgColor.r+","+i.bgColor.g+","+i.bgColor.b+","+e.o+")",d.fillRect(e.x,e.y,e.w,e.h),d.fillStyle="rgba("+i.textColor.r+","+i.textColor.g+","+i.textColor.b+","+e.o+")",e.n>999?d.fillText((e.n>9999?9:Math.floor(e.n/1e3))+"k+",Math.floor(e.x+e.w/2),Math.floor(e.y+e.h-.2*e.h)):d.fillText(e.n,Math.floor(e.x+e.w/2),Math.floor(e.y+e.h-.15*e.h)),d.closePath()};var I=function(e,t){y=function(){try{if(e>0){if(U.types[""+t]&&(i.animation=t),p.push({type:"badge",options:{n:e}}),p.length>100)throw"Too many badges requests in queue.";b.start()}else b.reset()}catch(o){throw"Error setting badge. Message: "+o.message}},l&&y()},A=function(e){y=function(){try{var t=e.width,o=e.height,n=document.createElement("img"),r=o/s>t/h?t/h:o/s;n.setAttribute("src",e.getAttribute("src")),n.height=o/r,n.width=t/r,d.clearRect(0,0,h,s),d.drawImage(n,0,0,h,s),L.setIcon(c)}catch(i){throw"Error setting image. Message: "+i.message}},l&&y()},E=function(e){y=function(){try{if("stop"===e)return w=!0,b.reset(),w=!1,void 0;e.addEventListener("play",function(){t(this)},!1)}catch(o){throw"Error setting video. Message: "+o.message}},l&&y()},T=function(e){if(window.URL&&window.URL.createObjectURL||(window.URL=window.URL||{},window.URL.createObjectURL=function(e){return e}),x.supported){var o=!1;navigator.getUserMedia=navigator.getUserMedia||navigator.oGetUserMedia||navigator.msGetUserMedia||navigator.mozGetUserMedia||navigator.webkitGetUserMedia,y=function(){try{if("stop"===e)return w=!0,b.reset(),w=!1,void 0;o=document.createElement("video"),o.width=h,o.height=s,navigator.getUserMedia({video:!0,audio:!1},function(e){o.src=URL.createObjectURL(e),o.play(),t(o)},function(){})}catch(n){throw"Error setting webcam. Message: "+n.message}},l&&y()}},L={};L.getIcon=function(){var e=!1,t="",o=function(){for(var e=document.getElementsByTagName("head")[0].getElementsByTagName("link"),t=e.length,o=t-1;o>=0;o--)if(/icon/i.test(e[o].getAttribute("rel")))return e[o];return!1};if(i.elementId?(e=document.getElementById(i.elementId),e.setAttribute("href",e.getAttribute("src"))):(e=o(),e===!1&&(e=document.createElement("link"),e.setAttribute("rel","icon"),document.getElementsByTagName("head")[0].appendChild(e))),t=i.elementId?e.src:e.href,-1===t.indexOf(document.location.hostname))throw new Error("Error setting favicon. Favicon image is on different domain (Icon: "+t+", Domain: "+document.location.hostname+")");return e.setAttribute("type","image/png"),e},L.setIcon=function(e){var t=e.toDataURL("image/png");if(i.elementId)document.getElementById(i.elementId).setAttribute("src",t);else if(x.ff||x.opera){var o=a;a=document.createElement("link"),x.opera&&a.setAttribute("rel","icon"),a.setAttribute("rel","icon"),a.setAttribute("type","image/png"),document.getElementsByTagName("head")[0].appendChild(a),a.setAttribute("href",t),o.parentNode&&o.parentNode.removeChild(o)}else a.setAttribute("href",t)};var U={};return U.duration=40,U.types={},U.types.fade=[{x:.4,y:.4,w:.6,h:.6,o:0},{x:.4,y:.4,w:.6,h:.6,o:.1},{x:.4,y:.4,w:.6,h:.6,o:.2},{x:.4,y:.4,w:.6,h:.6,o:.3},{x:.4,y:.4,w:.6,h:.6,o:.4},{x:.4,y:.4,w:.6,h:.6,o:.5},{x:.4,y:.4,w:.6,h:.6,o:.6},{x:.4,y:.4,w:.6,h:.6,o:.7},{x:.4,y:.4,w:.6,h:.6,o:.8},{x:.4,y:.4,w:.6,h:.6,o:.9},{x:.4,y:.4,w:.6,h:.6,o:1}],U.types.none=[{x:.4,y:.4,w:.6,h:.6,o:1}],U.types.pop=[{x:1,y:1,w:0,h:0,o:1},{x:.9,y:.9,w:.1,h:.1,o:1},{x:.8,y:.8,w:.2,h:.2,o:1},{x:.7,y:.7,w:.3,h:.3,o:1},{x:.6,y:.6,w:.4,h:.4,o:1},{x:.5,y:.5,w:.5,h:.5,o:1},{x:.4,y:.4,w:.6,h:.6,o:1}],U.types.popFade=[{x:.75,y:.75,w:0,h:0,o:0},{x:.65,y:.65,w:.1,h:.1,o:.2},{x:.6,y:.6,w:.2,h:.2,o:.4},{x:.55,y:.55,w:.3,h:.3,o:.6},{x:.5,y:.5,w:.4,h:.4,o:.8},{x:.45,y:.45,w:.5,h:.5,o:.9},{x:.4,y:.4,w:.6,h:.6,o:1}],U.types.slide=[{x:.4,y:1,w:.6,h:.6,o:1},{x:.4,y:.9,w:.6,h:.6,o:1},{x:.4,y:.9,w:.6,h:.6,o:1},{x:.4,y:.8,w:.6,h:.6,o:1},{x:.4,y:.7,w:.6,h:.6,o:1},{x:.4,y:.6,w:.6,h:.6,o:1},{x:.4,y:.5,w:.6,h:.6,o:1},{x:.4,y:.4,w:.6,h:.6,o:1}],U.run=function(e,t,o,a){var s=U.types[r()?"none":i.animation];return a=o===!0?"undefined"!=typeof a?a:s.length-1:"undefined"!=typeof a?a:0,t=t?t:function(){},a=0?(C[i.type](n(e,s[a])),setTimeout(function(){o?a-=1:a+=1,U.run(e,t,o,a)},U.duration),L.setIcon(c),void 0):(t(),void 0)},v(),{badge:I,video:E,image:A,webcam:T,reset:b.reset}};"undefined"!=typeof define&&define.amd?define([],function(){return e}):"undefined"!=typeof module&&module.exports?module.exports=e:this.Favico=e}(); \ No newline at end of file diff --git a/client/components/favico.js/favico.js b/client/components/favico.js/favico.js new file mode 100644 index 00000000..4d792aac --- /dev/null +++ b/client/components/favico.js/favico.js @@ -0,0 +1,805 @@ +/** + * @license MIT + * @fileOverview Favico animations + * @author Miroslav Magda, http://blog.ejci.net + * @version 0.3.4 + */ + +/** + * Create new favico instance + * @param {Object} Options + * @return {Object} Favico object + * @example + * var favico = new Favico({ + * bgColor : '#d00', + * textColor : '#fff', + * fontFamily : 'sans-serif', + * fontStyle : 'bold', + * position : 'down', + * type : 'circle', + * animation : 'slide', + * }); + */ +(function() { + + var Favico = (function(opt) {'use strict'; + opt = (opt) ? opt : {}; + var _def = { + bgColor : '#d00', + textColor : '#fff', + fontFamily : 'sans-serif', //Arial,Verdana,Times New Roman,serif,sans-serif,... + fontStyle : 'bold', //normal,italic,oblique,bold,bolder,lighter,100,200,300,400,500,600,700,800,900 + type : 'circle', + position : 'down', // down, up, left, leftup (upleft) + animation : 'slide', + elementId : false + }; + var _opt, _orig, _h, _w, _canvas, _context, _img, _ready, _lastBadge, _running, _readyCb, _stop, _browser; + + _browser = {}; + _browser.ff = (/firefox/i.test(navigator.userAgent.toLowerCase())); + _browser.chrome = (/chrome/i.test(navigator.userAgent.toLowerCase())); + _browser.opera = (/opera/i.test(navigator.userAgent.toLowerCase())); + _browser.ie = (/msie/i.test(navigator.userAgent.toLowerCase())) || (/trident/i.test(navigator.userAgent.toLowerCase())); + _browser.supported = (_browser.chrome || _browser.ff || _browser.opera); + + var _queue = []; + _readyCb = function() { + }; + _ready = _stop = false; + /** + * Initialize favico + */ + var init = function() { + //merge initial options + _opt = merge(_def, opt); + _opt.bgColor = hexToRgb(_opt.bgColor); + _opt.textColor = hexToRgb(_opt.textColor); + _opt.position = _opt.position.toLowerCase(); + _opt.animation = (animation.types['' + _opt.animation]) ? _opt.animation : _def.animation; + + var isUp = _opt.position.indexOf('up') > -1; + var isLeft = _opt.position.indexOf('left') > -1; + + //transform animation + if (isUp || isLeft) { + for (var i = 0; i < animation.types['' + _opt.animation].length; i++) { + var step = animation.types['' + _opt.animation][i]; + + if (isUp) { + if (step.y < 0.6) { + step.y = step.y - 0.4; + } else { + step.y = step.y - 2 * step.y + (1 - step.w); + } + } + + if (isLeft) { + if (step.x < 0.6) { + step.x = step.x - 0.4; + } else { + step.x = step.x - 2 * step.x + (1 - step.h); + } + } + + animation.types['' + _opt.animation][i] = step; + } + } + _opt.type = (type['' + _opt.type]) ? _opt.type : _def.type; + try { + _orig = link.getIcon(); + //create temp canvas + _canvas = document.createElement('canvas'); + //create temp image + _img = document.createElement('img'); + if (_orig.hasAttribute('href')) { + _img.setAttribute('src', _orig.getAttribute('href')); + //get width/height + _img.onload = function() { + _h = (_img.height > 0) ? _img.height : 32; + _w = (_img.width > 0) ? _img.width : 32; + _canvas.height = _h; + _canvas.width = _w; + _context = _canvas.getContext('2d'); + icon.ready(); + }; + } else { + _img.setAttribute('src', ''); + _h = 32; + _w = 32; + _img.height = _h; + _img.width = _w; + _canvas.height = _h; + _canvas.width = _w; + _context = _canvas.getContext('2d'); + icon.ready(); + } + } catch(e) { + throw 'Error initializing favico. Message: ' + e.message; + } + + }; + /** + * Icon namespace + */ + var icon = {}; + /** + * Icon is ready (reset icon) and start animation (if ther is any) + */ + icon.ready = function() { + _ready = true; + icon.reset(); + _readyCb(); + }; + /** + * Reset icon to default state + */ + icon.reset = function() { + //reset + _queue = []; + _lastBadge = false; + _context.clearRect(0, 0, _w, _h); + _context.drawImage(_img, 0, 0, _w, _h); + //_stop=true; + link.setIcon(_canvas); + //webcam('stop'); + //video('stop'); + }; + /** + * Start animation + */ + icon.start = function() { + if (!_ready || _running) { + return; + } + var finished = function() { + _lastBadge = _queue[0]; + _running = false; + if (_queue.length > 0) { + _queue.shift(); + icon.start(); + } else { + + } + }; + if (_queue.length > 0) { + _running = true; + if (_lastBadge) { + animation.run(_lastBadge.options, function() { + animation.run(_queue[0].options, function() { + finished(); + }, false); + }, true); + } else { + animation.run(_queue[0].options, function() { + finished(); + }, false); + } + } + }; + + /** + * Badge types + */ + var type = {}; + var options = function(opt) { + opt.n = Math.abs(opt.n); + opt.x = _w * opt.x; + opt.y = _h * opt.y; + opt.w = _w * opt.w; + opt.h = _h * opt.h; + return opt; + }; + /** + * Generate circle + * @param {Object} opt Badge options + */ + type.circle = function(opt) { + opt = options(opt); + var more = false; + if (opt.n > 9 && opt.n < 100) { + opt.x = opt.x - opt.w * 0.4; + opt.w = opt.w * 1.4; + more = true; + } else if (opt.n >= 100) { + opt.x = opt.x - opt.w * 0.65; + opt.w = opt.w * 1.65; + more = true; + } + _context.clearRect(0, 0, _w, _h); + _context.drawImage(_img, 0, 0, _w, _h); + _context.beginPath(); + _context.font = _opt.fontStyle + " " + Math.floor(opt.h * (opt.n > 99 ? 0.85 : 1)) + "px " + _opt.fontFamily; + _context.textAlign = 'center'; + if (more) { + _context.moveTo(opt.x + opt.w / 2, opt.y); + _context.lineTo(opt.x + opt.w - opt.h / 2, opt.y); + _context.quadraticCurveTo(opt.x + opt.w, opt.y, opt.x + opt.w, opt.y + opt.h / 2); + _context.lineTo(opt.x + opt.w, opt.y + opt.h - opt.h / 2); + _context.quadraticCurveTo(opt.x + opt.w, opt.y + opt.h, opt.x + opt.w - opt.h / 2, opt.y + opt.h); + _context.lineTo(opt.x + opt.h / 2, opt.y + opt.h); + _context.quadraticCurveTo(opt.x, opt.y + opt.h, opt.x, opt.y + opt.h - opt.h / 2); + _context.lineTo(opt.x, opt.y + opt.h / 2); + _context.quadraticCurveTo(opt.x, opt.y, opt.x + opt.h / 2, opt.y); + } else { + _context.arc(opt.x + opt.w / 2, opt.y + opt.h / 2, opt.h / 2, 0, 2 * Math.PI); + } + _context.fillStyle = 'rgba(' + _opt.bgColor.r + ',' + _opt.bgColor.g + ',' + _opt.bgColor.b + ',' + opt.o + ')'; + _context.fill(); + _context.closePath(); + _context.beginPath(); + _context.stroke(); + _context.fillStyle = 'rgba(' + _opt.textColor.r + ',' + _opt.textColor.g + ',' + _opt.textColor.b + ',' + opt.o + ')'; + //_context.fillText((more) ? '9+' : opt.n, Math.floor(opt.x + opt.w / 2), Math.floor(opt.y + opt.h - opt.h * 0.15)); + if (opt.n > 999) { + _context.fillText(((opt.n > 9999) ? 9 : Math.floor(opt.n / 1000) ) + 'k+', Math.floor(opt.x + opt.w / 2), Math.floor(opt.y + opt.h - opt.h * 0.2)); + } else { + _context.fillText(opt.n, Math.floor(opt.x + opt.w / 2), Math.floor(opt.y + opt.h - opt.h * 0.15)); + } + _context.closePath(); + }; + /** + * Generate rectangle + * @param {Object} opt Badge options + */ + type.rectangle = function(opt) { + opt = options(opt); + var more = false; + if (opt.n > 9 && opt.n < 100) { + opt.x = opt.x - opt.w * 0.4; + opt.w = opt.w * 1.4; + more = true; + } else if (opt.n >= 100) { + opt.x = opt.x - opt.w * 0.65; + opt.w = opt.w * 1.65; + more = true; + } + _context.clearRect(0, 0, _w, _h); + _context.drawImage(_img, 0, 0, _w, _h); + _context.beginPath(); + _context.font = "bold " + Math.floor(opt.h * (opt.n > 99 ? 0.9 : 1)) + "px sans-serif"; + _context.textAlign = 'center'; + _context.fillStyle = 'rgba(' + _opt.bgColor.r + ',' + _opt.bgColor.g + ',' + _opt.bgColor.b + ',' + opt.o + ')'; + _context.fillRect(opt.x, opt.y, opt.w, opt.h); + _context.fillStyle = 'rgba(' + _opt.textColor.r + ',' + _opt.textColor.g + ',' + _opt.textColor.b + ',' + opt.o + ')'; + //_context.fillText((more) ? '9+' : opt.n, Math.floor(opt.x + opt.w / 2), Math.floor(opt.y + opt.h - opt.h * 0.15)); + if (opt.n > 999) { + _context.fillText(((opt.n > 9999) ? 9 : Math.floor(opt.n / 1000) ) + 'k+', Math.floor(opt.x + opt.w / 2), Math.floor(opt.y + opt.h - opt.h * 0.2)); + } else { + _context.fillText(opt.n, Math.floor(opt.x + opt.w / 2), Math.floor(opt.y + opt.h - opt.h * 0.15)); + } + _context.closePath(); + }; + + /** + * Set badge + */ + var badge = function(number, animType) { + _readyCb = function() { + try { + if (number > 0) { + if (animation.types['' + animType]) { + _opt.animation = animType; + } + _queue.push({ + type : 'badge', + options : { + n : number + } + }); + if (_queue.length > 100) { + throw 'Too many badges requests in queue.'; + } + icon.start(); + } else { + icon.reset(); + } + } catch(e) { + throw 'Error setting badge. Message: ' + e.message; + } + }; + if (_ready) { + _readyCb(); + } + }; + + /** + * Set image as icon + */ + var image = function(imageElement) { + _readyCb = function() { + try { + var w = imageElement.width; + var h = imageElement.height; + var newImg = document.createElement('img'); + var ratio = (w / _w < h / _h) ? (w / _w) : (h / _h); + newImg.setAttribute('src', imageElement.getAttribute('src')); + newImg.height = (h / ratio); + newImg.width = (w / ratio); + _context.clearRect(0, 0, _w, _h); + _context.drawImage(newImg, 0, 0, _w, _h); + link.setIcon(_canvas); + } catch(e) { + throw 'Error setting image. Message: ' + e.message; + } + }; + if (_ready) { + _readyCb(); + } + }; + /** + * Set video as icon + */ + var video = function(videoElement) { + _readyCb = function() { + try { + if (videoElement === 'stop') { + _stop = true; + icon.reset(); + _stop = false; + return; + } + //var w = videoElement.width; + //var h = videoElement.height; + //var ratio = (w / _w < h / _h) ? (w / _w) : (h / _h); + videoElement.addEventListener('play', function() { + drawVideo(this); + }, false); + + } catch(e) { + throw 'Error setting video. Message: ' + e.message; + } + }; + if (_ready) { + _readyCb(); + } + }; + /** + * Set video as icon + */ + var webcam = function(action) { + //UR + if (!window.URL || !window.URL.createObjectURL) { + window.URL = window.URL || {}; + window.URL.createObjectURL = function(obj) { + return obj; + }; + } + if (_browser.supported) { + var newVideo = false; + navigator.getUserMedia = navigator.getUserMedia || navigator.oGetUserMedia || navigator.msGetUserMedia || navigator.mozGetUserMedia || navigator.webkitGetUserMedia; + _readyCb = function() { + try { + if (action === 'stop') { + _stop = true; + icon.reset(); + _stop = false; + return; + } + newVideo = document.createElement('video'); + newVideo.width = _w; + newVideo.height = _h; + navigator.getUserMedia({ + video : true, + audio : false + }, function(stream) { + newVideo.src = URL.createObjectURL(stream); + newVideo.play(); + drawVideo(newVideo); + }, function() { + }); + } catch(e) { + throw 'Error setting webcam. Message: ' + e.message; + } + }; + if (_ready) { + _readyCb(); + } + } + + }; + + /** + * Draw video to context and repeat :) + */ + function drawVideo(video) { + if (video.paused || video.ended || _stop) { + return false; + } + //nasty hack for FF webcam (Thanks to Julian Ćwirko, kontakt@redsunmedia.pl) + try { + _context.clearRect(0, 0, _w, _h); + _context.drawImage(video, 0, 0, _w, _h); + } catch(e) { + + } + setTimeout(drawVideo, animation.duration, video); + link.setIcon(_canvas); + } + + var link = {}; + /** + * Get icon from HEAD tag or create a new element + */ + link.getIcon = function() { + var elm = false; + var url = ''; + //get link element + var getLink = function() { + var link = document.getElementsByTagName('head')[0].getElementsByTagName('link'); + for (var l = link.length, i = (l - 1); i >= 0; i--) { + if ((/icon/i).test(link[i].getAttribute('rel'))) { + return link[i]; + } + } + return false; + }; + if (_opt.elementId) { + //if img element identified by elementId + elm = document.getElementById(_opt.elementId); + elm.setAttribute('href', elm.getAttribute('src')); + } else { + //if link element + elm = getLink(); + if (elm === false) { + elm = document.createElement('link'); + elm.setAttribute('rel', 'icon'); + document.getElementsByTagName('head')[0].appendChild(elm); + } + } + //check if image and link url is on same domain. if not raise error + url = (_opt.elementId) ? elm.src : elm.href; + if (url.indexOf(document.location.hostname) === -1) { + throw new Error('Error setting favicon. Favicon image is on different domain (Icon: ' + url + ', Domain: ' + document.location.hostname + ')'); + } + elm.setAttribute('type', 'image/png'); + return elm; + }; + link.setIcon = function(canvas) { + var url = canvas.toDataURL('image/png'); + if (_opt.elementId) { + //if is attached to element (image) + document.getElementById(_opt.elementId).setAttribute('src', url); + } else { + //if is attached to fav icon + if (_browser.ff || _browser.opera) { + //for FF we need to "recreate" element, atach to dom and remove old + //var originalType = _orig.getAttribute('rel'); + var old = _orig; + _orig = document.createElement('link'); + //_orig.setAttribute('rel', originalType); + if (_browser.opera) { + _orig.setAttribute('rel', 'icon'); + } + _orig.setAttribute('rel', 'icon'); + _orig.setAttribute('type', 'image/png'); + document.getElementsByTagName('head')[0].appendChild(_orig); + _orig.setAttribute('href', url); + if (old.parentNode) { + old.parentNode.removeChild(old); + } + } else { + _orig.setAttribute('href', url); + } + } + }; + + //http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb#answer-5624139 + //HEX to RGB convertor + function hexToRgb(hex) { + var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i; + hex = hex.replace(shorthandRegex, function(m, r, g, b) { + return r + r + g + g + b + b; + }); + var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); + return result ? { + r : parseInt(result[1], 16), + g : parseInt(result[2], 16), + b : parseInt(result[3], 16) + } : false; + } + + /** + * Merge options + */ + function merge(def, opt) { + var mergedOpt = {}; + var attrname; + for (attrname in def) { + mergedOpt[attrname] = def[attrname]; + } + for (attrname in opt) { + mergedOpt[attrname] = opt[attrname]; + } + return mergedOpt; + } + + /** + * Cross-browser page visibility shim + * http://stackoverflow.com/questions/12536562/detect-whether-a-window-is-visible + */ + function isPageHidden() { + return document.hidden || document.msHidden || document.webkitHidden || document.mozHidden; + } + + /** + * @namespace animation + */ + var animation = {}; + /** + * Animation "frame" duration + */ + animation.duration = 40; + /** + * Animation types (none,fade,pop,slide) + */ + animation.types = {}; + animation.types.fade = [{ + x : 0.4, + y : 0.4, + w : 0.6, + h : 0.6, + o : 0.0 + }, { + x : 0.4, + y : 0.4, + w : 0.6, + h : 0.6, + o : 0.1 + }, { + x : 0.4, + y : 0.4, + w : 0.6, + h : 0.6, + o : 0.2 + }, { + x : 0.4, + y : 0.4, + w : 0.6, + h : 0.6, + o : 0.3 + }, { + x : 0.4, + y : 0.4, + w : 0.6, + h : 0.6, + o : 0.4 + }, { + x : 0.4, + y : 0.4, + w : 0.6, + h : 0.6, + o : 0.5 + }, { + x : 0.4, + y : 0.4, + w : 0.6, + h : 0.6, + o : 0.6 + }, { + x : 0.4, + y : 0.4, + w : 0.6, + h : 0.6, + o : 0.7 + }, { + x : 0.4, + y : 0.4, + w : 0.6, + h : 0.6, + o : 0.8 + }, { + x : 0.4, + y : 0.4, + w : 0.6, + h : 0.6, + o : 0.9 + }, { + x : 0.4, + y : 0.4, + w : 0.6, + h : 0.6, + o : 1.0 + }]; + animation.types.none = [{ + x : 0.4, + y : 0.4, + w : 0.6, + h : 0.6, + o : 1 + }]; + animation.types.pop = [{ + x : 1, + y : 1, + w : 0, + h : 0, + o : 1 + }, { + x : 0.9, + y : 0.9, + w : 0.1, + h : 0.1, + o : 1 + }, { + x : 0.8, + y : 0.8, + w : 0.2, + h : 0.2, + o : 1 + }, { + x : 0.7, + y : 0.7, + w : 0.3, + h : 0.3, + o : 1 + }, { + x : 0.6, + y : 0.6, + w : 0.4, + h : 0.4, + o : 1 + }, { + x : 0.5, + y : 0.5, + w : 0.5, + h : 0.5, + o : 1 + }, { + x : 0.4, + y : 0.4, + w : 0.6, + h : 0.6, + o : 1 + }]; + animation.types.popFade = [{ + x : 0.75, + y : 0.75, + w : 0, + h : 0, + o : 0 + }, { + x : 0.65, + y : 0.65, + w : 0.1, + h : 0.1, + o : 0.2 + }, { + x : 0.6, + y : 0.6, + w : 0.2, + h : 0.2, + o : 0.4 + }, { + x : 0.55, + y : 0.55, + w : 0.3, + h : 0.3, + o : 0.6 + }, { + x : 0.50, + y : 0.50, + w : 0.4, + h : 0.4, + o : 0.8 + }, { + x : 0.45, + y : 0.45, + w : 0.5, + h : 0.5, + o : 0.9 + }, { + x : 0.4, + y : 0.4, + w : 0.6, + h : 0.6, + o : 1 + }]; + animation.types.slide = [{ + x : 0.4, + y : 1, + w : 0.6, + h : 0.6, + o : 1 + }, { + x : 0.4, + y : 0.9, + w : 0.6, + h : 0.6, + o : 1 + }, { + x : 0.4, + y : 0.9, + w : 0.6, + h : 0.6, + o : 1 + }, { + x : 0.4, + y : 0.8, + w : 0.6, + h : 0.6, + o : 1 + }, { + x : 0.4, + y : 0.7, + w : 0.6, + h : 0.6, + o : 1 + }, { + x : 0.4, + y : 0.6, + w : 0.6, + h : 0.6, + o : 1 + }, { + x : 0.4, + y : 0.5, + w : 0.6, + h : 0.6, + o : 1 + }, { + x : 0.4, + y : 0.4, + w : 0.6, + h : 0.6, + o : 1 + }]; + /** + * Run animation + * @param {Object} opt Animation options + * @param {Object} cb Callabak after all steps are done + * @param {Object} revert Reverse order? true|false + * @param {Object} step Optional step number (frame bumber) + */ + animation.run = function(opt, cb, revert, step) { + var animationType = animation.types[isPageHidden() ? 'none' : _opt.animation]; + if (revert === true) { + step = ( typeof step !== 'undefined') ? step : animationType.length - 1; + } else { + step = ( typeof step !== 'undefined') ? step : 0; + } + cb = (cb) ? cb : function() { + }; + if ((step < animationType.length) && (step >= 0)) { + type[_opt.type](merge(opt, animationType[step])); + setTimeout(function() { + if (revert) { + step = step - 1; + } else { + step = step + 1; + } + animation.run(opt, cb, revert, step); + }, animation.duration); + + link.setIcon(_canvas); + } else { + cb(); + return; + } + }; + //auto init + init(); + return { + badge : badge, + video : video, + image : image, + webcam : webcam, + reset : icon.reset + }; + }); + + // AMD / RequireJS + if ( typeof define !== 'undefined' && define.amd) { + define([], function() { + return Favico; + }); + } + // CommonJS + else if ( typeof module !== 'undefined' && module.exports) { + module.exports = Favico; + } + // included directly via - + - diff --git a/client/js/jquery.plugins.js b/client/js/jquery.plugins.js index 25534ccb..ed34c965 100644 --- a/client/js/jquery.plugins.js +++ b/client/js/jquery.plugins.js @@ -1,98 +1,3 @@ -/*! - * stickyscroll - * https://github.com/erming/stickyscroll - * - * Copyright (c) 2014 Mattias Erming - * Licensed under the MIT License. - * - * Version 1.3.1 - */ -(function($) { - $.fn.sticky = function(options) { - var settings = $.extend({ - disableManualScroll: false, - overflow: 'auto', - scrollToBottom: true, - speed: 0 - }, options); - - var self = this; - if (self.size() > 1) { - return self.each(function() { - $(this).sticky(options); - }); - } - - self.css('overflow-y', settings.overflow); - self.css('-webkit-overflow-scrolling', 'touch'); - if (settings.scrollToBottom) { - self.scrollToBottom(); - } - - var resizeTimer; - var resizing = false; - $(window).on('resize', function() { - self.finish(); - - // This will prevent the scroll event from triggering - // while resizing the browser. - resizing = true; - - clearTimeout(resizeTimer); - resizeTimer = setTimeout(function() { - resizing = false; - }, 100); - - if (sticky) { - self.scrollToBottom(); - } - }); - - var scrollTimer; - var sticky = true; - self.on('scroll', function() { - if (settings.disableManualScroll) { - self.scrollToBottom(); - } else if (!resizing) { - clearTimeout(scrollTimer); - scrollTimer = setTimeout(function() { - sticky = self.isScrollAtBottom(); - }, 50); - } - }); - self.trigger('scroll'); - self.on('prepend append', function() { - if (sticky) { - self.scrollToBottom(settings.speed); - } - }); - - return this; - }; - - // Normally, these functions won't trigger any events. - // Lets override them. - var events = ['prepend', 'append']; - $.each(events, function(i, e) { - var fn = $.fn[e]; - $.fn[e] = function() { - return fn.apply(this, arguments).trigger(e); - }; - }); - - $.fn.isScrollAtBottom = function() { - if ((this.scrollTop() + this.outerHeight() + 1) >= this.prop('scrollHeight')) { - return true; - } - }; - - $.fn.scrollToBottom = function(speed) { - return this.each(function() { - $(this).finish().animate({scrollTop: this.scrollHeight}, speed || 0); - }); - }; -})(jQuery); - /*! * tabcomplete * Lightweight tab completion for inputs and textareas @@ -413,121 +318,3 @@ return this; } })(jQuery); - -/*! - * jQuery Cookie Plugin v1.4.0 - * https://github.com/carhartl/jquery-cookie - * - * Copyright 2013 Klaus Hartl - * Released under the MIT license - */ -(function (factory) { - if (typeof define === 'function' && define.amd) { - // AMD. Register as anonymous module. - define(['jquery'], factory); - } else { - // Browser globals. - factory(jQuery); - } -}(function ($) { - - var pluses = /\+/g; - - function encode(s) { - return config.raw ? s : encodeURIComponent(s); - } - - function decode(s) { - return config.raw ? s : decodeURIComponent(s); - } - - function stringifyCookieValue(value) { - return encode(config.json ? JSON.stringify(value) : String(value)); - } - - function parseCookieValue(s) { - if (s.indexOf('"') === 0) { - // This is a quoted cookie as according to RFC2068, unescape... - s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\'); - } - - try { - // Replace server-side written pluses with spaces. - // If we can't decode the cookie, ignore it, it's unusable. - s = decodeURIComponent(s.replace(pluses, ' ')); - } catch(e) { - return; - } - - try { - // If we can't parse the cookie, ignore it, it's unusable. - return config.json ? JSON.parse(s) : s; - } catch(e) {} - } - - function read(s, converter) { - var value = config.raw ? s : parseCookieValue(s); - return $.isFunction(converter) ? converter(value) : value; - } - - var config = $.cookie = function (key, value, options) { - - // Write - if (value !== undefined && !$.isFunction(value)) { - options = $.extend({}, config.defaults, options); - - if (typeof options.expires === 'number') { - var days = options.expires, t = options.expires = new Date(); - t.setDate(t.getDate() + days); - } - - return (document.cookie = [ - encode(key), '=', stringifyCookieValue(value), - options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE - options.path ? '; path=' + options.path : '', - options.domain ? '; domain=' + options.domain : '', - options.secure ? '; secure' : '' - ].join('')); - } - - // Read - - var result = key ? undefined : {}; - - // To prevent the for loop in the first place assign an empty array - // in case there are no cookies at all. Also prevents odd result when - // calling $.cookie(). - var cookies = document.cookie ? document.cookie.split('; ') : []; - - for (var i = 0, l = cookies.length; i < l; i++) { - var parts = cookies[i].split('='); - var name = decode(parts.shift()); - var cookie = parts.join('='); - - if (key && key === name) { - // If second argument (value) is a function it's a converter... - result = read(cookie, value); - break; - } - - // Prevent storing a cookie that we couldn't decode. - if (!key && (cookie = read(cookie)) !== undefined) { - result[name] = cookie; - } - } - - return result; - }; - - config.defaults = {}; - - $.removeCookie = function (key, options) { - if ($.cookie(key) !== undefined) { - // Must not alter options, thus extending a fresh object... - $.cookie(key, '', $.extend({}, options, { expires: -1 })); - return true; - } - return false; - }; - -})); diff --git a/client/js/libs.js b/client/js/libs.js new file mode 100644 index 00000000..dfe0d624 --- /dev/null +++ b/client/js/libs.js @@ -0,0 +1,3 @@ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){function c(a){var b=a.length,c=_.type(a);return"function"===c||_.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}function d(a,b,c){if(_.isFunction(b))return _.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return _.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(hb.test(b))return _.filter(b,a,c);b=_.filter(b,a)}return _.grep(a,function(a){return U.call(b,a)>=0!==c})}function e(a,b){for(;(a=a[b])&&1!==a.nodeType;);return a}function f(a){var b=ob[a]={};return _.each(a.match(nb)||[],function(a,c){b[c]=!0}),b}function g(){Z.removeEventListener("DOMContentLoaded",g,!1),a.removeEventListener("load",g,!1),_.ready()}function h(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=_.expando+Math.random()}function i(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(ub,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:tb.test(c)?_.parseJSON(c):c}catch(e){}sb.set(a,b,c)}else c=void 0;return c}function j(){return!0}function k(){return!1}function l(){try{return Z.activeElement}catch(a){}}function m(a,b){return _.nodeName(a,"table")&&_.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function n(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function o(a){var b=Kb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function p(a,b){for(var c=0,d=a.length;d>c;c++)rb.set(a[c],"globalEval",!b||rb.get(b[c],"globalEval"))}function q(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(rb.hasData(a)&&(f=rb.access(a),g=rb.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)_.event.add(b,e,j[e][c])}sb.hasData(a)&&(h=sb.access(a),i=_.extend({},h),sb.set(b,i))}}function r(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&_.nodeName(a,b)?_.merge([a],c):c}function s(a,b){var c=b.nodeName.toLowerCase();"input"===c&&yb.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}function t(b,c){var d,e=_(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:_.css(e[0],"display");return e.detach(),f}function u(a){var b=Z,c=Ob[a];return c||(c=t(a,b),"none"!==c&&c||(Nb=(Nb||_("