├── .gitignore ├── .travis.yml ├── Gruntfile.js ├── LICENSE ├── README.md ├── bin └── install-wp-tests.sh ├── build └── wp-lazysizes.min.js ├── composer.json ├── css ├── lazysizes.css └── lazysizes.min.css ├── img └── loader.gif ├── js ├── lazysizes │ ├── lazysizes-umd.js │ ├── lazysizes-umd.min.js │ ├── lazysizes.js │ ├── lazysizes.min.js │ ├── plugins │ │ ├── aspectratio │ │ │ ├── ls.aspectratio.js │ │ │ └── ls.aspectratio.min.js │ │ ├── attrchange │ │ │ ├── ls.attrchange.js │ │ │ └── ls.attrchange.min.js │ │ ├── bgset │ │ │ ├── ls.bgset.js │ │ │ └── ls.bgset.min.js │ │ ├── custommedia │ │ │ ├── ls.custommedia.js │ │ │ └── ls.custommedia.min.js │ │ ├── fix-ios-sizes │ │ │ ├── fix-ios-sizes.js │ │ │ └── fix-ios-sizes.min.js │ │ ├── include │ │ │ ├── ls.include.js │ │ │ └── ls.include.min.js │ │ ├── noscript │ │ │ ├── ls.noscript.js │ │ │ └── ls.noscript.min.js │ │ ├── object-fit │ │ │ ├── ls.object-fit.js │ │ │ └── ls.object-fit.min.js │ │ ├── optimumx │ │ │ ├── ls.optimumx.js │ │ │ └── ls.optimumx.min.js │ │ ├── parent-fit │ │ │ ├── ls.parent-fit.js │ │ │ └── ls.parent-fit.min.js │ │ ├── print │ │ │ ├── ls.print.js │ │ │ └── ls.print.min.js │ │ ├── progressive │ │ │ ├── ls.progressive.js │ │ │ └── ls.progressive.min.js │ │ ├── respimg │ │ │ ├── ls.respimg.js │ │ │ └── ls.respimg.min.js │ │ ├── rias │ │ │ ├── ls.rias.js │ │ │ └── ls.rias.min.js │ │ ├── scrollintent │ │ │ └── ls.scrollintent.min.js │ │ ├── static-gecko-picture │ │ │ ├── ls.static-gecko-picture.js │ │ │ └── ls.static-gecko-picture.min.js │ │ ├── unload │ │ │ ├── ls.unload.js │ │ │ └── ls.unload.min.js │ │ ├── unveilhooks │ │ │ ├── ls.unveilhooks.js │ │ │ └── ls.unveilhooks.min.js │ │ └── video-embed │ │ │ ├── ls.video-embed.js │ │ │ └── ls.video-embed.min.js │ └── src │ │ └── lazysizes-core.js ├── ls.setup.js └── tests │ └── test-ls.setup.js ├── package.json ├── phpunit.xml.dist ├── readme.txt ├── settings.php ├── testem.json ├── tests ├── bootstrap.php └── test-lazysizes.php └── wp-lazysizes.php /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .DS_Store 3 | node_modules -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | notifications: 4 | email: 5 | on_success: never 6 | on_failure: change 7 | 8 | branches: 9 | only: 10 | - master 11 | 12 | php: 13 | - 5.3 14 | - 5.6 15 | 16 | env: 17 | - WP_VERSION=latest WP_MULTISITE=0 18 | 19 | matrix: 20 | include: 21 | - php: 5.3 22 | env: WP_VERSION=latest WP_MULTISITE=1 23 | 24 | before_script: 25 | - bash bin/install-wp-tests.sh wordpress_test root '' localhost $WP_VERSION 26 | 27 | script: phpunit 28 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | 4 | module.exports = function (grunt) { 5 | // Project configuration. 6 | grunt.initConfig({ 7 | copy: { 8 | update: { 9 | files: [ 10 | { 11 | expand: true, 12 | cwd: 'node_modules/', 13 | src: ['lazysizes/**/*.js'], 14 | dest: 'js/' 15 | } 16 | ] 17 | } 18 | }, 19 | 20 | uglify: { 21 | build: { 22 | files: { 23 | 'build/wp-lazysizes.min.js': ['js/ls.setup.js', 'js/lazysizes/lazysizes.js'] 24 | } 25 | } 26 | } 27 | }); 28 | 29 | grunt.loadNpmTasks('grunt-contrib-copy'); 30 | grunt.loadNpmTasks('grunt-contrib-uglify'); 31 | 32 | 33 | // Default task. 34 | grunt.registerTask('default', [ 'copy' ]); 35 | 36 | // Concatenate lazysizes JS with mobile detection JS files. 37 | grunt.registerTask('build', [ 'uglify' ]); 38 | }; 39 | })(); 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | {description} 294 | Copyright (C) {year} {fullname} 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | {signature of Ty Coon}, 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | 341 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # wp-lazysizes 2 | 3 | Brings [lazySizes.js](https://github.com/aFarkas/lazysizes) to WordPress. 4 | 5 | ## Contributing 6 | 7 | Although this WordPress plugin is pretty solid and can be used in production, it could be heavily improved. 8 | -------------------------------------------------------------------------------- /bin/install-wp-tests.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [ $# -lt 3 ]; then 4 | echo "usage: $0 [db-host] [wp-version]" 5 | exit 1 6 | fi 7 | 8 | DB_NAME=$1 9 | DB_USER=$2 10 | DB_PASS=$3 11 | DB_HOST=${4-localhost} 12 | WP_VERSION=${5-latest} 13 | 14 | WP_TESTS_DIR=${WP_TESTS_DIR-/tmp/wordpress-tests-lib} 15 | WP_CORE_DIR=${WP_CORE_DIR-/tmp/wordpress/} 16 | 17 | download() { 18 | if [ `which curl` ]; then 19 | curl -s "$1" > "$2"; 20 | elif [ `which wget` ]; then 21 | wget -nv -O "$2" "$1" 22 | fi 23 | } 24 | 25 | if [[ $WP_VERSION =~ [0-9]+\.[0-9]+(\.[0-9]+)? ]]; then 26 | WP_TESTS_TAG="tags/$WP_VERSION" 27 | elif [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then 28 | WP_TESTS_TAG="trunk" 29 | else 30 | # http serves a single offer, whereas https serves multiple. we only want one 31 | download http://api.wordpress.org/core/version-check/1.7/ /tmp/wp-latest.json 32 | grep '[0-9]+\.[0-9]+(\.[0-9]+)?' /tmp/wp-latest.json 33 | LATEST_VERSION=$(grep -o '"version":"[^"]*' /tmp/wp-latest.json | sed 's/"version":"//') 34 | if [[ -z "$LATEST_VERSION" ]]; then 35 | echo "Latest WordPress version could not be found" 36 | exit 1 37 | fi 38 | WP_TESTS_TAG="tags/$LATEST_VERSION" 39 | fi 40 | 41 | set -ex 42 | 43 | install_wp() { 44 | 45 | if [ -d $WP_CORE_DIR ]; then 46 | return; 47 | fi 48 | 49 | mkdir -p $WP_CORE_DIR 50 | 51 | if [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then 52 | mkdir -p /tmp/wordpress-nightly 53 | download https://wordpress.org/nightly-builds/wordpress-latest.zip /tmp/wordpress-nightly/wordpress-nightly.zip 54 | unzip -q /tmp/wordpress-nightly/wordpress-nightly.zip -d /tmp/wordpress-nightly/ 55 | mv /tmp/wordpress-nightly/wordpress/* $WP_CORE_DIR 56 | else 57 | if [ $WP_VERSION == 'latest' ]; then 58 | local ARCHIVE_NAME='latest' 59 | else 60 | local ARCHIVE_NAME="wordpress-$WP_VERSION" 61 | fi 62 | download https://wordpress.org/${ARCHIVE_NAME}.tar.gz /tmp/wordpress.tar.gz 63 | tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR 64 | fi 65 | 66 | download https://raw.github.com/markoheijnen/wp-mysqli/master/db.php $WP_CORE_DIR/wp-content/db.php 67 | } 68 | 69 | install_test_suite() { 70 | # portable in-place argument for both GNU sed and Mac OSX sed 71 | if [[ $(uname -s) == 'Darwin' ]]; then 72 | local ioption='-i .bak' 73 | else 74 | local ioption='-i' 75 | fi 76 | 77 | # set up testing suite if it doesn't yet exist 78 | if [ ! -d $WP_TESTS_DIR ]; then 79 | # set up testing suite 80 | mkdir -p $WP_TESTS_DIR 81 | svn co --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/includes/ $WP_TESTS_DIR/includes 82 | fi 83 | 84 | if [ ! -f wp-tests-config.php ]; then 85 | download https://develop.svn.wordpress.org/${WP_TESTS_TAG}/wp-tests-config-sample.php "$WP_TESTS_DIR"/wp-tests-config.php 86 | sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR':" "$WP_TESTS_DIR"/wp-tests-config.php 87 | sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" "$WP_TESTS_DIR"/wp-tests-config.php 88 | sed $ioption "s/yourusernamehere/$DB_USER/" "$WP_TESTS_DIR"/wp-tests-config.php 89 | sed $ioption "s/yourpasswordhere/$DB_PASS/" "$WP_TESTS_DIR"/wp-tests-config.php 90 | sed $ioption "s|localhost|${DB_HOST}|" "$WP_TESTS_DIR"/wp-tests-config.php 91 | fi 92 | 93 | } 94 | 95 | install_db() { 96 | # parse DB_HOST for port or socket references 97 | local PARTS=(${DB_HOST//\:/ }) 98 | local DB_HOSTNAME=${PARTS[0]}; 99 | local DB_SOCK_OR_PORT=${PARTS[1]}; 100 | local EXTRA="" 101 | 102 | if ! [ -z $DB_HOSTNAME ] ; then 103 | if [ $(echo $DB_SOCK_OR_PORT | grep -e '^[0-9]\{1,\}$') ]; then 104 | EXTRA=" --host=$DB_HOSTNAME --port=$DB_SOCK_OR_PORT --protocol=tcp" 105 | elif ! [ -z $DB_SOCK_OR_PORT ] ; then 106 | EXTRA=" --socket=$DB_SOCK_OR_PORT" 107 | elif ! [ -z $DB_HOSTNAME ] ; then 108 | EXTRA=" --host=$DB_HOSTNAME --protocol=tcp" 109 | fi 110 | fi 111 | 112 | # create database 113 | mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS"$EXTRA 114 | } 115 | 116 | install_wp 117 | install_test_suite 118 | install_db 119 | -------------------------------------------------------------------------------- /build/wp-lazysizes.min.js: -------------------------------------------------------------------------------- 1 | window.lazySizesConfig=window.lazySizesConfig||{preloadAfterLoad:"false"},function(a){a.checkIfMobile=function(a){return!(!/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|pad|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)&&!/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4)))},a.setSmartPreload=function(b){a.preloadAfterLoad="smart"===a.preloadAfterLoad?!b:JSON.parse(a.preloadAfterLoad)},a.convertToInt=function(b){a.expand=1*b},a.setSmartPreload(a.checkIfMobile(navigator.userAgent||navigator.vendor||window.opera)),a.convertToInt(a.expand)}(window.lazySizesConfig),function(a,b){var c=b(a,a.document);a.lazySizes=c,"object"==typeof module&&module.exports&&(module.exports=c)}(window,function(a,b){"use strict";if(b.getElementsByClassName){var c,d=b.documentElement,e=a.Date,f=a.HTMLPictureElement,g="addEventListener",h="getAttribute",i=a[g],j=a.setTimeout,k=a.requestAnimationFrame||j,l=a.requestIdleCallback,m=/^picture$/i,n=["load","error","lazyincluded","_lazyloaded"],o={},p=Array.prototype.forEach,q=function(a,b){return o[b]||(o[b]=new RegExp("(\\s|^)"+b+"(\\s|$)")),o[b].test(a[h]("class")||"")&&o[b]},r=function(a,b){q(a,b)||a.setAttribute("class",(a[h]("class")||"").trim()+" "+b)},s=function(a,b){var c;(c=q(a,b))&&a.setAttribute("class",(a[h]("class")||"").replace(c," "))},t=function(a,b,c){var d=c?g:"removeEventListener";c&&t(a,b),n.forEach(function(c){a[d](c,b)})},u=function(a,c,d,e,f){var g=b.createEvent("CustomEvent");return g.initCustomEvent(c,!e,!f,d||{}),a.dispatchEvent(g),g},v=function(b,d){var e;!f&&(e=a.picturefill||c.pf)?e({reevaluate:!0,elements:[b]}):d&&d.src&&(b.src=d.src)},w=function(a,b){return(getComputedStyle(a,null)||{})[b]},x=function(a,b,d){for(d=d||a.offsetWidth;d0,g&&"visible"!=w(f,"overflow")&&(e=f.getBoundingClientRect(),g=H>e.left&&Ge.top-1&&F500?500:400),J=c.expand,K=J*c.expFactor),Q3&&o>2?(Q=K,S=0):Q=o>1&&S>2&&R<6?J:P;for(;b=m&&(F=e.top)<=E&&(H=e.right)>=m*L&&(G=e.left)<=C&&(I||H||G||F)&&(l&&R<3&&!n&&(o<3||S<4)||U(f[b],j))){if(ba(f[b]),i=!0,R>9)break}else!i&&l&&!g&&R<4&&S<4&&o>2&&(k[0]||c.preloadAfterLoad)&&(k[0]||!n&&(I||H||G||F||"auto"!=f[b][h](c.sizesAttr)))&&(g=k[0]||f[b]);else ba(f[b]);g&&!i&&ba(g)}},W=A(V),X=function(a){r(a.target,c.loadedClass),s(a.target,c.loadingClass),t(a.target,Z)},Y=z(X),Z=function(a){Y({target:a.target})},$=function(a,b){try{a.contentWindow.location.replace(b)}catch(c){a.src=b}},_=function(a){var b,d,e=a[h](c.srcsetAttr);(b=c.customMedia[a[h]("data-media")||a[h]("media")])&&a.setAttribute("media",b),e&&a.setAttribute("srcset",e),b&&(d=a.parentNode,d.insertBefore(a.cloneNode(),a),d.removeChild(a))},aa=z(function(a,b,d,e,f){var g,i,k,l,o,q;(o=u(a,"lazybeforeunveil",b)).defaultPrevented||(e&&(d?r(a,c.autosizesClass):a.setAttribute("sizes",e)),i=a[h](c.srcsetAttr),g=a[h](c.srcAttr),f&&(k=a.parentNode,l=k&&m.test(k.nodeName||"")),q=b.firesLoad||"src"in a&&(i||g||l),o={target:a},q&&(t(a,T,!0),clearTimeout(n),n=j(T,2500),r(a,c.loadingClass),t(a,Z,!0)),l&&p.call(k.getElementsByTagName("source"),_),i?a.setAttribute("srcset",i):g&&!l&&(N.test(a.nodeName)?$(a,g):a.src=g),(i||l)&&v(a,{src:g})),y(function(){a._lazyRace&&delete a._lazyRace,s(a,c.lazyClass),q&&!a.complete||(q?T(o):R--,X(o))})}),ba=function(a){var b,d=M.test(a.nodeName),e=d&&(a[h](c.sizesAttr)||a[h]("sizes")),f="auto"==e;(!f&&l||!d||!a.src&&!a.srcset||a.complete||q(a,c.errorClass))&&(b=u(a,"lazyunveilread").detail,f&&D.updateElem(a,!0,a.offsetWidth),a._lazyRace=!0,R++,aa(a,b,f,e,d))},ca=function(){if(!l){if(e.now()-x<999)return void j(ca,999);var a=B(function(){c.loadMode=3,W()});l=!0,c.loadMode=3,W(),i("scroll",function(){3==c.loadMode&&(c.loadMode=2),a()},!0)}};return{_:function(){x=e.now(),f=b.getElementsByClassName(c.lazyClass),k=b.getElementsByClassName(c.lazyClass+" "+c.preloadClass),L=c.hFac,i("scroll",W,!0),i("resize",W,!0),a.MutationObserver?new MutationObserver(W).observe(d,{childList:!0,subtree:!0,attributes:!0}):(d[g]("DOMNodeInserted",W,!0),d[g]("DOMAttrModified",W,!0),setInterval(W,999)),i("hashchange",W,!0),["focus","mouseover","click","load","transitionend","animationend","webkitAnimationEnd"].forEach(function(a){b[g](a,W,!0)}),/d$|^c/.test(b.readyState)?ca():(i("load",ca),b[g]("DOMContentLoaded",W),j(ca,2e4)),W(f.length>0)},checkElems:W,unveil:ba}}(),D=function(){var a,d=z(function(a,b,c,d){var e,f,g;if(a._lazysizesWidth=d,d+="px",a.setAttribute("sizes",d),m.test(b.nodeName||""))for(e=b.getElementsByTagName("source"),f=0,g=e.length;ff&&(f=0),a||9>f&&l?i():j(i,f))}},B=function(a){var b,c,d=99,f=function(){b=null,a()},g=function(){var a=e.now()-c;d>a?j(g,d-a):(l||f)(f)};return function(){c=e.now(),b||(b=j(g,d))}},C=function(){var f,k,l,n,o,x,C,E,F,G,H,I,J,K,L,M=/^img$/i,N=/^iframe$/i,O="onscroll"in a&&!/glebot/.test(navigator.userAgent),P=0,Q=0,R=0,S=0,T=function(a){R--,a&&a.target&&t(a.target,T),(!a||0>R||!a.target)&&(R=0)},U=function(a,c){var e,f=a,g="hidden"==w(b.body,"visibility")||"hidden"!=w(a,"visibility");for(F-=c,I+=c,G-=c,H+=c;g&&(f=f.offsetParent)&&f!=b.body&&f!=d;)g=(w(f,"opacity")||1)>0,g&&"visible"!=w(f,"overflow")&&(e=f.getBoundingClientRect(),g=H>e.left&&Ge.top-1&&FR&&(a=f.length)){b=0,S++,null==K&&("expand"in c||(c.expand=d.clientHeight>500?500:400),J=c.expand,K=J*c.expFactor),K>Q&&1>R&&S>3&&o>2?(Q=K,S=0):Q=o>1&&S>2&&6>R?J:P;for(;a>b;b++)if(f[b]&&!f[b]._lazyRace)if(O)if((n=f[b][h]("data-expand"))&&(j=1*n)||(j=Q),p!==j&&(C=innerWidth+j*L,E=innerHeight+j,m=-1*j,p=j),e=f[b].getBoundingClientRect(),(I=e.bottom)>=m&&(F=e.top)<=E&&(H=e.right)>=m*L&&(G=e.left)<=C&&(I||H||G||F)&&(l&&3>R&&!n&&(3>o||4>S)||U(f[b],j))){if(ba(f[b]),i=!0,R>9)break}else!i&&l&&!g&&4>R&&4>S&&o>2&&(k[0]||c.preloadAfterLoad)&&(k[0]||!n&&(I||H||G||F||"auto"!=f[b][h](c.sizesAttr)))&&(g=k[0]||f[b]);else ba(f[b]);g&&!i&&ba(g)}},W=A(V),X=function(a){r(a.target,c.loadedClass),s(a.target,c.loadingClass),t(a.target,Z)},Y=z(X),Z=function(a){Y({target:a.target})},$=function(a,b){try{a.contentWindow.location.replace(b)}catch(c){a.src=b}},_=function(a){var b,d,e=a[h](c.srcsetAttr);(b=c.customMedia[a[h]("data-media")||a[h]("media")])&&a.setAttribute("media",b),e&&a.setAttribute("srcset",e),b&&(d=a.parentNode,d.insertBefore(a.cloneNode(),a),d.removeChild(a))},aa=z(function(a,b,d,e,f){var g,i,k,l,o,q;(o=u(a,"lazybeforeunveil",b)).defaultPrevented||(e&&(d?r(a,c.autosizesClass):a.setAttribute("sizes",e)),i=a[h](c.srcsetAttr),g=a[h](c.srcAttr),f&&(k=a.parentNode,l=k&&m.test(k.nodeName||"")),q=b.firesLoad||"src"in a&&(i||g||l),o={target:a},q&&(t(a,T,!0),clearTimeout(n),n=j(T,2500),r(a,c.loadingClass),t(a,Z,!0)),l&&p.call(k.getElementsByTagName("source"),_),i?a.setAttribute("srcset",i):g&&!l&&(N.test(a.nodeName)?$(a,g):a.src=g),(i||l)&&v(a,{src:g})),y(function(){a._lazyRace&&delete a._lazyRace,s(a,c.lazyClass),(!q||a.complete)&&(q?T(o):R--,X(o))})}),ba=function(a){var b,d=M.test(a.nodeName),e=d&&(a[h](c.sizesAttr)||a[h]("sizes")),f="auto"==e;(!f&&l||!d||!a.src&&!a.srcset||a.complete||q(a,c.errorClass))&&(b=u(a,"lazyunveilread").detail,f&&D.updateElem(a,!0,a.offsetWidth),a._lazyRace=!0,R++,aa(a,b,f,e,d))},ca=function(){if(!l){if(e.now()-x<999)return void j(ca,999);var a=B(function(){c.loadMode=3,W()});l=!0,c.loadMode=3,W(),i("scroll",function(){3==c.loadMode&&(c.loadMode=2),a()},!0)}};return{_:function(){x=e.now(),f=b.getElementsByClassName(c.lazyClass),k=b.getElementsByClassName(c.lazyClass+" "+c.preloadClass),L=c.hFac,i("scroll",W,!0),i("resize",W,!0),a.MutationObserver?new MutationObserver(W).observe(d,{childList:!0,subtree:!0,attributes:!0}):(d[g]("DOMNodeInserted",W,!0),d[g]("DOMAttrModified",W,!0),setInterval(W,999)),i("hashchange",W,!0),["focus","mouseover","click","load","transitionend","animationend","webkitAnimationEnd"].forEach(function(a){b[g](a,W,!0)}),/d$|^c/.test(b.readyState)?ca():(i("load",ca),b[g]("DOMContentLoaded",W),j(ca,2e4)),W(f.length>0)},checkElems:W,unveil:ba}}(),D=function(){var a,d=z(function(a,b,c,d){var e,f,g;if(a._lazysizesWidth=d,d+="px",a.setAttribute("sizes",d),m.test(b.nodeName||""))for(e=b.getElementsByTagName("source"),f=0,g=e.length;g>f;f++)e[f].setAttribute("sizes",d);c.detail.dataAttr||v(a,c.detail)}),e=function(a,b,c){var e,f=a.parentNode;f&&(c=x(a,f,c),e=u(a,"lazybeforesizes",{width:c,dataAttr:!!b}),e.defaultPrevented||(c=e.detail.width,c&&c!==a._lazysizesWidth&&d(a,f,e,c)))},f=function(){var b,c=a.length;if(c)for(b=0;c>b;b++)e(a[b])},g=B(f);return{_:function(){a=b.getElementsByClassName(c.autosizesClass),i("resize",g)},checkElems:g,updateElem:e}}(),E=function(){E.i||(E.i=!0,D._(),C._())};return function(){var b,d={lazyClass:"lazyload",loadedClass:"lazyloaded",loadingClass:"lazyloading",preloadClass:"lazypreload",errorClass:"lazyerror",autosizesClass:"lazyautosizes",srcAttr:"data-src",srcsetAttr:"data-srcset",sizesAttr:"data-sizes",minSize:40,customMedia:{},init:!0,expFactor:1.5,hFac:.8,loadMode:2};c=a.lazySizesConfig||a.lazysizesConfig||{};for(b in d)b in c||(c[b]=d[b]);a.lazySizesConfig=c,j(function(){c.init&&E()})}(),{cfg:c,autoSizer:D,loader:C,init:E,uP:v,aC:r,rC:s,hC:q,fire:u,gW:x,rAF:y}}}); -------------------------------------------------------------------------------- /js/lazysizes/lazysizes.min.js: -------------------------------------------------------------------------------- 1 | /*! lazysizes - v2.0.0 */ 2 | !function(a,b){var c=b(a,a.document);a.lazySizes=c,"object"==typeof module&&module.exports&&(module.exports=c)}(window,function(a,b){"use strict";if(b.getElementsByClassName){var c,d=b.documentElement,e=a.Date,f=a.HTMLPictureElement,g="addEventListener",h="getAttribute",i=a[g],j=a.setTimeout,k=a.requestAnimationFrame||j,l=a.requestIdleCallback,m=/^picture$/i,n=["load","error","lazyincluded","_lazyloaded"],o={},p=Array.prototype.forEach,q=function(a,b){return o[b]||(o[b]=new RegExp("(\\s|^)"+b+"(\\s|$)")),o[b].test(a[h]("class")||"")&&o[b]},r=function(a,b){q(a,b)||a.setAttribute("class",(a[h]("class")||"").trim()+" "+b)},s=function(a,b){var c;(c=q(a,b))&&a.setAttribute("class",(a[h]("class")||"").replace(c," "))},t=function(a,b,c){var d=c?g:"removeEventListener";c&&t(a,b),n.forEach(function(c){a[d](c,b)})},u=function(a,c,d,e,f){var g=b.createEvent("CustomEvent");return g.initCustomEvent(c,!e,!f,d||{}),a.dispatchEvent(g),g},v=function(b,d){var e;!f&&(e=a.picturefill||c.pf)?e({reevaluate:!0,elements:[b]}):d&&d.src&&(b.src=d.src)},w=function(a,b){return(getComputedStyle(a,null)||{})[b]},x=function(a,b,d){for(d=d||a.offsetWidth;df&&(f=0),a||9>f&&l?i():j(i,f))}},B=function(a){var b,c,d=99,f=function(){b=null,a()},g=function(){var a=e.now()-c;d>a?j(g,d-a):(l||f)(f)};return function(){c=e.now(),b||(b=j(g,d))}},C=function(){var f,k,l,n,o,x,C,E,F,G,H,I,J,K,L,M=/^img$/i,N=/^iframe$/i,O="onscroll"in a&&!/glebot/.test(navigator.userAgent),P=0,Q=0,R=0,S=0,T=function(a){R--,a&&a.target&&t(a.target,T),(!a||0>R||!a.target)&&(R=0)},U=function(a,c){var e,f=a,g="hidden"==w(b.body,"visibility")||"hidden"!=w(a,"visibility");for(F-=c,I+=c,G-=c,H+=c;g&&(f=f.offsetParent)&&f!=b.body&&f!=d;)g=(w(f,"opacity")||1)>0,g&&"visible"!=w(f,"overflow")&&(e=f.getBoundingClientRect(),g=H>e.left&&Ge.top-1&&FR&&(a=f.length)){b=0,S++,null==K&&("expand"in c||(c.expand=d.clientHeight>500?500:400),J=c.expand,K=J*c.expFactor),K>Q&&1>R&&S>3&&o>2?(Q=K,S=0):Q=o>1&&S>2&&6>R?J:P;for(;a>b;b++)if(f[b]&&!f[b]._lazyRace)if(O)if((n=f[b][h]("data-expand"))&&(j=1*n)||(j=Q),p!==j&&(C=innerWidth+j*L,E=innerHeight+j,m=-1*j,p=j),e=f[b].getBoundingClientRect(),(I=e.bottom)>=m&&(F=e.top)<=E&&(H=e.right)>=m*L&&(G=e.left)<=C&&(I||H||G||F)&&(l&&3>R&&!n&&(3>o||4>S)||U(f[b],j))){if(ba(f[b]),i=!0,R>9)break}else!i&&l&&!g&&4>R&&4>S&&o>2&&(k[0]||c.preloadAfterLoad)&&(k[0]||!n&&(I||H||G||F||"auto"!=f[b][h](c.sizesAttr)))&&(g=k[0]||f[b]);else ba(f[b]);g&&!i&&ba(g)}},W=A(V),X=function(a){r(a.target,c.loadedClass),s(a.target,c.loadingClass),t(a.target,Z)},Y=z(X),Z=function(a){Y({target:a.target})},$=function(a,b){try{a.contentWindow.location.replace(b)}catch(c){a.src=b}},_=function(a){var b,d,e=a[h](c.srcsetAttr);(b=c.customMedia[a[h]("data-media")||a[h]("media")])&&a.setAttribute("media",b),e&&a.setAttribute("srcset",e),b&&(d=a.parentNode,d.insertBefore(a.cloneNode(),a),d.removeChild(a))},aa=z(function(a,b,d,e,f){var g,i,k,l,o,q;(o=u(a,"lazybeforeunveil",b)).defaultPrevented||(e&&(d?r(a,c.autosizesClass):a.setAttribute("sizes",e)),i=a[h](c.srcsetAttr),g=a[h](c.srcAttr),f&&(k=a.parentNode,l=k&&m.test(k.nodeName||"")),q=b.firesLoad||"src"in a&&(i||g||l),o={target:a},q&&(t(a,T,!0),clearTimeout(n),n=j(T,2500),r(a,c.loadingClass),t(a,Z,!0)),l&&p.call(k.getElementsByTagName("source"),_),i?a.setAttribute("srcset",i):g&&!l&&(N.test(a.nodeName)?$(a,g):a.src=g),(i||l)&&v(a,{src:g})),y(function(){a._lazyRace&&delete a._lazyRace,s(a,c.lazyClass),(!q||a.complete)&&(q?T(o):R--,X(o))})}),ba=function(a){var b,d=M.test(a.nodeName),e=d&&(a[h](c.sizesAttr)||a[h]("sizes")),f="auto"==e;(!f&&l||!d||!a.src&&!a.srcset||a.complete||q(a,c.errorClass))&&(b=u(a,"lazyunveilread").detail,f&&D.updateElem(a,!0,a.offsetWidth),a._lazyRace=!0,R++,aa(a,b,f,e,d))},ca=function(){if(!l){if(e.now()-x<999)return void j(ca,999);var a=B(function(){c.loadMode=3,W()});l=!0,c.loadMode=3,W(),i("scroll",function(){3==c.loadMode&&(c.loadMode=2),a()},!0)}};return{_:function(){x=e.now(),f=b.getElementsByClassName(c.lazyClass),k=b.getElementsByClassName(c.lazyClass+" "+c.preloadClass),L=c.hFac,i("scroll",W,!0),i("resize",W,!0),a.MutationObserver?new MutationObserver(W).observe(d,{childList:!0,subtree:!0,attributes:!0}):(d[g]("DOMNodeInserted",W,!0),d[g]("DOMAttrModified",W,!0),setInterval(W,999)),i("hashchange",W,!0),["focus","mouseover","click","load","transitionend","animationend","webkitAnimationEnd"].forEach(function(a){b[g](a,W,!0)}),/d$|^c/.test(b.readyState)?ca():(i("load",ca),b[g]("DOMContentLoaded",W),j(ca,2e4)),W(f.length>0)},checkElems:W,unveil:ba}}(),D=function(){var a,d=z(function(a,b,c,d){var e,f,g;if(a._lazysizesWidth=d,d+="px",a.setAttribute("sizes",d),m.test(b.nodeName||""))for(e=b.getElementsByTagName("source"),f=0,g=e.length;g>f;f++)e[f].setAttribute("sizes",d);c.detail.dataAttr||v(a,c.detail)}),e=function(a,b,c){var e,f=a.parentNode;f&&(c=x(a,f,c),e=u(a,"lazybeforesizes",{width:c,dataAttr:!!b}),e.defaultPrevented||(c=e.detail.width,c&&c!==a._lazysizesWidth&&d(a,f,e,c)))},f=function(){var b,c=a.length;if(c)for(b=0;c>b;b++)e(a[b])},g=B(f);return{_:function(){a=b.getElementsByClassName(c.autosizesClass),i("resize",g)},checkElems:g,updateElem:e}}(),E=function(){E.i||(E.i=!0,D._(),C._())};return function(){var b,d={lazyClass:"lazyload",loadedClass:"lazyloaded",loadingClass:"lazyloading",preloadClass:"lazypreload",errorClass:"lazyerror",autosizesClass:"lazyautosizes",srcAttr:"data-src",srcsetAttr:"data-srcset",sizesAttr:"data-sizes",minSize:40,customMedia:{},init:!0,expFactor:1.5,hFac:.8,loadMode:2};c=a.lazySizesConfig||a.lazysizesConfig||{};for(b in d)b in c||(c[b]=d[b]);a.lazySizesConfig=c,j(function(){c.init&&E()})}(),{cfg:c,autoSizer:D,loader:C,init:E,uP:v,aC:r,rC:s,hC:q,fire:u,gW:x,rAF:y}}}); -------------------------------------------------------------------------------- /js/lazysizes/plugins/aspectratio/ls.aspectratio.js: -------------------------------------------------------------------------------- 1 | (function(window, document){ 2 | 'use strict'; 3 | 4 | if(!window.addEventListener){return;} 5 | 6 | var forEach = Array.prototype.forEach; 7 | 8 | var imageRatio, extend$, $; 9 | 10 | var regPicture = /^picture$/i; 11 | var aspectRatioAttr = 'data-aspectratio'; 12 | var aspectRatioSel = 'img[' + aspectRatioAttr + ']'; 13 | 14 | var matchesMedia = function(media){ 15 | if(window.matchMedia){ 16 | matchesMedia = function(media){ 17 | return !media || (matchMedia(media) || {}).matches; 18 | }; 19 | } else if(window.Modernizr && Modernizr.mq){ 20 | return !media || Modernizr.mq(media); 21 | } else { 22 | return !media; 23 | } 24 | return matchesMedia(media); 25 | }; 26 | 27 | var addClass = function(elem, className){ 28 | if($){ 29 | $(elem).addClass(className); 30 | } else if(window.lazySizes){ 31 | lazySizes.aC(elem, className); 32 | } else { 33 | elem.classList.add(className); 34 | } 35 | }; 36 | 37 | var removeClass = function(elem, className){ 38 | if($){ 39 | $(elem).removeClass(className); 40 | } else if(window.lazySizes){ 41 | lazySizes.rC(elem, className); 42 | } else { 43 | elem.classList.remove(className); 44 | } 45 | }; 46 | 47 | function AspectRatio(){ 48 | this.ratioElems = document.getElementsByClassName('lazyaspectratio'); 49 | this._setupEvents(); 50 | this.processImages(); 51 | } 52 | 53 | AspectRatio.prototype = { 54 | _setupEvents: function(){ 55 | var module = this; 56 | 57 | var addRemoveAspectRatio = function(elem){ 58 | if(elem.naturalWidth < 36){ 59 | module.addAspectRatio(elem, true); 60 | } else { 61 | module.removeAspectRatio(elem, true); 62 | } 63 | }; 64 | var onload = function(){ 65 | module.processImages(); 66 | }; 67 | 68 | document.addEventListener('load', function(e){ 69 | if(e.target.getAttribute && e.target.getAttribute(aspectRatioAttr)){ 70 | addRemoveAspectRatio(e.target); 71 | } 72 | }, true); 73 | 74 | addEventListener('resize', (function(){ 75 | var timer; 76 | var resize = function(){ 77 | forEach.call(module.ratioElems, addRemoveAspectRatio); 78 | }; 79 | 80 | return function(){ 81 | clearTimeout(timer); 82 | timer = setTimeout(resize, 99); 83 | }; 84 | })()); 85 | 86 | document.addEventListener('DOMContentLoaded', onload); 87 | 88 | addEventListener('load', onload); 89 | }, 90 | processImages: function(context){ 91 | var elements, i; 92 | 93 | if(!context){ 94 | context = document; 95 | } 96 | 97 | if('length' in context && !context.nodeName){ 98 | elements = context; 99 | } else { 100 | elements = context.querySelectorAll(aspectRatioSel); 101 | } 102 | 103 | for(i = 0; i < elements.length; i++){ 104 | if(elements[i].naturalWidth > 36){ 105 | this.removeAspectRatio(elements[i]); 106 | continue; 107 | } 108 | this.addAspectRatio(elements[i]); 109 | } 110 | }, 111 | getSelectedRatio: function(img){ 112 | var i, len, sources, customMedia, ratio; 113 | var parent = img.parentNode; 114 | if(parent && regPicture.test(parent.nodeName || '')){ 115 | sources = parent.getElementsByTagName('source'); 116 | 117 | for(i = 0, len = sources.length; i < len; i++){ 118 | customMedia = sources[i].getAttribute('data-media') || sources[i].getAttribute('media'); 119 | 120 | if(window.lazySizesConfig && lazySizesConfig.customMedia[customMedia]){ 121 | customMedia = lazySizesConfig.customMedia[customMedia]; 122 | } 123 | 124 | if(matchesMedia(customMedia)){ 125 | ratio = sources[i].getAttribute(aspectRatioAttr); 126 | break; 127 | } 128 | } 129 | } 130 | 131 | return ratio || img.getAttribute(aspectRatioAttr) || ''; 132 | }, 133 | parseRatio: (function(){ 134 | var regRatio = /^\s*([+\d\.]+)(\s*[\/x]\s*([+\d\.]+))?\s*$/; 135 | var ratioCache = {}; 136 | return function(ratio){ 137 | 138 | if(!ratioCache[ratio] && ratio.match(regRatio)){ 139 | if(RegExp.$3){ 140 | ratioCache[ratio] = RegExp.$1 / RegExp.$3; 141 | } else { 142 | ratioCache[ratio] = RegExp.$1 * 1; 143 | } 144 | } 145 | 146 | return ratioCache[ratio]; 147 | }; 148 | })(), 149 | addAspectRatio: function(img, notNew){ 150 | var ratio; 151 | var width = img.offsetWidth; 152 | var height = img.offsetHeight; 153 | 154 | if(!notNew){ 155 | addClass(img, 'lazyaspectratio'); 156 | } 157 | 158 | if(width < 36 && height <= 0){ 159 | if(width || height && window.console){ 160 | console.log('Define width or height of image, so we can calculate the other dimension'); 161 | } 162 | return; 163 | } 164 | 165 | ratio = this.getSelectedRatio(img); 166 | ratio = this.parseRatio(ratio); 167 | 168 | if(ratio){ 169 | if(width){ 170 | img.style.height = (width / ratio) + 'px'; 171 | } else { 172 | img.style.width = (height * ratio) + 'px'; 173 | } 174 | } 175 | }, 176 | removeAspectRatio: function(img){ 177 | removeClass(img, 'lazyaspectratio'); 178 | img.style.height = ''; 179 | img.style.width = ''; 180 | img.removeAttribute(aspectRatioAttr); 181 | } 182 | }; 183 | 184 | extend$ = function(){ 185 | $ = window.jQuery || window.Zepto || window.shoestring || window.$; 186 | if($ && $.fn && !$.fn.imageRatio && $.fn.filter && $.fn.add && $.fn.find){ 187 | $.fn.imageRatio = function(){ 188 | imageRatio.processImages(this.find(aspectRatioSel).add(this.filter(aspectRatioSel))); 189 | return this; 190 | }; 191 | } else { 192 | $ = false; 193 | } 194 | }; 195 | 196 | extend$(); 197 | setTimeout(extend$); 198 | 199 | imageRatio = new AspectRatio(); 200 | 201 | window.imageRatio = imageRatio; 202 | 203 | if(typeof module == 'object' && module.exports){ 204 | module.exports = imageRatio; 205 | } else if (typeof define == 'function' && define.amd) { 206 | define(imageRatio); 207 | } 208 | 209 | })(window, document); 210 | -------------------------------------------------------------------------------- /js/lazysizes/plugins/aspectratio/ls.aspectratio.min.js: -------------------------------------------------------------------------------- 1 | /*! lazysizes - v2.0.0 */ 2 | !function(a,b){"use strict";function c(){this.ratioElems=b.getElementsByClassName("lazyaspectratio"),this._setupEvents(),this.processImages()}if(a.addEventListener){var d,e,f,g=Array.prototype.forEach,h=/^picture$/i,i="data-aspectratio",j="img["+i+"]",k=function(b){return a.matchMedia?(k=function(a){return!a||(matchMedia(a)||{}).matches})(b):a.Modernizr&&Modernizr.mq?!b||Modernizr.mq(b):!b},l=function(b,c){f?f(b).addClass(c):a.lazySizes?lazySizes.aC(b,c):b.classList.add(c)},m=function(b,c){f?f(b).removeClass(c):a.lazySizes?lazySizes.rC(b,c):b.classList.remove(c)};c.prototype={_setupEvents:function(){var a=this,c=function(b){b.naturalWidth<36?a.addAspectRatio(b,!0):a.removeAspectRatio(b,!0)},d=function(){a.processImages()};b.addEventListener("load",function(a){a.target.getAttribute&&a.target.getAttribute(i)&&c(a.target)},!0),addEventListener("resize",function(){var b,d=function(){g.call(a.ratioElems,c)};return function(){clearTimeout(b),b=setTimeout(d,99)}}()),b.addEventListener("DOMContentLoaded",d),addEventListener("load",d)},processImages:function(a){var c,d;a||(a=b),c="length"in a&&!a.nodeName?a:a.querySelectorAll(j);for(d=0;d36?this.removeAspectRatio(c[d]):this.addAspectRatio(c[d])},getSelectedRatio:function(b){var c,d,e,f,g,j=b.parentNode;if(j&&h.test(j.nodeName||""))for(e=j.getElementsByTagName("source"),c=0,d=e.length;d>c;c++)if(f=e[c].getAttribute("data-media")||e[c].getAttribute("media"),a.lazySizesConfig&&lazySizesConfig.customMedia[f]&&(f=lazySizesConfig.customMedia[f]),k(f)){g=e[c].getAttribute(i);break}return g||b.getAttribute(i)||""},parseRatio:function(){var a=/^\s*([+\d\.]+)(\s*[\/x]\s*([+\d\.]+))?\s*$/,b={};return function(c){return!b[c]&&c.match(a)&&(RegExp.$3?b[c]=RegExp.$1/RegExp.$3:b[c]=1*RegExp.$1),b[c]}}(),addAspectRatio:function(b,c){var d,e=b.offsetWidth,f=b.offsetHeight;return c||l(b,"lazyaspectratio"),36>e&&0>=f?void((e||f&&a.console)&&console.log("Define width or height of image, so we can calculate the other dimension")):(d=this.getSelectedRatio(b),d=this.parseRatio(d),void(d&&(e?b.style.height=e/d+"px":b.style.width=f*d+"px")))},removeAspectRatio:function(a){m(a,"lazyaspectratio"),a.style.height="",a.style.width="",a.removeAttribute(i)}},e=function(){f=a.jQuery||a.Zepto||a.shoestring||a.$,f&&f.fn&&!f.fn.imageRatio&&f.fn.filter&&f.fn.add&&f.fn.find?f.fn.imageRatio=function(){return d.processImages(this.find(j).add(this.filter(j))),this}:f=!1},e(),setTimeout(e),d=new c,a.imageRatio=d,"object"==typeof module&&module.exports?module.exports=d:"function"==typeof define&&define.amd&&define(d)}}(window,document); -------------------------------------------------------------------------------- /js/lazysizes/plugins/attrchange/ls.attrchange.js: -------------------------------------------------------------------------------- 1 | (function(window, document){ 2 | 'use strict'; 3 | if(!window.addEventListener){return;} 4 | 5 | var rAF = window.requestAnimationFrame || setTimeout; 6 | 7 | var addObserver = function(){ 8 | var connect, disconnect, observer, connected; 9 | var lazySizes = window.lazySizes; 10 | var lsCfg = lazySizes.cfg; 11 | var attributes = {'data-bgset': 1, 'data-include': 1, 'data-poster': 1, 'data-bg': 1, 'data-script': 1}; 12 | var regClassTest = '(\\s|^)(' + lsCfg.loadedClass; 13 | var docElem = document.documentElement; 14 | 15 | var setClass = function(target){ 16 | rAF(function(){ 17 | lazySizes.rC(target, lsCfg.loadedClass); 18 | if(lsCfg.unloadedClass){ 19 | lazySizes.rC(target, lsCfg.unloadedClass); 20 | } 21 | lazySizes.aC(target, lsCfg.lazyClass); 22 | }); 23 | }; 24 | 25 | var onMutation = function(mutations){ 26 | var i, len, mutation, target; 27 | for(i = 0, len = mutations.length; i < len; i++){ 28 | mutation = mutations[i]; 29 | target = mutation.target; 30 | 31 | if(!target.getAttribute(mutation.attributeName)){continue;} 32 | 33 | if(target.localName == 'source' && target.parentNode){ 34 | target = target.parentNode.querySelector('img'); 35 | } 36 | 37 | if(target && regClassTest.test(target.className)){ 38 | setClass(target); 39 | } 40 | } 41 | }; 42 | 43 | if(lsCfg.unloadedClass){ 44 | regClassTest += '|' + lsCfg.unloadedClass; 45 | } 46 | 47 | regClassTest += '|' + lsCfg.loadingClass + ')(\\s|$)'; 48 | 49 | regClassTest = new RegExp(regClassTest); 50 | 51 | attributes[lsCfg.srcAttr] = 1; 52 | attributes[lsCfg.srcsetAttr] = 1; 53 | 54 | if(window.MutationObserver){ 55 | observer = new MutationObserver(onMutation); 56 | 57 | connect = function(){ 58 | if(!connected){ 59 | connected = true; 60 | observer.observe( docElem, { subtree: true, attributes: true, attributeFilter: Object.keys(attributes)} ); 61 | } 62 | }; 63 | disconnect = function(){ 64 | if(connected){ 65 | connected = false; 66 | observer.disconnect(); 67 | } 68 | }; 69 | } else { 70 | docElem.addEventListener('DOMAttrModified', (function(){ 71 | var runs; 72 | var modifications = []; 73 | var callMutations = function(){ 74 | onMutation(modifications); 75 | modifications = []; 76 | runs = false; 77 | }; 78 | return function(e){ 79 | if(connected && attributes[e.attrName] && e.newValue){ 80 | modifications.push({target: e.target, attributeName: e.attrName}); 81 | if(!runs){ 82 | setTimeout(callMutations); 83 | runs = true; 84 | } 85 | } 86 | }; 87 | })(), true); 88 | 89 | connect = function(){ 90 | connected = true; 91 | }; 92 | disconnect = function(){ 93 | connected = false; 94 | }; 95 | } 96 | 97 | addEventListener('lazybeforeunveil', disconnect, true); 98 | addEventListener('lazybeforeunveil', connect); 99 | 100 | addEventListener('lazybeforesizes', disconnect, true); 101 | addEventListener('lazybeforesizes', connect); 102 | connect(); 103 | 104 | removeEventListener('lazybeforeunveil', addObserver); 105 | }; 106 | 107 | 108 | addEventListener('lazybeforeunveil', addObserver); 109 | })(window, document); 110 | -------------------------------------------------------------------------------- /js/lazysizes/plugins/attrchange/ls.attrchange.min.js: -------------------------------------------------------------------------------- 1 | /*! lazysizes - v2.0.0 */ 2 | !function(a,b){"use strict";if(a.addEventListener){var c=a.requestAnimationFrame||setTimeout,d=function(){var e,f,g,h,i=a.lazySizes,j=i.cfg,k={"data-bgset":1,"data-include":1,"data-poster":1,"data-bg":1,"data-script":1},l="(\\s|^)("+j.loadedClass,m=b.documentElement,n=function(a){c(function(){i.rC(a,j.loadedClass),j.unloadedClass&&i.rC(a,j.unloadedClass),i.aC(a,j.lazyClass)})},o=function(a){var b,c,d,e;for(b=0,c=a.length;c>b;b++)d=a[b],e=d.target,e.getAttribute(d.attributeName)&&("source"==e.localName&&e.parentNode&&(e=e.parentNode.querySelector("img")),e&&l.test(e.className)&&n(e))};j.unloadedClass&&(l+="|"+j.unloadedClass),l+="|"+j.loadingClass+")(\\s|$)",l=new RegExp(l),k[j.srcAttr]=1,k[j.srcsetAttr]=1,a.MutationObserver?(g=new MutationObserver(o),e=function(){h||(h=!0,g.observe(m,{subtree:!0,attributes:!0,attributeFilter:Object.keys(k)}))},f=function(){h&&(h=!1,g.disconnect())}):(m.addEventListener("DOMAttrModified",function(){var a,b=[],c=function(){o(b),b=[],a=!1};return function(d){h&&k[d.attrName]&&d.newValue&&(b.push({target:d.target,attributeName:d.attrName}),a||(setTimeout(c),a=!0))}}(),!0),e=function(){h=!0},f=function(){h=!1}),addEventListener("lazybeforeunveil",f,!0),addEventListener("lazybeforeunveil",e),addEventListener("lazybeforesizes",f,!0),addEventListener("lazybeforesizes",e),e(),removeEventListener("lazybeforeunveil",d)};addEventListener("lazybeforeunveil",d)}}(window,document); -------------------------------------------------------------------------------- /js/lazysizes/plugins/bgset/ls.bgset.js: -------------------------------------------------------------------------------- 1 | (function(){ 2 | 'use strict'; 3 | if(!window.addEventListener){return;} 4 | 5 | var regWhite = /\s+/g; 6 | var regSplitSet = /\s*\|\s+|\s+\|\s*/g; 7 | var regSource = /^(.+?)(?:\s+\[\s*(.+?)\s*\])?$/; 8 | var allowedBackgroundSize = {contain: 1, cover: 1}; 9 | var proxyWidth = function(elem){ 10 | var width = lazySizes.gW(elem, elem.parentNode); 11 | 12 | if(!elem._lazysizesWidth || width > elem._lazysizesWidth){ 13 | elem._lazysizesWidth = width; 14 | } 15 | return elem._lazysizesWidth; 16 | }; 17 | var getBgSize = function(elem){ 18 | var bgSize; 19 | 20 | bgSize = (getComputedStyle(elem) || {getPropertyValue: function(){}}).getPropertyValue('background-size'); 21 | 22 | if(!allowedBackgroundSize[bgSize] && allowedBackgroundSize[elem.style.backgroundSize]){ 23 | bgSize = elem.style.backgroundSize; 24 | } 25 | 26 | return bgSize; 27 | }; 28 | var createPicture = function(sets, elem, img){ 29 | var picture = document.createElement('picture'); 30 | var sizes = elem.getAttribute(lazySizesConfig.sizesAttr); 31 | var ratio = elem.getAttribute('data-ratio'); 32 | var optimumx = elem.getAttribute('data-optimumx'); 33 | 34 | if(elem._lazybgset && elem._lazybgset.parentNode == elem){ 35 | elem.removeChild(elem._lazybgset); 36 | } 37 | 38 | Object.defineProperty(img, '_lazybgset', { 39 | value: elem, 40 | writable: true 41 | }); 42 | Object.defineProperty(elem, '_lazybgset', { 43 | value: picture, 44 | writable: true 45 | }); 46 | 47 | sets = sets.replace(regWhite, ' ').split(regSplitSet); 48 | 49 | picture.style.display = 'none'; 50 | img.className = lazySizesConfig.lazyClass; 51 | 52 | if(sets.length == 1 && !sizes){ 53 | sizes = 'auto'; 54 | } 55 | 56 | sets.forEach(function(set){ 57 | var source = document.createElement('source'); 58 | 59 | if(sizes && sizes != 'auto'){ 60 | source.setAttribute('sizes', sizes); 61 | } 62 | 63 | if(set.match(regSource)){ 64 | source.setAttribute(lazySizesConfig.srcsetAttr, RegExp.$1); 65 | if(RegExp.$2){ 66 | source.setAttribute('media', lazySizesConfig.customMedia[RegExp.$2] || RegExp.$2); 67 | } 68 | } 69 | picture.appendChild(source); 70 | }); 71 | 72 | if(sizes){ 73 | img.setAttribute(lazySizesConfig.sizesAttr, sizes); 74 | elem.removeAttribute(lazySizesConfig.sizesAttr); 75 | elem.removeAttribute('sizes'); 76 | } 77 | if(optimumx){ 78 | img.setAttribute('data-optimumx', optimumx); 79 | } 80 | if(ratio) { 81 | img.setAttribute('data-ratio', ratio); 82 | } 83 | 84 | picture.appendChild(img); 85 | 86 | elem.appendChild(picture); 87 | }; 88 | 89 | var proxyLoad = function(e){ 90 | if(!e.target._lazybgset){return;} 91 | 92 | var image = e.target; 93 | var elem = image._lazybgset; 94 | var bg = image.currentSrc || image.src; 95 | 96 | if(bg){ 97 | elem.style.backgroundImage = 'url('+ bg +')'; 98 | } 99 | 100 | if(image._lazybgsetLoading){ 101 | lazySizes.fire(elem, '_lazyloaded', {}, false, true); 102 | delete image._lazybgsetLoading; 103 | } 104 | }; 105 | 106 | addEventListener('lazybeforeunveil', function(e){ 107 | var set, image, elem; 108 | 109 | if(e.defaultPrevented || !(set = e.target.getAttribute('data-bgset'))){return;} 110 | 111 | elem = e.target; 112 | image = document.createElement('img'); 113 | 114 | image.alt = ''; 115 | 116 | image._lazybgsetLoading = true; 117 | e.detail.firesLoad = true; 118 | 119 | createPicture(set, elem, image); 120 | 121 | setTimeout(function(){ 122 | lazySizes.loader.unveil(image); 123 | 124 | lazySizes.rAF(function(){ 125 | lazySizes.fire(image, '_lazyloaded', {}, true, true); 126 | if(image.complete) { 127 | proxyLoad({target: image}); 128 | } 129 | }); 130 | }); 131 | 132 | }); 133 | 134 | document.addEventListener('load', proxyLoad, true); 135 | 136 | window.addEventListener('lazybeforesizes', function(e){ 137 | if(e.target._lazybgset && e.detail.dataAttr){ 138 | var elem = e.target._lazybgset; 139 | var bgSize = getBgSize(elem); 140 | 141 | if(allowedBackgroundSize[bgSize]){ 142 | e.target._lazysizesParentFit = bgSize; 143 | 144 | lazySizes.rAF(function(){ 145 | e.target.setAttribute('data-parent-fit', bgSize); 146 | if(e.target._lazysizesParentFit){ 147 | delete e.target._lazysizesParentFit; 148 | } 149 | }); 150 | } 151 | } 152 | }, true); 153 | 154 | document.documentElement.addEventListener('lazybeforesizes', function(e){ 155 | if(e.defaultPrevented || !e.target._lazybgset){return;} 156 | e.detail.width = proxyWidth(e.target._lazybgset); 157 | }); 158 | })(); 159 | -------------------------------------------------------------------------------- /js/lazysizes/plugins/bgset/ls.bgset.min.js: -------------------------------------------------------------------------------- 1 | /*! lazysizes - v2.0.0 */ 2 | !function(){"use strict";if(window.addEventListener){var a=/\s+/g,b=/\s*\|\s+|\s+\|\s*/g,c=/^(.+?)(?:\s+\[\s*(.+?)\s*\])?$/,d={contain:1,cover:1},e=function(a){var b=lazySizes.gW(a,a.parentNode);return(!a._lazysizesWidth||b>a._lazysizesWidth)&&(a._lazysizesWidth=b),a._lazysizesWidth},f=function(a){var b;return b=(getComputedStyle(a)||{getPropertyValue:function(){}}).getPropertyValue("background-size"),!d[b]&&d[a.style.backgroundSize]&&(b=a.style.backgroundSize),b},g=function(d,e,f){var g=document.createElement("picture"),h=e.getAttribute(lazySizesConfig.sizesAttr),i=e.getAttribute("data-ratio"),j=e.getAttribute("data-optimumx");e._lazybgset&&e._lazybgset.parentNode==e&&e.removeChild(e._lazybgset),Object.defineProperty(f,"_lazybgset",{value:e,writable:!0}),Object.defineProperty(e,"_lazybgset",{value:g,writable:!0}),d=d.replace(a," ").split(b),g.style.display="none",f.className=lazySizesConfig.lazyClass,1!=d.length||h||(h="auto"),d.forEach(function(a){var b=document.createElement("source");h&&"auto"!=h&&b.setAttribute("sizes",h),a.match(c)&&(b.setAttribute(lazySizesConfig.srcsetAttr,RegExp.$1),RegExp.$2&&b.setAttribute("media",lazySizesConfig.customMedia[RegExp.$2]||RegExp.$2)),g.appendChild(b)}),h&&(f.setAttribute(lazySizesConfig.sizesAttr,h),e.removeAttribute(lazySizesConfig.sizesAttr),e.removeAttribute("sizes")),j&&f.setAttribute("data-optimumx",j),i&&f.setAttribute("data-ratio",i),g.appendChild(f),e.appendChild(g)},h=function(a){if(a.target._lazybgset){var b=a.target,c=b._lazybgset,d=b.currentSrc||b.src;d&&(c.style.backgroundImage="url("+d+")"),b._lazybgsetLoading&&(lazySizes.fire(c,"_lazyloaded",{},!1,!0),delete b._lazybgsetLoading)}};addEventListener("lazybeforeunveil",function(a){var b,c,d;!a.defaultPrevented&&(b=a.target.getAttribute("data-bgset"))&&(d=a.target,c=document.createElement("img"),c.alt="",c._lazybgsetLoading=!0,a.detail.firesLoad=!0,g(b,d,c),setTimeout(function(){lazySizes.loader.unveil(c),lazySizes.rAF(function(){lazySizes.fire(c,"_lazyloaded",{},!0,!0),c.complete&&h({target:c})})}))}),document.addEventListener("load",h,!0),window.addEventListener("lazybeforesizes",function(a){if(a.target._lazybgset&&a.detail.dataAttr){var b=a.target._lazybgset,c=f(b);d[c]&&(a.target._lazysizesParentFit=c,lazySizes.rAF(function(){a.target.setAttribute("data-parent-fit",c),a.target._lazysizesParentFit&&delete a.target._lazysizesParentFit}))}},!0),document.documentElement.addEventListener("lazybeforesizes",function(a){!a.defaultPrevented&&a.target._lazybgset&&(a.detail.width=e(a.target._lazybgset))})}}(); -------------------------------------------------------------------------------- /js/lazysizes/plugins/custommedia/ls.custommedia.js: -------------------------------------------------------------------------------- 1 | /* 2 | html:after { 3 | display: none; 4 | content: '--small: (max-width: 500px) | --medium: (max-width: 1100px) | --large: (min-width: 1100px)'; 5 | } 6 | */ 7 | (function(window){ 8 | /*jshint eqnull:true */ 9 | 'use strict'; 10 | var docElem = document.documentElement; 11 | 12 | var create = function(){ 13 | if(!window.lazySizes || window.lazySizes.getCustomMedias){return;} 14 | var lazySizes = window.lazySizes; 15 | 16 | lazySizes.getCustomMedias = (function(){ 17 | var regCleanPseudos = /['"]/g; 18 | var regSplit = /\s*\|\s*/g; 19 | var regNamedQueries = /^([a-z0-9_-]+)\s*:\s*(.+)$/i; 20 | 21 | var getStyle = function(elem, pseudo){ 22 | return ((getComputedStyle(elem, pseudo) || {getPropertyValue: function(){}}).getPropertyValue('content') || 'none').replace(regCleanPseudos, '').trim(); 23 | }; 24 | var parse = function(string, object){ 25 | string.split(regSplit).forEach(function(query){ 26 | if(query.match(regNamedQueries)){ 27 | object[RegExp.$1] = RegExp.$2; 28 | } 29 | }); 30 | }; 31 | return function(object, element){ 32 | object = object || lazySizes.cfg.customMedia; 33 | element = element || document.querySelector('html'); 34 | parse(getStyle(element, ':before'), object); 35 | parse(getStyle(element, ':after'), object); 36 | return object; 37 | }; 38 | })(); 39 | 40 | lazySizes.updateCustomMedia = function(){ 41 | var i, len, customMedia; 42 | var elems = docElem.querySelectorAll('source[media][data-media][srcset]'); 43 | 44 | lazySizes.getCustomMedias(); 45 | 46 | for(i = 0, len = elems.length; i < len; i++){ 47 | if( (customMedia = lazySizes.cfg.customMedia[elems[i].getAttribute('data-media') || elems[i].getAttribute('media')]) ){ 48 | elems[i].setAttribute('media', customMedia); 49 | } 50 | } 51 | 52 | elems = docElem.querySelector('source[media][data-media][srcset] ~ img'); 53 | for(i = 0, len = elems.length; i < len; i++){ 54 | lazySizes.uP(elems[i]); 55 | } 56 | 57 | lazySizes.autoSizer.checkElems(); 58 | }; 59 | 60 | lazySizes.getCustomMedias(); 61 | docElem.removeEventListener('lazybeforeunveil', create); 62 | }; 63 | 64 | if(window.addEventListener){ 65 | docElem.addEventListener('lazybeforeunveil', create); 66 | create(); 67 | setTimeout(create); 68 | } 69 | 70 | })(window); 71 | -------------------------------------------------------------------------------- /js/lazysizes/plugins/custommedia/ls.custommedia.min.js: -------------------------------------------------------------------------------- 1 | /*! lazysizes - v2.0.0 */ 2 | !function(a){"use strict";var b=document.documentElement,c=function(){if(a.lazySizes&&!a.lazySizes.getCustomMedias){var d=a.lazySizes;d.getCustomMedias=function(){var a=/['"]/g,b=/\s*\|\s*/g,c=/^([a-z0-9_-]+)\s*:\s*(.+)$/i,e=function(b,c){return((getComputedStyle(b,c)||{getPropertyValue:function(){}}).getPropertyValue("content")||"none").replace(a,"").trim()},f=function(a,d){a.split(b).forEach(function(a){a.match(c)&&(d[RegExp.$1]=RegExp.$2)})};return function(a,b){return a=a||d.cfg.customMedia,b=b||document.querySelector("html"),f(e(b,":before"),a),f(e(b,":after"),a),a}}(),d.updateCustomMedia=function(){var a,c,e,f=b.querySelectorAll("source[media][data-media][srcset]");for(d.getCustomMedias(),a=0,c=f.length;c>a;a++)(e=d.cfg.customMedia[f[a].getAttribute("data-media")||f[a].getAttribute("media")])&&f[a].setAttribute("media",e);for(f=b.querySelector("source[media][data-media][srcset] ~ img"),a=0,c=f.length;c>a;a++)d.uP(f[a]);d.autoSizer.checkElems()},d.getCustomMedias(),b.removeEventListener("lazybeforeunveil",c)}};a.addEventListener&&(b.addEventListener("lazybeforeunveil",c),c(),setTimeout(c))}(window); -------------------------------------------------------------------------------- /js/lazysizes/plugins/fix-ios-sizes/fix-ios-sizes.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Some versions of iOS (8.1-) do load the first candidate of a srcset candidate list, if width descriptors with the sizes attribute is used. 3 | * This tiny extension prevents this wasted download by creating a picture structure around the image. 4 | * Note: This extension is already included in the ls.respimg.js file. 5 | * 6 | * Usage: 7 | * 8 | * 15 | */ 16 | 17 | (function(document){ 18 | 'use strict'; 19 | var regPicture; 20 | var img = document.createElement('img'); 21 | 22 | if(('srcset' in img) && !('sizes' in img) && !window.HTMLPictureElement){ 23 | regPicture = /^picture$/i; 24 | document.addEventListener('lazybeforeunveil', function(e){ 25 | var elem, parent, srcset, sizes, isPicture; 26 | var picture, source; 27 | if(e.defaultPrevented || 28 | lazySizesConfig.noIOSFix || 29 | !(elem = e.target) || 30 | !(srcset = elem.getAttribute(lazySizesConfig.srcsetAttr)) || 31 | !(parent = elem.parentNode) || 32 | ( 33 | !(isPicture = regPicture.test(parent.nodeName || '')) && 34 | !(sizes = elem.getAttribute('sizes') || elem.getAttribute(lazySizesConfig.sizesAttr)) 35 | ) 36 | ){return;} 37 | 38 | picture = isPicture ? parent : document.createElement('picture'); 39 | 40 | if(!elem._lazyImgSrc){ 41 | Object.defineProperty(elem, '_lazyImgSrc', { 42 | value: document.createElement('source'), 43 | writable: true 44 | }); 45 | } 46 | source = elem._lazyImgSrc; 47 | 48 | if(sizes){ 49 | source.setAttribute('sizes', sizes); 50 | } 51 | 52 | source.setAttribute(lazySizesConfig.srcsetAttr, srcset); 53 | elem.setAttribute('data-pfsrcset', srcset); 54 | elem.removeAttribute(lazySizesConfig.srcsetAttr); 55 | 56 | if(!isPicture){ 57 | parent.insertBefore(picture, elem); 58 | picture.appendChild(elem); 59 | } 60 | picture.insertBefore(source, elem); 61 | }); 62 | } 63 | })(document); 64 | -------------------------------------------------------------------------------- /js/lazysizes/plugins/fix-ios-sizes/fix-ios-sizes.min.js: -------------------------------------------------------------------------------- 1 | /*! lazysizes - v2.0.0 */ 2 | !function(a){"use strict";var b,c=a.createElement("img");!("srcset"in c)||"sizes"in c||window.HTMLPictureElement||(b=/^picture$/i,a.addEventListener("lazybeforeunveil",function(c){var d,e,f,g,h,i,j;!c.defaultPrevented&&!lazySizesConfig.noIOSFix&&(d=c.target)&&(f=d.getAttribute(lazySizesConfig.srcsetAttr))&&(e=d.parentNode)&&((h=b.test(e.nodeName||""))||(g=d.getAttribute("sizes")||d.getAttribute(lazySizesConfig.sizesAttr)))&&(i=h?e:a.createElement("picture"),d._lazyImgSrc||Object.defineProperty(d,"_lazyImgSrc",{value:a.createElement("source"),writable:!0}),j=d._lazyImgSrc,g&&j.setAttribute("sizes",g),j.setAttribute(lazySizesConfig.srcsetAttr,f),d.setAttribute("data-pfsrcset",f),d.removeAttribute(lazySizesConfig.srcsetAttr),h||(e.insertBefore(i,d),i.appendChild(d)),i.insertBefore(j,d))}))}(document); -------------------------------------------------------------------------------- /js/lazysizes/plugins/include/ls.include.js: -------------------------------------------------------------------------------- 1 | /* 2 | This plugin extends lazySizes to lazyLoad and/or conditionally load content 3 | */ 4 | 5 | (function(window, document){ 6 | /*jshint eqnull:true */ 7 | 'use strict'; 8 | 9 | if(!document.getElementsByClassName) { 10 | return; 11 | } 12 | var config, includeConfig, baseContentElement, basePseudos; 13 | var regSplitCan = /\s*,+\s+/; 14 | var uniqueUrls = {}; 15 | var regWhite = /\s+/; 16 | var regTypes = /^(amd|css|module)\:(.+)/i; 17 | var regUrlCan = /(.+)\s+(\(\s*(.+)\s*\))/; 18 | var regCleanPseudos = /['"]/g; 19 | var docElem = document.documentElement; 20 | var conditionalIncludes = document.getElementsByClassName('lazyconditionalinclude'); 21 | 22 | var getComputedStyle = function(){ 23 | return window.getComputedStyle.apply(window.getComputedStyle, arguments) || {getPropertyValue: function(){}}; 24 | }; 25 | 26 | var queue = (function(){ 27 | var lowTreshold = 2; 28 | var highTreshold = 3; 29 | var queueThreshold = lowTreshold; 30 | var inProgress = 0; 31 | var priosInProgress = 0; 32 | var queue = []; 33 | var resetQueue = (function(){ 34 | var timer; 35 | var reset = function(){ 36 | if(queue.length){ 37 | inProgress = 0; 38 | queue.d(); 39 | } 40 | }; 41 | 42 | return function(){ 43 | clearTimeout(timer); 44 | timer = setTimeout(reset, 999); 45 | }; 46 | })(); 47 | 48 | return { 49 | q: function(element){ 50 | var isPrio = element.getAttribute('data-lazyqueue') == null; 51 | if(isPrio){ 52 | priosInProgress++; 53 | queueThreshold = highTreshold; 54 | } 55 | 56 | if(inProgress > queueThreshold){ 57 | queue[isPrio ? 'unshift' : 'push'](element); 58 | } else if(findLoadCandidate(element)) { 59 | inProgress++; 60 | resetQueue(); 61 | } 62 | }, 63 | d: function(){ 64 | if(inProgress){ 65 | inProgress--; 66 | } 67 | if(priosInProgress > 0){ 68 | priosInProgress--; 69 | 70 | if(!priosInProgress){ 71 | queueThreshold = lowTreshold; 72 | } 73 | } 74 | 75 | if(inProgress > queueThreshold){ 76 | return; 77 | } 78 | 79 | while(queue.length){ 80 | if(findLoadCandidate(queue.shift())){ 81 | inProgress++; 82 | break; 83 | } 84 | } 85 | resetQueue(); 86 | } 87 | }; 88 | })(); 89 | var refreshIncludes = (function(){ 90 | var timer; 91 | var run = function(){ 92 | var i = 0; 93 | var len = conditionalIncludes.length; 94 | for(; i < len; i++){ 95 | if(!lazySizes.hC(conditionalIncludes[i], config.lazyClass) && findCandidate(conditionalIncludes[i])){ 96 | lazySizes.aC(conditionalIncludes[i], config.lazyClass); 97 | } 98 | } 99 | }; 100 | return function(e){ 101 | clearTimeout(timer); 102 | basePseudos = null; 103 | timer = setTimeout(run, e.type == 'resize' ? 31 : 0); 104 | }; 105 | })(); 106 | 107 | config = (window.lazySizes && lazySizes.cfg) || window.lazySizesConfig; 108 | 109 | if(!config){ 110 | config = {}; 111 | window.lazySizesConfig = config; 112 | } 113 | 114 | if(!config.include){ 115 | config.include = {}; 116 | } 117 | 118 | includeConfig = config.include; 119 | 120 | if(!includeConfig.contentElement){ 121 | includeConfig.contentElement = 'html'; 122 | } 123 | 124 | if(!includeConfig.conditions){ 125 | includeConfig.conditions = {}; 126 | } 127 | 128 | if(!includeConfig.map){ 129 | includeConfig.map = {}; 130 | } 131 | 132 | function addUrl(url){ 133 | /*jshint validthis:true */ 134 | if(url.match(regTypes)){ 135 | this.urls[RegExp.$1] = includeConfig.map[RegExp.$2] || RegExp.$2; 136 | } else { 137 | this.urls.include = includeConfig.map[url] || url; 138 | } 139 | } 140 | 141 | function parseCandidate(input){ 142 | var output, map, url; 143 | input = input.trim(); 144 | 145 | input = includeConfig.map[input] || input; 146 | 147 | map = input.match(regUrlCan); 148 | 149 | if(map){ 150 | url = RegExp.$1; 151 | output = { 152 | condition: config.include.conditions[RegExp.$3] || config.customMedia[RegExp.$3] || RegExp.$2 || null, 153 | name: RegExp.$3 154 | }; 155 | } else { 156 | url = input; 157 | output = { 158 | condition: null, 159 | name: '' 160 | }; 161 | } 162 | 163 | output.urls = {}; 164 | 165 | (includeConfig.map[url] || url).split(regWhite).forEach(addUrl, output); 166 | 167 | if(!output.urls.include && output.urls.amd){ 168 | /*jshint validthis:true */ 169 | this.saved = true; 170 | output.initial = this; 171 | } 172 | 173 | return output; 174 | } 175 | 176 | function getIncludeData(elem){ 177 | var len; 178 | var includeStr = (elem.getAttribute('data-include') || ''); 179 | var includeData = elem.lazyInclude; 180 | var initialContent; 181 | if(!includeData || includeData.str != includeStr){ 182 | initialContent = {saved: false, content: null}; 183 | includeData = { 184 | str: includeStr, 185 | candidates: (includeConfig.map[includeStr] || includeStr).split(regSplitCan).map(parseCandidate, initialContent) 186 | }; 187 | 188 | if(!(len = includeData.candidates.length) || includeData.candidates[len - 1].condition){ 189 | initialContent.saved = true; 190 | 191 | includeData.candidates.push({ 192 | urls: {}, 193 | condition: null, 194 | name: 'initial', 195 | content: initialContent 196 | }); 197 | } else if(initialContent.saved && includeData.candidates.length == 1){ 198 | initialContent.saved = false; 199 | } 200 | 201 | includeData.initialContent = initialContent; 202 | if(initialContent.saved){ 203 | initialContent.content = elem.innerHTML; 204 | } 205 | 206 | elem.lazyInclude = includeData; 207 | if(includeData.candidates.length > 1){ 208 | lazySizes.aC(elem, 'lazyconditionalinclude'); 209 | } else { 210 | lazySizes.rC(elem, 'lazyconditionalinclude'); 211 | } 212 | } 213 | return includeData; 214 | } 215 | 216 | function matchesCondition(elem, candidate){ 217 | var matches = !candidate.condition; 218 | 219 | if(candidate.condition){ 220 | createPseudoCondition(); 221 | if(basePseudos[candidate.name]){ 222 | matches = true; 223 | } else if(window.matchMedia && typeof candidate.condition == 'string'){ 224 | matches = (matchMedia(candidate.condition) || {}).matches; 225 | } else if(typeof candidate.condition == 'function'){ 226 | matches = candidate.condition(elem, candidate); 227 | } 228 | } 229 | return matches; 230 | } 231 | 232 | 233 | function createPseudoCondition(){ 234 | var cStyle; 235 | 236 | if(!basePseudos){ 237 | 238 | if(!baseContentElement){ 239 | baseContentElement = document.querySelector(includeConfig.contentElement); 240 | } 241 | 242 | if(baseContentElement){ 243 | cStyle = (getComputedStyle(baseContentElement, ':after').getPropertyValue('content') || 'none').replace(regCleanPseudos, ''); 244 | 245 | basePseudos = {}; 246 | 247 | if(cStyle){ 248 | basePseudos[cStyle] = 1; 249 | } 250 | cStyle = (getComputedStyle(baseContentElement, ':before').getPropertyValue('content') || 'none').replace(regCleanPseudos, ''); 251 | if(cStyle){ 252 | basePseudos[cStyle] = 1; 253 | } 254 | } else { 255 | basePseudos = {}; 256 | } 257 | } 258 | 259 | } 260 | 261 | function findCandidate(elem){ 262 | var i, candidate; 263 | var includeData = elem.lazyInclude; 264 | if(includeData && includeData.candidates){ 265 | for(i = 0; i < includeData.candidates.length; i++){ 266 | candidate = includeData.candidates[i]; 267 | if(matchesCondition(elem, candidate)){ 268 | break; 269 | } 270 | } 271 | } 272 | if(!candidate || candidate == includeData.current){ 273 | candidate = null; 274 | } 275 | return candidate; 276 | } 277 | 278 | function loadInclude(detail, includeCallback){ 279 | var request = new XMLHttpRequest(); 280 | 281 | request.addEventListener('readystatechange', function () { 282 | var DONE = this.DONE || 4; 283 | if (this.readyState === DONE){ 284 | 285 | includeCallback(request); 286 | request = null; 287 | } 288 | }, false); 289 | 290 | request.open.apply(request, detail.openArgs); 291 | request.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); 292 | if(detail.xhrModifier){ 293 | detail.xhrModifier(request, elem, candidate); 294 | } 295 | request.send(detail.sendData); 296 | } 297 | 298 | function loadRequire(urls, callback){ 299 | urls = urls.split('|,|'); 300 | require(urls, callback); 301 | } 302 | 303 | function loadStyle(url){ 304 | if(!uniqueUrls[url]){ 305 | var elem = document.createElement('link'); 306 | var insertElem = document.getElementsByTagName('script')[0]; 307 | 308 | elem.rel = 'stylesheet'; 309 | elem.href = url; 310 | insertElem.parentNode.insertBefore(elem, insertElem); 311 | uniqueUrls[url] = true; 312 | uniqueUrls[elem.href] = true; 313 | } 314 | } 315 | 316 | function loadStyles(urls){ 317 | urls = urls.split('|,|'); 318 | urls.forEach(loadStyle); 319 | } 320 | 321 | function transformInclude(module){ 322 | if(module && typeof module.lazytransform == 'function'){ 323 | /*jshint validthis:true */ 324 | module.lazytransform(this); 325 | } 326 | } 327 | 328 | function unloadModule(module){ 329 | if(module && typeof module.lazyunload == 'function'){ 330 | /*jshint validthis:true */ 331 | module.lazyunload(this); 332 | } 333 | } 334 | 335 | function loadModule(module){ 336 | if(module && typeof module.lazyload == 'function'){ 337 | /*jshint validthis:true */ 338 | module.lazyload(this); 339 | } 340 | } 341 | 342 | function loadCandidate(elem, candidate){ 343 | var include, xhrObj, modules; 344 | var old = elem.lazyInclude.current || null; 345 | var detail = { 346 | candidate: candidate, 347 | openArgs: ['GET', candidate.urls.include, true], 348 | sendData: null, 349 | xhrModifier: null, 350 | content: candidate.content && candidate.content.content || candidate.content, 351 | oldCandidate: old 352 | }; 353 | var event = lazySizes.fire(elem, 'lazyincludeload', detail); 354 | 355 | if(event.defaultPrevented){ 356 | queue.d(); 357 | return; 358 | } 359 | 360 | include = function(){ 361 | var event, loadRequireImportCB; 362 | var status = xhrObj.status; 363 | var content = xhrObj.content || xhrObj.responseText; 364 | var reset = !!(content == null && old && old.urls.include); 365 | var detail = { 366 | candidate: candidate, 367 | content: content, 368 | text: xhrObj.responseText || xhrObj.content, 369 | response: xhrObj.response, 370 | xml: xhrObj.responseXML, 371 | isSuccess: ('status' in xhrObj) ? status >= 200 && status < 300 || status === 304 : true, 372 | oldCandidate: old, 373 | insert: true, 374 | resetHTML: reset 375 | }; 376 | var moduleObj = {target: elem, details: detail, detail: detail}; 377 | 378 | candidate.modules = modules; 379 | 380 | if(old && old.modules){ 381 | old.modules.forEach(unloadModule, moduleObj); 382 | old.modules = null; 383 | 384 | if(detail.resetHTML && detail.content == null && candidate.initial && candidate.initial.saved){ 385 | detail.content = candidate.initial.content; 386 | } 387 | } 388 | 389 | 390 | modules.forEach(transformInclude, moduleObj); 391 | 392 | event = lazySizes.fire(elem, 'lazyincludeloaded', detail); 393 | 394 | if(detail.insert && detail.isSuccess && !event.defaultPrevented && detail.content != null && detail.content != elem.innerHTML){ 395 | if(window.jQuery){ 396 | jQuery(elem).html(detail.content); 397 | } else { 398 | elem.innerHTML = detail.content; 399 | } 400 | } 401 | 402 | queue.d(); 403 | 404 | modules.forEach(loadModule, moduleObj); 405 | 406 | setTimeout(function(){ 407 | lazySizes.fire(elem, 'lazyincluded', detail); 408 | }); 409 | 410 | xhrObj = null; 411 | modules = null; 412 | }; 413 | 414 | elem.lazyInclude.current = candidate; 415 | elem.setAttribute('data-currentinclude', candidate.name); 416 | 417 | if(candidate.urls.css){ 418 | loadStyles(candidate.urls.css); 419 | } 420 | if(detail.content == null && candidate.urls.include){ 421 | loadInclude(detail, function(data){ 422 | xhrObj = data; 423 | if(modules){ 424 | include(); 425 | } 426 | }); 427 | } else { 428 | xhrObj = detail; 429 | } 430 | 431 | if(candidate.urls.amd || candidate.urls.module){ 432 | loadRequireImportCB = function(){ 433 | modules = Array.prototype.slice.call(arguments); 434 | if(xhrObj){ 435 | include(); 436 | } 437 | }; 438 | if(candidate.urls.module && window.System && System.import){ 439 | System.import(candidate.urls.module).then(loadRequireImportCB); 440 | } else if(window.require) { 441 | loadRequire(candidate.urls.amd, loadRequireImportCB); 442 | } 443 | } else { 444 | modules = []; 445 | } 446 | 447 | if(xhrObj && modules){ 448 | include(); 449 | } 450 | } 451 | 452 | function findLoadCandidate(elem){ 453 | var candidate; 454 | var includeData = getIncludeData(elem); 455 | if(!includeData.candidates.length || !docElem.contains(elem) ){return;} 456 | candidate = findCandidate(elem); 457 | if(candidate){ 458 | loadCandidate(elem, candidate); 459 | } 460 | return true; 461 | } 462 | 463 | function beforeUnveil(e){ 464 | if(e.defaultPrevented || !e.target.getAttribute('data-include')){return;} 465 | queue.q(e.target); 466 | e.detail.firesLoad = true; 467 | } 468 | 469 | addEventListener('lazybeforeunveil', beforeUnveil, false); 470 | 471 | addEventListener('resize', refreshIncludes, false); 472 | addEventListener('lazyrefreshincludes', refreshIncludes, false); 473 | 474 | })(window, document); 475 | -------------------------------------------------------------------------------- /js/lazysizes/plugins/include/ls.include.min.js: -------------------------------------------------------------------------------- 1 | /*! lazysizes - v2.0.0 */ 2 | !function(a,b){"use strict";function c(a){a.match(z)?this.urls[RegExp.$1]=t.map[RegExp.$2]||RegExp.$2:this.urls.include=t.map[a]||a}function d(a){var b,d,e;return a=a.trim(),a=t.map[a]||a,d=a.match(A),d?(e=RegExp.$1,b={condition:s.include.conditions[RegExp.$3]||s.customMedia[RegExp.$3]||RegExp.$2||null,name:RegExp.$3}):(e=a,b={condition:null,name:""}),b.urls={},(t.map[e]||e).split(y).forEach(c,b),!b.urls.include&&b.urls.amd&&(this.saved=!0,b.initial=this),b}function e(a){var b,c,e=a.getAttribute("data-include")||"",f=a.lazyInclude;return f&&f.str==e||(c={saved:!1,content:null},f={str:e,candidates:(t.map[e]||e).split(w).map(d,c)},!(b=f.candidates.length)||f.candidates[b-1].condition?(c.saved=!0,f.candidates.push({urls:{},condition:null,name:"initial",content:c})):c.saved&&1==f.candidates.length&&(c.saved=!1),f.initialContent=c,c.saved&&(c.content=a.innerHTML),a.lazyInclude=f,f.candidates.length>1?lazySizes.aC(a,"lazyconditionalinclude"):lazySizes.rC(a,"lazyconditionalinclude")),f}function f(b,c){var d=!c.condition;return c.condition&&(g(),v[c.name]?d=!0:a.matchMedia&&"string"==typeof c.condition?d=(matchMedia(c.condition)||{}).matches:"function"==typeof c.condition&&(d=c.condition(b,c))),d}function g(){var a;v||(u||(u=b.querySelector(t.contentElement)),u?(a=(E(u,":after").getPropertyValue("content")||"none").replace(B,""),v={},a&&(v[a]=1),a=(E(u,":before").getPropertyValue("content")||"none").replace(B,""),a&&(v[a]=1)):v={})}function h(a){var b,c,d=a.lazyInclude;if(d&&d.candidates)for(b=0;b=200&&300>h||304===h:!0,oldCandidate:g,insert:!0,resetHTML:j},l={target:b,details:k,detail:k};c.modules=f,g&&g.modules&&(g.modules.forEach(n,l),g.modules=null,k.resetHTML&&null==k.content&&c.initial&&c.initial.saved&&(k.content=c.initial.content)),f.forEach(m,l),d=lazySizes.fire(b,"lazyincludeloaded",k),k.insert&&k.isSuccess&&!d.defaultPrevented&&null!=k.content&&k.content!=b.innerHTML&&(a.jQuery?jQuery(b).html(k.content):b.innerHTML=k.content),F.d(),f.forEach(o,l),setTimeout(function(){lazySizes.fire(b,"lazyincluded",k)}),e=null,f=null},b.lazyInclude.current=c,b.setAttribute("data-currentinclude",c.name),c.urls.css&&l(c.urls.css),null==h.content&&c.urls.include?i(h,function(a){e=a,f&&d()}):e=h,c.urls.amd||c.urls.module?(loadRequireImportCB=function(){f=Array.prototype.slice.call(arguments),e&&d()},c.urls.module&&a.System&&System["import"]?System["import"](c.urls.module).then(loadRequireImportCB):a.require&&j(c.urls.amd,loadRequireImportCB)):f=[],void(e&&f&&d()))}function q(a){var b,c=e(a);return c.candidates.length&&C.contains(a)?(b=h(a),b&&p(a,b),!0):void 0}function r(a){!a.defaultPrevented&&a.target.getAttribute("data-include")&&(F.q(a.target),a.detail.firesLoad=!0)}if(b.getElementsByClassName){var s,t,u,v,w=/\s*,+\s+/,x={},y=/\s+/,z=/^(amd|css|module)\:(.+)/i,A=/(.+)\s+(\(\s*(.+)\s*\))/,B=/['"]/g,C=b.documentElement,D=b.getElementsByClassName("lazyconditionalinclude"),E=function(){return a.getComputedStyle.apply(a.getComputedStyle,arguments)||{getPropertyValue:function(){}}},F=function(){var a=2,b=3,c=a,d=0,e=0,f=[],g=function(){var a,b=function(){f.length&&(d=0,f.d())};return function(){clearTimeout(a),a=setTimeout(b,999)}}();return{q:function(a){var h=null==a.getAttribute("data-lazyqueue");h&&(e++,c=b),d>c?f[h?"unshift":"push"](a):q(a)&&(d++,g())},d:function(){if(d&&d--,e>0&&(e--,e||(c=a)),!(d>c)){for(;f.length;)if(q(f.shift())){d++;break}g()}}}}(),G=function(){var a,b=function(){for(var a=0,b=D.length;b>a;a++)!lazySizes.hC(D[a],s.lazyClass)&&h(D[a])&&lazySizes.aC(D[a],s.lazyClass)};return function(c){clearTimeout(a),v=null,a=setTimeout(b,"resize"==c.type?31:0)}}();s=a.lazySizes&&lazySizes.cfg||a.lazySizesConfig,s||(s={},a.lazySizesConfig=s),s.include||(s.include={}),t=s.include,t.contentElement||(t.contentElement="html"),t.conditions||(t.conditions={}),t.map||(t.map={}),addEventListener("lazybeforeunveil",r,!1),addEventListener("resize",G,!1),addEventListener("lazyrefreshincludes",G,!1)}}(window,document); -------------------------------------------------------------------------------- /js/lazysizes/plugins/noscript/ls.noscript.js: -------------------------------------------------------------------------------- 1 | (function(){ 2 | /*jshint eqnull:true */ 3 | 'use strict'; 4 | 5 | if(window.addEventListener){ 6 | var dummyParent = {nodeName: ''}; 7 | var supportPicture = !!window.HTMLPictureElement && ('sizes' in document.createElement('img')); 8 | var config = (window.lazySizes && lazySizes.cfg) || window.lazySizesConfig; 9 | 10 | var handleLoadingElements = function(e){ 11 | var i, isResponsive, hasTriggered, onload, loading; 12 | 13 | var loadElements = e.target.querySelectorAll('img, iframe'); 14 | 15 | for(i = 0; i < loadElements.length; i++){ 16 | isResponsive = loadElements[i].getAttribute('srcset') || (loadElements[i].parentNode || dummyParent).nodeName.toLowerCase() == 'picture'; 17 | 18 | if(!supportPicture && isResponsive){ 19 | lazySizes.uP(loadElements[i]); 20 | } 21 | 22 | if(!loadElements[i].complete && (isResponsive || loadElements[i].src)){ 23 | e.detail.firesLoad = true; 24 | 25 | if(!onload || !loading){ 26 | loading = 0; 27 | /*jshint loopfunc:true */ 28 | onload = function(evt){ 29 | loading--; 30 | if((!evt || loading < 1) && !hasTriggered){ 31 | hasTriggered = true; 32 | e.detail.firesLoad = false; 33 | lazySizes.fire(e.target, '_lazyloaded', {}, false, true); 34 | } 35 | 36 | if(evt && evt.target){ 37 | evt.target.removeEventListener('load', onload); 38 | evt.target.removeEventListener('error', onload); 39 | } 40 | }; 41 | 42 | setTimeout(onload, 3500); 43 | } 44 | 45 | loading++; 46 | 47 | loadElements[i].addEventListener('load', onload); 48 | loadElements[i].addEventListener('error', onload); 49 | } 50 | } 51 | }; 52 | 53 | if(!config){ 54 | config = {}; 55 | window.lazySizesConfig = config; 56 | } 57 | 58 | config.getNoscriptContent = function(noScript){ 59 | return noScript.textContent || noScript.innerText; 60 | }; 61 | 62 | addEventListener('lazybeforeunveil', function(e){ 63 | if(e.defaultPrevented || e.target.getAttribute('data-noscript') == null){return;} 64 | 65 | var noScript = e.target.querySelector('noscript, script[type*="html"]') || {}; 66 | var content = config.getNoscriptContent(noScript); 67 | 68 | if(content){ 69 | e.target.innerHTML = content; 70 | handleLoadingElements(e); 71 | } 72 | }); 73 | } 74 | })(); 75 | -------------------------------------------------------------------------------- /js/lazysizes/plugins/noscript/ls.noscript.min.js: -------------------------------------------------------------------------------- 1 | /*! lazysizes - v2.0.0 */ 2 | !function(){"use strict";if(window.addEventListener){var a={nodeName:""},b=!!window.HTMLPictureElement&&"sizes"in document.createElement("img"),c=window.lazySizes&&lazySizes.cfg||window.lazySizesConfig,d=function(c){var d,e,f,g,h,i=c.target.querySelectorAll("img, iframe");for(d=0;dh)||f||(f=!0,c.detail.firesLoad=!1,lazySizes.fire(c.target,"_lazyloaded",{},!1,!0)),a&&a.target&&(a.target.removeEventListener("load",g),a.target.removeEventListener("error",g))},setTimeout(g,3500)),h++,i[d].addEventListener("load",g),i[d].addEventListener("error",g))};c||(c={},window.lazySizesConfig=c),c.getNoscriptContent=function(a){return a.textContent||a.innerText},addEventListener("lazybeforeunveil",function(a){if(!a.defaultPrevented&&null!=a.target.getAttribute("data-noscript")){var b=a.target.querySelector('noscript, script[type*="html"]')||{},e=c.getNoscriptContent(b);e&&(a.target.innerHTML=e,d(a))}})}}(); -------------------------------------------------------------------------------- /js/lazysizes/plugins/object-fit/ls.object-fit.js: -------------------------------------------------------------------------------- 1 | (function(){ 2 | 'use strict'; 3 | var style = document.createElement('a').style; 4 | var fitSupport = 'objectFit' in style; 5 | var positionSupport = fitSupport && 'objectPosition' in style; 6 | var regCssFit = /object-fit["']*\s*:\s*["']*(contain|cover)/; 7 | var regCssPosition = /object-position["']*\s*:\s*["']*(.+?)(?=($|,|'|"|;))/; 8 | var blankSrc = 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=='; 9 | var positionDefaults = { 10 | center: 'center', 11 | '50% 50%': 'center', 12 | }; 13 | 14 | function getObject(element){ 15 | var css = (getComputedStyle(element, null) || {}); 16 | var content = css.fontFamily || ''; 17 | var objectFit = content.match(regCssFit) || ''; 18 | var objectPosition = objectFit && content.match(regCssPosition) || ''; 19 | 20 | if(objectPosition){ 21 | objectPosition = objectPosition[1]; 22 | } 23 | 24 | return { 25 | fit: objectFit && objectFit[1] || '', 26 | position: positionDefaults[objectPosition] || objectPosition || 'center', 27 | }; 28 | } 29 | 30 | function initFix(element, config){ 31 | var styleElement = element.cloneNode(false); 32 | var styleElementStyle = styleElement.style; 33 | 34 | var onChange = function(){ 35 | var src = element.currentSrc || element.src; 36 | 37 | if(src){ 38 | styleElementStyle.backgroundImage = 'url(' + src + ')'; 39 | } 40 | }; 41 | 42 | element._lazysizesParentFit = config.fit; 43 | 44 | element.addEventListener('load', function(){ 45 | lazySizes.rAF(onChange); 46 | }, true); 47 | 48 | styleElement.addEventListener('load', function(){ 49 | var curSrc = styleElement.currentSrc || styleElement.src; 50 | 51 | if(curSrc && curSrc != blankSrc){ 52 | styleElement.src = blankSrc; 53 | styleElement.srcset = ''; 54 | } 55 | }); 56 | 57 | lazySizes.rAF(function(){ 58 | 59 | var hideElement = element; 60 | var container = element.parentNode; 61 | 62 | if(container.nodeName.toLowerCase() == 'PICTURE'){ 63 | hideElement = container; 64 | container = container.parentNode; 65 | } 66 | 67 | lazySizes.rC(styleElement, lazySizes.cfg.loadingClass); 68 | lazySizes.rC(styleElement, lazySizes.cfg.loadedClass); 69 | lazySizes.rC(styleElement, lazySizes.cfg.lazyClass); 70 | lazySizes.aC(styleElement, lazySizes.cfg.objectFitClass || 'lazysizes-display-clone'); 71 | 72 | styleElement.src = blankSrc; 73 | styleElement.srcset = ''; 74 | 75 | styleElementStyle.backgroundRepeat = 'no-repeat'; 76 | styleElementStyle.backgroundPosition = config.position; 77 | styleElementStyle.backgroundSize = config.fit; 78 | 79 | hideElement.style.display = 'none'; 80 | 81 | element.setAttribute('data-parent-fit', config.fit); 82 | element.setAttribute('data-parent-container', 'prev'); 83 | 84 | container.insertBefore(styleElement, hideElement); 85 | 86 | if(element._lazysizesParentFit){ 87 | delete element._lazysizesParentFit; 88 | } 89 | 90 | if(element.complete){ 91 | onChange(); 92 | } 93 | }); 94 | } 95 | 96 | if(!fitSupport || !positionSupport){ 97 | addEventListener('lazyunveilread', function(e){ 98 | var element = e.target; 99 | var obj = getObject(element); 100 | 101 | if(obj.fit && (!fitSupport || (obj.position != 'center'))){ 102 | initFix(element, obj); 103 | } 104 | }, true); 105 | } 106 | })(); 107 | -------------------------------------------------------------------------------- /js/lazysizes/plugins/object-fit/ls.object-fit.min.js: -------------------------------------------------------------------------------- 1 | /*! lazysizes - v2.0.0 */ 2 | !function(){"use strict";function a(a){var b=getComputedStyle(a,null)||{},c=b.fontFamily||"",d=c.match(f)||"",e=d&&c.match(g)||"";return e&&(e=e[1]),{fit:d&&d[1]||"",position:i[e]||e||"center"}}function b(a,b){var c=a.cloneNode(!1),d=c.style,e=function(){var b=a.currentSrc||a.src;b&&(d.backgroundImage="url("+b+")")};a._lazysizesParentFit=b.fit,a.addEventListener("load",function(){lazySizes.rAF(e)},!0),c.addEventListener("load",function(){var a=c.currentSrc||c.src;a&&a!=h&&(c.src=h,c.srcset="")}),lazySizes.rAF(function(){var f=a,g=a.parentNode;"PICTURE"==g.nodeName.toLowerCase()&&(f=g,g=g.parentNode),lazySizes.rC(c,lazySizes.cfg.loadingClass),lazySizes.rC(c,lazySizes.cfg.loadedClass),lazySizes.rC(c,lazySizes.cfg.lazyClass),lazySizes.aC(c,lazySizes.cfg.objectFitClass||"lazysizes-display-clone"),c.src=h,c.srcset="",d.backgroundRepeat="no-repeat",d.backgroundPosition=b.position,d.backgroundSize=b.fit,f.style.display="none",a.setAttribute("data-parent-fit",b.fit),a.setAttribute("data-parent-container","prev"),g.insertBefore(c,f),a._lazysizesParentFit&&delete a._lazysizesParentFit,a.complete&&e()})}var c=document.createElement("a").style,d="objectFit"in c,e=d&&"objectPosition"in c,f=/object-fit["']*\s*:\s*["']*(contain|cover)/,g=/object-position["']*\s*:\s*["']*(.+?)(?=($|,|'|"|;))/,h="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==",i={center:"center","50% 50%":"center"};d&&e||addEventListener("lazyunveilread",function(c){var e=c.target,f=a(e);!f.fit||d&&"center"==f.position||b(e,f)},!0)}(); -------------------------------------------------------------------------------- /js/lazysizes/plugins/optimumx/ls.optimumx.js: -------------------------------------------------------------------------------- 1 | /* 2 | This lazySizes extension helps to use responsive images, but to opt-out from too high retina support in case the w descriptor is used (for x descriptor this is not needed!), 3 | - data-sizes="auto" has to be used in conjunction 4 | 5 | 14 | 15 | see a live demo here: http://afarkas.github.io/lazysizes/maxdpr/ 16 | */ 17 | 18 | (function(window, document, undefined){ 19 | /*jshint eqnull:true */ 20 | 'use strict'; 21 | if(!window.addEventListener){return;} 22 | 23 | var config; 24 | 25 | var regPicture = /^picture$/i; 26 | var docElem = document.documentElement; 27 | 28 | var parseWsrcset = (function(){ 29 | var candidates; 30 | var reg = /(([^,\s].[^\s]+)\s+(\d+)(w|h)(\s+(\d+)(w|h))?)/g; 31 | var addCandidate = function(match, candidate, url, descNumber1, descType1, fullDesc, descNumber2, descType2){ 32 | candidates.push({ 33 | c: candidate, 34 | u: url, 35 | w: (descType2 == 'w' ? descNumber2 : descNumber1) * 1 36 | }); 37 | }; 38 | 39 | return function(input){ 40 | candidates = []; 41 | input.replace(reg, addCandidate); 42 | return candidates; 43 | }; 44 | })(); 45 | 46 | var parseImg = (function(){ 47 | 48 | var ascendingSort = function ( a, b ) { 49 | return a.w - b.w; 50 | }; 51 | 52 | var parseSets = function (elem, dataName){ 53 | var lazyData = {srcset: elem.getAttribute(lazySizes.cfg.srcsetAttr) || ''}; 54 | var cands = parseWsrcset(lazyData.srcset); 55 | Object.defineProperty(elem, dataName, { 56 | value: lazyData, 57 | writable: true 58 | }); 59 | 60 | lazyData.cands = cands; 61 | 62 | lazyData.index = 0; 63 | lazyData.dirty = false; 64 | if(cands[0] && cands[0].w){ 65 | 66 | cands.sort( ascendingSort ); 67 | lazyData.cSrcset = [cands[ lazyData.index ].c]; 68 | } else { 69 | lazyData.cSrcset = lazyData.srcset ? [lazyData.srcset] : []; 70 | lazyData.cands = []; 71 | } 72 | 73 | return lazyData; 74 | }; 75 | 76 | return function parseImg(elem, dataName){ 77 | var sources, i, len, parent; 78 | 79 | 80 | if(!elem[dataName]){ 81 | parent = elem.parentNode || {}; 82 | elem[dataName] = parseSets(elem, dataName); 83 | elem[dataName].isImg = true; 84 | if(regPicture.test(parent.nodeName || '')){ 85 | elem[dataName].picture = true; 86 | sources = parent.getElementsByTagName('source'); 87 | for(i = 0, len = sources.length; i < len; i++){ 88 | parseSets(sources[i], dataName).isImg = false; 89 | } 90 | } 91 | } 92 | 93 | return elem[dataName]; 94 | }; 95 | })(); 96 | 97 | var constraintFns = { 98 | _lazyOptimumx: (function(){ 99 | var takeHighRes = function (lowerCandidate, higherCandidateResolution, optimumx){ 100 | var low, bonusFactor, substract; 101 | if(!lowerCandidate || !lowerCandidate.d){ 102 | return true; 103 | } 104 | 105 | substract = optimumx > 0.7 ? 0.6 : 0.4; 106 | 107 | if(lowerCandidate.d >= optimumx){return false;} 108 | 109 | bonusFactor = Math.pow(lowerCandidate.d - substract, 1.6) || 0.1; 110 | 111 | if(bonusFactor < 0.1){ 112 | bonusFactor = 0.1; 113 | } else if(bonusFactor > 3){ 114 | bonusFactor = 3; 115 | } 116 | 117 | low = lowerCandidate.d + ((higherCandidateResolution - optimumx) * bonusFactor); 118 | 119 | return low < optimumx; 120 | }; 121 | 122 | return function (data, width, optimumx){ 123 | var i, can; 124 | 125 | for(i = 0; i < data.cands.length; i++){ 126 | can = data.cands[i]; 127 | can.d = (can.w || 1) / width; 128 | 129 | if(data.index >= i){continue;} 130 | 131 | if(can.d <= optimumx || takeHighRes(data.cands[i - 1], can.d, optimumx)){ 132 | data.cSrcset.push(can.c); 133 | data.index = i; 134 | } else { 135 | break; 136 | } 137 | } 138 | }; 139 | })() 140 | }; 141 | 142 | var constrainSets = (function(){ 143 | 144 | var constrainSet = function(elem, displayWidth, optimumx, attr, dataName){ 145 | var curIndex; 146 | var lazyData = elem[dataName]; 147 | 148 | if(!lazyData){return;} 149 | curIndex = lazyData.index; 150 | 151 | constraintFns[dataName](lazyData, displayWidth, optimumx); 152 | 153 | if(!lazyData.dirty || curIndex != lazyData.index){ 154 | lazyData.cSrcset.join(', '); 155 | elem.setAttribute(attr, lazyData.cSrcset.join(', ')); 156 | lazyData.dirty = true; 157 | } 158 | }; 159 | 160 | return function(image, displayWidth, optimumx, attr, dataName){ 161 | var sources, parent, len, i; 162 | var lazyData = image[dataName]; 163 | 164 | lazyData.width = displayWidth; 165 | 166 | if(lazyData.picture && (parent = image.parentNode)){ 167 | sources = parent.getElementsByTagName('source'); 168 | for(i = 0, len = sources.length; i < len; i++){ 169 | constrainSet(sources[i], displayWidth, optimumx, attr, dataName); 170 | } 171 | } 172 | 173 | constrainSet(image, displayWidth, optimumx, attr, dataName); 174 | }; 175 | })(); 176 | 177 | var getOptimumX = function(element){ 178 | var optimumx = element.getAttribute('data-optimumx') || element.getAttribute('data-maxdpr'); 179 | 180 | if(!optimumx && config.constrainPixelDensity){ 181 | optimumx = 'auto'; 182 | } 183 | 184 | if(optimumx){ 185 | if(optimumx == 'auto'){ 186 | optimumx = config.getOptimumX(element); 187 | } else { 188 | optimumx = parseFloat(optimumx, 10); 189 | } 190 | } 191 | return optimumx; 192 | }; 193 | 194 | var extentLazySizes = function(){ 195 | if(window.lazySizes && !window.lazySizes.getOptimumX){ 196 | lazySizes.getX = getOptimumX; 197 | lazySizes.pWS = parseWsrcset; 198 | docElem.removeEventListener('lazybeforeunveil', extentLazySizes); 199 | } 200 | }; 201 | 202 | docElem.addEventListener('lazybeforeunveil', extentLazySizes); 203 | setTimeout(extentLazySizes); 204 | 205 | config = (window.lazySizes && lazySizes.cfg) || window.lazySizesConfig; 206 | 207 | if(!config){ 208 | config = {}; 209 | window.lazySizesConfig = config; 210 | } 211 | 212 | if(typeof config.getOptimumX != 'function'){ 213 | config.getOptimumX = function(/*element*/){ 214 | var dpr = window.devicePixelRatio || 1; 215 | if(dpr > 2.6){ 216 | dpr *= 0.6; // returns 1.8 for 3 217 | } else if(dpr > 1.9){ 218 | dpr *= 0.8; // returns 1.6 for 2 219 | } else { 220 | dpr -= 0.01; // returns 0.99 for 1 221 | } 222 | return Math.min(Math.round(dpr * 100) / 100, 2); 223 | }; 224 | } 225 | 226 | if(!window.devicePixelRatio){return;} 227 | 228 | addEventListener('lazybeforesizes', function(e){ 229 | var optimumx, lazyData, width, attr; 230 | 231 | var elem = e.target; 232 | var detail = e.detail; 233 | var dataAttr = detail.dataAttr; 234 | 235 | if(e.defaultPrevented || 236 | !(optimumx = getOptimumX(elem)) || 237 | optimumx >= devicePixelRatio){return;} 238 | 239 | if(dataAttr && elem._lazyOptimumx && !detail.reloaded && (!config.unloadedClass || !lazySizes.hC(elem, config.unloadedClass))){ 240 | elem._lazyOptimumx = null; 241 | } 242 | 243 | lazyData = parseImg(elem, '_lazyOptimumx'); 244 | 245 | width = detail.width; 246 | 247 | if(width && (lazyData.width || 0) < width){ 248 | attr = dataAttr ? lazySizes.cfg.srcsetAttr : 'srcset'; 249 | 250 | lazySizes.rAF(function(){ 251 | constrainSets(elem, width, optimumx, attr, '_lazyOptimumx'); 252 | }); 253 | } 254 | }); 255 | 256 | })(window, document); 257 | -------------------------------------------------------------------------------- /js/lazysizes/plugins/optimumx/ls.optimumx.min.js: -------------------------------------------------------------------------------- 1 | /*! lazysizes - v2.0.0 */ 2 | !function(a,b,c){"use strict";if(a.addEventListener){var d,e=/^picture$/i,f=b.documentElement,g=function(){var a,b=/(([^,\s].[^\s]+)\s+(\d+)(w|h)(\s+(\d+)(w|h))?)/g,c=function(b,c,d,e,f,g,h,i){a.push({c:c,u:d,w:1*("w"==i?h:e)})};return function(d){return a=[],d.replace(b,c),a}}(),h=function(){var a=function(a,b){return a.w-b.w},b=function(b,c){var d={srcset:b.getAttribute(lazySizes.cfg.srcsetAttr)||""},e=g(d.srcset);return Object.defineProperty(b,c,{value:d,writable:!0}),d.cands=e,d.index=0,d.dirty=!1,e[0]&&e[0].w?(e.sort(a),d.cSrcset=[e[d.index].c]):(d.cSrcset=d.srcset?[d.srcset]:[],d.cands=[]),d};return function(a,c){var d,f,g,h;if(!a[c]&&(h=a.parentNode||{},a[c]=b(a,c),a[c].isImg=!0,e.test(h.nodeName||"")))for(a[c].picture=!0,d=h.getElementsByTagName("source"),f=0,g=d.length;g>f;f++)b(d[f],c).isImg=!1;return a[c]}}(),i={_lazyOptimumx:function(){var a=function(a,b,c){var d,e,f;return a&&a.d?(f=c>.7?.6:.4,a.d>=c?!1:(e=Math.pow(a.d-f,1.6)||.1,.1>e?e=.1:e>3&&(e=3),d=a.d+(b-c)*e,c>d)):!0};return function(b,c,d){var e,f;for(e=0;e=e)){if(!(f.d<=d||a(b.cands[e-1],f.d,d)))break;b.cSrcset.push(f.c),b.index=e}}}()},j=function(){var a=function(a,b,c,d,e){var f,g=a[e];g&&(f=g.index,i[e](g,b,c),g.dirty&&f==g.index||(g.cSrcset.join(", "),a.setAttribute(d,g.cSrcset.join(", ")),g.dirty=!0))};return function(b,c,d,e,f){var g,h,i,j,k=b[f];if(k.width=c,k.picture&&(h=b.parentNode))for(g=h.getElementsByTagName("source"),j=0,i=g.length;i>j;j++)a(g[j],c,d,e,f);a(b,c,d,e,f)}}(),k=function(a){var b=a.getAttribute("data-optimumx")||a.getAttribute("data-maxdpr");return!b&&d.constrainPixelDensity&&(b="auto"),b&&(b="auto"==b?d.getOptimumX(a):parseFloat(b,10)),b},l=function(){a.lazySizes&&!a.lazySizes.getOptimumX&&(lazySizes.getX=k,lazySizes.pWS=g,f.removeEventListener("lazybeforeunveil",l))};f.addEventListener("lazybeforeunveil",l),setTimeout(l),d=a.lazySizes&&lazySizes.cfg||a.lazySizesConfig,d||(d={},a.lazySizesConfig=d),"function"!=typeof d.getOptimumX&&(d.getOptimumX=function(){var b=a.devicePixelRatio||1;return b>2.6?b*=.6:b>1.9?b*=.8:b-=.01,Math.min(Math.round(100*b)/100,2)}),a.devicePixelRatio&&addEventListener("lazybeforesizes",function(a){var b,c,e,f,g=a.target,i=a.detail,l=i.dataAttr;a.defaultPrevented||!(b=k(g))||b>=devicePixelRatio||(!l||!g._lazyOptimumx||i.reloaded||d.unloadedClass&&lazySizes.hC(g,d.unloadedClass)||(g._lazyOptimumx=null),c=h(g,"_lazyOptimumx"),e=i.width,e&&(c.width||0) 40 && (displayRatio = width / height) && ((fit == 'cover' && displayRatio < imageRatio) || (fit == 'contain' && displayRatio > imageRatio))){ 126 | retWidth = width * (imageRatio / displayRatio); 127 | } 128 | } 129 | 130 | return retWidth; 131 | } 132 | }; 133 | 134 | var extend = function(){ 135 | if(window.lazySizes){ 136 | if(!lazySizes.parentFit){ 137 | lazySizes.parentFit = parentFit; 138 | } 139 | window.removeEventListener('lazyunveilread', extend, true); 140 | } 141 | }; 142 | 143 | window.addEventListener('lazyunveilread', extend, true); 144 | 145 | document.addEventListener('lazybeforesizes', function(e){ 146 | if(e.defaultPrevented){return;} 147 | var element = e.target; 148 | e.detail.width = parentFit.calculateSize(element, e.detail.width); 149 | }); 150 | 151 | setTimeout(extend); 152 | 153 | })(window, document); 154 | -------------------------------------------------------------------------------- /js/lazysizes/plugins/parent-fit/ls.parent-fit.min.js: -------------------------------------------------------------------------------- 1 | /*! lazysizes - v2.0.0 */ 2 | !function(a,b){"use strict";if(a.addEventListener){var c=/\s+(\d+)(w|h)\s+(\d+)(w|h)/,d=/parent-fit["']*\s*:\s*["']*(contain|cover|width)/,e=/parent-container["']*\s*:\s*["']*(.+?)(?=(\s|$|,|'|"|;))/,f=/^picture$/i,g=function(a){return getComputedStyle(a,null)||{}},h={getParent:function(b,c){var d=b,e=b.parentNode;return c&&"prev"!=c||!e||!f.test(e.nodeName||"")||(e=e.parentNode),"self"!=c&&(d="prev"==c?b.previousElementSibling:c&&(e.closest||a.jQuery)?(e.closest?e.closest(c):jQuery(e).closest(c)[0])||e:e),d},getFit:function(a){var b,c,f=g(a),i=f.content||f.fontFamily,j={fit:a._lazysizesParentFit||a.getAttribute("data-parent-fit")};return!j.fit&&i&&(b=i.match(d))&&(j.fit=b[1]),j.fit?(c=a._lazysizesParentContainer||a.getAttribute("data-parent-container"),!c&&i&&(b=i.match(e))&&(c=b[1]),j.parent=h.getParent(a,c)):j.fit=f.objectFit,j},getImageRatio:function(b){var d,e,g,h,i=b.parentNode,j=i&&f.test(i.nodeName||"")?i.querySelectorAll("source, img"):[b];for(d=0;d40&&(c=b/d)&&("cover"==h&&e>c||"contain"==h&&c>e)&&(f=b*(e/c))),f):b}},i=function(){a.lazySizes&&(lazySizes.parentFit||(lazySizes.parentFit=h),a.removeEventListener("lazyunveilread",i,!0))};a.addEventListener("lazyunveilread",i,!0),b.addEventListener("lazybeforesizes",function(a){if(!a.defaultPrevented){var b=a.target;a.detail.width=h.calculateSize(b,a.detail.width)}}),setTimeout(i)}}(window,document); -------------------------------------------------------------------------------- /js/lazysizes/plugins/print/ls.print.js: -------------------------------------------------------------------------------- 1 | /* 2 | This lazySizes extension adds better support for print. 3 | In case the user starts to print lazysizes will load all images. 4 | */ 5 | (function(window){ 6 | /*jshint eqnull:true */ 7 | 'use strict'; 8 | var config, elements, onprint, printMedia; 9 | // see also: http://tjvantoll.com/2012/06/15/detecting-print-requests-with-javascript/ 10 | if(window.addEventListener){ 11 | config = (window.lazySizes && lazySizes.cfg) || window.lazySizesConfig || {}; 12 | elements = config.lazyClass || 'lazyload'; 13 | onprint = function(){ 14 | var i, len; 15 | if(typeof elements == 'string'){ 16 | elements = document.getElementsByClassName(elements); 17 | } 18 | 19 | if(window.lazySizes){ 20 | for(i = 0, len = elements.length; i < len; i++){ 21 | lazySizes.loader.unveil(elements[i]); 22 | } 23 | } 24 | }; 25 | 26 | addEventListener('beforeprint', onprint, false); 27 | 28 | if(!('onbeforeprint' in window) && window.matchMedia && (printMedia = matchMedia('print')) && printMedia.addListener){ 29 | printMedia.addListener(function(){ 30 | if(printMedia.matches){ 31 | onprint(); 32 | } 33 | }); 34 | } 35 | } 36 | })(window); 37 | -------------------------------------------------------------------------------- /js/lazysizes/plugins/print/ls.print.min.js: -------------------------------------------------------------------------------- 1 | /*! lazysizes - v2.0.0 */ 2 | !function(a){"use strict";var b,c,d,e;a.addEventListener&&(b=a.lazySizes&&lazySizes.cfg||a.lazySizesConfig||{},c=b.lazyClass||"lazyload",d=function(){var b,d;if("string"==typeof c&&(c=document.getElementsByClassName(c)),a.lazySizes)for(b=0,d=c.length;d>b;b++)lazySizes.loader.unveil(c[b])},addEventListener("beforeprint",d,!1),!("onbeforeprint"in a)&&a.matchMedia&&(e=matchMedia("print"))&&e.addListener&&e.addListener(function(){e.matches&&d()}))}(window); -------------------------------------------------------------------------------- /js/lazysizes/plugins/progressive/ls.progressive.js: -------------------------------------------------------------------------------- 1 | /* 2 | This lazysizes plugin optimizes perceived performance by adding better support for rendering progressive JPGs/PNGs in conjunction with the LQIP pattern. 3 | */ 4 | (function(document){ 5 | /*jshint eqnull:true */ 6 | 'use strict'; 7 | var regImg, onLoad; 8 | 9 | if('srcset' in document.createElement('img')){ 10 | regImg = /^img$/i; 11 | 12 | onLoad = function(e){ 13 | e.target.style.backgroundSize = ''; 14 | e.target.style.backgroundImage = ''; 15 | e.target.removeEventListener(e.type, onLoad); 16 | }; 17 | 18 | document.addEventListener('lazybeforeunveil', function(e){ 19 | var img = e.target; 20 | if(!regImg.test(img.nodeName)){ 21 | return; 22 | } 23 | var src = img.getAttribute('src'); 24 | if(src) { 25 | img.style.backgroundSize = '100% 100%'; 26 | img.style.backgroundImage = 'url(' + src + ')'; 27 | img.removeAttribute('src'); 28 | img.addEventListener('load', onLoad); 29 | } 30 | }, false); 31 | } 32 | })(document); 33 | -------------------------------------------------------------------------------- /js/lazysizes/plugins/progressive/ls.progressive.min.js: -------------------------------------------------------------------------------- 1 | /*! lazysizes - v2.0.0 */ 2 | !function(a){"use strict";var b,c;"srcset"in a.createElement("img")&&(b=/^img$/i,c=function(a){a.target.style.backgroundSize="",a.target.style.backgroundImage="",a.target.removeEventListener(a.type,c)},a.addEventListener("lazybeforeunveil",function(a){var d=a.target;if(b.test(d.nodeName)){var e=d.getAttribute("src");e&&(d.style.backgroundSize="100% 100%",d.style.backgroundImage="url("+e+")",d.removeAttribute("src"),d.addEventListener("load",c))}},!1))}(document); -------------------------------------------------------------------------------- /js/lazysizes/plugins/respimg/ls.respimg.js: -------------------------------------------------------------------------------- 1 | (function(window, document, undefined){ 2 | /*jshint eqnull:true */ 3 | 'use strict'; 4 | var polyfill; 5 | var config = (window.lazySizes && lazySizes.cfg) || window.lazySizesConfig; 6 | var img = document.createElement('img'); 7 | var supportSrcset = ('sizes' in img) && ('srcset' in img); 8 | var regHDesc = /\s+\d+h/g; 9 | var fixEdgeHDescriptor = (function(){ 10 | var regDescriptors = /\s+(\d+)(w|h)\s+(\d+)(w|h)/; 11 | var forEach = Array.prototype.forEach; 12 | 13 | return function(edgeMatch){ 14 | var img = document.createElement('img'); 15 | var removeHDescriptors = function(source){ 16 | var ratio; 17 | var srcset = source.getAttribute(lazySizesConfig.srcsetAttr); 18 | if(srcset){ 19 | if(srcset.match(regDescriptors)){ 20 | if(RegExp.$2 == 'w'){ 21 | ratio = RegExp.$1 / RegExp.$3; 22 | } else { 23 | ratio = RegExp.$3 / RegExp.$1; 24 | } 25 | 26 | if(ratio){ 27 | source.setAttribute('data-aspectratio', ratio); 28 | } 29 | } 30 | source.setAttribute(lazySizesConfig.srcsetAttr, srcset.replace(regHDesc, '')); 31 | } 32 | }; 33 | var handler = function(e){ 34 | var picture = e.target.parentNode; 35 | 36 | if(picture && picture.nodeName == 'PICTURE'){ 37 | forEach.call(picture.getElementsByTagName('source'), removeHDescriptors); 38 | } 39 | removeHDescriptors(e.target); 40 | }; 41 | 42 | var test = function(){ 43 | if(!!img.currentSrc){ 44 | document.removeEventListener('lazybeforeunveil', handler); 45 | } 46 | }; 47 | 48 | if(edgeMatch[1]){ 49 | document.addEventListener('lazybeforeunveil', handler); 50 | 51 | if(true || edgeMatch[1] > 14){ 52 | img.onload = test; 53 | img.onerror = test; 54 | 55 | img.srcset = 'data:,a 1w 1h'; 56 | 57 | if(img.complete){ 58 | test(); 59 | } 60 | } 61 | } 62 | }; 63 | })(); 64 | 65 | 66 | if(!config){ 67 | config = {}; 68 | window.lazySizesConfig = config; 69 | } 70 | 71 | if(!config.supportsType){ 72 | config.supportsType = function(type/*, elem*/){ 73 | return !type; 74 | }; 75 | } 76 | 77 | if(window.picturefill || config.pf){return;} 78 | 79 | if(window.HTMLPictureElement && supportSrcset){ 80 | 81 | if(document.msElementsFromPoint){ 82 | fixEdgeHDescriptor(navigator.userAgent.match(/Edge\/(\d+)/)); 83 | } 84 | 85 | config.pf = function(){}; 86 | return; 87 | } 88 | 89 | config.pf = function(options){ 90 | var i, len; 91 | if(window.picturefill){return;} 92 | for(i = 0, len = options.elements.length; i < len; i++){ 93 | polyfill(options.elements[i]); 94 | } 95 | }; 96 | 97 | // partial polyfill 98 | polyfill = (function(){ 99 | var ascendingSort = function( a, b ) { 100 | return a.w - b.w; 101 | }; 102 | var regPxLength = /^\s*\d+px\s*$/; 103 | var reduceCandidate = function (srces) { 104 | var lowerCandidate, bonusFactor; 105 | var len = srces.length; 106 | var candidate = srces[len -1]; 107 | var i = 0; 108 | 109 | for(i; i < len;i++){ 110 | candidate = srces[i]; 111 | candidate.d = candidate.w / srces.w; 112 | 113 | if(candidate.d >= srces.d){ 114 | if(!candidate.cached && (lowerCandidate = srces[i - 1]) && 115 | lowerCandidate.d > srces.d - (0.13 * Math.pow(srces.d, 2.2))){ 116 | 117 | bonusFactor = Math.pow(lowerCandidate.d - 0.6, 1.6); 118 | 119 | if(lowerCandidate.cached) { 120 | lowerCandidate.d += 0.15 * bonusFactor; 121 | } 122 | 123 | if(lowerCandidate.d + ((candidate.d - srces.d) * bonusFactor) > srces.d){ 124 | candidate = lowerCandidate; 125 | } 126 | } 127 | break; 128 | } 129 | } 130 | return candidate; 131 | }; 132 | 133 | var parseWsrcset = (function(){ 134 | var candidates; 135 | var regWCandidates = /(([^,\s].[^\s]+)\s+(\d+)w)/g; 136 | var regMultiple = /\s/; 137 | var addCandidate = function(match, candidate, url, wDescriptor){ 138 | candidates.push({ 139 | c: candidate, 140 | u: url, 141 | w: wDescriptor * 1 142 | }); 143 | }; 144 | 145 | return function(input){ 146 | candidates = []; 147 | input = input.trim(); 148 | input 149 | .replace(regHDesc, '') 150 | .replace(regWCandidates, addCandidate) 151 | ; 152 | 153 | if(!candidates.length && input && !regMultiple.test(input)){ 154 | candidates.push({ 155 | c: input, 156 | u: input, 157 | w: 99 158 | }); 159 | } 160 | 161 | return candidates; 162 | }; 163 | })(); 164 | 165 | var runMatchMedia = function(){ 166 | if(runMatchMedia.init){return;} 167 | 168 | runMatchMedia.init = true; 169 | addEventListener('resize', (function(){ 170 | var timer; 171 | var matchMediaElems = document.getElementsByClassName('lazymatchmedia'); 172 | var run = function(){ 173 | var i, len; 174 | for(i = 0, len = matchMediaElems.length; i < len; i++){ 175 | polyfill(matchMediaElems[i]); 176 | } 177 | }; 178 | 179 | return function(){ 180 | clearTimeout(timer); 181 | timer = setTimeout(run, 66); 182 | }; 183 | })()); 184 | }; 185 | 186 | var createSrcset = function(elem, isImage){ 187 | var parsedSet; 188 | var srcSet = elem.getAttribute('srcset') || elem.getAttribute(config.srcsetAttr); 189 | 190 | if(!srcSet && isImage){ 191 | srcSet = !elem._lazypolyfill ? 192 | (elem.getAttribute('src') || elem.getAttribute(config.srcAttr)) : 193 | elem._lazypolyfill._set 194 | ; 195 | } 196 | 197 | if(!elem._lazypolyfill || elem._lazypolyfill._set != srcSet){ 198 | 199 | parsedSet = parseWsrcset( srcSet || '' ); 200 | if(isImage && elem.parentNode){ 201 | parsedSet.isPicture = elem.parentNode.nodeName.toUpperCase() == 'PICTURE'; 202 | 203 | if(parsedSet.isPicture){ 204 | if(window.matchMedia || (window.Modernizr && Modernizr.mq)){ 205 | lazySizes.aC(elem, 'lazymatchmedia'); 206 | runMatchMedia(); 207 | } 208 | } 209 | } 210 | 211 | parsedSet._set = srcSet; 212 | Object.defineProperty(elem, '_lazypolyfill', { 213 | value: parsedSet, 214 | writable: true 215 | }); 216 | } 217 | }; 218 | 219 | var getX = function(elem){ 220 | var dpr = window.devicePixelRatio || 1; 221 | var optimum = lazySizes.getX && lazySizes.getX(elem); 222 | return Math.min(optimum || dpr, 2.5, dpr); 223 | }; 224 | 225 | var matchesMedia = function(media){ 226 | if(window.matchMedia){ 227 | matchesMedia = function(media){ 228 | return !media || (matchMedia(media) || {}).matches; 229 | }; 230 | } else if(window.Modernizr && Modernizr.mq){ 231 | return !media || Modernizr.mq(media); 232 | } else { 233 | return !media; 234 | } 235 | 236 | return matchesMedia(media); 237 | }; 238 | 239 | var getCandidate = function(elem){ 240 | var sources, i, len, media, source, srces, src, width; 241 | 242 | source = elem; 243 | createSrcset(source, true); 244 | srces = source._lazypolyfill; 245 | 246 | if(srces.isPicture){ 247 | for(i = 0, sources = elem.parentNode.getElementsByTagName('source'), len = sources.length; i < len; i++){ 248 | if( config.supportsType(sources[i].getAttribute('type'), elem) && matchesMedia( sources[i].getAttribute('media')) ){ 249 | source = sources[i]; 250 | createSrcset(source); 251 | srces = source._lazypolyfill; 252 | break; 253 | } 254 | } 255 | } 256 | 257 | if(srces.length > 1){ 258 | width = source.getAttribute('sizes') || ''; 259 | width = regPxLength.test(width) && parseInt(width, 10) || lazySizes.gW(elem, elem.parentNode); 260 | srces.d = getX(elem); 261 | if(!srces.w || srces.w < width){ 262 | srces.w = width; 263 | src = reduceCandidate(srces.sort(ascendingSort)); 264 | } 265 | } else { 266 | src = srces[0]; 267 | } 268 | 269 | return src; 270 | }; 271 | 272 | var p = function(elem){ 273 | if(supportSrcset && elem.parentNode && elem.parentNode.nodeName.toUpperCase() != 'PICTURE'){return;} 274 | var candidate = getCandidate(elem); 275 | 276 | if(candidate && candidate.u && elem._lazypolyfill.cur != candidate.u){ 277 | elem._lazypolyfill.cur = candidate.u; 278 | candidate.cached = true; 279 | elem.setAttribute(config.srcAttr, candidate.u); 280 | elem.setAttribute('src', candidate.u); 281 | } 282 | }; 283 | 284 | p.parse = parseWsrcset; 285 | 286 | return p; 287 | })(); 288 | 289 | if(config.loadedClass && config.loadingClass){ 290 | (function(){ 291 | var sels = []; 292 | ['img[sizes$="px"][srcset].', 'picture > img:not([srcset]).'].forEach(function(sel){ 293 | sels.push(sel + config.loadedClass); 294 | sels.push(sel + config.loadingClass); 295 | }); 296 | config.pf({ 297 | elements: document.querySelectorAll(sels.join(', ')) 298 | }); 299 | })(); 300 | 301 | } 302 | })(window, document); 303 | 304 | /** 305 | * Some versions of iOS (8.1-) do load the first candidate of a srcset candidate list, if width descriptors with the sizes attribute is used. 306 | * This tiny extension prevents this wasted download by creating a picture structure around the image. 307 | * Note: This extension is already included in the ls.respimg.js file. 308 | * 309 | * Usage: 310 | * 311 | * 318 | */ 319 | 320 | (function(document){ 321 | 'use strict'; 322 | var regPicture; 323 | var img = document.createElement('img'); 324 | 325 | if(('srcset' in img) && !('sizes' in img) && !window.HTMLPictureElement){ 326 | regPicture = /^picture$/i; 327 | document.addEventListener('lazybeforeunveil', function(e){ 328 | var elem, parent, srcset, sizes, isPicture; 329 | var picture, source; 330 | if(e.defaultPrevented || 331 | lazySizesConfig.noIOSFix || 332 | !(elem = e.target) || 333 | !(srcset = elem.getAttribute(lazySizesConfig.srcsetAttr)) || 334 | !(parent = elem.parentNode) || 335 | ( 336 | !(isPicture = regPicture.test(parent.nodeName || '')) && 337 | !(sizes = elem.getAttribute('sizes') || elem.getAttribute(lazySizesConfig.sizesAttr)) 338 | ) 339 | ){return;} 340 | 341 | picture = isPicture ? parent : document.createElement('picture'); 342 | 343 | if(!elem._lazyImgSrc){ 344 | Object.defineProperty(elem, '_lazyImgSrc', { 345 | value: document.createElement('source'), 346 | writable: true 347 | }); 348 | } 349 | source = elem._lazyImgSrc; 350 | 351 | if(sizes){ 352 | source.setAttribute('sizes', sizes); 353 | } 354 | 355 | source.setAttribute(lazySizesConfig.srcsetAttr, srcset); 356 | elem.setAttribute('data-pfsrcset', srcset); 357 | elem.removeAttribute(lazySizesConfig.srcsetAttr); 358 | 359 | if(!isPicture){ 360 | parent.insertBefore(picture, elem); 361 | picture.appendChild(elem); 362 | } 363 | picture.insertBefore(source, elem); 364 | }); 365 | } 366 | })(document); 367 | -------------------------------------------------------------------------------- /js/lazysizes/plugins/respimg/ls.respimg.min.js: -------------------------------------------------------------------------------- 1 | /*! lazysizes - v2.0.0 */ 2 | !function(a,b,c){"use strict";var d,e=a.lazySizes&&lazySizes.cfg||a.lazySizesConfig,f=b.createElement("img"),g="sizes"in f&&"srcset"in f,h=/\s+\d+h/g,i=function(){var a=/\s+(\d+)(w|h)\s+(\d+)(w|h)/,c=Array.prototype.forEach;return function(d){var e=b.createElement("img"),f=function(b){var c,d=b.getAttribute(lazySizesConfig.srcsetAttr);d&&(d.match(a)&&(c="w"==RegExp.$2?RegExp.$1/RegExp.$3:RegExp.$3/RegExp.$1,c&&b.setAttribute("data-aspectratio",c)),b.setAttribute(lazySizesConfig.srcsetAttr,d.replace(h,"")))},g=function(a){var b=a.target.parentNode;b&&"PICTURE"==b.nodeName&&c.call(b.getElementsByTagName("source"),f),f(a.target)},i=function(){e.currentSrc&&b.removeEventListener("lazybeforeunveil",g)};d[1]&&(b.addEventListener("lazybeforeunveil",g),e.onload=i,e.onerror=i,e.srcset="data:,a 1w 1h",e.complete&&i())}}();if(e||(e={},a.lazySizesConfig=e),e.supportsType||(e.supportsType=function(a){return!a}),!a.picturefill&&!e.pf){if(a.HTMLPictureElement&&g)return b.msElementsFromPoint&&i(navigator.userAgent.match(/Edge\/(\d+)/)),void(e.pf=function(){});e.pf=function(b){var c,e;if(!a.picturefill)for(c=0,e=b.elements.length;e>c;c++)d(b.elements[c])},d=function(){var c=function(a,b){return a.w-b.w},f=/^\s*\d+px\s*$/,i=function(a){var b,c,d=a.length,e=a[d-1],f=0;for(f;d>f;f++)if(e=a[f],e.d=e.w/a.w,e.d>=a.d){!e.cached&&(b=a[f-1])&&b.d>a.d-.13*Math.pow(a.d,2.2)&&(c=Math.pow(b.d-.6,1.6),b.cached&&(b.d+=.15*c),b.d+(e.d-a.d)*c>a.d&&(e=b));break}return e},j=function(){var a,b=/(([^,\s].[^\s]+)\s+(\d+)w)/g,c=/\s/,d=function(b,c,d,e){a.push({c:c,u:d,w:1*e})};return function(e){return a=[],e=e.trim(),e.replace(h,"").replace(b,d),a.length||!e||c.test(e)||a.push({c:e,u:e,w:99}),a}}(),k=function(){k.init||(k.init=!0,addEventListener("resize",function(){var a,c=b.getElementsByClassName("lazymatchmedia"),e=function(){var a,b;for(a=0,b=c.length;b>a;a++)d(c[a])};return function(){clearTimeout(a),a=setTimeout(e,66)}}()))},l=function(b,c){var d,f=b.getAttribute("srcset")||b.getAttribute(e.srcsetAttr);!f&&c&&(f=b._lazypolyfill?b._lazypolyfill._set:b.getAttribute("src")||b.getAttribute(e.srcAttr)),b._lazypolyfill&&b._lazypolyfill._set==f||(d=j(f||""),c&&b.parentNode&&(d.isPicture="PICTURE"==b.parentNode.nodeName.toUpperCase(),d.isPicture&&(a.matchMedia||a.Modernizr&&Modernizr.mq)&&(lazySizes.aC(b,"lazymatchmedia"),k())),d._set=f,Object.defineProperty(b,"_lazypolyfill",{value:d,writable:!0}))},m=function(b){var c=a.devicePixelRatio||1,d=lazySizes.getX&&lazySizes.getX(b);return Math.min(d||c,2.5,c)},n=function(b){return a.matchMedia?(n=function(a){return!a||(matchMedia(a)||{}).matches})(b):a.Modernizr&&Modernizr.mq?!b||Modernizr.mq(b):!b},o=function(a){var b,d,g,h,j,k,o;if(h=a,l(h,!0),j=h._lazypolyfill,j.isPicture)for(d=0,b=a.parentNode.getElementsByTagName("source"),g=b.length;g>d;d++)if(e.supportsType(b[d].getAttribute("type"),a)&&n(b[d].getAttribute("media"))){h=b[d],l(h),j=h._lazypolyfill;break}return j.length>1?(o=h.getAttribute("sizes")||"",o=f.test(o)&&parseInt(o,10)||lazySizes.gW(a,a.parentNode),j.d=m(a),(!j.w||j.w img:not([srcset])."].forEach(function(b){a.push(b+e.loadedClass),a.push(b+e.loadingClass)}),e.pf({elements:b.querySelectorAll(a.join(", "))})}()}}(window,document),function(a){"use strict";var b,c=a.createElement("img");!("srcset"in c)||"sizes"in c||window.HTMLPictureElement||(b=/^picture$/i,a.addEventListener("lazybeforeunveil",function(c){var d,e,f,g,h,i,j;!c.defaultPrevented&&!lazySizesConfig.noIOSFix&&(d=c.target)&&(f=d.getAttribute(lazySizesConfig.srcsetAttr))&&(e=d.parentNode)&&((h=b.test(e.nodeName||""))||(g=d.getAttribute("sizes")||d.getAttribute(lazySizesConfig.sizesAttr)))&&(i=h?e:a.createElement("picture"),d._lazyImgSrc||Object.defineProperty(d,"_lazyImgSrc",{value:a.createElement("source"),writable:!0}),j=d._lazyImgSrc,g&&j.setAttribute("sizes",g),j.setAttribute(lazySizesConfig.srcsetAttr,f),d.setAttribute("data-pfsrcset",f),d.removeAttribute(lazySizesConfig.srcsetAttr),h||(e.insertBefore(i,d),i.appendChild(d)),i.insertBefore(j,d))}))}(document); -------------------------------------------------------------------------------- /js/lazysizes/plugins/rias/ls.rias.js: -------------------------------------------------------------------------------- 1 | (function(window, document, undefined){ 2 | /*jshint eqnull:true */ 3 | 'use strict'; 4 | 5 | if(!document.addEventListener){return;} 6 | 7 | var config, riasCfg; 8 | var replaceTypes = {string: 1, number: 1}; 9 | var regNumber = /^\-*\+*\d+\.*\d*$/; 10 | var regPicture = /^picture$/i; 11 | var regWidth = /\s*\{\s*width\s*\}\s*/i; 12 | var regHeight = /\s*\{\s*height\s*\}\s*/i; 13 | var regPlaceholder = /\s*\{\s*([a-z0-9]+)\s*\}\s*/ig; 14 | var regObj = /^\[.*\]|\{.*\}$/; 15 | var regAllowedSizes = /^(?:auto|\d+(px)?)$/; 16 | var anchor = document.createElement('a'); 17 | var img = document.createElement('img'); 18 | var buggySizes = ('srcset' in img) && !('sizes' in img); 19 | var supportPicture = !!window.HTMLPictureElement && !buggySizes; 20 | 21 | (function(){ 22 | var prop; 23 | var noop = function(){}; 24 | var riasDefaults = { 25 | prefix: '', 26 | postfix: '', 27 | srcAttr: 'data-src', 28 | absUrl: false, 29 | modifyOptions: noop, 30 | widthmap: {}, 31 | ratio: false 32 | }; 33 | 34 | config = (window.lazySizes && lazySizes.cfg) || window.lazySizesConfig; 35 | 36 | if(!config){ 37 | config = {}; 38 | window.lazySizesConfig = config; 39 | } 40 | 41 | if(!config.supportsType){ 42 | config.supportsType = function(type/*, elem*/){ 43 | return !type; 44 | }; 45 | } 46 | 47 | if(!config.rias){ 48 | config.rias = {}; 49 | } 50 | riasCfg = config.rias; 51 | 52 | if(!('widths' in riasCfg)){ 53 | riasCfg.widths = []; 54 | (function (widths){ 55 | var width; 56 | var i = 0; 57 | while(!width || width < 3000){ 58 | i += 5; 59 | if(i > 30){ 60 | i += 1; 61 | } 62 | width = (36 * i); 63 | widths.push(width); 64 | } 65 | })(riasCfg.widths); 66 | } 67 | 68 | for(prop in riasDefaults){ 69 | if(!(prop in riasCfg)){ 70 | riasCfg[prop] = riasDefaults[prop]; 71 | } 72 | } 73 | })(); 74 | 75 | function getElementOptions(elem, src){ 76 | var attr, parent, setOption, options; 77 | 78 | 79 | parent = elem.parentNode; 80 | options = { 81 | isPicture: !!(parent && regPicture.test(parent.nodeName || '')) 82 | }; 83 | 84 | setOption = function(attr, run){ 85 | var attrVal = elem.getAttribute('data-'+ attr); 86 | 87 | if(attrVal != null){ 88 | if(attrVal == 'true'){ 89 | attrVal = true; 90 | } else if(attrVal == 'false'){ 91 | attrVal = false; 92 | } else if(regNumber.test(attrVal)){ 93 | attrVal = parseFloat(attrVal); 94 | } else if(typeof riasCfg[attr] == 'function'){ 95 | attrVal = riasCfg[attr](elem, attrVal); 96 | } else if(regObj.test(attrVal)){ 97 | try { 98 | attrVal = JSON.parse(attrVal); 99 | } catch(e){} 100 | } 101 | options[attr] = attrVal; 102 | } else if((attr in riasCfg) && typeof riasCfg[attr] != 'function'){ 103 | options[attr] = riasCfg[attr]; 104 | } else if(run && typeof riasCfg[attr] == 'function'){ 105 | options[attr] = riasCfg[attr](elem, attrVal); 106 | } 107 | }; 108 | 109 | for(attr in riasCfg){ 110 | setOption(attr); 111 | } 112 | src.replace(regPlaceholder, function(full, match){ 113 | if(!(match in options)){ 114 | setOption(match, true); 115 | } 116 | }); 117 | 118 | return options; 119 | } 120 | 121 | function replaceUrlProps(url, options){ 122 | var candidates = []; 123 | var replaceFn = function(full, match){ 124 | return (replaceTypes[typeof options[match]]) ? options[match] : full; 125 | }; 126 | candidates.srcset = []; 127 | 128 | if(options.absUrl){ 129 | anchor.setAttribute('href', url); 130 | url = anchor.href; 131 | } 132 | 133 | url = ((options.prefix || '') + url + (options.postfix || '')).replace(regPlaceholder, replaceFn); 134 | 135 | options.widths.forEach(function(width){ 136 | var widthAlias = options.widthmap[width] || width; 137 | var candidate = { 138 | u: url.replace(regWidth, widthAlias) 139 | .replace(regHeight, options.ratio ? Math.round(width * options.ratio) : ''), 140 | w: width 141 | }; 142 | 143 | candidates.push(candidate); 144 | candidates.srcset.push( (candidate.c = candidate.u + ' ' + width + 'w') ); 145 | }); 146 | return candidates; 147 | } 148 | 149 | function setSrc(src, opts, elem){ 150 | var elemW = 0; 151 | var elemH = 0; 152 | var sizeElement = elem; 153 | 154 | if(!src){return;} 155 | 156 | if (opts.ratio === 'container') { 157 | // calculate image or parent ratio 158 | elemW = sizeElement.scrollWidth; 159 | elemH = sizeElement.scrollHeight; 160 | 161 | while ((!elemW || !elemH) && sizeElement !== document) { 162 | sizeElement = sizeElement.parentNode; 163 | elemW = sizeElement.scrollWidth; 164 | elemH = sizeElement.scrollHeight; 165 | } 166 | if (elemW && elemH) { 167 | opts.ratio = elemH / elemW; 168 | } 169 | } 170 | 171 | src = replaceUrlProps(src, opts); 172 | 173 | src.isPicture = opts.isPicture; 174 | 175 | if(buggySizes && elem.nodeName.toUpperCase() == 'IMG'){ 176 | elem.removeAttribute(config.srcsetAttr); 177 | } else { 178 | elem.setAttribute(config.srcsetAttr, src.srcset.join(', ')); 179 | } 180 | 181 | Object.defineProperty(elem, '_lazyrias', { 182 | value: src, 183 | writable: true 184 | }); 185 | } 186 | 187 | function createAttrObject(elem, src){ 188 | var opts = getElementOptions(elem, src); 189 | 190 | riasCfg.modifyOptions.call(elem, {target: elem, details: opts, detail: opts}); 191 | 192 | lazySizes.fire(elem, 'lazyriasmodifyoptions', opts); 193 | return opts; 194 | } 195 | 196 | function getSrc(elem){ 197 | return elem.getAttribute( elem.getAttribute('data-srcattr') || riasCfg.srcAttr ) || elem.getAttribute(config.srcsetAttr) || elem.getAttribute(config.srcAttr) || elem.getAttribute('data-pfsrcset') || ''; 198 | } 199 | 200 | addEventListener('lazybeforesizes', function(e){ 201 | var elem, src, elemOpts, parent, sources, i, len, sourceSrc, sizes, detail, hasPlaceholder, modified, emptyList; 202 | elem = e.target; 203 | 204 | if(!e.detail.dataAttr || e.defaultPrevented || riasCfg.disabled || !((sizes = elem.getAttribute(config.sizesAttr) || elem.getAttribute('sizes')) && regAllowedSizes.test(sizes))){return;} 205 | 206 | src = getSrc(elem); 207 | 208 | elemOpts = createAttrObject(elem, src); 209 | 210 | hasPlaceholder = regWidth.test(elemOpts.prefix) || regWidth.test(elemOpts.postfix); 211 | 212 | if(elemOpts.isPicture && (parent = elem.parentNode)){ 213 | sources = parent.getElementsByTagName('source'); 214 | for(i = 0, len = sources.length; i < len; i++){ 215 | if ( hasPlaceholder || regWidth.test(sourceSrc = getSrc(sources[i])) ){ 216 | setSrc(sourceSrc, elemOpts, sources[i]); 217 | modified = true; 218 | } 219 | } 220 | } 221 | 222 | if ( hasPlaceholder || regWidth.test(src) ){ 223 | setSrc(src, elemOpts, elem); 224 | modified = true; 225 | } else if (modified) { 226 | emptyList = []; 227 | emptyList.srcset = []; 228 | emptyList.isPicture = true; 229 | Object.defineProperty(elem, '_lazyrias', { 230 | value: emptyList, 231 | writable: true 232 | }); 233 | } 234 | 235 | if(modified){ 236 | if(supportPicture){ 237 | elem.removeAttribute(config.srcAttr); 238 | } else if(sizes != 'auto') { 239 | detail = { 240 | width: parseInt(sizes, 10) 241 | }; 242 | polyfill({ 243 | target: elem, 244 | detail: detail 245 | }); 246 | } 247 | } 248 | }, true); 249 | // partial polyfill 250 | var polyfill = (function(){ 251 | var ascendingSort = function( a, b ) { 252 | return a.w - b.w; 253 | }; 254 | 255 | var reduceCandidate = function (srces) { 256 | var lowerCandidate, bonusFactor; 257 | var len = srces.length; 258 | var candidate = srces[len -1]; 259 | var i = 0; 260 | 261 | for(i; i < len;i++){ 262 | candidate = srces[i]; 263 | candidate.d = candidate.w / srces.w; 264 | if(candidate.d >= srces.d){ 265 | if(!candidate.cached && (lowerCandidate = srces[i - 1]) && 266 | lowerCandidate.d > srces.d - (0.13 * Math.pow(srces.d, 2.2))){ 267 | 268 | bonusFactor = Math.pow(lowerCandidate.d - 0.6, 1.6); 269 | 270 | if(lowerCandidate.cached) { 271 | lowerCandidate.d += 0.15 * bonusFactor; 272 | } 273 | 274 | if(lowerCandidate.d + ((candidate.d - srces.d) * bonusFactor) > srces.d){ 275 | candidate = lowerCandidate; 276 | } 277 | } 278 | break; 279 | } 280 | } 281 | return candidate; 282 | }; 283 | 284 | var getWSet = function(elem, testPicture){ 285 | var src; 286 | if(!elem._lazyrias && lazySizes.pWS && (src = lazySizes.pWS(elem.getAttribute(config.srcsetAttr || ''))).length){ 287 | Object.defineProperty(elem, '_lazyrias', { 288 | value: src, 289 | writable: true 290 | }); 291 | if(testPicture && elem.parentNode){ 292 | src.isPicture = elem.parentNode.nodeName.toUpperCase() == 'PICTURE'; 293 | } 294 | } 295 | return elem._lazyrias; 296 | }; 297 | 298 | var getX = function(elem){ 299 | var dpr = window.devicePixelRatio || 1; 300 | var optimum = lazySizes.getX && lazySizes.getX(elem); 301 | return Math.min(optimum || dpr, 2.4, dpr); 302 | }; 303 | 304 | var getCandidate = function(elem, width){ 305 | var sources, i, len, media, srces, src; 306 | 307 | srces = elem._lazyrias; 308 | 309 | if(srces.isPicture && window.matchMedia){ 310 | for(i = 0, sources = elem.parentNode.getElementsByTagName('source'), len = sources.length; i < len; i++){ 311 | if(getWSet(sources[i]) && !sources[i].getAttribute('type') && ( !(media = sources[i].getAttribute('media')) || ((matchMedia(media) || {}).matches))){ 312 | srces = sources[i]._lazyrias; 313 | break; 314 | } 315 | } 316 | } 317 | 318 | if(!srces.w || srces.w < width){ 319 | srces.w = width; 320 | srces.d = getX(elem); 321 | src = reduceCandidate(srces.sort(ascendingSort)); 322 | } 323 | 324 | return src; 325 | }; 326 | 327 | var polyfill = function(e){ 328 | var candidate; 329 | var elem = e.target; 330 | 331 | if(!buggySizes && (window.respimage || window.picturefill || lazySizesConfig.pf)){ 332 | document.removeEventListener('lazybeforesizes', polyfill); 333 | return; 334 | } 335 | 336 | if(!('_lazyrias' in elem) && (!e.detail.dataAttr || !getWSet(elem, true))){ 337 | return; 338 | } 339 | 340 | candidate = getCandidate(elem, e.detail.width); 341 | 342 | if(candidate && candidate.u && elem._lazyrias.cur != candidate.u){ 343 | elem._lazyrias.cur = candidate.u; 344 | candidate.cached = true; 345 | lazySizes.rAF(function(){ 346 | elem.setAttribute(config.srcAttr, candidate.u); 347 | elem.setAttribute('src', candidate.u); 348 | }); 349 | } 350 | }; 351 | 352 | if(!supportPicture){ 353 | addEventListener('lazybeforesizes', polyfill); 354 | } else { 355 | polyfill = function(){}; 356 | } 357 | 358 | return polyfill; 359 | 360 | })(); 361 | 362 | })(window, document); 363 | -------------------------------------------------------------------------------- /js/lazysizes/plugins/rias/ls.rias.min.js: -------------------------------------------------------------------------------- 1 | /*! lazysizes - v2.0.0 */ 2 | !function(a,b,c){"use strict";function d(a,b){var c,d,e,f;d=a.parentNode,f={isPicture:!(!d||!m.test(d.nodeName||""))},e=function(b,c){var d=a.getAttribute("data-"+b);if(null!=d){if("true"==d)d=!0;else if("false"==d)d=!1;else if(l.test(d))d=parseFloat(d);else if("function"==typeof j[b])d=j[b](a,d);else if(q.test(d))try{d=JSON.parse(d)}catch(e){}f[b]=d}else b in j&&"function"!=typeof j[b]?f[b]=j[b]:c&&"function"==typeof j[b]&&(f[b]=j[b](a,d))};for(c in j)e(c);return b.replace(p,function(a,b){b in f||e(b,!0)}),f}function e(a,b){var c=[],d=function(a,c){return k[typeof b[c]]?b[c]:a};return c.srcset=[],b.absUrl&&(s.setAttribute("href",a),a=s.href),a=((b.prefix||"")+a+(b.postfix||"")).replace(p,d),b.widths.forEach(function(d){var e=b.widthmap[d]||d,f={u:a.replace(n,e).replace(o,b.ratio?Math.round(d*b.ratio):""),w:d};c.push(f),c.srcset.push(f.c=f.u+" "+d+"w")}),c}function f(a,c,d){var f=0,g=0,h=d;if(a){if("container"===c.ratio){for(f=h.scrollWidth,g=h.scrollHeight;!(f&&g||h===b);)h=h.parentNode,f=h.scrollWidth,g=h.scrollHeight;f&&g&&(c.ratio=g/f)}a=e(a,c),a.isPicture=c.isPicture,u&&"IMG"==d.nodeName.toUpperCase()?d.removeAttribute(i.srcsetAttr):d.setAttribute(i.srcsetAttr,a.srcset.join(", ")),Object.defineProperty(d,"_lazyrias",{value:a,writable:!0})}}function g(a,b){var c=d(a,b);return j.modifyOptions.call(a,{target:a,details:c,detail:c}),lazySizes.fire(a,"lazyriasmodifyoptions",c),c}function h(a){return a.getAttribute(a.getAttribute("data-srcattr")||j.srcAttr)||a.getAttribute(i.srcsetAttr)||a.getAttribute(i.srcAttr)||a.getAttribute("data-pfsrcset")||""}if(b.addEventListener){var i,j,k={string:1,number:1},l=/^\-*\+*\d+\.*\d*$/,m=/^picture$/i,n=/\s*\{\s*width\s*\}\s*/i,o=/\s*\{\s*height\s*\}\s*/i,p=/\s*\{\s*([a-z0-9]+)\s*\}\s*/gi,q=/^\[.*\]|\{.*\}$/,r=/^(?:auto|\d+(px)?)$/,s=b.createElement("a"),t=b.createElement("img"),u="srcset"in t&&!("sizes"in t),v=!!a.HTMLPictureElement&&!u;!function(){var b,c=function(){},d={prefix:"",postfix:"",srcAttr:"data-src",absUrl:!1,modifyOptions:c,widthmap:{},ratio:!1};i=a.lazySizes&&lazySizes.cfg||a.lazySizesConfig,i||(i={},a.lazySizesConfig=i),i.supportsType||(i.supportsType=function(a){return!a}),i.rias||(i.rias={}),j=i.rias,"widths"in j||(j.widths=[],function(a){for(var b,c=0;!b||3e3>b;)c+=5,c>30&&(c+=1),b=36*c,a.push(b)}(j.widths));for(b in d)b in j||(j[b]=d[b])}(),addEventListener("lazybeforesizes",function(a){var b,c,d,e,k,l,m,o,p,q,s,t,u;if(b=a.target,a.detail.dataAttr&&!a.defaultPrevented&&!j.disabled&&(p=b.getAttribute(i.sizesAttr)||b.getAttribute("sizes"))&&r.test(p)){if(c=h(b),d=g(b,c),s=n.test(d.prefix)||n.test(d.postfix),d.isPicture&&(e=b.parentNode))for(k=e.getElementsByTagName("source"),l=0,m=k.length;m>l;l++)(s||n.test(o=h(k[l])))&&(f(o,d,k[l]),t=!0);s||n.test(c)?(f(c,d,b),t=!0):t&&(u=[],u.srcset=[],u.isPicture=!0,Object.defineProperty(b,"_lazyrias",{value:u,writable:!0})),t&&(v?b.removeAttribute(i.srcAttr):"auto"!=p&&(q={width:parseInt(p,10)},w({target:b,detail:q})))}},!0);var w=function(){var c=function(a,b){return a.w-b.w},d=function(a){var b,c,d=a.length,e=a[d-1],f=0;for(f;d>f;f++)if(e=a[f],e.d=e.w/a.w,e.d>=a.d){!e.cached&&(b=a[f-1])&&b.d>a.d-.13*Math.pow(a.d,2.2)&&(c=Math.pow(b.d-.6,1.6),b.cached&&(b.d+=.15*c),b.d+(e.d-a.d)*c>a.d&&(e=b));break}return e},e=function(a,b){var c;return!a._lazyrias&&lazySizes.pWS&&(c=lazySizes.pWS(a.getAttribute(i.srcsetAttr||""))).length&&(Object.defineProperty(a,"_lazyrias",{value:c,writable:!0}),b&&a.parentNode&&(c.isPicture="PICTURE"==a.parentNode.nodeName.toUpperCase())),a._lazyrias},f=function(b){var c=a.devicePixelRatio||1,d=lazySizes.getX&&lazySizes.getX(b);return Math.min(d||c,2.4,c)},g=function(b,g){var h,i,j,k,l,m;if(l=b._lazyrias,l.isPicture&&a.matchMedia)for(i=0,h=b.parentNode.getElementsByTagName("source"),j=h.length;j>i;i++)if(e(h[i])&&!h[i].getAttribute("type")&&(!(k=h[i].getAttribute("media"))||(matchMedia(k)||{}).matches)){l=h[i]._lazyrias;break}return(!l.w||l.w img._pfLastSize) { 26 | img._pfLastSize = img.offsetWidth; 27 | sizes = img.sizes; 28 | img.sizes += ",100vw"; 29 | setTimeout(function() { 30 | img.sizes = sizes; 31 | }); 32 | } 33 | }; 34 | 35 | var findPictureImgs = function() { 36 | var i; 37 | var imgs = document.querySelectorAll("picture > img, img[srcset][sizes]"); 38 | for (i = 0; i < imgs.length; i++) { 39 | fixRespimg(imgs[i]); 40 | } 41 | }; 42 | var onResize = function() { 43 | clearTimeout(timer); 44 | timer = setTimeout(findPictureImgs, 99); 45 | }; 46 | var mq = window.matchMedia && matchMedia("(orientation: landscape)"); 47 | var init = function() { 48 | onResize(); 49 | 50 | if (mq && mq.addListener) { 51 | mq.addListener(onResize); 52 | } 53 | }; 54 | 55 | dummySrc.srcset = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="; 56 | 57 | if (/^[c|i]|d$/.test(document.readyState || "")) { 58 | init(); 59 | } else { 60 | document.addEventListener("DOMContentLoaded", init); 61 | } 62 | 63 | return onResize; 64 | })()); 65 | } 66 | })(window); 67 | -------------------------------------------------------------------------------- /js/lazysizes/plugins/static-gecko-picture/ls.static-gecko-picture.min.js: -------------------------------------------------------------------------------- 1 | /*! lazysizes - v2.0.0 */ 2 | !function(a){var b=navigator.userAgent;a.HTMLPictureElement&&/ecko/.test(b)&&b.match(/rv\:(\d+)/)&&RegExp.$1<41&&addEventListener("resize",function(){var b,c=document.createElement("source"),d=function(a){var b,d,e=a.parentNode;"PICTURE"===e.nodeName.toUpperCase()?(b=c.cloneNode(),e.insertBefore(b,e.firstElementChild),setTimeout(function(){e.removeChild(b)})):(!a._pfLastSize||a.offsetWidth>a._pfLastSize)&&(a._pfLastSize=a.offsetWidth,d=a.sizes,a.sizes+=",100vw",setTimeout(function(){a.sizes=d}))},e=function(){var a,b=document.querySelectorAll("picture > img, img[srcset][sizes]");for(a=0;a vBottom || box.bottom < vTop || box.left > vRight || box.right < vLeft) || 21 | (config.unloadHidden && !box.top && !box.bottom && !box.left && !box.right)){ 22 | unloadElements.push(checkElements[i]); 23 | } 24 | } 25 | requestAnimationFrame(unloader.unloadElements); 26 | }, 27 | unload: function(element){ 28 | var sources, isResponsive, i, len; 29 | var picture = element.parentNode; 30 | lazySizes.rC(element, config.loadedClass); 31 | 32 | if(element.getAttribute(config.srcsetAttr)){ 33 | element.setAttribute('srcset', config.emptySrc); 34 | isResponsive = true; 35 | } 36 | 37 | if(picture && picture.nodeName.toUpperCase() == 'PICTURE'){ 38 | sources = picture.getElementsByTagName('source'); 39 | 40 | for(i = 0, len = sources.length; i < len; i++){ 41 | sources[i].setAttribute('srcset', config.emptySrc); 42 | } 43 | 44 | isResponsive = true; 45 | } 46 | 47 | if(lazySizes.hC(element, config.autosizesClass)){ 48 | lazySizes.rC(element, config.autosizesClass); 49 | element.setAttribute(config.sizesAttr, 'auto'); 50 | } 51 | 52 | if(isResponsive || element.getAttribute(config.srcAttr)){ 53 | element.src = config.emptySrc; 54 | } 55 | 56 | lazySizes.aC(element, config.unloadedClass); 57 | lazySizes.aC(element, config.lazyClass); 58 | lazySizes.fire(element, 'lazyafterunload'); 59 | }, 60 | unloadElements: function(elements){ 61 | elements = Array.isArray(elements) ? elements : unloadElements; 62 | 63 | while(elements.length){ 64 | unloader.unload(elements.shift()); 65 | } 66 | }, 67 | _reload: function(e) { 68 | if(lazySizes.hC(e.target, config.unloadedClass) && e.detail){ 69 | e.detail.reloaded = true; 70 | lazySizes.rC(e.target, config.unloadedClass); 71 | } 72 | } 73 | }; 74 | 75 | function init(){ 76 | if(!window.lazySizes || checkElements){return;} 77 | var docElem = document.documentElement; 78 | var throttleRun = (function(){ 79 | var running; 80 | var run = function(){ 81 | unloader.checkElements(); 82 | running = false; 83 | }; 84 | return function(){ 85 | if(!running){ 86 | running = true; 87 | setTimeout(run, 999); 88 | } 89 | }; 90 | })(); 91 | 92 | config = lazySizes.cfg; 93 | removeEventListener('lazybeforeunveil', init); 94 | 95 | if(!('unloadClass' in config)){ 96 | config.unloadClass = 'lazyunload'; 97 | } 98 | 99 | if(!('unloadedClass' in config)){ 100 | config.unloadedClass = 'lazyunloaded'; 101 | } 102 | 103 | if(!('unloadHidden' in config)){ 104 | config.unloadHidden = true; 105 | } 106 | 107 | if(!('emptySrc' in config)){ 108 | config.emptySrc = 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=='; 109 | } 110 | 111 | if(!('autoUnload' in config)){ 112 | config.autoUnload = true; 113 | } 114 | 115 | if(!('unloadPixelThreshold' in config)){ 116 | config.unloadPixelThreshold = 60000; 117 | } 118 | 119 | if(config.autoUnload){ 120 | docElem.addEventListener('load', function(e){ 121 | if(e.target.naturalWidth * e.target.naturalHeight > config.unloadPixelThreshold && e.target.className && 122 | e.target.className.indexOf && e.target.className.indexOf(lazySizesConfig.loadingClass) != -1 && 123 | e.target.className.indexOf(lazySizesConfig.preloadClass) == -1){ 124 | lazySizes.aC(e.target, lazySizesConfig.unloadClass); 125 | } 126 | }, true); 127 | } 128 | 129 | lazySizes.unloader = unloader; 130 | 131 | expand = ((config.expand * config.expFactor) + 99) * 1.1; 132 | checkElements = document.getElementsByClassName([config.unloadClass, config.loadedClass].join(' ')); 133 | 134 | setInterval(throttleRun, 9999); 135 | addEventListener('lazybeforeunveil', throttleRun); 136 | addEventListener('lazybeforeunveil', unloader._reload, true); 137 | } 138 | 139 | addEventListener('lazybeforeunveil', init); 140 | })(window, document); 141 | -------------------------------------------------------------------------------- /js/lazysizes/plugins/unload/ls.unload.min.js: -------------------------------------------------------------------------------- 1 | /*! lazysizes - v2.0.0 */ 2 | !function(a,b,c){"use strict";function d(){if(a.lazySizes&&!f){var c=b.documentElement,h=function(){var a,b=function(){j.checkElements(),a=!1};return function(){a||(a=!0,setTimeout(b,999))}}();e=lazySizes.cfg,removeEventListener("lazybeforeunveil",d),"unloadClass"in e||(e.unloadClass="lazyunload"),"unloadedClass"in e||(e.unloadedClass="lazyunloaded"),"unloadHidden"in e||(e.unloadHidden=!0),"emptySrc"in e||(e.emptySrc="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="),"autoUnload"in e||(e.autoUnload=!0),"unloadPixelThreshold"in e||(e.unloadPixelThreshold=6e4),e.autoUnload&&c.addEventListener("load",function(a){a.target.naturalWidth*a.target.naturalHeight>e.unloadPixelThreshold&&a.target.className&&a.target.className.indexOf&&-1!=a.target.className.indexOf(lazySizesConfig.loadingClass)&&-1==a.target.className.indexOf(lazySizesConfig.preloadClass)&&lazySizes.aC(a.target,lazySizesConfig.unloadClass)},!0),lazySizes.unloader=j,g=1.1*(e.expand*e.expFactor+99),f=b.getElementsByClassName([e.unloadClass,e.loadedClass].join(" ")),setInterval(h,9999),addEventListener("lazybeforeunveil",h),addEventListener("lazybeforeunveil",j._reload,!0)}}if(b.addEventListener){var e,f,g,h=[],i=a.requestAnimationFrame||setTimeout,j={checkElements:function(){var a,b,c,d=-1*g,k=d,l=innerHeight+g,m=innerWidth+g;for(a=0,b=f.length;b>a;a++)c=f[a].getBoundingClientRect(),(c.top>l||c.bottomm||c.rightd;d++)b[d].setAttribute("srcset",e.emptySrc);c=!0}lazySizes.hC(a,e.autosizesClass)&&(lazySizes.rC(a,e.autosizesClass),a.setAttribute(e.sizesAttr,"auto")),(c||a.getAttribute(e.srcAttr))&&(a.src=e.emptySrc),lazySizes.aC(a,e.unloadedClass),lazySizes.aC(a,e.lazyClass),lazySizes.fire(a,"lazyafterunload")},unloadElements:function(a){for(a=Array.isArray(a)?a:h;a.length;)j.unload(a.shift())},_reload:function(a){lazySizes.hC(a.target,e.unloadedClass)&&a.detail&&(a.detail.reloaded=!0,lazySizes.rC(a.target,e.unloadedClass))}};addEventListener("lazybeforeunveil",d)}}(window,document); -------------------------------------------------------------------------------- /js/lazysizes/plugins/unveilhooks/ls.unveilhooks.js: -------------------------------------------------------------------------------- 1 | /* 2 | This plugin extends lazySizes to lazyLoad: 3 | background images, videos/posters and scripts 4 | 5 | Background-Image: 6 | For background images, use data-bg attribute: 7 |
8 | 9 | Video: 10 | For video/audio use data-poster and preload="none": 11 | 14 | 15 | Scripts: 16 | For scripts use data-script: 17 |
18 | 19 | 20 | Script modules using require: 21 | For modules using require use data-require: 22 |
23 | */ 24 | 25 | (function(window, document){ 26 | /*jshint eqnull:true */ 27 | 'use strict'; 28 | var bgLoad; 29 | var uniqueUrls = {}; 30 | 31 | if(document.addEventListener){ 32 | 33 | bgLoad = function (url, cb){ 34 | var img = document.createElement('img'); 35 | img.onload = function(){ 36 | img.onload = null; 37 | img.onerror = null; 38 | img = null; 39 | cb(); 40 | }; 41 | img.onerror = img.onload; 42 | 43 | img.src = url; 44 | 45 | if(img && img.complete && img.onload){ 46 | img.onload(); 47 | } 48 | }; 49 | 50 | addEventListener('lazybeforeunveil', function(e){ 51 | var tmp, load, bg, poster; 52 | if(!e.defaultPrevented) { 53 | 54 | if(e.target.preload == 'none'){ 55 | e.target.preload = 'auto'; 56 | } 57 | 58 | tmp = e.target.getAttribute('data-link'); 59 | if(tmp){ 60 | addStyleScript(tmp, true); 61 | } 62 | 63 | // handle data-script 64 | tmp = e.target.getAttribute('data-script'); 65 | if(tmp){ 66 | addStyleScript(tmp); 67 | } 68 | 69 | // handle data-require 70 | tmp = e.target.getAttribute('data-require'); 71 | if(tmp){ 72 | if(window.require){ 73 | require([tmp]); 74 | } 75 | } 76 | 77 | // handle data-bg 78 | bg = e.target.getAttribute('data-bg'); 79 | if (bg) { 80 | e.detail.firesLoad = true; 81 | load = function(){ 82 | e.target.style.backgroundImage = 'url(' + bg + ')'; 83 | e.detail.firesLoad = false; 84 | lazySizes.fire(e.target, '_lazyloaded', {}, true, true); 85 | }; 86 | 87 | bgLoad(bg, load); 88 | } 89 | 90 | // handle data-poster 91 | poster = e.target.getAttribute('data-poster'); 92 | if(poster){ 93 | e.detail.firesLoad = true; 94 | load = function(){ 95 | e.target.poster = poster; 96 | e.detail.firesLoad = false; 97 | lazySizes.fire(e.target, '_lazyloaded', {}, true, true); 98 | }; 99 | 100 | bgLoad(poster, load); 101 | 102 | } 103 | } 104 | }, false); 105 | 106 | } 107 | 108 | function addStyleScript(src, style){ 109 | if(uniqueUrls[src]){ 110 | return; 111 | } 112 | var elem = document.createElement(style ? 'link' : 'script'); 113 | var insertElem = document.getElementsByTagName('script')[0]; 114 | 115 | if(style){ 116 | elem.rel = 'stylesheet'; 117 | elem.href = src; 118 | } else { 119 | elem.src = src; 120 | } 121 | uniqueUrls[src] = true; 122 | uniqueUrls[elem.src || elem.href] = true; 123 | insertElem.parentNode.insertBefore(elem, insertElem); 124 | } 125 | })(window, document); 126 | -------------------------------------------------------------------------------- /js/lazysizes/plugins/unveilhooks/ls.unveilhooks.min.js: -------------------------------------------------------------------------------- 1 | /*! lazysizes - v2.0.0 */ 2 | !function(a,b){"use strict";function c(a,c){if(!e[a]){var d=b.createElement(c?"link":"script"),f=b.getElementsByTagName("script")[0];c?(d.rel="stylesheet",d.href=a):d.src=a,e[a]=!0,e[d.src||d.href]=!0,f.parentNode.insertBefore(d,f)}}var d,e={};b.addEventListener&&(d=function(a,c){var d=b.createElement("img");d.onload=function(){d.onload=null,d.onerror=null,d=null,c()},d.onerror=d.onload,d.src=a,d&&d.complete&&d.onload&&d.onload()},addEventListener("lazybeforeunveil",function(b){var e,f,g,h;b.defaultPrevented||("none"==b.target.preload&&(b.target.preload="auto"),e=b.target.getAttribute("data-link"),e&&c(e,!0),e=b.target.getAttribute("data-script"),e&&c(e),e=b.target.getAttribute("data-require"),e&&a.require&&require([e]),g=b.target.getAttribute("data-bg"),g&&(b.detail.firesLoad=!0,f=function(){b.target.style.backgroundImage="url("+g+")",b.detail.firesLoad=!1,lazySizes.fire(b.target,"_lazyloaded",{},!0,!0)},d(g,f)),h=b.target.getAttribute("data-poster"),h&&(b.detail.firesLoad=!0,f=function(){b.target.poster=h,b.detail.firesLoad=!1,lazySizes.fire(b.target,"_lazyloaded",{},!0,!0)},d(h,f)))},!1))}(window,document); -------------------------------------------------------------------------------- /js/lazysizes/plugins/video-embed/ls.video-embed.js: -------------------------------------------------------------------------------- 1 | (function(window, document){ 2 | /*jshint eqnull:true */ 3 | 'use strict'; 4 | if(!document.getElementsByClassName){return;} 5 | var protocol = location.protocol == 'https:' ? 6 | 'https:' : 7 | 'http:' 8 | ; 9 | var idIndex = Date.now(); 10 | var regId = /\{\{id}}/; 11 | var regAmp = /^&/; 12 | var youtubeImg = protocol + '//img.youtube.com/vi/{{id}}/sddefault.jpg'; 13 | var youtubeIframe = protocol + '//www.youtube.com/embed/{{id}}?autoplay=1'; 14 | var vimeoApi = protocol + '//vimeo.com/api/oembed.json?url=https%3A//vimeo.com/{{id}}'; 15 | var vimeoIframe = protocol + '//player.vimeo.com/video/{{id}}?autoplay=1'; 16 | 17 | function getJSON(url, callback){ 18 | var id = 'vimeoCallback' + idIndex; 19 | var script = document.createElement('script'); 20 | url += '&callback='+id; 21 | 22 | idIndex++; 23 | 24 | window[id] = function(data){ 25 | script.parentNode.removeChild(script); 26 | delete window[id]; 27 | callback(data); 28 | }; 29 | 30 | script.src = url; 31 | 32 | document.head.appendChild(script); 33 | } 34 | 35 | function embedVimeoImg(id, elem){ 36 | getJSON(vimeoApi.replace(regId, id), function(data){ 37 | if(data && data.thumbnail_url){ 38 | elem.style.backgroundImage = 'url('+ data.thumbnail_url +')'; 39 | } 40 | }); 41 | elem.addEventListener('click', embedVimeoIframe); 42 | } 43 | 44 | function embedVimeoIframe(e){ 45 | var elem = e.currentTarget; 46 | var id = elem.getAttribute('data-vimeo'); 47 | var vimeoParams = elem.getAttribute('data-vimeoparams') || ''; 48 | 49 | if(vimeoParams && !regAmp.test(vimeoParams)){ 50 | vimeoParams = '&'+ vimeoParams; 51 | } 52 | 53 | e.preventDefault(); 54 | 55 | elem.innerHTML = '' 57 | ; 58 | 59 | elem.removeEventListener('click', embedVimeoIframe); 60 | } 61 | 62 | function embedYoutubeImg(id, elem){ 63 | elem.style.backgroundImage = 'url('+ youtubeImg.replace(regId, id) +')'; 64 | elem.addEventListener('click', embedYoutubeIframe); 65 | } 66 | 67 | function embedYoutubeIframe(e){ 68 | var elem = e.currentTarget; 69 | var id = elem.getAttribute('data-youtube'); 70 | var youtubeParams = elem.getAttribute('data-ytparams') || ''; 71 | 72 | if(youtubeParams && !regAmp.test(youtubeParams)){ 73 | youtubeParams = '&'+ youtubeParams; 74 | } 75 | 76 | e.preventDefault(); 77 | 78 | elem.innerHTML = '' 80 | ; 81 | 82 | elem.removeEventListener('click', embedYoutubeIframe); 83 | } 84 | 85 | document.addEventListener('lazybeforeunveil', function(e){ 86 | var elem = e.target; 87 | var youtube = elem.getAttribute('data-youtube'); 88 | var vimeo = elem.getAttribute('data-vimeo'); 89 | 90 | if(youtube && elem){ 91 | embedYoutubeImg(youtube, elem); 92 | } 93 | if(vimeo && elem){ 94 | embedVimeoImg(vimeo, elem); 95 | } 96 | }); 97 | })(window, document); 98 | -------------------------------------------------------------------------------- /js/lazysizes/plugins/video-embed/ls.video-embed.min.js: -------------------------------------------------------------------------------- 1 | /*! lazysizes - v2.0.0 */ 2 | !function(a,b){"use strict";function c(c,d){var e="vimeoCallback"+i,f=b.createElement("script");c+="&callback="+e,i++,a[e]=function(b){f.parentNode.removeChild(f),delete a[e],d(b)},f.src=c,b.head.appendChild(f)}function d(a,b){c(n.replace(j,a),function(a){a&&a.thumbnail_url&&(b.style.backgroundImage="url("+a.thumbnail_url+")")}),b.addEventListener("click",e)}function e(a){var b=a.currentTarget,c=b.getAttribute("data-vimeo"),d=b.getAttribute("data-vimeoparams")||"";d&&!k.test(d)&&(d="&"+d),a.preventDefault(),b.innerHTML='',b.removeEventListener("click",e)}function f(a,b){b.style.backgroundImage="url("+l.replace(j,a)+")",b.addEventListener("click",g)}function g(a){var b=a.currentTarget,c=b.getAttribute("data-youtube"),d=b.getAttribute("data-ytparams")||"";d&&!k.test(d)&&(d="&"+d),a.preventDefault(),b.innerHTML='',b.removeEventListener("click",g)}if(b.getElementsByClassName){var h="https:"==location.protocol?"https:":"http:",i=Date.now(),j=/\{\{id}}/,k=/^&/,l=h+"//img.youtube.com/vi/{{id}}/sddefault.jpg",m=h+"//www.youtube.com/embed/{{id}}?autoplay=1",n=h+"//vimeo.com/api/oembed.json?url=https%3A//vimeo.com/{{id}}",o=h+"//player.vimeo.com/video/{{id}}?autoplay=1";b.addEventListener("lazybeforeunveil",function(a){var b=a.target,c=b.getAttribute("data-youtube"),e=b.getAttribute("data-vimeo");c&&b&&f(c,b),e&&b&&d(e,b)})}}(window,document); -------------------------------------------------------------------------------- /js/lazysizes/src/lazysizes-core.js: -------------------------------------------------------------------------------- 1 | function l(window, document) { 2 | 'use strict'; 3 | /*jshint eqnull:true */ 4 | if(!document.getElementsByClassName){return;} 5 | 6 | var lazySizesConfig; 7 | 8 | var docElem = document.documentElement; 9 | 10 | var Date = window.Date; 11 | 12 | var supportPicture = window.HTMLPictureElement; 13 | 14 | var _addEventListener = 'addEventListener'; 15 | 16 | var _getAttribute = 'getAttribute'; 17 | 18 | var addEventListener = window[_addEventListener]; 19 | 20 | var setTimeout = window.setTimeout; 21 | 22 | var requestAnimationFrame = window.requestAnimationFrame || setTimeout; 23 | 24 | var requestIdleCallback = window.requestIdleCallback; 25 | 26 | var regPicture = /^picture$/i; 27 | 28 | var loadEvents = ['load', 'error', 'lazyincluded', '_lazyloaded']; 29 | 30 | var regClassCache = {}; 31 | 32 | var forEach = Array.prototype.forEach; 33 | 34 | var hasClass = function(ele, cls) { 35 | if(!regClassCache[cls]){ 36 | regClassCache[cls] = new RegExp('(\\s|^)'+cls+'(\\s|$)'); 37 | } 38 | return regClassCache[cls].test(ele[_getAttribute]('class') || '') && regClassCache[cls]; 39 | }; 40 | 41 | var addClass = function(ele, cls) { 42 | if (!hasClass(ele, cls)){ 43 | ele.setAttribute('class', (ele[_getAttribute]('class') || '').trim() + ' ' + cls); 44 | } 45 | }; 46 | 47 | var removeClass = function(ele, cls) { 48 | var reg; 49 | if ((reg = hasClass(ele,cls))) { 50 | ele.setAttribute('class', (ele[_getAttribute]('class') || '').replace(reg, ' ')); 51 | } 52 | }; 53 | 54 | var addRemoveLoadEvents = function(dom, fn, add){ 55 | var action = add ? _addEventListener : 'removeEventListener'; 56 | if(add){ 57 | addRemoveLoadEvents(dom, fn); 58 | } 59 | loadEvents.forEach(function(evt){ 60 | dom[action](evt, fn); 61 | }); 62 | }; 63 | 64 | var triggerEvent = function(elem, name, detail, noBubbles, noCancelable){ 65 | var event = document.createEvent('CustomEvent'); 66 | 67 | event.initCustomEvent(name, !noBubbles, !noCancelable, detail || {}); 68 | 69 | elem.dispatchEvent(event); 70 | return event; 71 | }; 72 | 73 | var updatePolyfill = function (el, full){ 74 | var polyfill; 75 | if( !supportPicture && ( polyfill = (window.picturefill || lazySizesConfig.pf) ) ){ 76 | polyfill({reevaluate: true, elements: [el]}); 77 | } else if(full && full.src){ 78 | el.src = full.src; 79 | } 80 | }; 81 | 82 | var getCSS = function (elem, style){ 83 | return (getComputedStyle(elem, null) || {})[style]; 84 | }; 85 | 86 | var getWidth = function(elem, parent, width){ 87 | width = width || elem.offsetWidth; 88 | 89 | while(width < lazySizesConfig.minSize && parent && !elem._lazysizesWidth){ 90 | width = parent.offsetWidth; 91 | parent = parent.parentNode; 92 | } 93 | 94 | return width; 95 | }; 96 | 97 | var rAF = (function(){ 98 | var running, waiting; 99 | var fns = []; 100 | 101 | var run = function(){ 102 | var fn; 103 | running = true; 104 | waiting = false; 105 | while(fns.length){ 106 | fn = fns.shift(); 107 | fn[0].apply(fn[1], fn[2]); 108 | } 109 | running = false; 110 | }; 111 | 112 | return function(fn){ 113 | if(running){ 114 | fn.apply(this, arguments); 115 | } else { 116 | fns.push([fn, this, arguments]); 117 | 118 | if(!waiting){ 119 | waiting = true; 120 | (document.hidden ? setTimeout : requestAnimationFrame)(run); 121 | } 122 | } 123 | }; 124 | })(); 125 | 126 | var rAFIt = function(fn, simple){ 127 | return simple ? 128 | function() { 129 | rAF(fn); 130 | } : 131 | function(){ 132 | var that = this; 133 | var args = arguments; 134 | rAF(function(){ 135 | fn.apply(that, args); 136 | }); 137 | } 138 | ; 139 | }; 140 | 141 | var throttle = function(fn){ 142 | var running; 143 | var lastTime = 0; 144 | var gDelay = 125; 145 | var RIC_DEFAULT_TIMEOUT = 999; 146 | var rICTimeout = RIC_DEFAULT_TIMEOUT; 147 | var run = function(){ 148 | running = false; 149 | lastTime = Date.now(); 150 | fn(); 151 | }; 152 | var idleCallback = requestIdleCallback ? 153 | function(){ 154 | requestIdleCallback(run, {timeout: rICTimeout}); 155 | if(rICTimeout !== RIC_DEFAULT_TIMEOUT){ 156 | rICTimeout = RIC_DEFAULT_TIMEOUT; 157 | } 158 | }: 159 | rAFIt(function(){ 160 | setTimeout(run); 161 | }, true) 162 | ; 163 | 164 | return function(isPriority){ 165 | var delay; 166 | if((isPriority = isPriority === true)){ 167 | rICTimeout = 66; 168 | } 169 | 170 | if(running){ 171 | return; 172 | } 173 | 174 | running = true; 175 | 176 | delay = gDelay - (Date.now() - lastTime); 177 | 178 | if(delay < 0){ 179 | delay = 0; 180 | } 181 | 182 | if(isPriority || (delay < 9 && requestIdleCallback)){ 183 | idleCallback(); 184 | } else { 185 | setTimeout(idleCallback, delay); 186 | } 187 | }; 188 | }; 189 | 190 | //based on http://modernjavascript.blogspot.de/2013/08/building-better-debounce.html 191 | var debounce = function(func) { 192 | var timeout, timestamp; 193 | var wait = 99; 194 | var run = function(){ 195 | timeout = null; 196 | func(); 197 | }; 198 | var later = function() { 199 | var last = Date.now() - timestamp; 200 | 201 | if (last < wait) { 202 | setTimeout(later, wait - last); 203 | } else { 204 | (requestIdleCallback || run)(run); 205 | } 206 | }; 207 | 208 | return function() { 209 | timestamp = Date.now(); 210 | 211 | if (!timeout) { 212 | timeout = setTimeout(later, wait); 213 | } 214 | }; 215 | }; 216 | 217 | 218 | var loader = (function(){ 219 | var lazyloadElems, preloadElems, isCompleted, resetPreloadingTimer, loadMode, started; 220 | 221 | var eLvW, elvH, eLtop, eLleft, eLright, eLbottom; 222 | 223 | var defaultExpand, preloadExpand, hFac; 224 | 225 | var regImg = /^img$/i; 226 | var regIframe = /^iframe$/i; 227 | 228 | var supportScroll = ('onscroll' in window) && !(/glebot/.test(navigator.userAgent)); 229 | 230 | var shrinkExpand = 0; 231 | var currentExpand = 0; 232 | 233 | var isLoading = 0; 234 | var lowRuns = 0; 235 | 236 | var resetPreloading = function(e){ 237 | isLoading--; 238 | if(e && e.target){ 239 | addRemoveLoadEvents(e.target, resetPreloading); 240 | } 241 | 242 | if(!e || isLoading < 0 || !e.target){ 243 | isLoading = 0; 244 | } 245 | }; 246 | 247 | var isNestedVisible = function(elem, elemExpand){ 248 | var outerRect; 249 | var parent = elem; 250 | var visible = getCSS(document.body, 'visibility') == 'hidden' || getCSS(elem, 'visibility') != 'hidden'; 251 | 252 | eLtop -= elemExpand; 253 | eLbottom += elemExpand; 254 | eLleft -= elemExpand; 255 | eLright += elemExpand; 256 | 257 | while(visible && (parent = parent.offsetParent) && parent != document.body && parent != docElem){ 258 | visible = ((getCSS(parent, 'opacity') || 1) > 0); 259 | 260 | if(visible && getCSS(parent, 'overflow') != 'visible'){ 261 | outerRect = parent.getBoundingClientRect(); 262 | visible = eLright > outerRect.left && 263 | eLleft < outerRect.right && 264 | eLbottom > outerRect.top - 1 && 265 | eLtop < outerRect.bottom + 1 266 | ; 267 | } 268 | } 269 | 270 | return visible; 271 | }; 272 | 273 | var checkElements = function() { 274 | var eLlen, i, rect, autoLoadElem, loadedSomething, elemExpand, elemNegativeExpand, elemExpandVal, beforeExpandVal; 275 | 276 | if((loadMode = lazySizesConfig.loadMode) && isLoading < 8 && (eLlen = lazyloadElems.length)){ 277 | 278 | i = 0; 279 | 280 | lowRuns++; 281 | 282 | if(preloadExpand == null){ 283 | if(!('expand' in lazySizesConfig)){ 284 | lazySizesConfig.expand = docElem.clientHeight > 500 ? 500 : 400; 285 | } 286 | 287 | defaultExpand = lazySizesConfig.expand; 288 | preloadExpand = defaultExpand * lazySizesConfig.expFactor; 289 | } 290 | 291 | if(currentExpand < preloadExpand && isLoading < 1 && lowRuns > 3 && loadMode > 2){ 292 | currentExpand = preloadExpand; 293 | lowRuns = 0; 294 | } else if(loadMode > 1 && lowRuns > 2 && isLoading < 6){ 295 | currentExpand = defaultExpand; 296 | } else { 297 | currentExpand = shrinkExpand; 298 | } 299 | 300 | for(; i < eLlen; i++){ 301 | 302 | if(!lazyloadElems[i] || lazyloadElems[i]._lazyRace){continue;} 303 | 304 | if(!supportScroll){unveilElement(lazyloadElems[i]);continue;} 305 | 306 | if(!(elemExpandVal = lazyloadElems[i][_getAttribute]('data-expand')) || !(elemExpand = elemExpandVal * 1)){ 307 | elemExpand = currentExpand; 308 | } 309 | 310 | if(beforeExpandVal !== elemExpand){ 311 | eLvW = innerWidth + (elemExpand * hFac); 312 | elvH = innerHeight + elemExpand; 313 | elemNegativeExpand = elemExpand * -1; 314 | beforeExpandVal = elemExpand; 315 | } 316 | 317 | rect = lazyloadElems[i].getBoundingClientRect(); 318 | 319 | if ((eLbottom = rect.bottom) >= elemNegativeExpand && 320 | (eLtop = rect.top) <= elvH && 321 | (eLright = rect.right) >= elemNegativeExpand * hFac && 322 | (eLleft = rect.left) <= eLvW && 323 | (eLbottom || eLright || eLleft || eLtop) && 324 | ((isCompleted && isLoading < 3 && !elemExpandVal && (loadMode < 3 || lowRuns < 4)) || isNestedVisible(lazyloadElems[i], elemExpand))){ 325 | unveilElement(lazyloadElems[i]); 326 | loadedSomething = true; 327 | if(isLoading > 9){break;} 328 | } else if(!loadedSomething && isCompleted && !autoLoadElem && 329 | isLoading < 4 && lowRuns < 4 && loadMode > 2 && 330 | (preloadElems[0] || lazySizesConfig.preloadAfterLoad) && 331 | (preloadElems[0] || (!elemExpandVal && ((eLbottom || eLright || eLleft || eLtop) || lazyloadElems[i][_getAttribute](lazySizesConfig.sizesAttr) != 'auto')))){ 332 | autoLoadElem = preloadElems[0] || lazyloadElems[i]; 333 | } 334 | } 335 | 336 | if(autoLoadElem && !loadedSomething){ 337 | unveilElement(autoLoadElem); 338 | } 339 | } 340 | }; 341 | 342 | var throttledCheckElements = throttle(checkElements); 343 | 344 | var switchLoadingClass = function(e){ 345 | addClass(e.target, lazySizesConfig.loadedClass); 346 | removeClass(e.target, lazySizesConfig.loadingClass); 347 | addRemoveLoadEvents(e.target, rafSwitchLoadingClass); 348 | }; 349 | var rafedSwitchLoadingClass = rAFIt(switchLoadingClass); 350 | var rafSwitchLoadingClass = function(e){ 351 | rafedSwitchLoadingClass({target: e.target}); 352 | }; 353 | 354 | var changeIframeSrc = function(elem, src){ 355 | try { 356 | elem.contentWindow.location.replace(src); 357 | } catch(e){ 358 | elem.src = src; 359 | } 360 | }; 361 | 362 | var handleSources = function(source){ 363 | var customMedia, parent; 364 | 365 | var sourceSrcset = source[_getAttribute](lazySizesConfig.srcsetAttr); 366 | 367 | if( (customMedia = lazySizesConfig.customMedia[source[_getAttribute]('data-media') || source[_getAttribute]('media')]) ){ 368 | source.setAttribute('media', customMedia); 369 | } 370 | 371 | if(sourceSrcset){ 372 | source.setAttribute('srcset', sourceSrcset); 373 | } 374 | 375 | //https://bugzilla.mozilla.org/show_bug.cgi?id=1170572 376 | if(customMedia){ 377 | parent = source.parentNode; 378 | parent.insertBefore(source.cloneNode(), source); 379 | parent.removeChild(source); 380 | } 381 | }; 382 | 383 | var lazyUnveil = rAFIt(function (elem, detail, isAuto, sizes, isImg){ 384 | var src, srcset, parent, isPicture, event, firesLoad; 385 | 386 | if(!(event = triggerEvent(elem, 'lazybeforeunveil', detail)).defaultPrevented){ 387 | 388 | if(sizes){ 389 | if(isAuto){ 390 | addClass(elem, lazySizesConfig.autosizesClass); 391 | } else { 392 | elem.setAttribute('sizes', sizes); 393 | } 394 | } 395 | 396 | srcset = elem[_getAttribute](lazySizesConfig.srcsetAttr); 397 | src = elem[_getAttribute](lazySizesConfig.srcAttr); 398 | 399 | if(isImg) { 400 | parent = elem.parentNode; 401 | isPicture = parent && regPicture.test(parent.nodeName || ''); 402 | } 403 | 404 | firesLoad = detail.firesLoad || (('src' in elem) && (srcset || src || isPicture)); 405 | 406 | event = {target: elem}; 407 | 408 | if(firesLoad){ 409 | addRemoveLoadEvents(elem, resetPreloading, true); 410 | clearTimeout(resetPreloadingTimer); 411 | resetPreloadingTimer = setTimeout(resetPreloading, 2500); 412 | 413 | addClass(elem, lazySizesConfig.loadingClass); 414 | addRemoveLoadEvents(elem, rafSwitchLoadingClass, true); 415 | } 416 | 417 | if(isPicture){ 418 | forEach.call(parent.getElementsByTagName('source'), handleSources); 419 | } 420 | 421 | if(srcset){ 422 | elem.setAttribute('srcset', srcset); 423 | } else if(src && !isPicture){ 424 | if(regIframe.test(elem.nodeName)){ 425 | changeIframeSrc(elem, src); 426 | } else { 427 | elem.src = src; 428 | } 429 | } 430 | 431 | if(srcset || isPicture){ 432 | updatePolyfill(elem, {src: src}); 433 | } 434 | } 435 | 436 | rAF(function(){ 437 | if(elem._lazyRace){ 438 | delete elem._lazyRace; 439 | } 440 | removeClass(elem, lazySizesConfig.lazyClass); 441 | 442 | if( !firesLoad || elem.complete ){ 443 | if(firesLoad){ 444 | resetPreloading(event); 445 | } else { 446 | isLoading--; 447 | } 448 | switchLoadingClass(event); 449 | } 450 | }); 451 | }); 452 | 453 | var unveilElement = function (elem){ 454 | var detail; 455 | 456 | var isImg = regImg.test(elem.nodeName); 457 | 458 | //allow using sizes="auto", but don't use. it's invalid. Use data-sizes="auto" or a valid value for sizes instead (i.e.: sizes="80vw") 459 | var sizes = isImg && (elem[_getAttribute](lazySizesConfig.sizesAttr) || elem[_getAttribute]('sizes')); 460 | var isAuto = sizes == 'auto'; 461 | 462 | if( (isAuto || !isCompleted) && isImg && (elem.src || elem.srcset) && !elem.complete && !hasClass(elem, lazySizesConfig.errorClass)){return;} 463 | 464 | detail = triggerEvent(elem, 'lazyunveilread').detail; 465 | 466 | if(isAuto){ 467 | autoSizer.updateElem(elem, true, elem.offsetWidth); 468 | } 469 | 470 | elem._lazyRace = true; 471 | isLoading++; 472 | 473 | lazyUnveil(elem, detail, isAuto, sizes, isImg); 474 | }; 475 | 476 | var onload = function(){ 477 | if(isCompleted){return;} 478 | if(Date.now() - started < 999){ 479 | setTimeout(onload, 999); 480 | return; 481 | } 482 | var afterScroll = debounce(function(){ 483 | lazySizesConfig.loadMode = 3; 484 | throttledCheckElements(); 485 | }); 486 | 487 | isCompleted = true; 488 | 489 | lazySizesConfig.loadMode = 3; 490 | 491 | throttledCheckElements(); 492 | 493 | addEventListener('scroll', function(){ 494 | if(lazySizesConfig.loadMode == 3){ 495 | lazySizesConfig.loadMode = 2; 496 | } 497 | afterScroll(); 498 | }, true); 499 | }; 500 | 501 | return { 502 | _: function(){ 503 | started = Date.now(); 504 | 505 | lazyloadElems = document.getElementsByClassName(lazySizesConfig.lazyClass); 506 | preloadElems = document.getElementsByClassName(lazySizesConfig.lazyClass + ' ' + lazySizesConfig.preloadClass); 507 | hFac = lazySizesConfig.hFac; 508 | 509 | addEventListener('scroll', throttledCheckElements, true); 510 | 511 | addEventListener('resize', throttledCheckElements, true); 512 | 513 | if(window.MutationObserver){ 514 | new MutationObserver( throttledCheckElements ).observe( docElem, {childList: true, subtree: true, attributes: true} ); 515 | } else { 516 | docElem[_addEventListener]('DOMNodeInserted', throttledCheckElements, true); 517 | docElem[_addEventListener]('DOMAttrModified', throttledCheckElements, true); 518 | setInterval(throttledCheckElements, 999); 519 | } 520 | 521 | addEventListener('hashchange', throttledCheckElements, true); 522 | 523 | //, 'fullscreenchange' 524 | ['focus', 'mouseover', 'click', 'load', 'transitionend', 'animationend', 'webkitAnimationEnd'].forEach(function(name){ 525 | document[_addEventListener](name, throttledCheckElements, true); 526 | }); 527 | 528 | if((/d$|^c/.test(document.readyState))){ 529 | onload(); 530 | } else { 531 | addEventListener('load', onload); 532 | document[_addEventListener]('DOMContentLoaded', throttledCheckElements); 533 | setTimeout(onload, 20000); 534 | } 535 | 536 | throttledCheckElements(lazyloadElems.length > 0); 537 | }, 538 | checkElems: throttledCheckElements, 539 | unveil: unveilElement 540 | }; 541 | })(); 542 | 543 | 544 | var autoSizer = (function(){ 545 | var autosizesElems; 546 | 547 | var sizeElement = rAFIt(function(elem, parent, event, width){ 548 | var sources, i, len; 549 | elem._lazysizesWidth = width; 550 | width += 'px'; 551 | 552 | elem.setAttribute('sizes', width); 553 | 554 | if(regPicture.test(parent.nodeName || '')){ 555 | sources = parent.getElementsByTagName('source'); 556 | for(i = 0, len = sources.length; i < len; i++){ 557 | sources[i].setAttribute('sizes', width); 558 | } 559 | } 560 | 561 | if(!event.detail.dataAttr){ 562 | updatePolyfill(elem, event.detail); 563 | } 564 | }); 565 | var getSizeElement = function (elem, dataAttr, width){ 566 | var event; 567 | var parent = elem.parentNode; 568 | 569 | if(parent){ 570 | width = getWidth(elem, parent, width); 571 | event = triggerEvent(elem, 'lazybeforesizes', {width: width, dataAttr: !!dataAttr}); 572 | 573 | if(!event.defaultPrevented){ 574 | width = event.detail.width; 575 | 576 | if(width && width !== elem._lazysizesWidth){ 577 | sizeElement(elem, parent, event, width); 578 | } 579 | } 580 | } 581 | }; 582 | 583 | var updateElementsSizes = function(){ 584 | var i; 585 | var len = autosizesElems.length; 586 | if(len){ 587 | i = 0; 588 | 589 | for(; i < len; i++){ 590 | getSizeElement(autosizesElems[i]); 591 | } 592 | } 593 | }; 594 | 595 | var debouncedUpdateElementsSizes = debounce(updateElementsSizes); 596 | 597 | return { 598 | _: function(){ 599 | autosizesElems = document.getElementsByClassName(lazySizesConfig.autosizesClass); 600 | addEventListener('resize', debouncedUpdateElementsSizes); 601 | }, 602 | checkElems: debouncedUpdateElementsSizes, 603 | updateElem: getSizeElement 604 | }; 605 | })(); 606 | 607 | var init = function(){ 608 | if(!init.i){ 609 | init.i = true; 610 | autoSizer._(); 611 | loader._(); 612 | } 613 | }; 614 | 615 | (function(){ 616 | var prop; 617 | 618 | var lazySizesDefaults = { 619 | lazyClass: 'lazyload', 620 | loadedClass: 'lazyloaded', 621 | loadingClass: 'lazyloading', 622 | preloadClass: 'lazypreload', 623 | errorClass: 'lazyerror', 624 | //strictClass: 'lazystrict', 625 | autosizesClass: 'lazyautosizes', 626 | srcAttr: 'data-src', 627 | srcsetAttr: 'data-srcset', 628 | sizesAttr: 'data-sizes', 629 | //preloadAfterLoad: false, 630 | minSize: 40, 631 | customMedia: {}, 632 | init: true, 633 | expFactor: 1.5, 634 | hFac: 0.8, 635 | loadMode: 2 636 | }; 637 | 638 | lazySizesConfig = window.lazySizesConfig || window.lazysizesConfig || {}; 639 | 640 | for(prop in lazySizesDefaults){ 641 | if(!(prop in lazySizesConfig)){ 642 | lazySizesConfig[prop] = lazySizesDefaults[prop]; 643 | } 644 | } 645 | 646 | window.lazySizesConfig = lazySizesConfig; 647 | 648 | setTimeout(function(){ 649 | if(lazySizesConfig.init){ 650 | init(); 651 | } 652 | }); 653 | })(); 654 | 655 | return { 656 | cfg: lazySizesConfig, 657 | autoSizer: autoSizer, 658 | loader: loader, 659 | init: init, 660 | uP: updatePolyfill, 661 | aC: addClass, 662 | rC: removeClass, 663 | hC: hasClass, 664 | fire: triggerEvent, 665 | gW: getWidth, 666 | rAF: rAF, 667 | }; 668 | } 669 | -------------------------------------------------------------------------------- /js/ls.setup.js: -------------------------------------------------------------------------------- 1 | window.lazySizesConfig = window.lazySizesConfig || {preloadAfterLoad: 'false'}; 2 | 3 | (function (c) { 4 | 5 | c.checkIfMobile = function (a) { 6 | return /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|pad|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4)) ? true : false; 7 | }; 8 | 9 | c.setSmartPreload = function (isMobile) { 10 | // convert 'true' or 'false' string from wp_localize_script to boolean: 11 | c.preloadAfterLoad = (c.preloadAfterLoad === 'smart') ? !isMobile : JSON.parse(c.preloadAfterLoad); 12 | }; 13 | 14 | c.convertToInt = function (value) { 15 | c.expand = value * 1; 16 | }; 17 | 18 | c.setSmartPreload( c.checkIfMobile(navigator.userAgent || navigator.vendor || window.opera) ); 19 | 20 | c.convertToInt(c.expand); 21 | 22 | }) (window.lazySizesConfig); 23 | -------------------------------------------------------------------------------- /js/tests/test-ls.setup.js: -------------------------------------------------------------------------------- 1 | 2 | var chrome_ua = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36'; 3 | var iphone_ua = 'Mozilla/5.0 (iPhone; CPU iPhone OS 6_1_4 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10B350 Safari/8536.25' 4 | 5 | 6 | beforeEach(function () { 7 | window.lazySizesConfig = window.lazySizesConfig || {}; 8 | window.lazySizesConfig.preloadAfterLoad = 'false'; 9 | window.lazySizesConfig.expand = '359'; 10 | }); 11 | 12 | 13 | describe('checkIfMobile', function () { 14 | it('should exist', function () { 15 | expect(typeof window.lazySizesConfig.checkIfMobile === 'function').toBe(true); 16 | }); 17 | 18 | it('should return false when given desktop Chrome useragent', function () { 19 | expect(window.lazySizesConfig.checkIfMobile(chrome_ua)).toBe(false); 20 | }); 21 | 22 | it('should return true when given a phone useragent', function () { 23 | expect(window.lazySizesConfig.checkIfMobile(iphone_ua)).toBe(true); 24 | }); 25 | }); 26 | 27 | 28 | describe('setSmartPreload', function () { 29 | it('should exist', function () { 30 | expect(typeof window.lazySizesConfig.setSmartPreload === 'function').toBe(true); 31 | }); 32 | 33 | it('should change the value of window.lazySizesConfig.preloadAfterLoad to boolean "true" or "false" if set to "smart"', function () { 34 | window.lazySizesConfig.preloadAfterLoad = 'smart'; 35 | // pass false to simulate desktop 36 | window.lazySizesConfig.setSmartPreload( false ); 37 | expect(window.lazySizesConfig.preloadAfterLoad).toBe(true); 38 | 39 | window.lazySizesConfig.preloadAfterLoad = 'smart'; 40 | // pass true to simulate mobile 41 | window.lazySizesConfig.setSmartPreload( true ) 42 | expect(window.lazySizesConfig.preloadAfterLoad).toBe(false); 43 | }); 44 | 45 | it('should convert window.lazySizesConfig.preloadAfterLoad to boolean if not "smart", regardless of if mobile', function() { 46 | // simulate desktop with default 'false' preloadAfterLoad setting 47 | window.lazySizesConfig.setSmartPreload( false ); 48 | expect(window.lazySizesConfig.preloadAfterLoad).toBe(false); 49 | 50 | // simulate mobile with default 'false' preloadAfterLoad setting 51 | window.lazySizesConfig.setSmartPreload( true ); 52 | expect(window.lazySizesConfig.preloadAfterLoad).toBe(false); 53 | 54 | window.lazySizesConfig.preloadAfterLoad = 'true'; 55 | 56 | // simulate desktop with preloadAfterLoad set to 'true' 57 | window.lazySizesConfig.setSmartPreload( false ); 58 | expect(window.lazySizesConfig.preloadAfterLoad).toBe(true); 59 | 60 | // simulate mobile with preloadAfterLoad set to 'true' 61 | window.lazySizesConfig.setSmartPreload( true ); 62 | expect(window.lazySizesConfig.preloadAfterLoad).toBe(true); 63 | }); 64 | }); 65 | 66 | describe('convertToInt', function () { 67 | it('should convert the "expand" value to an integer', function() { 68 | window.lazySizesConfig.convertToInt(window.lazySizesConfig.expand); 69 | expect(window.lazySizesConfig.expand).toBe(359); 70 | }); 71 | }); 72 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wp-lazysizes", 3 | "description": "Lazyload responsive images with automatic sizes calculation", 4 | "version": "0.9.4", 5 | "author": "Alexander Farkas ", 6 | "contributors": [ 7 | { 8 | "name": "Viktor Szépe", 9 | "email": "viktor@szepe.net" 10 | }, 11 | { 12 | "name": "Joel Birch", 13 | "email": "joeldbirch@gmail.com" 14 | }, 15 | { 16 | "name": "Vitaly Nikolaev", 17 | "email": "trilliput@gmail.com" 18 | } 19 | ], 20 | "repository": { 21 | "type": "git", 22 | "url": "git://github.com/aFarkas/wp-lazysizes.git" 23 | }, 24 | "devDependencies": { 25 | "grunt": "^0.4.5", 26 | "grunt-contrib-copy": "^0.7.0", 27 | "grunt-contrib-uglify": "^1.0.1", 28 | "lazysizes": ">=1.3.1", 29 | "testem": "^1.7.4" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | ./tests/ 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- 1 | == Changelog == 2 | 3 | = 0.9.4 = 4 | 5 | * Updated lazysizes v2.0.0 6 | 7 | = 0.9.2 = 8 | 9 | Release Date: TBD 10 | 11 | * Enhancements: 12 | * Code cleanup 13 | -------------------------------------------------------------------------------- /settings.php: -------------------------------------------------------------------------------- 1 | 86 | value='true'> 87 | 97 | 104 | 115 | 120 | 128 | '> 129 | 140 | 145 | 146 | 158 |
159 | 160 | 161 | 162 | 167 | 168 |
169 | assertTrue( is_plugin_active('wp-lazysizes/wp-lazysizes.php') ); 14 | } 15 | 16 | 17 | function test_get_js_config() { 18 | global $lazySizesDefaults; 19 | 20 | ob_start(); 21 | 22 | $changed_option = ['preloadAfterLoad' => 'smart']; 23 | update_option('lazysizes_settings', array_merge($lazySizesDefaults, $changed_option ) ); 24 | do_action('wp_head'); 25 | 26 | $content = ob_get_contents(); 27 | ob_end_clean(); 28 | 29 | $this->assertTrue( !empty($content) ); 30 | $this->assertTrue( strpos($content, 'var lazySizesConfig =' ) !== false ); 31 | $this->assertTrue( strpos($content, '"preloadAfterLoad":"smart"' ) !== false ); 32 | } 33 | 34 | } 35 | 36 | -------------------------------------------------------------------------------- /wp-lazysizes.php: -------------------------------------------------------------------------------- 1 | 359, 26 | 'optimumx' => 'false', 27 | 'intrinsicRatio' => 'false', 28 | 'iframes' => 'false', 29 | 'autosize' => 'true', 30 | 'preloadAfterLoad' => 'false' 31 | ); 32 | require_once( plugin_dir_path( __FILE__ ) . 'settings.php' ); 33 | 34 | 35 | class LazySizes { 36 | 37 | const version = '0.9.4'; 38 | private static $options = array(); 39 | private static $instance; 40 | 41 | function __construct() { 42 | 43 | if ( !is_admin() ) { 44 | 45 | add_action( 'wp_enqueue_scripts', array( $this, '_get_options' ), 1 ); 46 | add_action( 'wp_enqueue_scripts', array( $this, 'add_styles' ), 1 ); 47 | add_action( 'wp_enqueue_scripts', array( $this, 'add_scripts' ), 200 ); 48 | // Run this later, so other content filters have run, including image_add_wh on WP.com 49 | add_filter( 'the_content', array( $this, 'filter_images'), 200 ); 50 | add_filter( 'post_thumbnail_html', array( $this, 'filter_images'), 200 ); 51 | add_filter( 'widget_text', array( $this, 'filter_images'), 200 ); 52 | if ($this->_get_option('iframes') != 'false') { 53 | add_filter('oembed_result', array($this, 'filter_iframes'), 200); 54 | add_filter('embed_oembed_html', array($this, 'filter_iframes'), 200); 55 | } 56 | add_filter('get_avatar', array($this, 'filter_avatar'), 200); 57 | } 58 | } 59 | 60 | 61 | public static function get_instance() { 62 | if (!isset(self::$instance)) { 63 | self::$instance = new self; 64 | } 65 | return self::$instance; 66 | } 67 | 68 | 69 | public function _get_options() { 70 | 71 | global $lazySizesDefaults; 72 | 73 | self::$options = get_option( 'lazysizes_settings', $lazySizesDefaults); 74 | 75 | if ( is_numeric( $this->_get_option( 'expand' ) ) ) { 76 | self::$options['expand'] = (float)self::$options['expand']; 77 | } else { 78 | self::$options['expand'] = $lazySizesDefaults['expand']; 79 | } 80 | } 81 | 82 | protected function _get_option( $name ) { 83 | 84 | if ( ! isset( self::$options[$name] ) ) { 85 | return false; 86 | } 87 | 88 | return self::$options[$name]; 89 | } 90 | 91 | function add_styles() { 92 | 93 | wp_enqueue_style( 'lazysizes', $this->get_url( 'css/lazysizes.min.css' ), array(), self::version ); 94 | } 95 | 96 | function add_scripts() { 97 | 98 | wp_enqueue_script( 'lazysizes', $this->get_url( 'build/wp-lazysizes.min.js' ), array(), self::version, false ); 99 | 100 | if ( $this->_get_option( 'optimumx' ) !== 'false' ) { 101 | wp_enqueue_script( 'lazysizesoptimumx', 102 | $this->get_url( 'js/lazysizes/plugins/optimumx/ls.optimumx.min.js' ), array(), self::version, false ); 103 | } 104 | 105 | wp_localize_script( 'lazysizes', 'lazySizesConfig', $this->get_js_config() ); 106 | 107 | } 108 | 109 | private function get_js_config() { 110 | return array( 111 | 'expand' => $this->_get_option('expand'), 112 | 'preloadAfterLoad' => $this->_get_option('preloadAfterLoad') 113 | ); 114 | } 115 | 116 | public function filter_avatar( $content ) { 117 | 118 | return $this->filter_images( $content, 'noratio' ); 119 | } 120 | 121 | public function filter_iframes( $html ) { 122 | 123 | if ( false === strpos( $html, 'iframe' ) ) { 124 | return $html; 125 | } 126 | 127 | return $this->_add_class( $html, 'lazyload' ); 128 | } 129 | 130 | function filter_images( $content, $type = 'ratio' ) { 131 | 132 | if ( is_feed() 133 | || intval( get_query_var( 'print' ) ) == 1 134 | || intval( get_query_var( 'printpage' ) ) == 1 135 | || strpos( $_SERVER['HTTP_USER_AGENT'], 'Opera Mini' ) !== false 136 | ) { 137 | return $content; 138 | } 139 | 140 | $respReplace = 'data-sizes="auto" data-srcset='; 141 | 142 | if ( $this->_get_option('optimumx') != 'false' ) { 143 | $respReplace = 'data-optimumx="' . $this->_get_option('optimumx') . '" ' . $respReplace; 144 | } 145 | 146 | $matches = array(); 147 | $skip_images_regex = '/class=".*lazyload.*"/'; 148 | $placeholder_image = apply_filters( 'lazysizes_placeholder_image', 149 | 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==' ); 150 | preg_match_all( '//', $content, $matches ); 151 | 152 | $search = array(); 153 | $replace = array(); 154 | 155 | foreach ( $matches[0] as $imgHTML ) { 156 | 157 | // Don't to the replacement if a skip class is provided and the image has the class. 158 | if ( ! ( preg_match( $skip_images_regex, $imgHTML ) ) ) { 159 | 160 | $replaceHTML = preg_replace( '/_add_class( $replaceHTML, 'lazyload' ); 166 | 167 | $replaceHTML .= ''; 168 | 169 | if ( $type == 'ratio' && $this->_get_option('intrinsicRatio') != 'false' ) { 170 | if ( preg_match( '/width=["|\']*(\d+)["|\']*/', $imgHTML, $width ) == 1 171 | && preg_match( '/height=["|\']*(\d+)["|\']*/', $imgHTML, $height ) == 1 ) { 172 | 173 | $ratioBox = '' 186 | . $replaceHTML . ''; 187 | } 188 | } 189 | 190 | array_push( $search, $imgHTML ); 191 | array_push( $replace, $replaceHTML ); 192 | } 193 | } 194 | 195 | $content = str_replace( $search, $replace, $content ); 196 | 197 | return $content; 198 | } 199 | 200 | function get_url( $path = '' ) { 201 | 202 | return plugins_url( ltrim( $path, '/' ), __FILE__ ); 203 | } 204 | 205 | private function _add_class( $htmlString = '', $newClass ) { 206 | 207 | $pattern = '/class="([^"]*)"/'; 208 | 209 | // Class attribute set. 210 | if ( preg_match( $pattern, $htmlString, $matches ) ) { 211 | $definedClasses = explode( ' ', $matches[1] ); 212 | if ( ! in_array( $newClass, $definedClasses ) ) { 213 | $definedClasses[] = $newClass; 214 | $htmlString = str_replace( 215 | $matches[0], 216 | sprintf( 'class="%s"', implode( ' ', $definedClasses ) ), 217 | $htmlString 218 | ); 219 | } 220 | // Class attribute not set. 221 | } else { 222 | $htmlString = preg_replace( '/(\<.+\s)/', sprintf( '$1class="%s" ', $newClass ), $htmlString ); 223 | } 224 | 225 | return $htmlString; 226 | } 227 | } 228 | 229 | LazySizes::get_instance(); 230 | 231 | endif; 232 | --------------------------------------------------------------------------------