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.
@@ -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
- <%= image_tag(image.jpeg, :class => "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}) %>
10
- <% else %>
11
- <a href="<%= url_for(image) %>" data-fancybox-href= "<%= image.video_url %>" class="fancybox">
12
- <%= video_tag(image.video_url, :class => "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}) %>
13
- <% end %>
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
- </a>
18
- <%= render "/layouts/lentil/image_popup", :image => image %>
19
- <%= f.input :id, :as => :hidden %>
20
+ <%= render "/layouts/lentil/image_popup", :image => image %>
21
+ <%= f.input :id, :as => :hidden %>
20
22
 
21
- </div>
22
- <div class="battle-submit-tile">
23
- <%= f.action :submit, :as => :button, :label => t('lentil.battle.pick_me'), :button_html => {:value => "#{image.id}", :name => "vote", :class => "btn btn-large battle-form"} %>
24
- </div>
25
- <% end -%>
26
- </div>
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
- <% end -%>
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
- <div id="image_<%= image.id %>" class="battle-image-tile">
32
- <% unless image.media_type == "video" %>
33
- <a href="<%= url_for(image) %>" data-fancybox-href= "<%= image.jpeg %>" class="fancybox">
34
- <%= image_tag(image.jpeg, :class => "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}) %>
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
- <%= video_tag(image.video_url, :class => "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}) %>
38
- <% end %>
39
- <div class="battle-image-desc trunc-small"><div class="battle-image-inner-desc"><%= truncate(image.description, :length => 35) %></div></div>
40
- <div class="battle-image-desc trunc-medium"><div class="battle-image-inner-desc"><%= truncate(image.description, :length => 50) %></div></div>
41
- <div class="battle-image-desc trunc-large"><div class="battle-image-inner-desc"><%= truncate(image.description, :length => 70) %></div></div>
42
- </a>
43
- <%= render "/layouts/lentil/image_popup", :image => image %>
44
- </div>
45
- <div class="battle-submit-tile battle-result-tile">
46
- <h4><%= t('lentil.battle.win_pct') %></h4>
47
- <h4><%= number_to_percentage(image.win_pct, :precision => 0) %></h4>
48
- <% if image.id == @prev_winner %>
49
- <div class="battle-result-arrow-wrap">
50
- <p><i class="icon-arrow-left winner-left"></i> <%= t 'lentil.battle.you_picked' %> <i class="icon-arrow-right winner-right"></i></p>
51
- </div>
52
- <% end %>
53
- </div>
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>
@@ -1,3 +1,3 @@
1
1
  module Lentil
2
- VERSION = "0.6.0"
2
+ VERSION = "0.7.1"
3
3
  end
@@ -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));