<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>The source code</title> <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" /> <script type="text/javascript" src="../resources/prettify/prettify.js"></script> <style type="text/css"> .highlight { display: block; background-color: #ddd; } </style> <script type="text/javascript"> function highlight() { document.getElementById(location.hash.replace(/#/, "")).className = "highlight"; } </script> </head> <body onload="prettyPrint(); highlight();"> <pre class="prettyprint lang-js"><span id='Ext-layout-component-Button'>/** </span> * Component layout for buttons * @private */ Ext.define('Ext.layout.component.Button', { /* Begin Definitions */ alias: ['layout.button'], extend: 'Ext.layout.component.Auto', /* End Definitions */ type: 'button', cellClsRE: /-btn-(tl|br)\b/, htmlRE: /<.*>/, constructor: function () { this.callParent(arguments); this.hackWidth = Ext.isIE && (!Ext.isStrict || Ext.isIE6 || Ext.isIE7 || Ext.isIE8); this.heightIncludesPadding = Ext.isIE6 && Ext.isStrict; }, // TODO - use last run results if text has not changed? beginLayout: function (ownerContext) { this.callParent(arguments); this.cacheTargetInfo(ownerContext); }, beginLayoutCycle: function(ownerContext) { var me = this, empty = '', owner = me.owner, btnEl = owner.btnEl, btnInnerEl = owner.btnInnerEl, text = owner.text, htmlAutoHeight; me.callParent(arguments); btnInnerEl.setStyle('overflow', empty); // Clear all element widths if (!ownerContext.widthModel.natural) { owner.el.setStyle('width', empty); } // If the text is HTML we need to let the browser automatically size things to cope with the case where the text // is multi-line. This incurs a cost as we then have to measure those elements to derive other sizes htmlAutoHeight = ownerContext.heightModel.shrinkWrap && text && me.htmlRE.test(text); btnEl.setStyle('width', empty); btnEl.setStyle('height', htmlAutoHeight ? 'auto' : empty); btnInnerEl.setStyle('width', empty); btnInnerEl.setStyle('height', htmlAutoHeight ? 'auto' : empty); btnInnerEl.setStyle('line-height', htmlAutoHeight ? 'normal' : empty); btnInnerEl.setStyle('padding-top', empty); owner.btnIconEl.setStyle('width', empty); }, calculateOwnerHeightFromContentHeight: function (ownerContext, contentHeight) { return contentHeight; }, calculateOwnerWidthFromContentWidth: function (ownerContext, contentWidth) { return contentWidth; }, measureContentWidth: function (ownerContext) { var me = this, owner = me.owner, btnEl = owner.btnEl, btnInnerEl = owner.btnInnerEl, text = owner.text, btnFrameWidth, metrics, sizeIconEl, width, btnElContext, btnInnerElContext; // IE suffers from various sizing problems, usually caused by relying on it to size elements automatically. Even // if an element is sized correctly it can prove necessary to set that size explicitly on the element to get it // to size and position its children correctly. While the exact nature of the problems varies depending on the // browser version, doctype and button configuration there is a common solution: set the sizes manually. if (owner.text && me.hackWidth && btnEl) { btnFrameWidth = me.btnFrameWidth; // If the button text is something like '<' or '<<' then we need to escape it or it won't be measured // correctly. The button text is supposed to be HTML and strictly speaking '<' and '<<' aren't valid HTML. // However in practice they are commonly used and have worked 'correctly' in previous versions. if (text.indexOf('>') === -1) { text = text.replace(/</g, '&lt;'); } metrics = Ext.util.TextMetrics.measure(btnInnerEl, text); width = metrics.width + btnFrameWidth + me.adjWidth; btnElContext = ownerContext.getEl('btnEl'); btnInnerElContext = ownerContext.getEl('btnInnerEl'); sizeIconEl = (owner.icon || owner.iconCls) && (owner.iconAlign == "top" || owner.iconAlign == "bottom"); // This cheat works (barely) with publishOwnerWidth which calls setProp also // to publish the width. Since it is the same value we set here, the dirty bit // we set true will not be cleared by publishOwnerWidth. ownerContext.setWidth(width); // not setWidth (no framing) btnElContext.setWidth(metrics.width + btnFrameWidth); btnInnerElContext.setWidth(metrics.width + btnFrameWidth); if (sizeIconEl) { owner.btnIconEl.setWidth(metrics.width + btnFrameWidth); } } else { width = ownerContext.el.getWidth(); } return width; }, measureContentHeight: function (ownerContext) { var me = this, owner = me.owner, btnInnerEl = owner.btnInnerEl, btnItem = ownerContext.getEl('btnEl'), btnInnerItem = ownerContext.getEl('btnInnerEl'), minTextHeight = me.minTextHeight, adjHeight = me.adjHeight, text = owner.getText(), height, textHeight, topPadding; if (owner.vertical) { height = Ext.util.TextMetrics.measure(btnInnerEl, owner.text).width; height += me.btnFrameHeight + adjHeight; // Vertical buttons need height explicitly set ownerContext.setHeight(height, /*dirty=*/true, /*force=*/true); } else { // If the button text is HTML we have to handle it specially as it could contain multiple lines if (text && me.htmlRE.test(text)) { textHeight = btnInnerEl.getHeight(); // HTML content doesn't guarantee multiple lines: in the single line case it could now be too short for the icon if (textHeight < minTextHeight) { topPadding = Math.floor((minTextHeight - textHeight) / 2); // Resize the span and use padding to center the text vertically. The hack to remove the padding // from the height on IE6 is especially needed for link buttons btnInnerItem.setHeight(minTextHeight - (me.heightIncludesPadding ? topPadding : 0)); btnInnerItem.setProp('padding-top', topPadding); textHeight = minTextHeight; } // Calculate the height relative to the text span, auto can't be trusted in IE quirks height = textHeight + adjHeight; } else { height = ownerContext.el.getHeight(); } } // IE quirks needs the button height setting using style or it won't position the icon correctly (even if the height was already correct) btnItem.setHeight(height - adjHeight); return height; }, publishInnerHeight: function(ownerContext, height) { var me = this, owner = me.owner, isNum = Ext.isNumber, btnItem = ownerContext.getEl('btnEl'), btnInnerEl = owner.btnInnerEl, btnInnerItem = ownerContext.getEl('btnInnerEl'), btnHeight = isNum(height) ? height - me.adjHeight : height, btnFrameHeight = me.btnFrameHeight, text = owner.getText(), textHeight, paddingTop; btnItem.setHeight(btnHeight); btnInnerItem.setHeight(btnHeight); // Only need the line-height setting for regular, horizontal Buttons if (!owner.vertical && btnHeight >= 0) { btnInnerItem.setProp('line-height', btnHeight - btnFrameHeight + 'px'); } // Button text may contain markup that would force it to wrap to more than one line (e.g. 'Button<br>Label'). // When this happens, we cannot use the line-height set above for vertical centering; we instead reset the // line-height to normal, measure the rendered text height, and add padding-top to center the text block // vertically within the button's height. This is more expensive than the basic line-height approach so // we only do it if the text contains markup. if (text && me.htmlRE.test(text)) { btnInnerItem.setProp('line-height', 'normal'); btnInnerEl.setStyle('line-height', 'normal'); textHeight = Ext.util.TextMetrics.measure(btnInnerEl, text).height; paddingTop = Math.floor(Math.max(btnHeight - btnFrameHeight - textHeight, 0) / 2); btnInnerItem.setProp('padding-top', me.btnFrameTop + paddingTop); btnInnerItem.setHeight(btnHeight - (me.heightIncludesPadding ? paddingTop : 0)); } }, publishInnerWidth: function(ownerContext, width) { var me = this, isNum = Ext.isNumber, btnItem = ownerContext.getEl('btnEl'), btnInnerItem = ownerContext.getEl('btnInnerEl'), btnWidth = isNum(width) ? width - me.adjWidth : width; btnItem.setWidth(btnWidth); btnInnerItem.setWidth(btnWidth); }, clearTargetCache: function(){ delete this.adjWidth; }, cacheTargetInfo: function(ownerContext) { var me = this, owner = me.owner, scale = owner.scale, padding, frameSize, btnWrapPadding, btnInnerEl, innerFrameSize; // The cache is only valid for a particular scale if (!('adjWidth' in me) || me.lastScale !== scale) { // If there has been a previous layout run it could have sullied the line-height if (me.lastScale) { owner.btnInnerEl.setStyle('line-height', ''); } me.lastScale = scale; padding = ownerContext.getPaddingInfo(); frameSize = ownerContext.getFrameInfo(); btnWrapPadding = ownerContext.getEl('btnWrap').getPaddingInfo(); btnInnerEl = ownerContext.getEl('btnInnerEl'); innerFrameSize = btnInnerEl.getPaddingInfo(); Ext.apply(me, { // Width adjustment must take into account the arrow area. The btnWrap is the <em> which has padding to accommodate the arrow. adjWidth : btnWrapPadding.width + frameSize.width + padding.width, adjHeight : btnWrapPadding.height + frameSize.height + padding.height, btnFrameWidth : innerFrameSize.width, btnFrameHeight : innerFrameSize.height, btnFrameTop : innerFrameSize.top, // Use the line-height rather than height because if the text is multi-line then the height will be 'wrong' minTextHeight : parseInt(btnInnerEl.getStyle('line-height'), 10) }); } me.callParent(arguments); }, finishedLayout: function(){ var owner = this.owner; this.callParent(arguments); // Fixes issue EXTJSIV-5989. Looks like a browser repaint bug // This hack can be removed once it is resolved. if (Ext.isWebKit) { owner.el.dom.offsetWidth; } } }); </pre> </body> </html>