| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515 | <!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-button-Button'>/**</span> * @docauthor Robert Dougan <rob@sencha.com> * * Create simple buttons with this component. Customisations include {@link #iconAlign aligned} * {@link #iconCls icons}, {@link #cfg-menu dropdown menus}, {@link #tooltip tooltips} * and {@link #scale sizing options}. Specify a {@link #handler handler} to run code when * a user clicks the button, or use {@link #listeners listeners} for other events such as * {@link #mouseover mouseover}. Example usage: * *     @example *     Ext.create('Ext.Button', { *         text: 'Click me', *         renderTo: Ext.getBody(), *         handler: function() { *             alert('You clicked the button!'); *         } *     }); * * The {@link #handler} configuration can also be updated dynamically using the {@link #setHandler} * method.  Example usage: * *     @example *     Ext.create('Ext.Button', { *         text    : 'Dynamic Handler Button', *         renderTo: Ext.getBody(), *         handler : function() { *             // this button will spit out a different number every time you click it. *             // so firstly we must check if that number is already set: *             if (this.clickCount) { *                 // looks like the property is already set, so lets just add 1 to that number and alert the user *                 this.clickCount++; *                 alert('You have clicked the button "' + this.clickCount + '" times.\n\nTry clicking it again..'); *             } else { *                 // if the clickCount property is not set, we will set it and alert the user *                 this.clickCount = 1; *                 alert('You just clicked the button for the first time!\n\nTry pressing it again..'); *             } *         } *     }); * * A button within a container: * *     @example *     Ext.create('Ext.Container', { *         renderTo: Ext.getBody(), *         items   : [ *             { *                 xtype: 'button', *                 text : 'My Button' *             } *         ] *     }); * * A useful option of Button is the {@link #scale} configuration. This configuration has three different options: * * - `'small'` * - `'medium'` * - `'large'` * * Example usage: * *     @example *     Ext.create('Ext.Button', { *         renderTo: document.body, *         text    : 'Click me', *         scale   : 'large' *     }); * * Buttons can also be toggled. To enable this, you simple set the {@link #enableToggle} property to `true`. * Example usage: * *     @example *     Ext.create('Ext.Button', { *         renderTo: Ext.getBody(), *         text: 'Click Me', *         enableToggle: true *     }); * * You can assign a menu to a button by using the {@link #cfg-menu} configuration. This standard configuration * can either be a reference to a {@link Ext.menu.Menu menu} object, a {@link Ext.menu.Menu menu} id or a * {@link Ext.menu.Menu menu} config blob. When assigning a menu to a button, an arrow is automatically * added to the button.  You can change the alignment of the arrow using the {@link #arrowAlign} configuration * on button.  Example usage: * *     @example *     Ext.create('Ext.Button', { *         text      : 'Menu button', *         renderTo  : Ext.getBody(), *         arrowAlign: 'bottom', *         menu      : [ *             {text: 'Item 1'}, *             {text: 'Item 2'}, *             {text: 'Item 3'}, *             {text: 'Item 4'} *         ] *     }); * * Using listeners, you can easily listen to events fired by any component, using the {@link #listeners} * configuration or using the {@link #addListener} method.  Button has a variety of different listeners: * * - `click` * - `toggle` * - `mouseover` * - `mouseout` * - `mouseshow` * - `menuhide` * - `menutriggerover` * - `menutriggerout` * * Example usage: * *     @example *     Ext.create('Ext.Button', { *         text     : 'Button', *         renderTo : Ext.getBody(), *         listeners: { *             click: function() { *                 // this == the button, as we are in the local scope *                 this.setText('I was clicked!'); *             }, *             mouseover: function() { *                 // set a new config which says we moused over, if not already set *                 if (!this.mousedOver) { *                     this.mousedOver = true; *                     alert('You moused over a button!\n\nI wont do this again.'); *                 } *             } *         } *     }); */Ext.define('Ext.button.Button', {    /* Begin Definitions */    alias: 'widget.button',    extend: 'Ext.Component',    requires: [        'Ext.menu.Manager',        'Ext.util.ClickRepeater',        'Ext.layout.component.Button',        'Ext.util.TextMetrics',        'Ext.util.KeyMap'    ],    alternateClassName: 'Ext.Button',    /* End Definitions */    /*     * @property {Boolean} isAction     * `true` in this class to identify an object as an instantiated Button, or subclass thereof.     */    isButton: true,    componentLayout: 'button',<span id='Ext-button-Button-property-hidden'>    /**</span>     * @property {Boolean} hidden     * True if this button is hidden.     * @readonly     */    hidden: false,<span id='Ext-button-Button-property-disabled'>    /**</span>     * @property {Boolean} disabled     * True if this button is disabled.     * @readonly     */    disabled: false,<span id='Ext-button-Button-property-pressed'>    /**</span>     * @property {Boolean} pressed     * True if this button is pressed (only if enableToggle = true).     * @readonly     */    pressed: false,<span id='Ext-button-Button-cfg-text'>    /**</span>     * @cfg {String} text     * The button text to be used as innerHTML (html tags are accepted).     */<span id='Ext-button-Button-cfg-icon'>    /**</span>     * @cfg {String} icon     * The path to an image to display in the button.     */<span id='Ext-button-Button-cfg-handler'>    /**</span>     * @cfg {Function} handler     * A function called when the button is clicked (can be used instead of click event).     * @cfg {Ext.button.Button} handler.button This button.     * @cfg {Ext.EventObject} handler.e The click event.     */<span id='Ext-button-Button-cfg-minWidth'>    /**</span>     * @cfg {Number} minWidth     * The minimum width for this button (used to give a set of buttons a common width).     * See also {@link Ext.panel.Panel}.{@link Ext.panel.Panel#minButtonWidth minButtonWidth}.     */<span id='Ext-button-Button-cfg-tooltip'>    /**</span>     * @cfg {String/Object} tooltip     * The tooltip for the button - can be a string to be used as innerHTML (html tags are accepted) or     * QuickTips config object.     */<span id='Ext-button-Button-cfg-hidden'>    /**</span>     * @cfg {Boolean} [hidden=false]     * True to start hidden.     */<span id='Ext-button-Button-cfg-disabled'>    /**</span>     * @cfg {Boolean} [disabled=false]     * True to start disabled.     */<span id='Ext-button-Button-cfg-pressed'>    /**</span>     * @cfg {Boolean} [pressed=false]     * True to start pressed (only if enableToggle = true)     */<span id='Ext-button-Button-cfg-toggleGroup'>    /**</span>     * @cfg {String} toggleGroup     * The group this toggle button is a member of (only 1 per group can be pressed). If a toggleGroup     * is specified, the {@link #enableToggle} configuration will automatically be set to true.     */<span id='Ext-button-Button-cfg-repeat'>    /**</span>     * @cfg {Boolean/Object} [repeat=false]     * True to repeat fire the click event while the mouse is down. This can also be a     * {@link Ext.util.ClickRepeater ClickRepeater} config object.     */<span id='Ext-button-Button-cfg-tabIndex'>    /**</span>     * @cfg {Number} tabIndex     * Set a DOM tabIndex for this button.     */<span id='Ext-button-Button-cfg-allowDepress'>    /**</span>     * @cfg {Boolean} [allowDepress=true]     * False to not allow a pressed Button to be depressed. Only valid when {@link #enableToggle} is true.     */<span id='Ext-button-Button-cfg-enableToggle'>    /**</span>     * @cfg {Boolean} [enableToggle=false]     * True to enable pressed/not pressed toggling. If a {@link #toggleGroup} is specified, this     * option will be set to true.     */    enableToggle: false,<span id='Ext-button-Button-cfg-toggleHandler'>    /**</span>     * @cfg {Function} toggleHandler     * Function called when a Button with {@link #enableToggle} set to true is clicked.     * @cfg {Ext.button.Button} toggleHandler.button This button.     * @cfg {Boolean} toggleHandler.state The next state of the Button, true means pressed.     */<span id='Ext-button-Button-cfg-menu'>    /**</span>     * @cfg {Ext.menu.Menu/String/Object} menu     * Standard menu attribute consisting of a reference to a menu object, a menu id or a menu config blob.     */<span id='Ext-button-Button-cfg-menuAlign'>    /**</span>     * @cfg {String} menuAlign     * The position to align the menu to (see {@link Ext.Element#alignTo} for more details).     */    menuAlign: 'tl-bl?',<span id='Ext-button-Button-cfg-textAlign'>    /**</span>     * @cfg {String} textAlign     * The text alignment for this button (center, left, right).     */    textAlign: 'center',<span id='Ext-button-Button-cfg-overflowText'>    /**</span>     * @cfg {String} overflowText     * If used in a {@link Ext.toolbar.Toolbar Toolbar}, the text to be used if this item is shown in the overflow menu.     * See also {@link Ext.toolbar.Item}.`{@link Ext.toolbar.Item#overflowText overflowText}`.     */<span id='Ext-button-Button-cfg-iconCls'>    /**</span>     * @cfg {String} iconCls     * A css class which sets a background image to be used as the icon for this button.     */<span id='Ext-button-Button-cfg-type'>    /**</span>     * @cfg {String} type     * The type of `<input>` to create: submit, reset or button.     */    type: 'button',<span id='Ext-button-Button-cfg-clickEvent'>    /**</span>     * @cfg {String} clickEvent     * The DOM event that will fire the handler of the button. This can be any valid event name (dblclick, contextmenu).     */    clickEvent: 'click',<span id='Ext-button-Button-cfg-preventDefault'>    /**</span>     * @cfg {Boolean} preventDefault     * True to prevent the default action when the {@link #clickEvent} is processed.     */    preventDefault: true,<span id='Ext-button-Button-cfg-handleMouseEvents'>    /**</span>     * @cfg {Boolean} handleMouseEvents     * False to disable visual cues on mouseover, mouseout and mousedown.     */    handleMouseEvents: true,<span id='Ext-button-Button-cfg-tooltipType'>    /**</span>     * @cfg {String} tooltipType     * The type of tooltip to use. Either 'qtip' for QuickTips or 'title' for title attribute.     */    tooltipType: 'qtip',<span id='Ext-button-Button-cfg-baseCls'>    /**</span>     * @cfg {String} [baseCls='x-btn']     * The base CSS class to add to all buttons.     */    baseCls: Ext.baseCSSPrefix + 'btn',<span id='Ext-button-Button-cfg-pressedCls'>    /**</span>     * @cfg {String} pressedCls     * The CSS class to add to a button when it is in the pressed state.     */    pressedCls: 'pressed',<span id='Ext-button-Button-cfg-overCls'>    /**</span>     * @cfg {String} overCls     * The CSS class to add to a button when it is in the over (hovered) state.     */    overCls: 'over',<span id='Ext-button-Button-cfg-focusCls'>    /**</span>     * @cfg {String} focusCls     * The CSS class to add to a button when it is in the focussed state.     */    focusCls: 'focus',<span id='Ext-button-Button-cfg-menuActiveCls'>    /**</span>     * @cfg {String} menuActiveCls     * The CSS class to add to a button when it's menu is active.     */    menuActiveCls: 'menu-active',<span id='Ext-button-Button-cfg-href'>    /**</span>     * @cfg {String} href     * The URL to open when the button is clicked. Specifying this config causes the Button to be     * rendered with an anchor (An `<a>` element) as its active element, referencing the specified URL.     *     * This is better than specifying a click handler of     *     *     function() { window.location = "http://www.sencha.com" }     *     * because the UI will provide meaningful hints to the user as to what to expect upon clicking     * the button, and will also allow the user to open in a new tab or window, bookmark or drag the URL, or directly save     * the URL stream to disk.     *     * See also the {@link #hrefTarget} config.     */    <span id='Ext-button-Button-cfg-hrefTarget'>    /**</span>      * @cfg {String} [hrefTarget="_blank"]      * The target attribute to use for the underlying anchor. Only used if the {@link #href}      * property is specified.      */     hrefTarget: '_blank',          border: true,<span id='Ext-button-Button-cfg-baseParams'>    /**</span>     * @cfg {Object} baseParams     * An object literal of parameters to pass to the url when the {@link #href} property is specified.     */<span id='Ext-button-Button-cfg-params'>    /**</span>     * @cfg {Object} params     * An object literal of parameters to pass to the url when the {@link #href} property is specified. Any params     * override {@link #baseParams}. New params can be set using the {@link #setParams} method.     */    childEls: [        'btnEl', 'btnWrap', 'btnInnerEl', 'btnIconEl'    ],    renderTpl: [        '<em id="{id}-btnWrap"<tpl if="splitCls"> class="{splitCls}"</tpl>>',            '<tpl if="href">',                '<a id="{id}-btnEl" href="{href}" class="{btnCls}" target="{hrefTarget}"',                    '<tpl if="tabIndex"> tabIndex="{tabIndex}"</tpl>',                    '<tpl if="disabled"> disabled="disabled"</tpl>',                    ' role="link">',                    '<span id="{id}-btnInnerEl" class="{baseCls}-inner">',                        '{text}',                    '</span>',                    '<span id="{id}-btnIconEl" class="{baseCls}-icon {iconCls}"<tpl if="iconUrl"> style="background-image:url({iconUrl})"</tpl>></span>',                '</a>',            '<tpl else>',                '<button id="{id}-btnEl" type="{type}" class="{btnCls}" hidefocus="true"',                    // the autocomplete="off" is required to prevent Firefox from remembering                    // the button's disabled state between page reloads.                    '<tpl if="tabIndex"> tabIndex="{tabIndex}"</tpl>',                    '<tpl if="disabled"> disabled="disabled"</tpl>',                    ' role="button" autocomplete="off">',                    '<span id="{id}-btnInnerEl" class="{baseCls}-inner" style="{innerSpanStyle}">',                        '{text}',                    '</span>',                    '<span id="{id}-btnIconEl" class="{baseCls}-icon {iconCls}"<tpl if="iconUrl"> style="background-image:url({iconUrl})"</tpl>></span>',                '</button>',            '</tpl>',        '</em>',        '<tpl if="closable">',            '<a id="{id}-closeEl" href="#" class="{baseCls}-close-btn" title="{closeText}"></a>',        '</tpl>'    ],<span id='Ext-button-Button-cfg-scale'>    /**</span>     * @cfg {String} scale     * The size of the Button. Three values are allowed:     *     * - 'small' - Results in the button element being 16px high.     * - 'medium' - Results in the button element being 24px high.     * - 'large' - Results in the button element being 32px high.     */    scale: 'small',<span id='Ext-button-Button-property-allowedScales'>    /**</span>     * @private     * An array of allowed scales.     */    allowedScales: ['small', 'medium', 'large'],<span id='Ext-button-Button-cfg-scope'>    /**</span>     * @cfg {Object} scope     * The scope (**this** reference) in which the `{@link #handler}` and `{@link #toggleHandler}` is executed.     * Defaults to this Button.     */<span id='Ext-button-Button-cfg-iconAlign'>    /**</span>     * @cfg {String} iconAlign     * The side of the Button box to render the icon. Four values are allowed:     *     * - 'top'     * - 'right'     * - 'bottom'     * - 'left'     */    iconAlign: 'left',<span id='Ext-button-Button-cfg-arrowAlign'>    /**</span>     * @cfg {String} arrowAlign     * The side of the Button box to render the arrow if the button has an associated {@link #cfg-menu}. Two     * values are allowed:     *     * - 'right'     * - 'bottom'     */    arrowAlign: 'right',<span id='Ext-button-Button-cfg-arrowCls'>    /**</span>     * @cfg {String} arrowCls     * The className used for the inner arrow element if the button has a menu.     */    arrowCls: 'arrow',<span id='Ext-button-Button-property-template'>    /**</span>     * @property {Ext.Template} template     * A {@link Ext.Template Template} used to create the Button's DOM structure.     *     * Instances, or subclasses which need a different DOM structure may provide a different template layout in     * conjunction with an implementation of {@link #getTemplateArgs}.     */<span id='Ext-button-Button-cfg-cls'>    /**</span>     * @cfg {String} cls     * A CSS class string to apply to the button's main element.     */<span id='Ext-button-Button-property-menu'>    /**</span>     * @property {Ext.menu.Menu} menu     * The {@link Ext.menu.Menu Menu} object associated with this Button when configured with the {@link #cfg-menu} config     * option.     */    maskOnDisable: false,    <span id='Ext-button-Button-property-persistentPadding'>    /**</span>     * @private     * @property persistentPadding     * The padding spuriously added to a &lt;button> element which must be accounted for in the margins of the innerEl.     * This is calculated at first render time by creating a hidden button and measuring its insides.     */    persistentPadding: undefined,    shrinkWrap: 3,    frame: true,    // inherit docs    initComponent: function() {        var me = this;        me.callParent(arguments);        me.addEvents(<span id='Ext-button-Button-event-click'>            /**</span>             * @event click             * Fires when this button is clicked, before the configured {@link #handler} is invoked. Execution of the             * {@link #handler} may be vetoed by returning <code>false</code> to this event.             * @param {Ext.button.Button} this             * @param {Event} e The click event             */            'click',<span id='Ext-button-Button-event-toggle'>            /**</span>             * @event toggle             * Fires when the 'pressed' state of this button changes (only if enableToggle = true)             * @param {Ext.button.Button} this             * @param {Boolean} pressed             */            'toggle',<span id='Ext-button-Button-event-mouseover'>            /**</span>             * @event mouseover             * Fires when the mouse hovers over the button             * @param {Ext.button.Button} this             * @param {Event} e The event object             */            'mouseover',<span id='Ext-button-Button-event-mouseout'>            /**</span>             * @event mouseout             * Fires when the mouse exits the button             * @param {Ext.button.Button} this             * @param {Event} e The event object             */            'mouseout',<span id='Ext-button-Button-event-menushow'>            /**</span>             * @event menushow             * If this button has a menu, this event fires when it is shown             * @param {Ext.button.Button} this             * @param {Ext.menu.Menu} menu             */            'menushow',<span id='Ext-button-Button-event-menuhide'>            /**</span>             * @event menuhide             * If this button has a menu, this event fires when it is hidden             * @param {Ext.button.Button} this             * @param {Ext.menu.Menu} menu             */            'menuhide',<span id='Ext-button-Button-event-menutriggerover'>            /**</span>             * @event menutriggerover             * If this button has a menu, this event fires when the mouse enters the menu triggering element             * @param {Ext.button.Button} this             * @param {Ext.menu.Menu} menu             * @param {Event} e             */            'menutriggerover',<span id='Ext-button-Button-event-menutriggerout'>            /**</span>             * @event menutriggerout             * If this button has a menu, this event fires when the mouse leaves the menu triggering element             * @param {Ext.button.Button} this             * @param {Ext.menu.Menu} menu             * @param {Event} e             */            'menutriggerout'        );        if (me.menu) {            // Flag that we'll have a splitCls            me.split = true;            // retrieve menu by id or instantiate instance if needed            me.menu = Ext.menu.Manager.get(me.menu);            me.menu.ownerButton = me;        }        // Accept url as a synonym for href        if (me.url) {            me.href = me.url;        }        // preventDefault defaults to false for links        if (me.href && !me.hasOwnProperty('preventDefault')) {            me.preventDefault = false;        }        if (Ext.isString(me.toggleGroup) && me.toggleGroup !== '') {            me.enableToggle = true;        }                if (me.html && !me.text) {            me.text = me.html;            delete me.html;        }    },    // inherit docs    getActionEl: function() {        return this.btnEl;    },    // inherit docs    getFocusEl: function() {        return this.useElForFocus ? this.el : this.btnEl;    },    // Buttons add the focus class to the *outermost element*, not the focusEl!    onFocus: function(e) {        var me = this;        // Set this flag, so that when AbstractComponent's onFocus gets the focusEl to add the focusCls        // to, it will get the encapsulating element - that's what the CSS rules for Button need right now        me.useElForFocus = true;        me.callParent(arguments);        me.useElForFocus = false;    },    // See comments in onFocus    onBlur : function(e) {        this.useElForFocus = true;        this.callParent(arguments);        this.useElForFocus = false;    },        // See comments in onFocus    onDisable: function(){        this.useElForFocus = true;        this.callParent(arguments);        this.useElForFocus = false;    },    // private    setComponentCls: function() {        var me = this,            cls = me.getComponentCls();        if (!Ext.isEmpty(me.oldCls)) {            me.removeClsWithUI(me.oldCls);            me.removeClsWithUI(me.pressedCls);        }        me.oldCls = cls;        me.addClsWithUI(cls);    },    getComponentCls: function() {        var me = this,            cls = [];        // Check whether the button has an icon or not, and if it has an icon, what is the alignment        if (me.iconCls || me.icon) {            if (me.text) {                cls.push('icon-text-' + me.iconAlign);            } else {                cls.push('icon');            }        } else if (me.text) {            cls.push('noicon');        }        if (me.pressed) {            cls.push(me.pressedCls);        }        return cls;    },    beforeRender: function () {        var me = this;        me.callParent();        // Add all needed classes to the protoElement.        me.oldCls = me.getComponentCls();        me.addClsWithUI(me.oldCls);        // Apply the renderData to the template args        Ext.applyIf(me.renderData, me.getTemplateArgs());        if (me.scale) {            me.setScale(me.scale);        }    },    // private    onRender: function() {        var me = this,            addOnclick,            btn,            btnListeners;        me.doc = Ext.getDoc();        me.callParent(arguments);        // If it is a split button + has a toolip for the arrow        if (me.split && me.arrowTooltip) {            me.arrowEl.dom.setAttribute(me.getTipAttr(), me.arrowTooltip);        }        // Set btn as a local variable for easy access        btn = me.el;        if (me.tooltip) {            me.setTooltip(me.tooltip, true);        }        // Add the mouse events to the button        if (me.handleMouseEvents) {            btnListeners = {                scope: me,                mouseover: me.onMouseOver,                mouseout: me.onMouseOut,                mousedown: me.onMouseDown            };            if (me.split) {                btnListeners.mousemove = me.onMouseMove;            }        } else {            btnListeners = {                scope: me            };        }        // Check if the button has a menu        if (me.menu) {            me.mon(me.menu, {                scope: me,                show: me.onMenuShow,                hide: me.onMenuHide            });            me.keyMap = new Ext.util.KeyMap({                target: me.el,                key: Ext.EventObject.DOWN,                handler: me.onDownKey,                scope: me            });        }        // Check if it is a repeat button        if (me.repeat) {            me.mon(new Ext.util.ClickRepeater(btn, Ext.isObject(me.repeat) ? me.repeat: {}), 'click', me.onRepeatClick, me);        } else {            // If the activation event already has a handler, make a note to add the handler later            if (btnListeners[me.clickEvent]) {                addOnclick = true;            } else {                btnListeners[me.clickEvent] = me.onClick;            }        }        // Add whatever button listeners we need        me.mon(btn, btnListeners);        // If the listeners object had an entry for our clickEvent, add a listener now        if (addOnclick) {            me.mon(btn, me.clickEvent, me.onClick, me);        }        // Register the button in the toggle manager        Ext.ButtonToggleManager.register(me);    },<span id='Ext-button-Button-method-getTemplateArgs'>    /**</span>     * This method returns an object which provides substitution parameters for the {@link #renderTpl XTemplate} used to     * create this Button's DOM structure.     *     * Instances or subclasses which use a different Template to create a different DOM structure may need to provide     * their own implementation of this method.     *     * @return {Object} Substitution data for a Template. The default implementation which provides data for the default     * {@link #template} returns an Object containing the following properties:     * @return {String} return.type The `<button>`'s {@link #type}     * @return {String} return.splitCls A CSS class to determine the presence and position of an arrow icon.     * (`'x-btn-arrow'` or `'x-btn-arrow-bottom'` or `''`)     * @return {String} return.cls A CSS class name applied to the Button's main `<tbody>` element which determines the     * button's scale and icon alignment.     * @return {String} return.text The {@link #text} to display ion the Button.     * @return {Number} return.tabIndex The tab index within the input flow.     */    getTemplateArgs: function() {        var me = this,            persistentPadding = me.getPersistentPadding(),            innerSpanStyle = '';        // Create negative margin offsets to counteract persistent button padding if needed        if (Math.max.apply(Math, persistentPadding) > 0) {            innerSpanStyle = 'margin:' + Ext.Array.map(persistentPadding, function(pad) {                return -pad + 'px';            }).join(' ');        }        return {            href     : me.getHref(),            disabled : me.disabled,            hrefTarget: me.hrefTarget,            type     : me.type,            btnCls   : me.getBtnCls(),            splitCls : me.getSplitCls(),            iconUrl  : me.icon,            iconCls  : me.iconCls,            text     : me.text || '&#160;',            tabIndex : me.tabIndex,            innerSpanStyle: innerSpanStyle        };    },<span id='Ext-button-Button-method-getHref'>    /**</span>     * @private     * If there is a configured href for this Button, returns the href with parameters appended.     * @returns The href string with parameters appended.     */    getHref: function() {        var me = this,            params = Ext.apply({}, me.baseParams);        // write baseParams first, then write any params        params = Ext.apply(params, me.params);        return me.href ? Ext.urlAppend(me.href, Ext.Object.toQueryString(params)) : false;    },<span id='Ext-button-Button-method-setParams'>    /**</span>     * Sets the href of the link dynamically according to the params passed, and any {@link #baseParams} configured.     *     * **Only valid if the Button was originally configured with a {@link #href}**     *     * @param {Object} params Parameters to use in the href URL.     */    setParams: function(params) {        this.params = params;        this.btnEl.dom.href = this.getHref();    },    getSplitCls: function() {        var me = this;        return me.split ? (me.baseCls + '-' + me.arrowCls) + ' ' + (me.baseCls + '-' + me.arrowCls + '-' + me.arrowAlign) : '';    },    getBtnCls: function() {        return this.textAlign ? this.baseCls + '-' + this.textAlign : '';    },<span id='Ext-button-Button-method-setIconCls'>    /**</span>     * Sets the CSS class that provides a background image to use as the button's icon. This method also changes the     * value of the {@link #iconCls} config internally.     * @param {String} cls The CSS class providing the icon image     * @return {Ext.button.Button} this     */    setIconCls: function(cls) {        var me = this,            btnIconEl = me.btnIconEl,            oldCls = me.iconCls;                    me.iconCls = cls;        if (btnIconEl) {            // Remove the previous iconCls from the button            btnIconEl.removeCls(oldCls);            btnIconEl.addCls(cls || '');            me.setComponentCls();            if (me.didIconStateChange(oldCls, cls)) {                me.updateLayout();            }        }        return me;    },<span id='Ext-button-Button-method-setTooltip'>    /**</span>     * Sets the tooltip for this Button.     *     * @param {String/Object} tooltip This may be:     *     *   - **String** : A string to be used as innerHTML (html tags are accepted) to show in a tooltip     *   - **Object** : A configuration object for {@link Ext.tip.QuickTipManager#register}.     *     * @return {Ext.button.Button} this     */    setTooltip: function(tooltip, initial) {        var me = this;        if (me.rendered) {            if (!initial) {                me.clearTip();            }            if (Ext.isObject(tooltip)) {                Ext.tip.QuickTipManager.register(Ext.apply({                    target: me.btnEl.id                },                tooltip));                me.tooltip = tooltip;            } else {                me.btnEl.dom.setAttribute(me.getTipAttr(), tooltip);            }        } else {            me.tooltip = tooltip;        }        return me;    },<span id='Ext-button-Button-method-setTextAlign'>    /**</span>     * Sets the text alignment for this button.     * @param {String} align The new alignment of the button text. See {@link #textAlign}.     */    setTextAlign: function(align) {        var me = this,            btnEl = me.btnEl;        if (btnEl) {            btnEl.removeCls(me.baseCls + '-' + me.textAlign);            btnEl.addCls(me.baseCls + '-' + align);        }        me.textAlign = align;        return me;    },    getTipAttr: function(){        return this.tooltipType == 'qtip' ? 'data-qtip' : 'title';    },    // private    getRefItems: function(deep){        var menu = this.menu,            items;                if (menu) {            items = menu.getRefItems(deep);            items.unshift(menu);        }        return items || [];    },    // private    clearTip: function() {        if (Ext.isObject(this.tooltip)) {            Ext.tip.QuickTipManager.unregister(this.btnEl);        }    },    // private    beforeDestroy: function() {        var me = this;        if (me.rendered) {            me.clearTip();        }        if (me.menu && me.destroyMenu !== false) {            Ext.destroy(me.menu);        }        Ext.destroy(me.btnInnerEl, me.repeater);        me.callParent();    },    // private    onDestroy: function() {        var me = this;        if (me.rendered) {            me.doc.un('mouseover', me.monitorMouseOver, me);            me.doc.un('mouseup', me.onMouseUp, me);            delete me.doc;            Ext.ButtonToggleManager.unregister(me);            Ext.destroy(me.keyMap);            delete me.keyMap;        }        me.callParent();    },<span id='Ext-button-Button-method-setHandler'>    /**</span>     * Assigns this Button's click handler     * @param {Function} handler The function to call when the button is clicked     * @param {Object} [scope] The scope (`this` reference) in which the handler function is executed.     * Defaults to this Button.     * @return {Ext.button.Button} this     */    setHandler: function(handler, scope) {        this.handler = handler;        this.scope = scope;        return this;    },<span id='Ext-button-Button-method-setText'>    /**</span>     * Sets this Button's text     * @param {String} text The button text     * @return {Ext.button.Button} this     */    setText: function(text) {        var me = this;        me.text = text;        if (me.rendered) {            me.btnInnerEl.update(text || '&#160;');            me.setComponentCls();            if (Ext.isStrict && Ext.isIE8) {                // weird repaint issue causes it to not resize                me.el.repaint();            }            me.updateLayout();        }        return me;    },<span id='Ext-button-Button-method-setIcon'>    /**</span>     * Sets the background image (inline style) of the button. This method also changes the value of the {@link #icon}     * config internally.     * @param {String} icon The path to an image to display in the button     * @return {Ext.button.Button} this     */    setIcon: function(icon) {        var me = this,            btnIconEl = me.btnIconEl,            oldIcon = me.icon;                    me.icon = icon;        if (btnIconEl) {            btnIconEl.setStyle('background-image', icon ? 'url(' + icon + ')': '');            me.setComponentCls();            if (me.didIconStateChange(oldIcon, icon)) {                me.updateLayout();            }        }        return me;    },    <span id='Ext-button-Button-method-didIconStateChange'>    /**</span>     * Checks if the icon/iconCls changed from being empty to having a value, or having a value to being empty.     * @private     * @param {String} old The old icon/iconCls     * @param {String} current The current icon/iconCls     * @return {Boolean} True if the icon state changed     */    didIconStateChange: function(old, current) {        var currentEmpty = Ext.isEmpty(current);        return Ext.isEmpty(old) ? !currentEmpty : currentEmpty;    },<span id='Ext-button-Button-method-getText'>    /**</span>     * Gets the text for this Button     * @return {String} The button text     */    getText: function() {        return this.text;    },<span id='Ext-button-Button-method-toggle'>    /**</span>     * If a state it passed, it becomes the pressed state otherwise the current state is toggled.     * @param {Boolean} [state] Force a particular state     * @param {Boolean} [suppressEvent=false] True to stop events being fired when calling this method.     * @return {Ext.button.Button} this     */    toggle: function(state, suppressEvent) {        var me = this;        state = state === undefined ? !me.pressed: !!state;        if (state !== me.pressed) {            if (me.rendered) {                me[state ? 'addClsWithUI': 'removeClsWithUI'](me.pressedCls);            }            me.pressed = state;            if (!suppressEvent) {                me.fireEvent('toggle', me, state);                Ext.callback(me.toggleHandler, me.scope || me, [me, state]);            }        }        return me;    },        maybeShowMenu: function(){        var me = this;        if (me.menu && !me.hasVisibleMenu() && !me.ignoreNextClick) {            me.showMenu();        }    },<span id='Ext-button-Button-method-showMenu'>    /**</span>     * Shows this button's menu (if it has one)     */    showMenu: function() {        var me = this;        if (me.rendered && me.menu) {            if (me.tooltip && me.getTipAttr() != 'title') {                Ext.tip.QuickTipManager.getQuickTip().cancelShow(me.btnEl);            }            if (me.menu.isVisible()) {                me.menu.hide();            }            me.menu.showBy(me.el, me.menuAlign, ((!Ext.isStrict && Ext.isIE) || Ext.isIE6) ? [-2, -2] : undefined);        }        return me;    },<span id='Ext-button-Button-method-hideMenu'>    /**</span>     * Hides this button's menu (if it has one)     */    hideMenu: function() {        if (this.hasVisibleMenu()) {            this.menu.hide();        }        return this;    },<span id='Ext-button-Button-method-hasVisibleMenu'>    /**</span>     * Returns true if the button has a menu and it is visible     * @return {Boolean}     */    hasVisibleMenu: function() {        var menu = this.menu;        return menu && menu.rendered && menu.isVisible();    },    // private    onRepeatClick: function(repeat, e) {        this.onClick(e);    },    // private    onClick: function(e) {        var me = this;        if (me.preventDefault || (me.disabled && me.getHref()) && e) {            e.preventDefault();        }        if (e.button !== 0) {            return;        }        if (!me.disabled) {            me.doToggle();            me.maybeShowMenu();            me.fireHandler(e);        }    },        fireHandler: function(e){        var me = this,            handler = me.handler;                    if (me.fireEvent('click', me, e) !== false) {            if (handler) {                handler.call(me.scope || me, me, e);            }            me.blur();        }    },        doToggle: function(){        var me = this;            if (me.enableToggle && (me.allowDepress !== false || !me.pressed)) {            me.toggle();        }    },<span id='Ext-button-Button-method-onMouseOver'>    /**</span>     * @private mouseover handler called when a mouseover event occurs anywhere within the encapsulating element.     * The targets are interrogated to see what is being entered from where.     * @param e     */    onMouseOver: function(e) {        var me = this;        if (!me.disabled && !e.within(me.el, true, true)) {            me.onMouseEnter(e);        }    },<span id='Ext-button-Button-method-onMouseOut'>    /**</span>     * @private     * mouseout handler called when a mouseout event occurs anywhere within the encapsulating element -     * or the mouse leaves the encapsulating element.     * The targets are interrogated to see what is being exited to where.     * @param e     */    onMouseOut: function(e) {        var me = this;        if (!e.within(me.el, true, true)) {            if (me.overMenuTrigger) {                me.onMenuTriggerOut(e);            }            me.onMouseLeave(e);        }    },<span id='Ext-button-Button-method-onMouseMove'>    /**</span>     * @private     * mousemove handler called when the mouse moves anywhere within the encapsulating element.     * The position is checked to determine if the mouse is entering or leaving the trigger area. Using     * mousemove to check this is more resource intensive than we'd like, but it is necessary because     * the trigger area does not line up exactly with sub-elements so we don't always get mouseover/out     * events when needed. In the future we should consider making the trigger a separate element that     * is absolutely positioned and sized over the trigger area.     */    onMouseMove: function(e) {        var me = this,            el = me.el,            over = me.overMenuTrigger,            overlap, btnSize;        if (me.split) {            if (me.arrowAlign === 'right') {                overlap = e.getX() - el.getX();                btnSize = el.getWidth();            } else {                overlap = e.getY() - el.getY();                btnSize = el.getHeight();            }            if (overlap > (btnSize - me.getTriggerSize())) {                if (!over) {                    me.onMenuTriggerOver(e);                }            } else {                if (over) {                    me.onMenuTriggerOut(e);                }            }        }    },<span id='Ext-button-Button-method-getTriggerSize'>    /**</span>     * @private     * Measures the size of the trigger area for menu and split buttons. Will be a width for     * a right-aligned trigger and a height for a bottom-aligned trigger. Cached after first measurement.     */    getTriggerSize: function() {        var me = this,            size = me.triggerSize,            side, sideFirstLetter, undef;        if (size === undef) {            side = me.arrowAlign;            sideFirstLetter = side.charAt(0);            size = me.triggerSize = me.el.getFrameWidth(sideFirstLetter) + me.btnWrap.getFrameWidth(sideFirstLetter) + me.frameSize[side];        }        return size;    },<span id='Ext-button-Button-method-onMouseEnter'>    /**</span>     * @private     * virtual mouseenter handler called when it is detected that the mouseout event     * signified the mouse entering the encapsulating element.     * @param e     */    onMouseEnter: function(e) {        var me = this;        me.addClsWithUI(me.overCls);        me.fireEvent('mouseover', me, e);    },<span id='Ext-button-Button-method-onMouseLeave'>    /**</span>     * @private     * virtual mouseleave handler called when it is detected that the mouseover event     * signified the mouse entering the encapsulating element.     * @param e     */    onMouseLeave: function(e) {        var me = this;        me.removeClsWithUI(me.overCls);        me.fireEvent('mouseout', me, e);    },<span id='Ext-button-Button-method-onMenuTriggerOver'>    /**</span>     * @private     * virtual mouseenter handler called when it is detected that the mouseover event     * signified the mouse entering the arrow area of the button - the `<em>`.     * @param e     */    onMenuTriggerOver: function(e) {        var me = this;        me.overMenuTrigger = true;        me.fireEvent('menutriggerover', me, me.menu, e);    },<span id='Ext-button-Button-method-onMenuTriggerOut'>    /**</span>     * @private     * virtual mouseleave handler called when it is detected that the mouseout event     * signified the mouse leaving the arrow area of the button - the `<em>`.     * @param e     */    onMenuTriggerOut: function(e) {        var me = this;        delete me.overMenuTrigger;        me.fireEvent('menutriggerout', me, me.menu, e);    },    // inherit docs    enable : function(silent) {        var me = this;        me.callParent(arguments);        if (me.btnEl) {            me.btnEl.dom.disabled = false;        }        me.removeClsWithUI('disabled');        return me;    },    // inherit docs    disable : function(silent) {        var me = this;        me.callParent(arguments);        if (me.btnEl) {            me.btnEl.dom.disabled = true;        }        me.addClsWithUI('disabled');        me.removeClsWithUI(me.overCls);        // IE renders disabled text by layering gray text on top of white text, offset by 1 pixel. Normally this is fine        // but in some circumstances (such as using formBind) it gets confused and renders them side by side instead.        if (me.btnInnerEl && (Ext.isIE6 || Ext.isIE7)) {            me.btnInnerEl.repaint();        }        return me;    },<span id='Ext-button-Button-method-setScale'>    /**</span>     * Method to change the scale of the button. See {@link #scale} for allowed configurations.     * @param {String} scale The scale to change to.     */    setScale: function(scale) {        var me = this,            ui = me.ui.replace('-' + me.scale, '');        //check if it is an allowed scale        if (!Ext.Array.contains(me.allowedScales, scale)) {            throw('#setScale: scale must be an allowed scale (' + me.allowedScales.join(', ') + ')');        }        me.scale = scale;        me.setUI(ui);    },    // inherit docs    setUI: function(ui) {        var me = this;        //we need to append the scale to the UI, if not already done        if (me.scale && !ui.match(me.scale)) {            ui = ui + '-' + me.scale;        }        me.callParent([ui]);        // Set all the state classNames, as they need to include the UI        // me.disabledCls += ' ' + me.baseCls + '-' + me.ui + '-disabled';    },    // private    onMouseDown: function(e) {        var me = this;        if (!me.disabled && e.button === 0) {            me.addClsWithUI(me.pressedCls);            me.doc.on('mouseup', me.onMouseUp, me);        }    },    // private    onMouseUp: function(e) {        var me = this;        if (e.button === 0) {            if (!me.pressed) {                me.removeClsWithUI(me.pressedCls);            }            me.doc.un('mouseup', me.onMouseUp, me);        }    },    // private    onMenuShow: function(e) {        var me = this;        me.ignoreNextClick = 0;        me.addClsWithUI(me.menuActiveCls);        me.fireEvent('menushow', me, me.menu);    },    // private    onMenuHide: function(e) {        var me = this;        me.removeClsWithUI(me.menuActiveCls);        me.ignoreNextClick = Ext.defer(me.restoreClick, 250, me);        me.fireEvent('menuhide', me, me.menu);    },    // private    restoreClick: function() {        this.ignoreNextClick = 0;    },    // private    onDownKey: function() {        var me = this;        if (!me.disabled) {            if (me.menu) {                me.showMenu();            }        }    },<span id='Ext-button-Button-method-getPersistentPadding'>    /**</span>     * @private     * Some browsers (notably Safari and older Chromes on Windows) add extra "padding" inside the button     * element that cannot be removed. This method returns the size of that padding with a one-time detection.     * @return {Number[]} [top, right, bottom, left]     */    getPersistentPadding: function() {        var me = this,            reset = Ext.scopeResetCSS,            padding = me.persistentPadding,            btn, leftTop, btnEl, btnInnerEl, wrap;        // Create auto-size button offscreen and measure its insides        // Short-circuit IE as it sometimes gives false positive for padding        if (!padding) {            padding = me.self.prototype.persistentPadding = [0, 0, 0, 0];            if (!Ext.isIE) {                btn = new Ext.button.Button({                    text: 'test',                    style: 'position:absolute;top:-999px;'                });                btn.el = Ext.DomHelper.append(Ext.resetElement, btn.getRenderTree(), true);                btn.applyChildEls(btn.el);                btnEl = btn.btnEl;                btnInnerEl = btn.btnInnerEl;                btnEl.setSize(null, null); //clear any hard dimensions on the button el to see what it does naturally                leftTop = btnInnerEl.getOffsetsTo(btnEl);                padding[0] = leftTop[1];                padding[1] = btnEl.getWidth() - btnInnerEl.getWidth() - leftTop[0];                padding[2] = btnEl.getHeight() - btnInnerEl.getHeight() - leftTop[1];                padding[3] = leftTop[0];                                btn.destroy();                btn.el.remove();            }        }        return padding;    }}, function() {    var groups = {},        toggleGroup = function(btn, state) {            if (state) {                var g = groups[btn.toggleGroup],                    length = g.length,                    i;                for (i = 0; i < length; i++) {                    if (g[i] !== btn) {                        g[i].toggle(false);                    }                }            }        };    // Private utility class used by Button    Ext.ButtonToggleManager = {        register: function(btn) {            if (!btn.toggleGroup) {                return;            }            var group = groups[btn.toggleGroup];            if (!group) {                group = groups[btn.toggleGroup] = [];            }            group.push(btn);            btn.on('toggle', toggleGroup);        },        unregister: function(btn) {            if (!btn.toggleGroup) {                return;            }            var group = groups[btn.toggleGroup];            if (group) {                Ext.Array.remove(group, btn);                btn.un('toggle', toggleGroup);            }        },        // Gets the pressed button in the passed group or null        // @param {String} group        // @return {Ext.button.Button}        getPressed: function(group) {            var g = groups[group],                i = 0,                len;            if (g) {                for (len = g.length; i < len; i++) {                    if (g[i].pressed === true) {                        return g[i];                    }                }            }            return null;        }    };});</pre></body></html>
 |