lazyloadjs 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 51c40c2b88b4e1a415f022b10bf1ad5af028f34b
4
+ data.tar.gz: 6e143739da584749fe738ab47cc139da05d241a4
5
+ SHA512:
6
+ metadata.gz: 9577c3886e170e3da926d22ed97f148d6d110020f5f8437316bb14aab719c4dcc6216264a65395df3ac62aa963787ec77d1d82fab3e0bdef0faa693d9e1cd3b1
7
+ data.tar.gz: 0de95df104c5fad259678827bd52f0245451ad6261611c20522f01b16b95ccba2493ec4943e9dc11d529656bff4bdb998c4a94c52fb41e322dbddfbba47bb254
data/README.md ADDED
@@ -0,0 +1,40 @@
1
+ # Lazyloadjs
2
+
3
+ Implementing LazyLoad ( http://github.com/fasterize/lazyload ) for Ruby on Rails
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'lazyloadjs'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install lazyloadjs
18
+
19
+ ## Usage
20
+
21
+ Add lazyloadjs in Assets Pipeline (e.g. `app/assets/javascripts/application.js`)
22
+
23
+ # Add it after all your others scripts
24
+ //= lazy_load
25
+
26
+ Restart your application. Done.
27
+
28
+ This gem provides a helper that allows you to render `<img>` tag
29
+
30
+ # image_lazy 'image_url', *options
31
+ # eg
32
+ = image_lazy image_url("my_logo.png"), style: "height: 200px;", alt: "My logo"
33
+
34
+ ## Contributing
35
+
36
+ 1. Fork it ( http://github.com/angelodlfrtr/lazyloadjs/fork )
37
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
38
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
39
+ 4. Push to the branch (`git push origin my-new-feature`)
40
+ 5. Create new Pull Request
@@ -0,0 +1,9 @@
1
+ require 'lazyloadjs/view_helpers'
2
+
3
+ module Lazyloadjs
4
+ class Railtie < Rails::Railtie
5
+ initializer "lazyloadjs.view_helpers" do
6
+ ActionView::Base.send :include, ViewHelpers
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,3 @@
1
+ module Lazyloadjs
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,10 @@
1
+ module Lazyloadjs
2
+ module ViewHelpers
3
+ def image_lazy image_path, args = {}
4
+ options = ''
5
+ args.each{|arg| options += "#{arg[0]}='#{arg[1]}'"}
6
+
7
+ raw "<img data-frz-src='#{image_path}' src=data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== onload=lzld(this) onerror=lzld(this) #{options} />"
8
+ end
9
+ end
10
+ end
data/lib/lazyloadjs.rb ADDED
@@ -0,0 +1,9 @@
1
+ require "lazyloadjs/version"
2
+ require 'lazyloadjs/railtie' if defined?(Rails)
3
+
4
+ module Lazyloadjs
5
+ module Rails
6
+ class Engine < ::Rails::Engine
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,308 @@
1
+ /*
2
+ lazyload.js: Image lazy loading
3
+
4
+ Copyright (c) 2012 Vincent Voyer, http://fasterize.com
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining
7
+ a copy of this software and associated documentation files (the
8
+ "Software"), to deal in the Software without restriction, including
9
+ without limitation the rights to use, copy, modify, merge, publish,
10
+ distribute, sublicense, and/or sell copies of the Software, and to
11
+ permit persons to whom the Software is furnished to do so, subject to
12
+ the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be
15
+ included in all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
+ */
25
+
26
+ // Prevent double lazyload script on same page
27
+ // We NEED to use string as closure compiler would otherwise compile this statement badly
28
+ if (!window['lzld']) {
29
+ (function(window, document){
30
+ var
31
+ // Vertical offset in px. Used for preloading images while scrolling
32
+ offset = 200,
33
+ //where to get real src
34
+ lazyAttr = 'data-frz-src',
35
+ // Window height
36
+ winH = viewport(),
37
+ // Self-populated page images array, we do not getElementsByTagName
38
+ imgs = [],
39
+ pageHasLoaded = false,
40
+ unsubscribed = false,
41
+
42
+ // throttled functions, so that we do not call them too much
43
+ saveViewportT = throttle(viewport, 20),
44
+ showImagesT = throttle(showImages, 20);
45
+
46
+ // Override image element .getAttribute globally so that we give the real src
47
+ // does not works for ie < 8: http://perfectionkills.com/whats-wrong-with-extending-the-dom/
48
+ // Internet Explorer 7 (and below) [...] does not expose global Node, Element, HTMLElement, HTMLParagraphElement
49
+ window['HTMLImageElement'] && overrideGetattribute();
50
+
51
+ // Called from every lazy <img> onload event
52
+ window['lzld'] = onDataSrcImgLoad;
53
+
54
+ // init
55
+ domready(findImages);
56
+ addEvent(window, 'load', onLoad);
57
+
58
+ // Bind events
59
+ subscribe();
60
+
61
+ // called by img onload= or onerror= for IE6/7
62
+ function onDataSrcImgLoad(img) {
63
+ // if image is not already in the imgs array
64
+ // it can already be in it if domready was fast and img onload slow
65
+ if (inArray(img, imgs) === -1) {
66
+ // this case happens when the page had loaded but we inserted more lazyload images with
67
+ // javascript (ajax). We need to re-watch scroll/resize
68
+ if (unsubscribed) {
69
+ subscribe();
70
+ }
71
+ showIfVisible(img, imgs.push(img) - 1);
72
+ }
73
+ }
74
+
75
+ // find and merge images on domready with possibly already present onload= onerror= imgs
76
+ function findImages() {
77
+ var
78
+ domreadyImgs = document.getElementsByTagName('img'),
79
+ currentImg;
80
+
81
+ // merge them with already self onload registered imgs
82
+ for (var imgIndex = 0, max = domreadyImgs.length; imgIndex < max; imgIndex += 1) {
83
+ currentImg = domreadyImgs[imgIndex];
84
+ if (currentImg.getAttribute(lazyAttr) && inArray(currentImg, imgs) === -1) {
85
+ imgs.push(currentImg);
86
+ }
87
+ }
88
+
89
+ showImages();
90
+ setTimeout(showImagesT, 25);
91
+ }
92
+
93
+ function onLoad() {
94
+ pageHasLoaded = true;
95
+ // if page height changes (hiding elements at start)
96
+ // we should recheck for new in viewport images that need to be shown
97
+ // see onload test
98
+ showImagesT();
99
+ // we could be the first to be notified about onload, so let others event handlers
100
+ // pass and then try again
101
+ // because they could change things on images
102
+ setTimeout(showImagesT, 25);
103
+ }
104
+
105
+ function throttle(fn, minDelay) {
106
+ var lastCall = 0;
107
+ return function() {
108
+ var now = +new Date();
109
+ if (now - lastCall < minDelay) {
110
+ return;
111
+ }
112
+ lastCall = now;
113
+ // we do not return anything as
114
+ // https://github.com/documentcloud/underscore/issues/387
115
+ fn.apply(this, arguments);
116
+ }
117
+ }
118
+
119
+ // X-browser
120
+ function addEvent( el, type, fn ) {
121
+ if (el.attachEvent) {
122
+ el.attachEvent && el.attachEvent( 'on' + type, fn );
123
+ } else {
124
+ el.addEventListener( type, fn, false );
125
+ }
126
+ }
127
+
128
+ // X-browser
129
+ function removeEvent( el, type, fn ) {
130
+ if (el.detachEvent) {
131
+ el.detachEvent && el.detachEvent( 'on' + type, fn );
132
+ } else {
133
+ el.removeEventListener( type, fn, false );
134
+ }
135
+ }
136
+
137
+ // custom domready function
138
+ // ripped from https://github.com/dperini/ContentLoaded/blob/master/src/contentloaded.js
139
+ // http://javascript.nwbox.com/ContentLoaded/
140
+ // http://javascript.nwbox.com/ContentLoaded/MIT-LICENSE
141
+ // kept the inner logic, merged with our helpers/variables
142
+ function domready(callback) {
143
+ var
144
+ done = false,
145
+ top = true;
146
+
147
+ function init(e) {
148
+ if (e.type === 'readystatechange' && document.readyState !== 'complete') return;
149
+ removeEvent((e.type === 'load' ? window : document), e.type, init);
150
+ if (!done) {
151
+ done = true;
152
+ callback();
153
+ }
154
+ }
155
+
156
+ function poll() {
157
+ try { document.documentElement.doScroll('left'); } catch(e) { setTimeout(poll, 50); return; }
158
+ init('poll');
159
+ }
160
+
161
+ if (document.readyState === 'complete') callback();
162
+ else {
163
+ if (document.createEventObject && document.documentElement.doScroll) {
164
+ try { top = !window.frameElement; } catch(e) { }
165
+ if (top) poll();
166
+ }
167
+ addEvent(document, 'DOMContentLoaded', init);
168
+ addEvent(document, 'readystatechange', init);
169
+ addEvent(window, 'load', init);
170
+ }
171
+
172
+ }
173
+
174
+ // img = dom element
175
+ // index = imgs array index
176
+ function showIfVisible(img, index) {
177
+ // We have to check that the current node is in the DOM
178
+ // It could be a detached() dom node
179
+ // http://bugs.jquery.com/ticket/4996
180
+ if (contains(document.documentElement, img)
181
+ && img.getBoundingClientRect().top < winH + offset) {
182
+ // To avoid onload loop calls
183
+ // removeAttribute on IE is not enough to prevent the event to fire
184
+ img.onload = null;
185
+ img.removeAttribute('onload');
186
+ // on IE < 8 we get an onerror event instead of an onload event
187
+ img.onerror = null;
188
+ img.removeAttribute('onerror');
189
+
190
+ img.src = img.getAttribute(lazyAttr);
191
+ img.removeAttribute(lazyAttr);
192
+ imgs[index] = null;
193
+
194
+ return true; // img shown
195
+ } else {
196
+ return false; // img to be shown
197
+ }
198
+ }
199
+
200
+ // cross browser viewport calculation
201
+ function viewport() {
202
+ if (document.documentElement.clientHeight >= 0) {
203
+ return document.documentElement.clientHeight;
204
+ } else if (document.body && document.body.clientHeight >= 0) {
205
+ return document.body.clientHeight
206
+ } else if (window.innerHeight >= 0) {
207
+ return window.innerHeight;
208
+ } else {
209
+ return 0;
210
+ }
211
+ }
212
+
213
+ function saveViewport() {
214
+ winH = viewport();
215
+ }
216
+
217
+ // Loop through images array to find to-be-shown images
218
+ function showImages() {
219
+ var
220
+ last = imgs.length,
221
+ current,
222
+ allImagesDone = true;
223
+
224
+ for (current = 0; current < last; current++) {
225
+ var img = imgs[current];
226
+ // if showIfVisible is false, it means we have some waiting images to be
227
+ // shown
228
+ if(img !== null && !showIfVisible(img, current)) {
229
+ allImagesDone = false;
230
+ }
231
+ }
232
+
233
+ if (allImagesDone && pageHasLoaded) {
234
+ unsubscribe();
235
+ }
236
+ }
237
+
238
+ function unsubscribe() {
239
+ unsubscribed = true;
240
+ removeEvent(window, 'resize', saveViewportT);
241
+ removeEvent(window, 'scroll', showImagesT);
242
+ removeEvent(window, 'load', onLoad);
243
+ }
244
+
245
+ function subscribe() {
246
+ unsubscribed = false;
247
+ addEvent(window, 'resize', saveViewportT);
248
+ addEvent(window, 'scroll', showImagesT);
249
+ }
250
+
251
+ function overrideGetattribute() {
252
+ var original = HTMLImageElement.prototype.getAttribute;
253
+ HTMLImageElement.prototype.getAttribute = function(name) {
254
+ if(name === 'src') {
255
+ var realSrc = original.call(this, lazyAttr);
256
+ return realSrc || original.call(this, name);
257
+ } else {
258
+ // our own lazyloader will go through theses lines
259
+ // because we use getAttribute(lazyAttr)
260
+ return original.call(this, name);
261
+ }
262
+ }
263
+ }
264
+
265
+ // https://github.com/jquery/sizzle/blob/3136f48b90e3edc84cbaaa6f6f7734ef03775a07/sizzle.js#L708
266
+ var contains = document.documentElement.compareDocumentPosition ?
267
+ function( a, b ) {
268
+ return !!(a.compareDocumentPosition( b ) & 16);
269
+ } :
270
+ document.documentElement.contains ?
271
+ function( a, b ) {
272
+ return a !== b && ( a.contains ? a.contains( b ) : false );
273
+ } :
274
+ function( a, b ) {
275
+ while ( (b = b.parentNode) ) {
276
+ if ( b === a ) {
277
+ return true;
278
+ }
279
+ }
280
+ return false;
281
+ };
282
+
283
+ // https://github.com/jquery/jquery/blob/f3515b735e4ee00bb686922b2e1565934da845f8/src/core.js#L610
284
+ // We cannot use Array.prototype.indexOf because it's not always available
285
+ function inArray(elem, array, i) {
286
+ var len;
287
+
288
+ if ( array ) {
289
+ if ( Array.prototype.indexOf ) {
290
+ return Array.prototype.indexOf.call( array, elem, i );
291
+ }
292
+
293
+ len = array.length;
294
+ i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
295
+
296
+ for ( ; i < len; i++ ) {
297
+ // Skip accessing in sparse arrays
298
+ if ( i in array && array[ i ] === elem ) {
299
+ return i;
300
+ }
301
+ }
302
+ }
303
+
304
+ return -1;
305
+ }
306
+
307
+ }(this, document))
308
+ }
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lazyloadjs
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Angelo Delefortrie
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-03-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.5'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: railties
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Implementing LazyLoad ( http://github.com/fasterize/lazyload ) for Ruby
56
+ on Rails
57
+ email:
58
+ - angelo.delefortrie@gmail.com
59
+ executables: []
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - README.md
64
+ - lib/lazyloadjs.rb
65
+ - lib/lazyloadjs/railtie.rb
66
+ - lib/lazyloadjs/version.rb
67
+ - lib/lazyloadjs/view_helpers.rb
68
+ - vendor/assets/javascripts/lazyload.js
69
+ homepage: http://github.com/angelodlfrtr/lazyloadjs/
70
+ licenses:
71
+ - MIT
72
+ metadata: {}
73
+ post_install_message:
74
+ rdoc_options: []
75
+ require_paths:
76
+ - lib
77
+ required_ruby_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ required_rubygems_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ requirements: []
88
+ rubyforge_project:
89
+ rubygems_version: 2.2.2
90
+ signing_key:
91
+ specification_version: 4
92
+ summary: Implementing LazyLoad ( http://github.com/fasterize/lazyload ) for Ruby on
93
+ Rails
94
+ test_files: []