OLD | NEW |
(Empty) | |
| 1 Polymer({ |
| 2 is: 'iron-image', |
| 3 |
| 4 properties: { |
| 5 /** |
| 6 * The URL of an image. |
| 7 */ |
| 8 src: { |
| 9 observer: '_srcChanged', |
| 10 type: String, |
| 11 value: '' |
| 12 }, |
| 13 |
| 14 /** |
| 15 * A short text alternative for the image. |
| 16 */ |
| 17 alt: { |
| 18 type: String, |
| 19 value: null |
| 20 }, |
| 21 |
| 22 /** |
| 23 * When true, the image is prevented from loading and any placeholder is |
| 24 * shown. This may be useful when a binding to the src property is know
n to |
| 25 * be invalid, to prevent 404 requests. |
| 26 */ |
| 27 preventLoad: { |
| 28 type: Boolean, |
| 29 value: false, |
| 30 observer: '_preventLoadChanged' |
| 31 }, |
| 32 |
| 33 /** |
| 34 * Sets a sizing option for the image. Valid values are `contain` (full |
| 35 * aspect ratio of the image is contained within the element and |
| 36 * letterboxed) or `cover` (image is cropped in order to fully cover the |
| 37 * bounds of the element), or `null` (default: image takes natural size)
. |
| 38 */ |
| 39 sizing: { |
| 40 type: String, |
| 41 value: null, |
| 42 reflectToAttribute: true |
| 43 }, |
| 44 |
| 45 /** |
| 46 * When a sizing option is used (`cover` or `contain`), this determines |
| 47 * how the image is aligned within the element bounds. |
| 48 */ |
| 49 position: { |
| 50 type: String, |
| 51 value: 'center' |
| 52 }, |
| 53 |
| 54 /** |
| 55 * When `true`, any change to the `src` property will cause the `placeho
lder` |
| 56 * image to be shown until the new image has loaded. |
| 57 */ |
| 58 preload: { |
| 59 type: Boolean, |
| 60 value: false |
| 61 }, |
| 62 |
| 63 /** |
| 64 * This image will be used as a background/placeholder until the src ima
ge has |
| 65 * loaded. Use of a data-URI for placeholder is encouraged for instant
rendering. |
| 66 */ |
| 67 placeholder: { |
| 68 type: String, |
| 69 value: null, |
| 70 observer: '_placeholderChanged' |
| 71 }, |
| 72 |
| 73 /** |
| 74 * When `preload` is true, setting `fade` to true will cause the image t
o |
| 75 * fade into place. |
| 76 */ |
| 77 fade: { |
| 78 type: Boolean, |
| 79 value: false |
| 80 }, |
| 81 |
| 82 /** |
| 83 * Read-only value that is true when the image is loaded. |
| 84 */ |
| 85 loaded: { |
| 86 notify: true, |
| 87 readOnly: true, |
| 88 type: Boolean, |
| 89 value: false |
| 90 }, |
| 91 |
| 92 /** |
| 93 * Read-only value that tracks the loading state of the image when the `
preload` |
| 94 * option is used. |
| 95 */ |
| 96 loading: { |
| 97 notify: true, |
| 98 readOnly: true, |
| 99 type: Boolean, |
| 100 value: false |
| 101 }, |
| 102 |
| 103 /** |
| 104 * Read-only value that indicates that the last set `src` failed to load
. |
| 105 */ |
| 106 error: { |
| 107 notify: true, |
| 108 readOnly: true, |
| 109 type: Boolean, |
| 110 value: false |
| 111 }, |
| 112 |
| 113 /** |
| 114 * Can be used to set the width of image (e.g. via binding); size may al
so be |
| 115 * set via CSS. |
| 116 */ |
| 117 width: { |
| 118 observer: '_widthChanged', |
| 119 type: Number, |
| 120 value: null |
| 121 }, |
| 122 |
| 123 /** |
| 124 * Can be used to set the height of image (e.g. via binding); size may a
lso be |
| 125 * set via CSS. |
| 126 * |
| 127 * @attribute height |
| 128 * @type number |
| 129 * @default null |
| 130 */ |
| 131 height: { |
| 132 observer: '_heightChanged', |
| 133 type: Number, |
| 134 value: null |
| 135 }, |
| 136 }, |
| 137 |
| 138 observers: [ |
| 139 '_transformChanged(sizing, position)' |
| 140 ], |
| 141 |
| 142 ready: function() { |
| 143 var img = this.$.img; |
| 144 |
| 145 img.onload = function() { |
| 146 if (this.$.img.src !== this._resolveSrc(this.src)) return; |
| 147 |
| 148 this._setLoading(false); |
| 149 this._setLoaded(true); |
| 150 this._setError(false); |
| 151 }.bind(this); |
| 152 |
| 153 img.onerror = function() { |
| 154 if (this.$.img.src !== this._resolveSrc(this.src)) return; |
| 155 |
| 156 this._reset(); |
| 157 |
| 158 this._setLoading(false); |
| 159 this._setLoaded(false); |
| 160 this._setError(true); |
| 161 }.bind(this); |
| 162 |
| 163 this._resolvedSrc = ''; |
| 164 }, |
| 165 |
| 166 _load: function(src) { |
| 167 if (src) { |
| 168 this.$.img.src = src; |
| 169 } else { |
| 170 this.$.img.removeAttribute('src'); |
| 171 } |
| 172 this.$.sizedImgDiv.style.backgroundImage = src ? 'url("' + src + '")' :
''; |
| 173 |
| 174 this._setLoading(true); |
| 175 this._setLoaded(false); |
| 176 this._setError(false); |
| 177 }, |
| 178 |
| 179 _reset: function() { |
| 180 this.$.img.removeAttribute('src'); |
| 181 this.$.sizedImgDiv.style.backgroundImage = ''; |
| 182 |
| 183 this._setLoading(false); |
| 184 this._setLoaded(false); |
| 185 this._setError(false); |
| 186 }, |
| 187 |
| 188 _computePlaceholderHidden: function() { |
| 189 return !this.preload || (!this.fade && !this.loading && this.loaded); |
| 190 }, |
| 191 |
| 192 _computePlaceholderClassName: function() { |
| 193 return (this.preload && this.fade && !this.loading && this.loaded) ? 'fa
ded-out' : ''; |
| 194 }, |
| 195 |
| 196 _computeImgDivHidden: function() { |
| 197 return !this.sizing; |
| 198 }, |
| 199 |
| 200 _computeImgDivARIAHidden: function() { |
| 201 return this.alt === '' ? 'true' : undefined; |
| 202 }, |
| 203 |
| 204 _computeImgDivARIALabel: function() { |
| 205 if (this.alt !== null) { |
| 206 return this.alt; |
| 207 } |
| 208 |
| 209 // Polymer.ResolveUrl.resolveUrl will resolve '' relative to a URL x to |
| 210 // that URL x, but '' is the default for src. |
| 211 if (this.src === '') { |
| 212 return ''; |
| 213 } |
| 214 |
| 215 var pathComponents = (new URL(this._resolveSrc(this.src))).pathname.spli
t("/"); |
| 216 return pathComponents[pathComponents.length - 1]; |
| 217 }, |
| 218 |
| 219 _computeImgHidden: function() { |
| 220 return !!this.sizing; |
| 221 }, |
| 222 |
| 223 _widthChanged: function() { |
| 224 this.style.width = isNaN(this.width) ? this.width : this.width + 'px'; |
| 225 }, |
| 226 |
| 227 _heightChanged: function() { |
| 228 this.style.height = isNaN(this.height) ? this.height : this.height + 'px
'; |
| 229 }, |
| 230 |
| 231 _preventLoadChanged: function() { |
| 232 if (this.preventLoad || this.loaded) return; |
| 233 |
| 234 this._reset(); |
| 235 this._load(this.src); |
| 236 }, |
| 237 |
| 238 _srcChanged: function(newSrc, oldSrc) { |
| 239 var newResolvedSrc = this._resolveSrc(newSrc); |
| 240 if (newResolvedSrc === this._resolvedSrc) return; |
| 241 this._resolvedSrc = newResolvedSrc; |
| 242 |
| 243 this._reset(); |
| 244 if (!this.preventLoad) { |
| 245 this._load(newSrc); |
| 246 } |
| 247 }, |
| 248 |
| 249 _placeholderChanged: function() { |
| 250 this.$.placeholder.style.backgroundImage = |
| 251 this.placeholder ? 'url("' + this.placeholder + '")' : ''; |
| 252 }, |
| 253 |
| 254 _transformChanged: function() { |
| 255 var sizedImgDivStyle = this.$.sizedImgDiv.style; |
| 256 var placeholderStyle = this.$.placeholder.style; |
| 257 |
| 258 sizedImgDivStyle.backgroundSize = |
| 259 placeholderStyle.backgroundSize = |
| 260 this.sizing; |
| 261 |
| 262 sizedImgDivStyle.backgroundPosition = |
| 263 placeholderStyle.backgroundPosition = |
| 264 this.sizing ? this.position : ''; |
| 265 |
| 266 sizedImgDivStyle.backgroundRepeat = |
| 267 placeholderStyle.backgroundRepeat = |
| 268 this.sizing ? 'no-repeat' : ''; |
| 269 }, |
| 270 |
| 271 _resolveSrc: function(testSrc) { |
| 272 return Polymer.ResolveUrl.resolveUrl(testSrc, this.ownerDocument.baseURI
); |
| 273 } |
| 274 }); |
OLD | NEW |