lentil 0.6.0 → 0.7.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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));