-
Notifications
You must be signed in to change notification settings - Fork 6
/
x-picture.html
101 lines (90 loc) · 3.78 KB
/
x-picture.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
<element name="x-picture" attributes="src srcset title alt">
<template>
<style>
img { max-width: 100%; }
</style>
<content select="source"></content>
<img src="{{ src }}" id="the" />
</template>
<script>
var src;
Polymer.register(this, {
ready: function () {
var sources, img, findMatchedMedia, getDensity, getSrcFromElement;
sources = this.getElementsByTagName('source');
img = this.$.the;
getSrcFromElement = function (el) {
var deviceRatio, src, srcs, srcset, imgDPR, min = 1, max = 1;
if (el) {
// src wins if it exists
if (el.src) {
return el.src;
} else if (srcset = el.getAttribute('srcset')) {
// next prefer srcset, parsed for pixel density
//if window.devicePixelRatio is undefined assume dpr === 1
// When defined, win.dpr is always a number, therefore
// it can be parsed as an int.
// If it is < 1 (it never is) it should be treated as 1.
// If it is a float, it will be floored.
// If it is higher than the highest defined srcset, it will use
// the highest defined srcset.
deviceRatio = parseInt(window.devicePixelRatio, 10) || 1;
srcs = srcset.replace(/^\s*|\s*$/g, '').split(',');
for (var i = srcs.length - 1; i >= 0; i--) {
src = srcs[i].replace(/^\s*|\s*$/g, '').split(' ');
// return if we have an exact match
if (src[1].match(deviceRatio + 'x')) {
return src[0];
}
// Prep for edge cases.
imgDPR = (src[1]) ? parseInt(src[1].replace('x', ''), 10): 1;
if (imgDPR > max) {
max = [src[0], imgDPR];
}
if (imgDPR < min) {
min = [src[0], imgDPR];
}
}
// Edge case when dpr is out of range supplied in srcset.
if (deviceRatio > max[1]) {
return max[0];
} else if (deviceRatio < min[1]) {
return min[0];
}
}
} else {
// If there is no src or srcset on the element, no vaild url can exist
return '';
}
};
findMatchedMedia = function () {
var source, i, len, media, mediaLess;
/*
* So the question is do we want the first matched media vis-a-vis <video>,
* or the last match vis-a-vis CSS. I feel like the use of <picture> is more
* akin in spirit to CSS than <video>. So to encourage a mobile first approach
* have similar behavior to CSS media query behavior, the last match wins.
*/
// Backwards to return as early as possible on last source order match.
for (i = sources.length-1; i >= 0; i-- ) {
source = sources[i];
media = source.getAttribute('media');
if (window.matchMedia && window.matchMedia(media).matches) {
return source;
} else if (!media) {
// If no media matches, then the last source with no media attr wins,
// We can't break as there may be a media match up stream which always
// wins over no media so don't overwrite the first medialess source.
mediaLess = mediaLess || source;
}
}
return mediaLess
};
img.src = getSrcFromElement(findMatchedMedia());
window.addEventListener('resize', function (e) {
img.src = getSrcFromElement(findMatchedMedia());
});
}
});
</script>
</element>