/** * Simple helper class for easily creating image components. This renders an image tag to * the DOM with the configured src. * * {@img Ext.Img/Ext.Img.png Ext.Img component} * * ## Example usage: * * var changingImage = Ext.create('Ext.Img', { * src: 'http://www.sencha.com/img/20110215-feat-html5.png', * width: 184, * height: 90, * renderTo: Ext.getBody() * }); * * // change the src of the image programmatically * changingImage.setSrc('http://www.sencha.com/img/20110215-feat-perf.png'); * * By default, only an img element is rendered and that is this component's primary * {@link Ext.Component#getEl element}. If the {@link Ext.Component#autoEl} property * is other than 'img' (the default), the a child img element will be added to the primary * element. This can be used to create a wrapper element around the img. * * ## Wrapping the img in a div: * * var wrappedImage = Ext.create('Ext.Img', { * src: 'http://www.sencha.com/img/20110215-feat-html5.png', * autoEl: 'div', // wrap in a div * renderTo: Ext.getBody() * }); * * ## Using a glyph * * var glyphImage = Ext.create('Ext.Img', { * glyph: 'xf015@FontAwesome', // the "home" icon * renderTo: Ext.getBody() * }); * * ## Image Dimensions * * You should include height and width dimensions for any image owned by a parent * container. By omitting dimensions, an owning container will not know how to * size and position the image in the initial layout. */Ext.define('Ext.Img', { extend: 'Ext.Component', alias: ['widget.image', 'widget.imagecomponent'], requires: [ 'Ext.Glyph' ], /** * @cfg autoEl * @inheritdoc */ autoEl: 'img', /** * @cfg baseCls * @inheritdoc */ baseCls: Ext.baseCSSPrefix + 'img', config: { /** * @cfg {String} src * The source of this image. See {@link Ext#resolveResource} for details on * locating application resources. * @accessor */ src: null, /** * @cfg glyph * @inheritdoc Ext.panel.Header#cfg-glyph */ glyph: null }, /** * @cfg {String} alt * The descriptive text for non-visual UI description. */ alt: '', /** * @cfg {String} title * Specifies additional information about the image. */ title: '', /** * @cfg {String} imgCls * Optional CSS classes to add to the img element. */ imgCls: '', /** * @cfg {Number/String} glyph * A numeric unicode character code to serve as the image. If this option is used * The image will be rendered using a div with innerHTML set to the html entity * for the given character code. The default font-family for glyphs can be set * globally using {@link Ext#setGlyphFontFamily Ext.setGlyphFontFamily()}. Alternatively, * this config option accepts a string with the charCode and font-family separated by * the `@` symbol. For example '65@My Font Family'. */ /** * @property maskOnDisable * @inheritdoc */ maskOnDisable: false, applySrc: function (src) { return src && Ext.resolveResource(src); }, getElConfig: function() { var me = this, autoEl = me.autoEl, config = me.callParent(), glyph = me.glyph, img; // We were configured with a glyph, then this is a div with a single char content if (glyph) { config.tag = 'div'; config.html = glyph.character; config.style = config.style || {}; config.style.fontFamily = glyph.fontFamily; // A glyph is a graphic which is not an <img> tag so it should have // the corresponding role for Accessibility interface to recognize config.role = 'img'; } // The default; an img element else if (autoEl === 'img' || (Ext.isObject(autoEl) && autoEl.tag === 'img')) { img = config; } // It is sometimes helpful (like in a panel header icon) to have the img wrapped // by a div. If our autoEl is not 'img' then we just add an img child to the el. else { config.cn = [img = { tag: 'img', id: me.id + '-img' }]; } if (img) { if (me.imgCls) { img.cls = (img.cls ? img.cls + ' ' : '') + me.imgCls; } img.src = me.src || Ext.BLANK_IMAGE_URL; } if (me.alt) { (img || config).alt = me.alt; } else { // Images that do not have alt attribute can't be properly announced // by screen readers. In best case they will be silently skipped; // in worst case screen reader will announce data url. Yes, that very long // base-64 encoded string. :/ // That will make the application totally unusable for blind people. (img || config).alt = ''; //<debug> Ext.log.warn('For WAI-ARIA compliance, IMG elements SHOULD have an alt attribute.'); //</debug> } if (me.title) { (img || config).title = me.title; } return config; }, onRender: function () { var me = this, autoEl = me.autoEl, el; me.callParent(arguments); el = me.el; if (autoEl === 'img' || (Ext.isObject(autoEl) && autoEl.tag === 'img')) { me.imgEl = el; } else { me.imgEl = el.getById(me.id + '-img'); } }, doDestroy: function() { var me = this, imgEl = me.imgEl; // Only clean up when the img is a child, otherwise it will get handled // by the element destruction in the parent if (imgEl && me.el !== imgEl) { imgEl.destroy(); } me.imgEl = null; me.callParent(); }, getTitle: function () { return this.title; }, /** * Updates the {@link #title} of the image. * @param {String} title */ setTitle: function (title) { var me = this, imgEl = me.imgEl; me.title = title || ''; if (imgEl) { imgEl.dom.title = title || ''; } }, afterComponentLayout: function(width, height, oldWidth, oldHeight) { var heightModel = this.getSizeModel().height, h; // If we have our height set, then size the glyph as requested to make image scalable. if ((heightModel.calculated || heightModel.configured) && height && this.glyph) { h = height + 'px'; this.setStyle({ 'line-height': h, 'font-size': h }); } this.callParent([width, height, oldWidth, oldHeight]); }, getAlt: function () { return this.alt; }, /** * Updates the {@link #alt} of the image. * @param {String} alt */ setAlt: function (alt) { var me = this, imgEl = me.imgEl; me.alt = alt || ''; if (imgEl) { imgEl.dom.alt = alt || ''; } }, _naturalSize: null, /** * Returns the size of the image as an object. * @return {Object} The size and aspect ratio of the image. * @return {Number} return.aspect The aspect ration of the image (`width / height`). * @return {Number} return.height The height of the image. * @return {Number} return.width The width of the image. * @since 6.2.0 */ getNaturalSize: function () { var me = this, img = me.imgEl, naturalSize = me._naturalSize, style, w, h; if (img && !naturalSize) { img = img.dom; me._naturalSize = naturalSize = { width: w = img.naturalWidth, height: img.naturalHeight }; if (!w) { style = img.style; w = style.width; h = style.height; // As long as the width/height styles are "auto", the IMG dom element // will have "width" and "height" properties that are the natural size. style.width = style.height = 'auto'; naturalSize.width = img.width; naturalSize.height = img.height; style.width = w; style.height = h; } naturalSize.aspect = naturalSize.width / naturalSize.height; } return naturalSize; }, updateSrc: function (src) { var imgEl = this.imgEl; if (imgEl) { imgEl.dom.src = src || Ext.BLANK_IMAGE_URL; } }, applyGlyph: function(glyph, oldGlyph) { if (glyph) { if (!glyph.isGlyph) { glyph = new Ext.Glyph(glyph); } if (glyph.isEqual(oldGlyph)) { glyph = undefined; } } return glyph; }, updateGlyph: function(glyph, oldGlyph) { var el = this.el; if (el) { el.dom.innerHTML = glyph.character; el.setStyle(glyph.getStyle()); } }});