lentil 0.6.0 → 0.7.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 +4 -4
- data/README.md +1 -1
- data/app/assets/javascripts/lentil/addinfinitescroll.js.erb +3 -0
- data/app/assets/javascripts/lentil/addobjectfit.js +9 -0
- data/app/assets/javascripts/lentil/{iframe.js → iframe.js.erb} +9 -4
- data/app/assets/javascripts/lentil/imageerrors.js +0 -3
- data/app/assets/javascripts/lentil/images.js +3 -1
- data/app/assets/stylesheets/lentil.css.scss +2 -1
- data/app/assets/stylesheets/lentil/breakpoint/sass/_components.scss +53 -19
- data/app/assets/stylesheets/lentil/breakpoint/sass/_structure.scss +14 -14
- data/app/assets/stylesheets/lentil/iframe.css.scss +12 -4
- data/app/controllers/lentil/images_controller.rb +5 -0
- data/app/views/layouts/lentil/iframe.html.erb +6 -0
- data/app/views/lentil/images/_image_tiles.erb +2 -2
- data/app/views/lentil/images/animate.html.erb +3 -3
- data/app/views/lentil/images/iframe.html.erb +1 -1
- data/app/views/lentil/images/index.html.erb +15 -13
- data/app/views/lentil/thisorthat/_battle_form.html.erb +43 -38
- data/lib/lentil/version.rb +1 -1
- data/vendor/assets/javascripts/polyfill.object-fit/polyfill.object-fit.js +711 -0
- data/vendor/assets/stylesheets/polyfill.object-fit/polyfill.object-fit.css +89 -0
- metadata +82 -80
@@ -4,53 +4,58 @@
|
|
4
4
|
<div class="battle-image-wrap grid__cell">
|
5
5
|
<%= semantic_fields_for "image[#{image.id}]", image do |f| %>
|
6
6
|
<div id="image_<%= image.id %>" class="battle-image-tile">
|
7
|
+
<div>
|
7
8
|
<% unless image.media_type == "video" %>
|
8
9
|
<a href="<%= url_for(image) %>" data-fancybox-href= "<%= image.jpeg %>" class="fancybox">
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
<%= image_tag(image.jpeg, :class => "square-media battle-img instagram-img", :data => {:battles_count => image.battles_count, :win_pct => image.win_pct, :popularity => image.popular_score, :staff_like => image.staff_like, :like_votes_count => image.like_votes_count, :media_type => image.media_type}) %>
|
11
|
+
<% else %>
|
12
|
+
<a href="<%= url_for(image) %>" data-fancybox-href= "<%= image.video_url %>" class="fancybox">
|
13
|
+
<%= video_tag(image.video_url, :class => "square-media battle-img instagram-img " + image.id.to_s, :height => "100%", :width => "100%", :poster => image.jpeg, :controls => "controls", :data => {:battles_count => image.battles_count, :win_pct => image.win_pct, :popularity => image.popular_score, :staff_like => image.staff_like, :like_votes_count => image.like_votes_count, :media_type => image.media_type}) %>
|
14
|
+
<% end %>
|
15
|
+
</a>
|
16
|
+
</div>
|
14
17
|
<div class="battle-image-desc trunc-small"><div class="battle-image-inner-desc"><%= truncate(image.description, :length => 35) %></div></div>
|
15
18
|
<div class="battle-image-desc trunc-medium"><div class="battle-image-inner-desc"><%= truncate(image.description, :length => 50) %></div></div>
|
16
19
|
<div class="battle-image-desc trunc-large"><div class="battle-image-inner-desc"><%= truncate(image.description, :length => 70) %></div></div>
|
17
|
-
|
18
|
-
|
19
|
-
<%= f.input :id, :as => :hidden %>
|
20
|
+
<%= render "/layouts/lentil/image_popup", :image => image %>
|
21
|
+
<%= f.input :id, :as => :hidden %>
|
20
22
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
23
|
+
</div>
|
24
|
+
<div class="battle-submit-tile">
|
25
|
+
<%= f.action :submit, :as => :button, :label => t('lentil.battle.pick_me'), :button_html => {:value => "#{image.id}", :name => "vote", :class => "btn btn-large battle-form"} %>
|
26
|
+
</div>
|
27
|
+
<% end -%>
|
28
|
+
</div>
|
29
|
+
<% end -%>
|
27
30
|
<% end -%>
|
28
|
-
|
29
|
-
<% @prev_images.each do |image| %>
|
31
|
+
<% @prev_images.each do |image| %>
|
30
32
|
<div class="battle-image-wrap grid__cell" style="background:#e6e6e6">
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
33
|
+
<div id="image_<%= image.id %>" class="battle-image-tile">
|
34
|
+
<div>
|
35
|
+
<% unless image.media_type == "video" %>
|
36
|
+
<a href="<%= url_for(image) %>" data-fancybox-href= "<%= image.jpeg %>" class="fancybox">
|
37
|
+
<%= image_tag(image.jpeg, :class => "square-media battle-img instagram-img", :data => {:battles_count => image.battles_count, :win_pct => image.win_pct, :popularity => image.popular_score, :staff_like => image.staff_like, :like_votes_count => image.like_votes_count, :media_type => image.media_type}) %>
|
35
38
|
<% else %>
|
36
39
|
<a href="<%= url_for(image) %>" data-fancybox-href= "<%= image.video_url %>" class="fancybox">
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
</
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
40
|
+
<%= video_tag(image.video_url, :class => "square-media battle-img instagram-img " + image.id.to_s, :height => "100%", :width => "100%", :poster => image.jpeg, :controls => "controls", :data => {:battles_count => image.battles_count, :win_pct => image.win_pct, :popularity => image.popular_score, :staff_like => image.staff_like, :like_votes_count => image.like_votes_count, :media_type => image.media_type}) %>
|
41
|
+
<% end %>
|
42
|
+
</a>
|
43
|
+
</div>
|
44
|
+
<div class="battle-image-desc trunc-small"><div class="battle-image-inner-desc"><%= truncate(image.description, :length => 35) %></div></div>
|
45
|
+
<div class="battle-image-desc trunc-medium"><div class="battle-image-inner-desc"><%= truncate(image.description, :length => 50) %></div></div>
|
46
|
+
<div class="battle-image-desc trunc-large"><div class="battle-image-inner-desc"><%= truncate(image.description, :length => 70) %></div></div>
|
47
|
+
</a>
|
48
|
+
<%= render "/layouts/lentil/image_popup", :image => image %>
|
49
|
+
</div>
|
50
|
+
<div class="battle-submit-tile battle-result-tile">
|
51
|
+
<h4><%= t('lentil.battle.win_pct') %></h4>
|
52
|
+
<h4><%= number_to_percentage(image.win_pct, :precision => 0) %></h4>
|
53
|
+
<% if image.id == @prev_winner %>
|
54
|
+
<div class="battle-result-arrow-wrap">
|
55
|
+
<p><i class="icon-arrow-left winner-left"></i> <%= t 'lentil.battle.you_picked' %> <i class="icon-arrow-right winner-right"></i></p>
|
56
|
+
</div>
|
57
|
+
<% end %>
|
58
|
+
</div>
|
54
59
|
</div>
|
55
60
|
<% end -%>
|
56
|
-
</div>
|
61
|
+
</div>
|
data/lib/lentil/version.rb
CHANGED
@@ -0,0 +1,711 @@
|
|
1
|
+
(function (ELEMENT) {
|
2
|
+
ELEMENT.matches = ELEMENT.matches || ELEMENT.mozMatchesSelector || ELEMENT.msMatchesSelector || ELEMENT.oMatchesSelector || ELEMENT.webkitMatchesSelector || function matches(selector) {
|
3
|
+
var
|
4
|
+
element = this,
|
5
|
+
elements = (element.document || element.ownerDocument).querySelectorAll(selector),
|
6
|
+
index = 0;
|
7
|
+
|
8
|
+
while (elements[index] && elements[index] !== element) {
|
9
|
+
++index;
|
10
|
+
}
|
11
|
+
|
12
|
+
return elements[index] ? true : false;
|
13
|
+
};
|
14
|
+
|
15
|
+
ELEMENT.closest = ELEMENT.closest || function closest(selector) {
|
16
|
+
var element = this;
|
17
|
+
|
18
|
+
while (element) {
|
19
|
+
if (element.matches(selector)) {
|
20
|
+
break;
|
21
|
+
}
|
22
|
+
|
23
|
+
element = element.parentElement;
|
24
|
+
}
|
25
|
+
|
26
|
+
return element;
|
27
|
+
};
|
28
|
+
}(Element.prototype));
|
29
|
+
|
30
|
+
/*!
|
31
|
+
* A polyfill for Webkit's window.getMatchedCSSRules, based on
|
32
|
+
* https://gist.github.com/ydaniv/3033012
|
33
|
+
*
|
34
|
+
* @author: Yehonatan Daniv
|
35
|
+
* @author: ssafejava
|
36
|
+
* @author: Christian "Schepp" Schaefer <schaepp@gmx.de>
|
37
|
+
*
|
38
|
+
*/
|
39
|
+
|
40
|
+
'use strict';
|
41
|
+
|
42
|
+
(function () {
|
43
|
+
// polyfill window.getMatchedCSSRules() in FireFox 6+
|
44
|
+
if (typeof window.getMatchedCSSRules === 'function') {
|
45
|
+
return;
|
46
|
+
}
|
47
|
+
|
48
|
+
var ELEMENT_RE = /[\w-]+/g,
|
49
|
+
ID_RE = /#[\w-]+/g,
|
50
|
+
CLASS_RE = /\.[\w-]+/g,
|
51
|
+
ATTR_RE = /\[[^\]]+\]/g,
|
52
|
+
// :not() pseudo-class does not add to specificity, but its content does as if it was outside it
|
53
|
+
PSEUDO_CLASSES_RE = /\:(?!not)[\w-]+(\(.*\))?/g,
|
54
|
+
PSEUDO_ELEMENTS_RE = /\:\:?(after|before|first-letter|first-line|selection)/g;
|
55
|
+
|
56
|
+
// convert an array-like object to array
|
57
|
+
var toArray = function (list) {
|
58
|
+
var items = [];
|
59
|
+
var i = 0;
|
60
|
+
var listLength = list.length;
|
61
|
+
|
62
|
+
for (; i < listLength; i++) {
|
63
|
+
items.push(list[i]);
|
64
|
+
}
|
65
|
+
|
66
|
+
return items;
|
67
|
+
};
|
68
|
+
|
69
|
+
// get host of stylesheet
|
70
|
+
var getCSSHost = function (href) {
|
71
|
+
var fakeLinkOfSheet = document.createElement('a');
|
72
|
+
|
73
|
+
fakeLinkOfSheet.href = href;
|
74
|
+
|
75
|
+
return fakeLinkOfSheet.host;
|
76
|
+
};
|
77
|
+
|
78
|
+
// handles extraction of `cssRules` as an `Array` from a stylesheet or something that behaves the same
|
79
|
+
var getSheetRules = function (stylesheet) {
|
80
|
+
var sheetMedia = stylesheet.media && stylesheet.media.mediaText;
|
81
|
+
var sheetHost;
|
82
|
+
|
83
|
+
// if this sheet is cross-origin and option is set skip it
|
84
|
+
if (objectFit.disableCrossDomain == 'true') {
|
85
|
+
sheetHost = getCSSHost(stylesheet.href);
|
86
|
+
|
87
|
+
if ((sheetHost !== window.location.host)) {
|
88
|
+
return [];
|
89
|
+
}
|
90
|
+
}
|
91
|
+
|
92
|
+
|
93
|
+
// if this sheet is disabled skip it
|
94
|
+
if (stylesheet.disabled) {
|
95
|
+
return [];
|
96
|
+
}
|
97
|
+
|
98
|
+
if (!window.matchMedia) {
|
99
|
+
if (sheetMedia && sheetMedia.length) {
|
100
|
+
return [];
|
101
|
+
}
|
102
|
+
}
|
103
|
+
// if this sheet's media is specified and doesn't match the viewport then skip it
|
104
|
+
else if (sheetMedia && sheetMedia.length && ! window.matchMedia(sheetMedia).matches) {
|
105
|
+
return [];
|
106
|
+
}
|
107
|
+
|
108
|
+
// get the style rules of this sheet
|
109
|
+
return toArray(stylesheet.cssRules);
|
110
|
+
};
|
111
|
+
|
112
|
+
var _find = function (string, re) {
|
113
|
+
var matches = string.match(re);
|
114
|
+
|
115
|
+
return re ? re.length : 0;
|
116
|
+
};
|
117
|
+
|
118
|
+
// calculates the specificity of a given `selector`
|
119
|
+
var calculateScore = function (selector) {
|
120
|
+
var score = [0, 0, 0];
|
121
|
+
var parts = selector.split(' ');
|
122
|
+
var part;
|
123
|
+
var match;
|
124
|
+
|
125
|
+
//TODO: clean the ':not' part since the last ELEMENT_RE will pick it up
|
126
|
+
while (part = parts.shift(), typeof part === 'string') {
|
127
|
+
// find all pseudo-elements
|
128
|
+
match = _find(part, PSEUDO_ELEMENTS_RE);
|
129
|
+
score[2] = match;
|
130
|
+
// and remove them
|
131
|
+
match && (part = part.replace(PSEUDO_ELEMENTS_RE, ''));
|
132
|
+
// find all pseudo-classes
|
133
|
+
match = _find(part, PSEUDO_CLASSES_RE);
|
134
|
+
score[1] = match;
|
135
|
+
// and remove them
|
136
|
+
match && (part = part.replace(PSEUDO_CLASSES_RE, ''));
|
137
|
+
// find all attributes
|
138
|
+
match = _find(part, ATTR_RE);
|
139
|
+
score[1] += match;
|
140
|
+
// and remove them
|
141
|
+
match && (part = part.replace(ATTR_RE, ''));
|
142
|
+
// find all IDs
|
143
|
+
match = _find(part, ID_RE);
|
144
|
+
score[0] = match;
|
145
|
+
// and remove them
|
146
|
+
match && (part = part.replace(ID_RE, ''));
|
147
|
+
// find all classes
|
148
|
+
match = _find(part, CLASS_RE);
|
149
|
+
score[1] += match;
|
150
|
+
// and remove them
|
151
|
+
match && (part = part.replace(CLASS_RE, ''));
|
152
|
+
// find all elements
|
153
|
+
score[2] += _find(part, ELEMENT_RE);
|
154
|
+
}
|
155
|
+
|
156
|
+
return parseInt(score.join(''), 10);
|
157
|
+
};
|
158
|
+
|
159
|
+
// returns the heights possible specificity score an element can get from a give rule's selectorText
|
160
|
+
var getSpecificityScore = function (element, selectorText) {
|
161
|
+
var selectors = selectorText.split(','),
|
162
|
+
selector, score, result = 0;
|
163
|
+
|
164
|
+
while (selector = selectors.shift()) {
|
165
|
+
if (element.closest(selector)) {
|
166
|
+
score = calculateScore(selector);
|
167
|
+
result = score > result ? score : result;
|
168
|
+
}
|
169
|
+
}
|
170
|
+
|
171
|
+
return result;
|
172
|
+
};
|
173
|
+
|
174
|
+
var sortBySpecificity = function (element, rules) {
|
175
|
+
// comparing function that sorts CSSStyleRules according to specificity of their `selectorText`
|
176
|
+
var compareSpecificity = function (a, b) {
|
177
|
+
return getSpecificityScore(element, b.selectorText) - getSpecificityScore(element, a.selectorText);
|
178
|
+
};
|
179
|
+
|
180
|
+
return rules.sort(compareSpecificity);
|
181
|
+
};
|
182
|
+
|
183
|
+
//TODO: not supporting 2nd argument for selecting pseudo elements
|
184
|
+
//TODO: not supporting 3rd argument for checking author style sheets only
|
185
|
+
window.getMatchedCSSRules = function (element) { /*, pseudo, author_only*/
|
186
|
+
var styleSheets;
|
187
|
+
var result = [];
|
188
|
+
var sheet;
|
189
|
+
var rules;
|
190
|
+
var rule;
|
191
|
+
|
192
|
+
// get stylesheets and convert to a regular Array
|
193
|
+
styleSheets = toArray(window.document.styleSheets);
|
194
|
+
|
195
|
+
// assuming the browser hands us stylesheets in order of appearance
|
196
|
+
// we iterate them from the beginning to follow proper cascade order
|
197
|
+
while (sheet = styleSheets.shift()) {
|
198
|
+
// get the style rules of this sheet
|
199
|
+
rules = getSheetRules(sheet);
|
200
|
+
|
201
|
+
// loop the rules in order of appearance
|
202
|
+
while (rule = rules.shift()) {
|
203
|
+
// if this is an @import rule
|
204
|
+
if (rule.styleSheet) {
|
205
|
+
// insert the imported stylesheet's rules at the beginning of this stylesheet's rules
|
206
|
+
rules = getSheetRules(rule.styleSheet).concat(rules);
|
207
|
+
// and skip this rule
|
208
|
+
continue;
|
209
|
+
}
|
210
|
+
// if there's no stylesheet attribute BUT there IS a media attribute it's a media rule
|
211
|
+
else if (rule.media) {
|
212
|
+
// insert the contained rules of this media rule to the beginning of this stylesheet's rules
|
213
|
+
rules = getSheetRules(rule).concat(rules);
|
214
|
+
// and skip it
|
215
|
+
continue;
|
216
|
+
}
|
217
|
+
|
218
|
+
// check if this element matches this rule's selector
|
219
|
+
if (element.closest(rule.selectorText)) {
|
220
|
+
// push the rule to the results set
|
221
|
+
result.push(rule);
|
222
|
+
}
|
223
|
+
}
|
224
|
+
}
|
225
|
+
// sort according to specificity
|
226
|
+
return sortBySpecificity(element, result);
|
227
|
+
};
|
228
|
+
}());
|
229
|
+
|
230
|
+
/*
|
231
|
+
* raf.js
|
232
|
+
* https://github.com/ngryman/raf.js
|
233
|
+
*
|
234
|
+
* original requestAnimationFrame polyfill by Erik Möller
|
235
|
+
* inspired from paul_irish gist and post
|
236
|
+
*
|
237
|
+
* Copyright (c) 2013 ngryman
|
238
|
+
* Licensed under the MIT license.
|
239
|
+
*/
|
240
|
+
|
241
|
+
(function(window) {
|
242
|
+
var lastTime = 0,
|
243
|
+
vendors = ['webkit', 'moz'],
|
244
|
+
requestAnimationFrame = window.requestAnimationFrame,
|
245
|
+
cancelAnimationFrame = window.cancelAnimationFrame,
|
246
|
+
i = vendors.length;
|
247
|
+
|
248
|
+
// try to un-prefix existing raf
|
249
|
+
while (--i >= 0 && !requestAnimationFrame) {
|
250
|
+
requestAnimationFrame = window[vendors[i] + 'RequestAnimationFrame'];
|
251
|
+
cancelAnimationFrame = window[vendors[i] + 'CancelAnimationFrame'];
|
252
|
+
}
|
253
|
+
|
254
|
+
// polyfill with setTimeout fallback
|
255
|
+
// heavily inspired from @darius gist mod: https://gist.github.com/paulirish/1579671#comment-837945
|
256
|
+
if (!requestAnimationFrame || !cancelAnimationFrame) {
|
257
|
+
requestAnimationFrame = function(callback) {
|
258
|
+
var now = +new Date(), nextTime = Math.max(lastTime + 16, now);
|
259
|
+
return setTimeout(function() {
|
260
|
+
callback(lastTime = nextTime);
|
261
|
+
}, nextTime - now);
|
262
|
+
};
|
263
|
+
|
264
|
+
cancelAnimationFrame = clearTimeout;
|
265
|
+
}
|
266
|
+
|
267
|
+
// export to window
|
268
|
+
window.requestAnimationFrame = requestAnimationFrame;
|
269
|
+
window.cancelAnimationFrame = cancelAnimationFrame;
|
270
|
+
}(window));
|
271
|
+
|
272
|
+
/*!
|
273
|
+
* Polyfill CSS object-fit
|
274
|
+
* http://helloanselm.com/object-fit
|
275
|
+
*
|
276
|
+
* @author: Anselm Hannemann <hello@anselm-hannemann.com>
|
277
|
+
* @author: Christian "Schepp" Schaefer <schaepp@gmx.de>
|
278
|
+
* @version: 0.3.4
|
279
|
+
*
|
280
|
+
*/
|
281
|
+
|
282
|
+
(function (global) {
|
283
|
+
|
284
|
+
'use strict';
|
285
|
+
|
286
|
+
// Storage variable
|
287
|
+
var objectFit = {};
|
288
|
+
|
289
|
+
objectFit._debug = false;
|
290
|
+
|
291
|
+
objectFit.observer = null;
|
292
|
+
|
293
|
+
objectFit.disableCrossDomain = 'false';
|
294
|
+
|
295
|
+
objectFit.getComputedStyle = function(element, context) {
|
296
|
+
context = context || window;
|
297
|
+
|
298
|
+
if (context.getComputedStyle) {
|
299
|
+
return context.getComputedStyle(element, null);
|
300
|
+
}
|
301
|
+
else {
|
302
|
+
return element.currentStyle;
|
303
|
+
}
|
304
|
+
};
|
305
|
+
|
306
|
+
objectFit.getDefaultComputedStyle = function(element){
|
307
|
+
var newelement = element.cloneNode(true);
|
308
|
+
var styles = {};
|
309
|
+
var iframe = document.createElement('iframe');
|
310
|
+
document.body.appendChild(iframe);
|
311
|
+
iframe.contentWindow.document.open();
|
312
|
+
iframe.contentWindow.document.write('<body></body>');
|
313
|
+
iframe.contentWindow.document.body.appendChild(newelement);
|
314
|
+
iframe.contentWindow.document.close();
|
315
|
+
|
316
|
+
var defaultElement = iframe.contentWindow.document.querySelectorAll(element.nodeName.toLowerCase())[0];
|
317
|
+
var defaultComputedStyle = this.getComputedStyle(defaultElement, iframe.contentWindow);
|
318
|
+
var value;
|
319
|
+
var property;
|
320
|
+
|
321
|
+
for (property in defaultComputedStyle) {
|
322
|
+
if (defaultComputedStyle.getPropertyValue === true) {
|
323
|
+
value = defaultComputedStyle.getPropertyValue(property);
|
324
|
+
} else {
|
325
|
+
value = defaultComputedStyle[property];
|
326
|
+
}
|
327
|
+
|
328
|
+
if (value !== null) {
|
329
|
+
switch (property) {
|
330
|
+
default:
|
331
|
+
styles[property] = value;
|
332
|
+
break;
|
333
|
+
|
334
|
+
case 'width':
|
335
|
+
case 'height':
|
336
|
+
case 'minWidth':
|
337
|
+
case 'minHeight':
|
338
|
+
case 'maxWidth':
|
339
|
+
case 'maxHeight':
|
340
|
+
break;
|
341
|
+
}
|
342
|
+
}
|
343
|
+
}
|
344
|
+
|
345
|
+
document.body.removeChild(iframe);
|
346
|
+
|
347
|
+
return styles;
|
348
|
+
};
|
349
|
+
|
350
|
+
objectFit.getMatchedStyle = function(element, property){
|
351
|
+
// element property has highest priority
|
352
|
+
var val = null;
|
353
|
+
var inlineval = null;
|
354
|
+
|
355
|
+
if (element.style.getPropertyValue) {
|
356
|
+
inlineval = element.style.getPropertyValue(property);
|
357
|
+
} else if (element.currentStyle) {
|
358
|
+
inlineval = element.currentStyle[property];
|
359
|
+
}
|
360
|
+
|
361
|
+
// get matched rules
|
362
|
+
var rules = window.getMatchedCSSRules(element);
|
363
|
+
var i = rules.length;
|
364
|
+
var r;
|
365
|
+
var important;
|
366
|
+
|
367
|
+
if (i) {
|
368
|
+
// iterate the rules backwards
|
369
|
+
// rules are ordered by priority, highest last
|
370
|
+
for (; i --> 0;) {
|
371
|
+
r = rules[i];
|
372
|
+
important = r.style.getPropertyPriority(property);
|
373
|
+
|
374
|
+
// if set, only reset if important
|
375
|
+
if (val === null || important) {
|
376
|
+
val = r.style.getPropertyValue(property);
|
377
|
+
|
378
|
+
// done if important
|
379
|
+
if (important) {
|
380
|
+
break;
|
381
|
+
}
|
382
|
+
}
|
383
|
+
}
|
384
|
+
}
|
385
|
+
|
386
|
+
// if it's important, we are done
|
387
|
+
if (!val && inlineval !== null) {
|
388
|
+
val = inlineval;
|
389
|
+
}
|
390
|
+
|
391
|
+
return val;
|
392
|
+
};
|
393
|
+
|
394
|
+
// Detects orientation
|
395
|
+
objectFit.orientation = function(replacedElement) {
|
396
|
+
if (replacedElement.parentNode && replacedElement.parentNode.nodeName.toLowerCase() === 'x-object-fit') {
|
397
|
+
var width = replacedElement.naturalWidth || replacedElement.clientWidth;
|
398
|
+
var height = replacedElement.naturalHeight || replacedElement.clientHeight;
|
399
|
+
var parentWidth = replacedElement.parentNode.clientWidth;
|
400
|
+
var parentHeight = replacedElement.parentNode.clientHeight;
|
401
|
+
|
402
|
+
if (!height || width / height > parentWidth / parentHeight) {
|
403
|
+
if (replacedElement.getAttribute('data-x-object-relation') !== 'wider') {
|
404
|
+
replacedElement.setAttribute('data-x-object-relation','wider');
|
405
|
+
replacedElement.className += ' x-object-fit-wider';
|
406
|
+
|
407
|
+
if (this._debug && window.console) {
|
408
|
+
console.log('x-object-fit-wider');
|
409
|
+
}
|
410
|
+
}
|
411
|
+
} else {
|
412
|
+
if (replacedElement.getAttribute('data-x-object-relation') !== 'taller') {
|
413
|
+
replacedElement.setAttribute('data-x-object-relation','taller');
|
414
|
+
replacedElement.className += ' x-object-fit-taller';
|
415
|
+
|
416
|
+
if (this._debug && window.console) {
|
417
|
+
console.log('x-object-fit-taller');
|
418
|
+
}
|
419
|
+
}
|
420
|
+
}
|
421
|
+
}
|
422
|
+
};
|
423
|
+
|
424
|
+
objectFit.process = function(args) {
|
425
|
+
if (!args.selector || !args.replacedElements) {
|
426
|
+
return;
|
427
|
+
}
|
428
|
+
|
429
|
+
// Set option objectFit.disableCrossDomain
|
430
|
+
objectFit.disableCrossDomain = args.disableCrossDomain || 'false';
|
431
|
+
|
432
|
+
// Set option fit-type
|
433
|
+
args.fittype = args.fittype || 'none';
|
434
|
+
|
435
|
+
switch (args.fittype) {
|
436
|
+
default:
|
437
|
+
return;
|
438
|
+
|
439
|
+
case 'none':
|
440
|
+
case 'fill':
|
441
|
+
case 'contain':
|
442
|
+
case 'cover':
|
443
|
+
break;
|
444
|
+
}
|
445
|
+
|
446
|
+
// Set option replacedElements
|
447
|
+
var replacedElements = args.replacedElements;
|
448
|
+
|
449
|
+
if(!replacedElements.length) {
|
450
|
+
return;
|
451
|
+
}
|
452
|
+
|
453
|
+
for (var i = 0, replacedElementsLength = replacedElements.length; i < replacedElementsLength; i++) {
|
454
|
+
this.processElement(replacedElements[i], args);
|
455
|
+
}
|
456
|
+
};
|
457
|
+
|
458
|
+
objectFit.processElement = function(replacedElement, args) {
|
459
|
+
var property;
|
460
|
+
var value;
|
461
|
+
var replacedElementStyles = objectFit.getComputedStyle(replacedElement);
|
462
|
+
var replacedElementDefaultStyles = objectFit.getDefaultComputedStyle(replacedElement);
|
463
|
+
var wrapperElement = document.createElement('x-object-fit');
|
464
|
+
|
465
|
+
if (objectFit._debug && window.console) {
|
466
|
+
console.log('Applying to WRAPPER-------------------------------------------------------');
|
467
|
+
}
|
468
|
+
|
469
|
+
for (property in replacedElementStyles) {
|
470
|
+
switch (property) {
|
471
|
+
default:
|
472
|
+
value = objectFit.getMatchedStyle(replacedElement, property);
|
473
|
+
|
474
|
+
if (value !== null && value !== '') {
|
475
|
+
if (objectFit._debug && window.console) {
|
476
|
+
console.log(property + ': ' + value);
|
477
|
+
}
|
478
|
+
|
479
|
+
wrapperElement.style[property] = value;
|
480
|
+
}
|
481
|
+
break;
|
482
|
+
|
483
|
+
case 'length':
|
484
|
+
case 'parentRule':
|
485
|
+
break;
|
486
|
+
}
|
487
|
+
}
|
488
|
+
|
489
|
+
if (objectFit._debug && window.console) {
|
490
|
+
console.log('Applying to REPLACED ELEMENT-------------------------------------------------------');
|
491
|
+
}
|
492
|
+
for (property in replacedElementDefaultStyles) {
|
493
|
+
switch (property) {
|
494
|
+
default:
|
495
|
+
value = replacedElementDefaultStyles[property];
|
496
|
+
|
497
|
+
if (objectFit._debug && window.console && value !== '') {
|
498
|
+
console.log(property + ': ' + value);
|
499
|
+
|
500
|
+
if (replacedElement.style[property] === undefined) {
|
501
|
+
console.log('Indexed style properties (`' + property + '`) not supported in: ' + window.navigator.userAgent);
|
502
|
+
}
|
503
|
+
}
|
504
|
+
|
505
|
+
if (replacedElement.style[property]) {
|
506
|
+
replacedElement.style[property] = value; // should work in Firefox 35+ and all other browsers
|
507
|
+
} else {
|
508
|
+
replacedElement.style.property = value;
|
509
|
+
}
|
510
|
+
break;
|
511
|
+
|
512
|
+
case 'length':
|
513
|
+
case 'parentRule':
|
514
|
+
break;
|
515
|
+
}
|
516
|
+
}
|
517
|
+
|
518
|
+
wrapperElement.setAttribute('class','x-object-fit-' + args.fittype);
|
519
|
+
replacedElement.parentNode.insertBefore(wrapperElement, replacedElement);
|
520
|
+
wrapperElement.appendChild(replacedElement);
|
521
|
+
|
522
|
+
objectFit.orientation(replacedElement);
|
523
|
+
|
524
|
+
var resizeTimer = null;
|
525
|
+
var resizeAction = function () {
|
526
|
+
if (resizeTimer !== null) {
|
527
|
+
window.cancelAnimationFrame(resizeTimer);
|
528
|
+
}
|
529
|
+
resizeTimer = window.requestAnimationFrame(function(){
|
530
|
+
objectFit.orientation(replacedElement);
|
531
|
+
});
|
532
|
+
};
|
533
|
+
|
534
|
+
switch (args.fittype) {
|
535
|
+
default:
|
536
|
+
break;
|
537
|
+
|
538
|
+
case 'contain':
|
539
|
+
case 'cover':
|
540
|
+
if (window.addEventListener) {
|
541
|
+
replacedElement.addEventListener('load', resizeAction, false);
|
542
|
+
window.addEventListener('resize', resizeAction, false);
|
543
|
+
window.addEventListener('orientationchange', resizeAction, false);
|
544
|
+
} else {
|
545
|
+
replacedElement.attachEvent('onload', resizeAction);
|
546
|
+
window.attachEvent('onresize', resizeAction);
|
547
|
+
}
|
548
|
+
break;
|
549
|
+
}
|
550
|
+
};
|
551
|
+
|
552
|
+
objectFit.listen = function (args) {
|
553
|
+
var domInsertedAction = function (element){
|
554
|
+
var i = 0;
|
555
|
+
var argsLength = args.length;
|
556
|
+
|
557
|
+
for (; i < argsLength; i++) {
|
558
|
+
if ((element.mozMatchesSelector && element.mozMatchesSelector(args[i].selector)) ||
|
559
|
+
(element.msMatchesSelector && element.msMatchesSelector(args[i].selector)) ||
|
560
|
+
(element.oMatchesSelector && element.oMatchesSelector(args[i].selector)) ||
|
561
|
+
(element.webkitMatchesSelector && element.webkitMatchesSelector(args[i].selector))
|
562
|
+
) {
|
563
|
+
args[i].replacedElements = [element];
|
564
|
+
objectFit.process(args[i]);
|
565
|
+
|
566
|
+
if (objectFit._debug && window.console) {
|
567
|
+
console.log('Matching node inserted: ' + element.nodeName);
|
568
|
+
}
|
569
|
+
}
|
570
|
+
}
|
571
|
+
};
|
572
|
+
|
573
|
+
var domInsertedObserverFunction = function (element) {
|
574
|
+
objectFit.observer.disconnect();
|
575
|
+
domInsertedAction(element);
|
576
|
+
objectFit.observer.observe(document.documentElement, {
|
577
|
+
childList: true,
|
578
|
+
subtree: true
|
579
|
+
});
|
580
|
+
};
|
581
|
+
|
582
|
+
var domInsertedEventFunction = function (event) {
|
583
|
+
window.removeEventListener('DOMNodeInserted', domInsertedEventFunction, false);
|
584
|
+
domInsertedAction(event.target);
|
585
|
+
window.addEventListener('DOMNodeInserted', domInsertedEventFunction, false);
|
586
|
+
};
|
587
|
+
|
588
|
+
var domRemovedAction = function (element) {
|
589
|
+
if (element.nodeName.toLowerCase() === 'x-object-fit') {
|
590
|
+
element.parentNode.removeChild(element);
|
591
|
+
|
592
|
+
if (objectFit._debug && window.console) {
|
593
|
+
console.log('Matching node removed: ' + element.nodeName);
|
594
|
+
}
|
595
|
+
}
|
596
|
+
};
|
597
|
+
|
598
|
+
var domRemovedObserverFunction = function (element) {
|
599
|
+
objectFit.observer.disconnect();
|
600
|
+
domRemovedAction(element);
|
601
|
+
objectFit.observer.observe(document.documentElement, {
|
602
|
+
childList: true,
|
603
|
+
subtree: true
|
604
|
+
});
|
605
|
+
};
|
606
|
+
|
607
|
+
var domRemovedEventFunction = function (event) {
|
608
|
+
window.removeEventListener('DOMNodeRemoved', domRemovedEventFunction, false);
|
609
|
+
domRemovedAction(event.target.parentNode);
|
610
|
+
window.addEventListener('DOMNodeRemoved', domRemovedEventFunction, false);
|
611
|
+
};
|
612
|
+
|
613
|
+
if (window.MutationObserver) {
|
614
|
+
if (objectFit._debug && window.console) {
|
615
|
+
console.log('DOM MutationObserver');
|
616
|
+
}
|
617
|
+
|
618
|
+
this.observer = new MutationObserver(function(mutations) {
|
619
|
+
mutations.forEach(function(mutation) {
|
620
|
+
if (mutation.addedNodes && mutation.addedNodes.length) {
|
621
|
+
var nodes = mutation.addedNodes;
|
622
|
+
for (var i = 0, nodesLength = nodes.length; i < nodesLength; i++) {
|
623
|
+
domInsertedObserverFunction(nodes[i]);
|
624
|
+
}
|
625
|
+
}
|
626
|
+
if (mutation.removedNodes && mutation.removedNodes.length) {
|
627
|
+
domRemovedObserverFunction(mutation.target);
|
628
|
+
}
|
629
|
+
});
|
630
|
+
});
|
631
|
+
|
632
|
+
this.observer.observe(document.documentElement, {
|
633
|
+
childList: true,
|
634
|
+
subtree: true
|
635
|
+
});
|
636
|
+
} else if (window.addEventListener) {
|
637
|
+
if (objectFit._debug && window.console) {
|
638
|
+
console.log('DOM Mutation Events');
|
639
|
+
}
|
640
|
+
|
641
|
+
window.addEventListener('DOMNodeInserted', domInsertedEventFunction, false);
|
642
|
+
window.addEventListener('DOMNodeRemoved', domRemovedEventFunction, false);
|
643
|
+
}
|
644
|
+
};
|
645
|
+
|
646
|
+
objectFit.init = function (args) {
|
647
|
+
if (!args) {
|
648
|
+
return;
|
649
|
+
}
|
650
|
+
|
651
|
+
if (!(args instanceof Array)) {
|
652
|
+
args = [args];
|
653
|
+
}
|
654
|
+
|
655
|
+
var i = 0;
|
656
|
+
var argsLength = args.length;
|
657
|
+
|
658
|
+
for (; i < argsLength; i++) {
|
659
|
+
args[i].replacedElements = document.querySelectorAll(args[i].selector);
|
660
|
+
this.process(args[i]);
|
661
|
+
}
|
662
|
+
|
663
|
+
this.listen(args);
|
664
|
+
};
|
665
|
+
|
666
|
+
objectFit.polyfill = function (args) {
|
667
|
+
if('objectFit' in document.documentElement.style === false) {
|
668
|
+
if (objectFit._debug && window.console) {
|
669
|
+
console.log('object-fit not natively supported');
|
670
|
+
}
|
671
|
+
|
672
|
+
// If the library is loaded after document onload event
|
673
|
+
if (document.readyState === 'complete') {
|
674
|
+
objectFit.init(args);
|
675
|
+
} else {
|
676
|
+
// Otherwise attach event listeners
|
677
|
+
if (window.addEventListener) {
|
678
|
+
window.addEventListener('load', function(){
|
679
|
+
objectFit.init(args);
|
680
|
+
}, false);
|
681
|
+
} else {
|
682
|
+
window.attachEvent('onload', function(){
|
683
|
+
objectFit.init(args);
|
684
|
+
});
|
685
|
+
}
|
686
|
+
}
|
687
|
+
} else {
|
688
|
+
if (objectFit._debug && window.console) {
|
689
|
+
console.log('object-fit natively supported');
|
690
|
+
}
|
691
|
+
}
|
692
|
+
};
|
693
|
+
|
694
|
+
/*
|
695
|
+
* AMD, module loader, global registration
|
696
|
+
*/
|
697
|
+
|
698
|
+
// Expose modal for loaders that implement the Node module pattern.
|
699
|
+
if (typeof module === 'object' && module && typeof module.exports === 'object') {
|
700
|
+
module.exports = objectFit;
|
701
|
+
|
702
|
+
// Register as an AMD module
|
703
|
+
} else if (typeof define === 'function' && define.amd) {
|
704
|
+
define([], function () { return objectFit; });
|
705
|
+
|
706
|
+
// Export into global space
|
707
|
+
} else if (typeof global === 'object' && typeof global.document === 'object') {
|
708
|
+
global.objectFit = objectFit;
|
709
|
+
}
|
710
|
+
|
711
|
+
}(window));
|