diff --git a/.travis.yml b/.travis.yml index c14aa95..baacaea 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,31 +1,19 @@ language: node_js sudo: 'false' -before_script: - - npm install -g polymer-cli - - polymer install --variants - - >- - npm run update-types && git diff --exit-code || (echo -e - '\n\033[31mERROR:\033[0m Typings are stale. Please run "npm run - update-types".' && false) - - >- - npm run format && git diff --exit-code || (echo -e '\n\033[31mERROR:\033[0m - Project is not formatted. Please run "npm run format".' && false) +before_script: npm install -g polymer-cli env: global: - - secure: >- - bS/K6VaNmFe29US/L/DyVggFf0oJF71OvhdMCYwhm9aaxatKwKpXJjBYjyuiDASxf9fLlyVWh/5wkIKXw3uMCs4AESf2iqPvFl8f9CdhvE6mj8xjQ8KjrF6rsm7vbJdAgKzw3mg7M8s5VS+3acC7hospm/n0LX5z2wUyvWy0EWo= - - secure: >- - SesBHWzkY+KIPS4cg75+1tG4RdP+2y1ihOj1ib1YmjhVXJ+tiCc9B5GBxR/ARfYOePyhamJ2qT29qG47lr/ACagv33CHK5cRl7YZTLT9euYBYCzMSZxDRgXr1jfbKkbVCBKBC2S6it/1Y3QhA/QPiLIt0w/Wk8d/6s4mydvyh7U= + - secure: bS/K6VaNmFe29US/L/DyVggFf0oJF71OvhdMCYwhm9aaxatKwKpXJjBYjyuiDASxf9fLlyVWh/5wkIKXw3uMCs4AESf2iqPvFl8f9CdhvE6mj8xjQ8KjrF6rsm7vbJdAgKzw3mg7M8s5VS+3acC7hospm/n0LX5z2wUyvWy0EWo= + - secure: SesBHWzkY+KIPS4cg75+1tG4RdP+2y1ihOj1ib1YmjhVXJ+tiCc9B5GBxR/ARfYOePyhamJ2qT29qG47lr/ACagv33CHK5cRl7YZTLT9euYBYCzMSZxDRgXr1jfbKkbVCBKBC2S6it/1Y3QhA/QPiLIt0w/Wk8d/6s4mydvyh7U= node_js: '9' addons: firefox: latest chrome: stable script: - - xvfb-run polymer test - - >- - if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then polymer test -s 'default'; - fi + - xvfb-run polymer test --module-resolution=node --npm + - 'if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then polymer test --module-resolution=node --npm -s ''default''; fi' dist: trusty cache: directories: - node_modules + diff --git a/bower.json b/bower.json deleted file mode 100644 index 67bbd8b..0000000 --- a/bower.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "name": "iron-image", - "version": "2.2.1", - "license": "http://polymer.github.io/LICENSE.txt", - "description": "An image-displaying element with lots of convenient features", - "private": true, - "authors": [ - "The Polymer Authors" - ], - "keywords": [ - "web-components", - "polymer", - "media" - ], - "repository": { - "type": "git", - "url": "git://github.com/PolymerElements/iron-image.git" - }, - "main": "iron-image.html", - "ignore": [], - "dependencies": { - "polymer": "Polymer/polymer#1.9 - 2" - }, - "devDependencies": { - "iron-component-page": "PolymerElements/iron-component-page#1 - 2", - "iron-demo-helpers": "PolymerElements/iron-demo-helpers#1 - 2", - "paper-styles": "PolymerElements/paper-styles#1 - 2", - "web-component-tester": "^6.0.0", - "webcomponentsjs": "webcomponents/webcomponentsjs#^1.0.0" - }, - "variants": { - "1.x": { - "dependencies": { - "polymer": "Polymer/polymer#^1.9" - }, - "devDependencies": { - "iron-component-page": "PolymerElements/iron-component-page#^1.0.0", - "iron-demo-helpers": "PolymerElements/iron-demo-helpers#^1.0.0", - "paper-styles": "PolymerElements/paper-styles#^1.0.4", - "web-component-tester": "^4.0.0", - "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0" - }, - "resolutions": { - "webcomponentsjs": "^0.7" - } - } - }, - "resolutions": { - "webcomponentsjs": "^1.0.0" - } -} diff --git a/demo/index.html b/demo/index.html index 9637b41..7e6779b 100644 --- a/demo/index.html +++ b/demo/index.html @@ -17,14 +17,25 @@ - + - - - - + + + + - + + - + -
+ diff --git a/index.html b/index.html index bb7da82..385fc14 100644 --- a/index.html +++ b/index.html @@ -12,8 +12,8 @@ iron-image - - + + diff --git a/iron-image.d.ts b/iron-image.d.ts deleted file mode 100644 index 29cbf12..0000000 --- a/iron-image.d.ts +++ /dev/null @@ -1,170 +0,0 @@ -/** - * DO NOT EDIT - * - * This file was automatically generated by - * https://github.com/Polymer/gen-typescript-declarations - * - * To modify these typings, edit the source file(s): - * iron-image.html - */ - -/// - -/** - * `iron-image` is an element for displaying an image that provides useful sizing and - * preloading options not found on the standard `` tag. - * - * The `sizing` option allows the image to be either cropped (`cover`) or - * letterboxed (`contain`) to fill a fixed user-size placed on the element. - * - * The `preload` option prevents the browser from rendering the image until the - * image is fully loaded. In the interim, either the element's CSS `background-color` - * can be be used as the placeholder, or the `placeholder` property can be - * set to a URL (preferably a data-URI, for instant rendering) for an - * placeholder image. - * - * The `fade` option (only valid when `preload` is set) will cause the placeholder - * image/color to be faded out once the image is rendered. - * - * Examples: - * - * Basically identical to `` tag: - * - * - * - * Will letterbox the image to fit: - * - * - * - * Will crop the image to fit: - * - * - * - * Will show light-gray background until the image loads: - * - * - * - * Will show a base-64 encoded placeholder image until the image loads: - * - * - * - * Will fade the light-gray background out once the image is loaded: - * - * - * - * Custom property | Description | Default - * ----------------|-------------|---------- - * `--iron-image-placeholder` | Mixin applied to #placeholder | `{}` - * `--iron-image-width` | Sets the width of the wrapped image | `auto` - * `--iron-image-height` | Sets the height of the wrapped image | `auto` - */ -interface IronImageElement extends Polymer.Element { - - /** - * The URL of an image. - */ - src: string|null|undefined; - - /** - * A short text alternative for the image. - */ - alt: string|null|undefined; - - /** - * CORS enabled images support: - * https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image - */ - crossorigin: string|null|undefined; - - /** - * When true, the image is prevented from loading and any placeholder is - * shown. This may be useful when a binding to the src property is known to - * be invalid, to prevent 404 requests. - */ - preventLoad: boolean|null|undefined; - - /** - * Sets a sizing option for the image. Valid values are `contain` (full - * aspect ratio of the image is contained within the element and - * letterboxed) or `cover` (image is cropped in order to fully cover the - * bounds of the element), or `null` (default: image takes natural size). - */ - sizing: string|null|undefined; - - /** - * When a sizing option is used (`cover` or `contain`), this determines - * how the image is aligned within the element bounds. - */ - position: string|null|undefined; - - /** - * When `true`, any change to the `src` property will cause the - * `placeholder` image to be shown until the new image has loaded. - */ - preload: boolean|null|undefined; - - /** - * This image will be used as a background/placeholder until the src image - * has loaded. Use of a data-URI for placeholder is encouraged for instant - * rendering. - */ - placeholder: string|null|undefined; - - /** - * When `preload` is true, setting `fade` to true will cause the image to - * fade into place. - */ - fade: boolean|null|undefined; - - /** - * Read-only value that is true when the image is loaded. - */ - readonly loaded: boolean|null|undefined; - - /** - * Read-only value that tracks the loading state of the image when the - * `preload` option is used. - */ - readonly loading: boolean|null|undefined; - - /** - * Read-only value that indicates that the last set `src` failed to load. - */ - readonly error: boolean|null|undefined; - - /** - * Can be used to set the width of image (e.g. via binding); size may also - * be set via CSS. - */ - width: number|null|undefined; - - /** - * Can be used to set the height of image (e.g. via binding); size may also - * be set via CSS. - */ - height: number|null|undefined; - created(): void; - _imgOnLoad(): void; - _imgOnError(): void; - _computePlaceholderHidden(): any; - _computePlaceholderClassName(): any; - _computeImgDivHidden(): any; - _computeImgDivARIAHidden(): any; - _computeImgDivARIALabel(): any; - _computeImgHidden(): any; - _widthChanged(): void; - _heightChanged(): void; - _loadStateObserver(src: any, preventLoad: any): void; - _placeholderChanged(): void; - _transformChanged(): void; - _resolveSrc(testSrc: any): any; -} - -interface HTMLElementTagNameMap { - "iron-image": IronImageElement; -} diff --git a/iron-image.html b/iron-image.html deleted file mode 100644 index dec9841..0000000 --- a/iron-image.html +++ /dev/null @@ -1,380 +0,0 @@ - - - - - - - - - - - diff --git a/iron-image.js b/iron-image.js new file mode 100644 index 0000000..614bc57 --- /dev/null +++ b/iron-image.js @@ -0,0 +1,371 @@ +/** +@license +Copyright (c) 2016 The Polymer Project Authors. All rights reserved. +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt +The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt +Code distributed by Google as part of the polymer project is also +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt +*/ +/** +`iron-image` is an element for displaying an image that provides useful sizing and +preloading options not found on the standard `` tag. + +The `sizing` option allows the image to be either cropped (`cover`) or +letterboxed (`contain`) to fill a fixed user-size placed on the element. + +The `preload` option prevents the browser from rendering the image until the +image is fully loaded. In the interim, either the element's CSS `background-color` +can be be used as the placeholder, or the `placeholder` property can be +set to a URL (preferably a data-URI, for instant rendering) for an +placeholder image. + +The `fade` option (only valid when `preload` is set) will cause the placeholder +image/color to be faded out once the image is rendered. + +Examples: + + Basically identical to `` tag: + + + + Will letterbox the image to fit: + + + + Will crop the image to fit: + + + + Will show light-gray background until the image loads: + + + + Will show a base-64 encoded placeholder image until the image loads: + + + + Will fade the light-gray background out once the image is loaded: + + + +Custom property | Description | Default +----------------|-------------|---------- +`--iron-image-placeholder` | Mixin applied to #placeholder | `{}` +`--iron-image-width` | Sets the width of the wrapped image | `auto` +`--iron-image-height` | Sets the height of the wrapped image | `auto` + +@group Iron Elements +@element iron-image +@demo demo/index.html +*/ +/* + FIXME(polymer-modulizer): the above comments were extracted + from HTML and may be out of place here. Review them and + then delete this comment! +*/ +import '@polymer/polymer/polymer-legacy.js'; + +import { Polymer } from '@polymer/polymer/lib/legacy/polymer-fn.js'; +import { html } from '@polymer/polymer/lib/utils/html-tag.js'; +import { resolveUrl } from '@polymer/polymer/lib/utils/resolve-url.js'; +Polymer({ + _template: html` + + + + + +
+`, + + is: 'iron-image', + + properties: { + /** + * The URL of an image. + */ + src: {type: String, value: ''}, + + /** + * A short text alternative for the image. + */ + alt: {type: String, value: null}, + + /** + * CORS enabled images support: + * https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image + */ + crossorigin: {type: String, value: null}, + + /** + * When true, the image is prevented from loading and any placeholder is + * shown. This may be useful when a binding to the src property is known to + * be invalid, to prevent 404 requests. + */ + preventLoad: {type: Boolean, value: false}, + + /** + * Sets a sizing option for the image. Valid values are `contain` (full + * aspect ratio of the image is contained within the element and + * letterboxed) or `cover` (image is cropped in order to fully cover the + * bounds of the element), or `null` (default: image takes natural size). + */ + sizing: {type: String, value: null, reflectToAttribute: true}, + + /** + * When a sizing option is used (`cover` or `contain`), this determines + * how the image is aligned within the element bounds. + */ + position: {type: String, value: 'center'}, + + /** + * When `true`, any change to the `src` property will cause the + * `placeholder` image to be shown until the new image has loaded. + */ + preload: {type: Boolean, value: false}, + + /** + * This image will be used as a background/placeholder until the src image + * has loaded. Use of a data-URI for placeholder is encouraged for instant + * rendering. + */ + placeholder: {type: String, value: null, observer: '_placeholderChanged'}, + + /** + * When `preload` is true, setting `fade` to true will cause the image to + * fade into place. + */ + fade: {type: Boolean, value: false}, + + /** + * Read-only value that is true when the image is loaded. + */ + loaded: {notify: true, readOnly: true, type: Boolean, value: false}, + + /** + * Read-only value that tracks the loading state of the image when the + * `preload` option is used. + */ + loading: {notify: true, readOnly: true, type: Boolean, value: false}, + + /** + * Read-only value that indicates that the last set `src` failed to load. + */ + error: {notify: true, readOnly: true, type: Boolean, value: false}, + + /** + * Can be used to set the width of image (e.g. via binding); size may also + * be set via CSS. + */ + width: {observer: '_widthChanged', type: Number, value: null}, + + /** + * Can be used to set the height of image (e.g. via binding); size may also + * be set via CSS. + * + * @attribute height + * @type number + * @default null + */ + height: {observer: '_heightChanged', type: Number, value: null}, + }, + + observers: [ + '_transformChanged(sizing, position)', + '_loadStateObserver(src, preventLoad)' + ], + + created: function() { + this._resolvedSrc = ''; + }, + + _imgOnLoad: function() { + if (this.$.img.src !== this._resolveSrc(this.src)) { + return; + } + + this._setLoading(false); + this._setLoaded(true); + this._setError(false); + }, + + _imgOnError: function() { + if (this.$.img.src !== this._resolveSrc(this.src)) { + return; + } + + this.$.img.removeAttribute('src'); + this.$.sizedImgDiv.style.backgroundImage = ''; + + this._setLoading(false); + this._setLoaded(false); + this._setError(true); + }, + + _computePlaceholderHidden: function() { + return !this.preload || (!this.fade && !this.loading && this.loaded); + }, + + _computePlaceholderClassName: function() { + return (this.preload && this.fade && !this.loading && this.loaded) ? + 'faded-out' : + ''; + }, + + _computeImgDivHidden: function() { + return !this.sizing; + }, + + _computeImgDivARIAHidden: function() { + return this.alt === '' ? 'true' : undefined; + }, + + _computeImgDivARIALabel: function() { + if (this.alt !== null) { + return this.alt; + } + + // Polymer.ResolveUrl.resolveUrl will resolve '' relative to a URL x to + // that URL x, but '' is the default for src. + if (this.src === '') { + return ''; + } + + // NOTE: Use of `URL` was removed here because IE11 doesn't support + // constructing it. If this ends up being problematic, we should + // consider reverting and adding the URL polyfill as a dev dependency. + var resolved = this._resolveSrc(this.src); + // Remove query parts, get file name. + return resolved.replace(/[?|#].*/g, '').split('/').pop(); + }, + + _computeImgHidden: function() { + return !!this.sizing; + }, + + _widthChanged: function() { + this.style.width = isNaN(this.width) ? this.width : this.width + 'px'; + }, + + _heightChanged: function() { + this.style.height = isNaN(this.height) ? this.height : this.height + 'px'; + }, + + _loadStateObserver: function(src, preventLoad) { + var newResolvedSrc = this._resolveSrc(src); + if (newResolvedSrc === this._resolvedSrc) { + return; + } + + this._resolvedSrc = ''; + this.$.img.removeAttribute('src'); + this.$.sizedImgDiv.style.backgroundImage = ''; + + if (src === '' || preventLoad) { + this._setLoading(false); + this._setLoaded(false); + this._setError(false); + } else { + this._resolvedSrc = newResolvedSrc; + this.$.img.src = this._resolvedSrc; + this.$.sizedImgDiv.style.backgroundImage = + 'url("' + this._resolvedSrc + '")'; + + this._setLoading(true); + this._setLoaded(false); + this._setError(false); + } + }, + + _placeholderChanged: function() { + this.$.placeholder.style.backgroundImage = + this.placeholder ? 'url("' + this.placeholder + '")' : ''; + }, + + _transformChanged: function() { + var sizedImgDivStyle = this.$.sizedImgDiv.style; + var placeholderStyle = this.$.placeholder.style; + + sizedImgDivStyle.backgroundSize = placeholderStyle.backgroundSize = + this.sizing; + + sizedImgDivStyle.backgroundPosition = placeholderStyle.backgroundPosition = + this.sizing ? this.position : ''; + + sizedImgDivStyle.backgroundRepeat = placeholderStyle.backgroundRepeat = + this.sizing ? 'no-repeat' : ''; + }, + + _resolveSrc: function(testSrc) { + var resolved = + resolveUrl(testSrc, this.$.baseURIAnchor.href); + // NOTE: Use of `URL` was removed here because IE11 doesn't support + // constructing it. If this ends up being problematic, we should + // consider reverting and adding the URL polyfill as a dev dependency. + if (resolved[0] === '/') { + // In IE location.origin might not work + // https://connect.microsoft.com/IE/feedback/details/1763802/location-origin-is-undefined-in-ie-11-on-windows-10-but-works-on-windows-7 + resolved = (location.origin || location.protocol + '//' + location.host) + + resolved; + } + return resolved; + } +}); diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..31db7f5 --- /dev/null +++ b/manifest.json @@ -0,0 +1,24 @@ +{ + "files": { + "iron-image.html": { + "convertedUrl": "iron-image.js", + "exports": {} + }, + "index.html": { + "convertedUrl": "index.html", + "exports": {} + }, + "demo/index.html": { + "convertedUrl": "demo/index.html", + "exports": {} + }, + "test/index.html": { + "convertedUrl": "test/index.html", + "exports": {} + }, + "test/iron-image.html": { + "convertedUrl": "test/iron-image.html", + "exports": {} + } + } +} diff --git a/package.json b/package.json index 7cd6586..4c117e5 100644 --- a/package.json +++ b/package.json @@ -1,19 +1,41 @@ { - "name": "@polymer/iron-image", - "private": true, "description": "An image-displaying element with lots of convenient features", + "keywords": [ + "web-components", + "polymer", + "media" + ], "repository": { "type": "git", "url": "git://github.com/PolymerElements/iron-image.git" }, + "name": "@polymer/iron-image", "license": "BSD-3-Clause", "devDependencies": { "@polymer/gen-typescript-declarations": "^1.2.2", "bower": "^1.8.0", - "webmat": "^0.2.0" + "webmat": "^0.2.0", + "@polymer/iron-component-page": "^3.0.0-pre.20", + "@polymer/iron-demo-helpers": "^3.0.0-pre.20", + "@polymer/paper-styles": "^3.0.0-pre.20", + "wct-browser-legacy": "^1.0.1", + "@webcomponents/webcomponentsjs": "^2.0.0" }, "scripts": { "update-types": "bower install && gen-typescript-declarations --deleteExisting --outDir .", "format": "webmat && npm run update-types" + }, + "version": "3.0.0-pre.20", + "resolutions": { + "inherits": "2.0.3", + "samsam": "1.1.3", + "supports-color": "3.1.2", + "type-detect": "1.0.0", + "@webcomponents/webcomponentsjs": "2.0.0-beta.2" + }, + "main": "iron-image.js", + "author": "The Polymer Authors", + "dependencies": { + "@polymer/polymer": "^3.0.0" } } diff --git a/test/index.html b/test/index.html index 079cae8..4f55c63 100644 --- a/test/index.html +++ b/test/index.html @@ -8,8 +8,8 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt --> - - + + - + + - - - + + + @@ -71,442 +71,445 @@ - + + test( + '#sizedImgDiv aria-label text is last path component of src when iron-image alt text is undefined', + function() { + image.src = '/some/path.components/file.jpg?a=b&c=d#anchor'; + + assert.isTrue(image.$.sizedImgDiv.hasAttribute('aria-label')); + assert.strictEqual( + image.$.sizedImgDiv.getAttribute('aria-label'), 'file.jpg'); + }); + }); + }); +}); +