/* global Ext */
/*******************************************************************************
 * This file is distributed on an AS IS BASIS WITHOUT ANY WARRANTY; without even
 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * ***********************************************************************************
 *
 * License: ux.ManagedIFrame and ux.ManagedIFramePanel 1.2 are licensed under
 * the terms of the Open Source LGPL 3.0 license:
 * http://www.gnu.org/licenses/lgpl.html
 *
 * Commercial use is prohibited without a Commercial License. See
 * http://licensing.theactivegroup.com.
 *
 * Donations are welcomed: http://donate.theactivegroup.com
 *
 * <p>
 * An Ext.Element harness for iframe elements.
 *
 * Adds Ext.UpdateManager(Updater) support and a compatible 'update' method for
 * writing content directly into an iFrames' document structure.
 *
 * Signals various DOM/document states as the frames content changes with
 * 'domready', 'documentloaded', and 'exception' events. The domready event is
 * only raised when a proper security context exists for the frame's DOM to
 * permit modification. (ie, Updates via Updater or documents retrieved from
 * same-domain servers).
 *
 * Frame sand-box permits eval/script-tag writes of javascript source. (See
 * execScript, writeScript, and loadFunction methods for more info.)
 *
 * Usage:<br>
 *
 * <pre><code>
 * // Harnessed from an existing Iframe from markup:
 * var i = new Ext.ux.ManagedIFrame(&quot;myIframe&quot;);
 * // Replace the iFrames document structure with the response from the requested URL.
 * i.load(&quot;http://myserver.com/index.php&quot;, &quot;param1=1&amp;param2=2&quot;);
 *
 * // Notes:  this is not the same as setting the Iframes src property !
 * // Content loaded in this fashion does not share the same document namespaces as it's parent --
 * // meaning, there (by default) will be no Ext namespace defined in it since the document is
 * // overwritten after each call to the update method, and no styleSheets.
 * </code></pre>
 *
 * <br>
 * Release: 1.2.5 (5/16/2009)
 *     Fix: X-frame messaging: needed mixin function (apply) for frames without Ext loaded into them. (thx: livinphp)
 * Release: 1.2.4 (4/29/2009)
 *     Add: Support for Ext 3.0, resize event
 * Release: 1.2.3 (1/11/2009)
        Fix: frameConfig attributes not being passed to IFRAME element.
 * Release: 1.2.2( 11/10/2008)
 *      Fix: setSrc ( {url: url,callback: function(){}....}) style calls were broken.
 * Release: 1.2.1( 11/3/2008)
 *      Mod: Corrected <noframes> support (unsupportedText)
 *      Mod: Improved domready detection for Opera, Webkit, and IE. jsDOC updates.
 *      Mod: MIFP frameConfig now honors either frameConfig:{id:'someId': name:'someName',....}
 *           or frameConfig: {autoCreate:{ id:'someId': name:'someName',....}}
 *      Add: resetUrl class property to override the reset URL used by default with the reset method.
 *      Add: (MIF/MIFP):setLocation method. Identical to setSrc, but uses location.replace
 *           on the frame instead, preventing a History update.
 *      Add: scope parameter to
 *           all methods supporting callbacks
 *      Mod: callbacks are invoke as soon as domready status is detected.
 *      Mod: MIFPanel now honors the contentEl cfg option, meaning IFRAMEs authored in page markup
 *           may be converted to MIFrames when the Panel is rendered.
 *
 * 1.2 (8/22/2008) FF3 Compatibility Fixes, loadMask tweaks
 *
 * 1.1 (4/13/2008) Adds Ext.Element, CSS Selectors (query,select) fly, and CSS
 * interface support (same-domain only) Adds blur,focus,unload events
 * (same-domain only)
 *
 */

(function() {

    var addListener = function () {
            if (window.addEventListener) {
                return function(el, eventName, fn, capture) {
                    el.addEventListener(eventName, fn, !!capture);
                };
            } else if (window.attachEvent) {
                return function(el, eventName, fn, capture) {
                    el.attachEvent("on" + eventName, fn);
                };
            } else {
                return function() {
                };
            }
        }(),
       removeListener = function() {
            if (window.removeEventListener) {
                return function (el, eventName, fn, capture) {
                    el.removeEventListener(eventName, fn, (capture));
                };
            } else if (window.detachEvent) {
                return function (el, eventName, fn) {
                    el.detachEvent("on" + eventName, fn);
                };
            } else {
                return function() {
                };
            }
        }();
  
    
    var EV = Ext.lib.Event;
    var MIM;
    /**
   * @class Ext.ux.ManagedIFrame
   * @extends Ext.Element
   * @extends Ext.util.Observable
   * @version:  1.2.4 (4/29/2009)
   * @license <a href="http://www.gnu.org/licenses/lgpl.html">LGPL 3.0</a>
   * @author: Doug Hendricks. Forum ID: <a href="http://extjs.com/forum/member.php?u=8730">hendricd</a>
   * @donate <form action="https://www.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_donations">
<input type="hidden" name="business" value="doug@theactivegroup.com">
<input type="hidden" name="item_name" value="ux.ManagedIFrame">
<input type="hidden" name="item_number" value="MIF/P">
<input type="hidden" name="no_shipping" value="1">
<input type="hidden" name="return" value="http://donate.theactivegroup.com/thankyou.html">
<input type="hidden" name="cn" value="Optional Comments">
<input type="hidden" name="currency_code" value="USD">
<input type="hidden" name="tax" value="0">
<input type="hidden" name="lc" value="US">
<input type="hidden" name="bn" value="PP-DonationsBF">
<input type="image" src="http://www.paypal.com/en_US/i/btn/x-click-butcc-donate.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!">
<img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1">
</form>
   *
   * @cfg {Boolean/Object} autoCreate True to auto generate the IFRAME element, or a {@link Ext.DomHelper} config of the IFRAME to create
   * @cfg {String} html Any markup to be applied to the IFRAME's document content when rendered.
   * @cfg {Object} loadMask An {@link Ext.LoadMask} config or true to mask the iframe while using the update or setSrc methods (defaults to false).
   * @cfg {Object} src  The src attribute to be assigned to the Iframe after initialization (overrides the autoCreate config src attribute)
   * @constructor
   * @param {Mixed} el, Config object The iframe element or it's id to harness or a valid config object.
   */

    /** @private */

    Ext.ux.ManagedIFrame = function() {
        var args = Array.prototype.slice.call(arguments, 0),
            el = Ext.get(args[0]),
            config = args[0];

        if (el && el.dom && el.dom.tagName == 'IFRAME') {
            config = args[1] || {};
        } else {
            config = args[0] || args[1] || {};

            el = config.autoCreate ? Ext.get(Ext.DomHelper.append(
                    config.autoCreate.parent || Ext.getBody(), Ext.apply({
                        tag : 'iframe',
                        frameborder : 0,
                        src : (Ext.isIE && Ext.isSecure)? Ext.SSL_SECURE_URL: 'about:blank'
                    }, config.autoCreate)))
                    : null;

            if(el && this.unsupportedText){
                Ext.DomHelper.append(el.dom.parentNode, {tag:'noframes',html:this.unsupportedText } );
            }
        }

        if (!el || el.dom.tagName != 'IFRAME') { return el; }

        el.dom.name || (el.dom.name = el.dom.id); // make sure there is a valid frame name
        el.dom.ownerEl = el;

        this.addEvents({
            /**
             * Fires when the frame gets focus. Note: This event is only
             * available when overwriting the iframe document using the
             * {@link #Ext.ux.ManagedIFrame-update} method and to pages
             * retrieved from a "same-origin" domain. Returning false from the
             * eventHandler [MAY] NOT cancel the event, as this event is NOT
             * ALWAYS cancellable in all browsers.
             *
             * @event focus
             * @param {Ext.ux.ManagedIFrame} this
             * @param {Ext.Event} event
             *
             */
            "focus" : true,

            /**
             * Fires when the frame is blurred (loses focus). Note: This event
             * is only available when overwriting the iframe document using the
             * update method and to pages retrieved from a "same-origin" domain.
             * Returning false from the eventHandler [MAY] NOT cancel the event,
             * as this event is NOT ALWAYS cancellable in all browsers.
             *
             * @event blur
             * @param {Ext.ux.ManagedIFrame} this
             * @param {Ext.Event} event
             */
            "blur" : true,

            /**
             * Note: This event is only available when overwriting the iframe
             * document using the {@link #Ext.ux.ManagedIFrame-update} method
             * and to documents retrieved from a "same-origin" domains. Fires
             * when(if) the frames window object raises the unload event<br />
             * Note: Opera does not raise this event.
             *
             * @event unload
             * @param {Ext.ux.ManagedIFrame} this
             * @param {Ext.Event} event
             */
            "unload" : true,

            /**
             * Note: This event is only available when overwriting the iframe
             * document using the {@link #Ext.ux.ManagedIFrame-update} method
             * and to documents retrieved from a "same-origin" domains. Fires
             * ONLY when an iFrame's Document(DOM) has reach a state where the
             * DOM may be manipulated (ie same domain policy) Returning false
             * from the eventHandler stops further event (documentloaded)
             * processing.
             *
             * @event domready
             * @param {Ext.ux.ManagedIFrame} this
             */
            "domready" : true,

            /**
             * Fires when the iFrame has reached a loaded/complete state.
             *
             * @event documentloaded
             * @param {Ext.ux.ManagedIFrame} this
             */
            "documentloaded" : true,

            /**
             * Fires when the frame actions raise an error
             *
             * @event exception
             * @param {Ext.ux.ManagedIFrame} this
             * @param {Error|string} exception
             */
            "exception" : true,
            /**
             * Fires upon receipt of a message generated by window.sendMessage
             * method of the embedded Iframe.window object
             *
             * @event message
             * @param {Ext.ux.ManagedIFrame} this
             * @param {Object} message members:
             *            <ul>
             *            <li><b>type</b> {string}
             *            <p class="sub-desc">
             *            literal "message"
             *            </p>
             *            </li>
             *            <li><b>data</b> {Mixed}
             *            <p class="sub-desc">
             *            the message payload]
             *            </p>
             *            </li>
             *            <li><b>domain</b> {String}
             *            <p class="sub-desc">
             *            the document domain from which the message originated
             *            </p>
             *            </li>
             *            <li><b>uri</b> {string}
             *            <p class="sub-desc">
             *            the document URI of the message sender
             *            </p>
             *            </li>
             *            <li><b>source</b> (Object)
             *            <p class="sub-desc">
             *            the window context of the message sender
             *            </p>
             *            </li>
             *            <li><b>tag</b> {string}
             *            <p class="sub-desc">
             *            optional reference tag sent by the message sender }
             *            </p>
             *            </li>
             *            </ul>
             */
            "message" : true
                // "message:tagName" is supported for X-frame messaging
                /**
                 * Alternate event handler syntax for message:tag filtering
                 * Fires upon receipt of a message generated by
                 * window.sendMessage method which includes a specific tag value
                 * of the embedded Iframe.window object
                 *
                 * @event message:tag
                 * @param {Ext.ux.ManagedIFrame} this
                 * @param {Object} message members:
                 *            <ul>
                 *            <li><b>type</b> {string}
                 *            <p class="sub-desc">
                 *            literal "message"
                 *            </p>
                 *            </li>
                 *            <li><b>data</b> {Mixed}
                 *            <p class="sub-desc">
                 *            the message payload]
                 *            </p>
                 *            </li>
                 *            <li><b>domain</b> {String}
                 *            <p class="sub-desc">
                 *            the document domain from which the message
                 *            originated
                 *            </p>
                 *            </li>
                 *            <li><b>uri</b> {string}
                 *            <p class="sub-desc">
                 *            the document URI of the message sender
                 *            </p>
                 *            </li>
                 *            <li><b>source</b> (Object)
                 *            <p class="sub-desc">
                 *            the window context of the message sender
                 *            </p>
                 *            </li>
                 *            <li><b>tag</b> {string}
                 *            <p class="sub-desc">
                 *            optional reference tag sent by the message sender }
                 *            </p>
                 *            </li>
                 *            </ul>
                 */

            });

        if (config.listeners) {
            this.listeners = config.listeners;
            Ext.ux.ManagedIFrame.superclass.constructor.call(this);
        }

        Ext.apply(el, this); // apply this class interface ( pseudo Decorator
                                // )

        el.addClass('x-managed-iframe');
        if (config.style) {
            el.applyStyles(config.style);
        }

        Ext.apply(el, {
            disableMessaging : config.disableMessaging === true,
            loadMask : !!config.loadMask ? Ext.apply({
                        msg : 'Loading..',
                        msgCls : 'x-mask-loading',
                        maskEl : null,
                        hideOnReady : false,
                        disabled : false
                    }, config.loadMask) : false

            ,
            _windowContext : null,
            eventsFollowFrameLinks : typeof config.eventsFollowFrameLinks == 'undefined'
                    ? true : config.eventsFollowFrameLinks
        });


        if(el.loadMask ){
           el.loadMask.maskEl ||
           ( el.loadMask.maskEl = el.parent('.x-managed-iframe-mask') || el.parent().addClass('x-managed-iframe-mask'));
        }


        var um = el.updateManager = new Ext.UpdateManager(el, true);
        um.showLoadIndicator = config.showLoadIndicator || false;

        Ext.ux.ManagedIFrame.Manager.register(el);

        if (config.src) {
            el.setSrc(config.src);
        } else {
            var content = config.html || config.content || false;

            if (content) {
                el.reset(null,function(frame){
                    // permit the syntax for supported arguments: content or [content, loadScripts, callback, scope]
                    frame.update.apply(el, [].concat(content)); });
            }
        }

        return el;
    };


    Ext.extend(Ext.ux.ManagedIFrame, Ext.util.Observable, {
        /** (read-only) The last known URI set programmatically by the Component
         * @cfg {String|Function} src The target URI of the Component to set after render.
         * @property
         * @type String
         */
        src : null,

        /** (read-only) For "same-origin" frames only.  Provides a reference to
         * the Ext.util.CSS singleton to manipulate the style sheets of the frame's
         * embedded document.
         *
         * @property
         * @type Ext.util.CSS
         */
        CSS : null,

        /** Provides a reference to the managing Ext.ux.ManagedIFrame.Manager instance.
         *
         * @property
         * @type Ext.ux.ManagedIFrame.Manager
         */
        manager : null,

         /**
          * Enables/disables internal cross-frame messaging interface
          * @cfg {Boolean} disableMessaging False to enable cross-frame messaging API
          * Default = true
          *
          */
        disableMessaging :  true,

        /**
         * @cfg {String} resetUrl Frame document reset string for use with the {@link #Ext.ux.ManagedIFrame-reset} method.
         * Defaults:<p> For IE on SSL domains - the current value of Ext.SSL_SECURE_URL<p> "about:blank" for all others.
         */
        resetUrl : (function(){
            if(Ext.isIE && Ext.isSecure){
                return Ext.SSL_SECURE_URL;
            } else {
                return 'about:blank';
            }
        })(),

        /**
         * @cfg {String} unsupportedText Text to display when the IFRAMES.FRAMESETS are disabled by the browser.
         *
         */
        unsupportedText : 'Inline frames are NOT enabled\/supported by your browser.',

        /**
         * Sets the embedded Iframe src property. Note: invoke the function with
         * no arguments to refresh the iframe based on the current src value.
         *
         * @param {String/Function} url (Optional) A string or reference to a Function that
         *            returns a URI string when called
         * @param {Boolean} discardUrl (Optional) If not passed as <tt>false</tt>
         *            the URL of this action becomes the default SRC attribute
         *            for this iframe, and will be subsequently used in future
         *            setSrc calls (emulates autoRefresh by calling setSrc
         *            without params).
         * @param {Function} callback (Optional) A callback function invoked when the
         *            frame document has been fully loaded.
         * @param {Object} scope (Optional) scope by which the callback function is
         *            invoked.
         */
        setSrc : function(url, discardUrl, callback, scope) {

            if (url && typeof url == 'object') {
                callback = url.callback || false;
                discardUrl = url.discardUrl || false;
                url = url.url || false;
                scope = url.scope || null;
            }

            var src = url || this.src || this.resetUrl;

            this._windowContext = null;
            this._unHook();
            this._frameAction = this.frameInit = this._domReady = false;

            this.showMask();

            (function() {
                var s = this._targetURI = typeof src == 'function' ? src() || '' : src;
                try {
                    this._frameAction = true; // signal listening now
                    this._callBack = typeof callback == 'function' ? callback.createDelegate(scope) : null;
                    this.dom.src = s;
                    this.frameInit = true; // control initial event chatter
                    this.checkDOM();
                } catch (ex) {
                    this.fireEvent('exception', this, ex);
                }

             }).defer(10, this);

            if (discardUrl !== true) {
                this.src = src;
            }

            return this;

        },
        /**
         * Sets the embedded Iframe location using its replace method. Note: invoke the function with
         * no arguments to refresh the iframe based on the current src value.
         *
         * @param {String/Function} url (Optional) A string or reference to a Function that
         *            returns a URI string when called
         * @param {Boolean} discardUrl (Optional) If not passed as <tt>false</tt>
         *            the URL of this action becomes the default SRC attribute
         *            for this iframe, and will be subsequently used in future
         *            setSrc calls (emulates autoRefresh by calling setSrc
         *            without params).
         * @param {Function} callback (Optional) A callback function invoked when the
         *            frame document has been fully loaded.
         * @param {Object} scope (Optional) scope by which the callback function is
         *            invoked.
         *
         */

        setLocation : function(url, discardUrl, callback, scope) {

            if (url && typeof url == 'object') {
                callback = url.callback || false;
                discardUrl = url.discardUrl || false;
                url = url.url || false;
                scope = url.scope || null;
            }

            var src = url || this.src || this.resetUrl;

            this._windowContext = null;
            this._unHook();
            this._frameAction = this.frameInit = this._domReady = false;

            this.showMask();

            (function() {
                var s = this._targetURI = typeof src == 'function' ? src()
                        || '' : src;
                try {
                    this._frameAction = true; // signal listening now
                    this._callBack = typeof callback == 'function' ? callback.createDelegate(scope) : null;
                    this.getWindow().location.replace(s);
                    this.frameInit = true; // control initial event chatter
                    this.checkDOM();
                } catch (ex) {
                    this.fireEvent('exception', this, ex);
                }

            }).defer(10, this);

            if (discardUrl !== true) {
                this.src = src;
            }

            return this;

        },
        /**
         * Resets the frame to a neutral (blank document) state without
         * loadMasking.
         *
         * @param {String}
         *            src (Optional) A specific reset string (eg. 'about:blank')
         *            to use for resetting the frame.
         * @param {Function}
         *            callback (Optional) A callback function invoked when the
         *            frame reset is complete.
         * @param {Object}
         *            scope (Optional) scope by which the callback function is
         *            invoked.
         */
        reset : function(src, callback, scope) {

            this._unHook();

            var loadMaskOff = false;
            if(this.loadMask){
                loadMaskOff = this.loadMask.disabled;
                this.loadMask.disabled = false;
            }


            this._callBack = function(frame) {
                if(frame.loadMask){
                    frame.loadMask.disabled = loadMaskOff;
                };
                frame._frameAction = false;
                frame.frameInit = true;
                this._isReset= false;

                if (callback) {
                    callback.call(scope || window, frame);
                }
            };
            this.hideMask(true);
            this._frameAction = false; // no chatter on reset
            this.frameInit = true
            this._isReset= true;
            var s = src;
            if (typeof src == 'function') { s = src();}

            s = this._targetURI = Ext.isEmpty(s, true)? this.resetUrl: s;
            this.getWindow().location.href = s;

            return this;

        },

       /**
        * Regular Expression filter pattern for script tag removal.
        * @cfg {regexp} scriptRE script removal RegeXp
        * Default: "/(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/gi"
        */
        scriptRE : /(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/gi,

        /**
         * Write(replacing) string content into the IFrames document structure
         * @param {String} content The new content
         * @param {Boolean} loadScripts
         * (optional) true to also render and process embedded scripts
         * @param {Function} callback (Optional) A callback function invoked when the
         * frame document has been written and fully loaded. @param {Object}
         * scope (Optional) scope by which the callback function is invoked.
         */
        update : function(content, loadScripts, callback, scope) {

            loadScripts = loadScripts || this.getUpdateManager().loadScripts || false;

            content = Ext.DomHelper.markup(content || '');
            content = loadScripts === true ? content : content.replace(this.scriptRE, "");

            var doc;

            if ((doc = this.getDocument()) && !!content.length) {

                this._unHook();
                this._windowContext = this.src = null;
                this._targetURI = location.href;

                this.frameInit = true; // control initial event chatter
                this.showMask();

                (function() {
                    this._callBack = typeof callback == 'function' ? callback.createDelegate(scope) : null;
                    doc.open();
                    this._frameAction = true;
                    doc.write(content);
                    doc.close();

                    this.checkDOM();
                 }).defer(10, this);

            } else {
                this.hideMask(true);

                if (callback) {
                    callback.call(scope, this);
                }
            }
            return this;
        },

        /**
         * Enables/disables internal cross-frame messaging interface
         *
         * @cfg {Boolean} disableMessaging False to enable cross-frame messaging
         *      API (default is True)
         */
        disableMessaging : true,

        /**
         * @private, frame messaging interface (for same-domain-policy frames
         *           only)
         */
        _XFrameMessaging : function() {
            // each tag gets a hash queue ($ = no tag ).
            var tagStack = { '$' : [] };
            var isEmpty = function(v, allowBlank) {
                return v === null || v === undefined
                        || (!allowBlank ? v === '' : false);
            };
            var apply = function(o, c, defaults) {
                if (defaults) { apply(o, defaults); }
                if (o && c && typeof c == 'object') {
                    for (var p in c) {
                        o[p] = c[p];
                    }
                }
                return o;
            };

            window.sendMessage = function(message, tag, origin) {
                var MIF;
                if (MIF = arguments.callee.manager) {
                    if (message._fromHost) {
                        var fn, result;
                        // only raise matching-tag handlers
                        var compTag = message.tag || tag || null;
                        var mstack = !isEmpty(compTag) ? tagStack[compTag.toLowerCase()] || [] : tagStack["$"];

                        for (var i = 0, l = mstack.length; i < l; i++) {
                            if (fn = mstack[i]) {
                                result = fn.apply(fn.__scope, arguments) === false? false: result;
                                if (fn.__single) {
                                    mstack[i] = null;
                                }
                                if (result === false) {
                                    break;
                                }
                            }
                        }

                        return result;
                    } else {

                        message = {
                            type : isEmpty(tag) ? 'message' : 'message:'
                                    + tag.toLowerCase().replace(/^\s+|\s+$/g,''),
                            data : message,
                            domain : origin || document.domain,
                            uri : document.documentURI,
                            source : window,
                            tag : isEmpty(tag) ? null : tag.toLowerCase()
                        };

                        try {
                            return MIF.disableMessaging !== true
                                    ? MIF.fireEvent.call(MIF, message.type,MIF, message)
                                    : null;
                        } catch (ex) {
                        } // trap for message:tag handlers not yet defined

                        return null;
                    }

                }
            };
            window.onhostmessage = function(fn, scope, single, tag) {

                if (typeof fn == 'function') {
                    if (!isEmpty(fn.__index)) {
                        throw "onhostmessage: duplicate handler definition"
                                + (tag ? " for tag:" + tag : '');
                    }

                    var k = isEmpty(tag) ? "$" : tag.toLowerCase();
                    tagStack[k] || (tagStack[k] = []);
                    apply(fn, {
                                __tag : k,
                                __single : single || false,
                                __scope : scope || window,
                                __index : tagStack[k].length
                            });
                    tagStack[k].push(fn);

                } else {
                    throw "onhostmessage: function required";
                }

            };
            window.unhostmessage = function(fn) {
                if (typeof fn == 'function' && typeof fn.__index != 'undefined') {
                    var k = fn.__tag || "$";
                    tagStack[k][fn.__index] = null;
                }
            };

        },

        /**
         * Method to retrieve frame's history object.
         * @return {object} or null if permission was denied
         */
        getHistory  : function(){
            var h=null;
            try{ h=this.getWindow().history; }catch(eh){}
            return h;

        },
        /**
         * Method to retrieve embedded frame Element objects. Uses simple
         * caching (per frame) to consistently return the same object.
         * Automatically fixes if an object was recreated with the same id via
         * AJAX or DOM.
         *
         * @param {Mixed}
         *            el The id of the node, a DOM Node or an existing Element.
         * @return {Element} The Element object (or null if no matching element
         *         was found)
         */

        get : function(el) {
            return MIM.El.get(this, el);
        },

        /**
         * Gets the globally shared flyweight Element for the frame, with the
         * passed node as the active element. Do not store a reference to this
         * element - the dom node can be overwritten by other code.
         *
         * @param {String/HTMLElement}
         *            el The dom node or id
         * @param {String}
         *            named (optional) Allows for creation of named reusable
         *            flyweights to prevent conflicts (e.g. internally Ext uses
         *            "_internal")
         * @return {Element} The shared Element object (or null if no matching
         *         element was found)
         */

        fly : function(el, named) {
            named = named || '_global';
            el = this.getDom(el);
            if (!el) {
                return null;
            }
            if (!MIM._flyweights[named]) {
                MIM._flyweights[named] = new Ext.Element.Flyweight();
            }
            MIM._flyweights[named].dom = el;
            return MIM._flyweights[named];
        },
        /**
         * Return the dom node for the passed string (id), dom node, or
         * Ext.Element relative to the embedded frame document context.
         *
         * @param {Mixed} el
         * @return HTMLElement
         */

        getDom : function(el) {
            var d;
            if (!el || !(d = this.getDocument())) {
                return null;
            }
            return el.dom ? el.dom : (typeof el == 'string' ? d
                    .getElementById(el) : el);

        },
        /**
         * Creates a {@link Ext.CompositeElement} for child nodes based on the
         * passed CSS selector (the selector should not contain an id).
         *
         * @param {String} selector The CSS selector
         * @param {Boolean} unique (optional) True to create a unique Ext.Element for
         *            each child (defaults to false, which creates a single
         *            shared flyweight object)
         * @return {Ext.CompositeElement/Ext.CompositeElementLite} The composite element
         */

        select : function(selector, unique) {
            var d;
            return (d = this.getDocument()) ? Ext.Element.select(selector,unique, d) : null;
        },

        /**
         * Selects frame document child nodes based on the passed CSS selector
         * (the selector should not contain an id).
         *
         * @param {String} selector The CSS selector
         * @return {Array} An array of the matched nodes
         */

        query : function(selector) {
            var d;
            return (d = this.getDocument()) ? Ext.DomQuery.select(selector, d): null;
        },

        /**
         * Returns the frame's current HTML document object as an
         * {@link Ext.Element}.
         *
         * @return {Ext.Element} The document
         */

        getDoc : function() {
            return this.get(this.getDocument());
        },

        /**
         * Removes a DOM Element from the embedded documents
         *
         * @param {Element/String} node The node id or node Element to remove
         *
         */

        removeNode : function(node) {
            MIM.removeNode(this, this.getDom(node));
        },

        /** @private : clear all event listeners and Element cache */

        _unHook : function() {

            var elcache, h = MIM.getFrameHash(this) || {};

            if (this._hooked){
                if( h && (elcache = h.elCache)) {
            
	                for (var id in elcache) {
	                    var el = elcache[id];
	
	                    if (el.removeAllListeners) {
	                        el.removeAllListeners();
	                    }
	                    delete elcache[id];
	                }
	                if (h.docEl) {
	                    h.docEl.removeAllListeners();
	                    h.docEl = null;
	                    delete h.docEl;
	                }
                    
                }
                var w;
                if(this._frameProxy && (w = this.getWindow())){
                    removeListener(w, 'focus', this._frameProxy);
                    removeListener(w, 'blur', this._frameProxy);
                    removeListener(w, 'resize', this._frameProxy);
                    removeListener(w, 'unload', this._frameProxy);
                }
            }

            this.CSS = this.CSS ? this.CSS.destroy() : null;
            this._hooked = this._domReady = this._domFired = this._frameAction = false;

        },
        // Private execScript sandbox and messaging interface

        _renderHook : function() {

            this._windowContext = null;
            this.CSS = this.CSS ? this.CSS.destroy() : null;
            this._hooked = false;
            try {
                if (this.writeScript('(function(){(window.hostMIF = parent.Ext.get("'
                                + this.dom.id
                                + '"))._windowContext='
                                + (Ext.isIE
                                        ? 'window'
                                        : '{eval:function(s){return eval(s);}}')
                                + ';})();')) {
                    this._frameProxy || (this._frameProxy = MIM.eventProxy.createDelegate(this));
                    var w;

                    if(w = this.getWindow()){
                            addListener(w, 'focus', this._frameProxy);
                            addListener(w, 'blur', this._frameProxy);
                            addListener(w, 'resize', this._frameProxy);
                            addListener(w, 'unload', this._frameProxy);
                    }

                    if (this.disableMessaging !== true) {
                        this.loadFunction({
                                    name : 'XMessage',
                                    fn : this._XFrameMessaging
                                }, false, true);
                        var sm;
                        if (sm = w.sendMessage) {
                            sm.manager = this;
                        }
                    }
                    this.CSS = new CSSInterface(this.getDocument());

                }

            } catch (ex) {
            }

            return this.domWritable();

        },
        /**
         * dispatch a message to the embedded frame-window context
         * @name sendMessage
         * @methodOf Ext.ux.ManagedIFrame
         * @param {Mixed} message The message payload @param {String} tag Optional reference tag @param
         * {String} origin Optional domain designation of the sender (defaults
         * to document.domain).
         */
        sendMessage : function(message, tag, origin) {
            var win;
            if (this.disableMessaging !== true && (win = this.getWindow())) {
                // support frame-to-frame messaging relay
                tag || (tag = message.tag || '');
                tag = tag.toLowerCase();
                message = Ext.applyIf(message.data ? message : {
                            data : message
                        }, {
                            type : Ext.isEmpty(tag) ? 'message' : 'message:'
                                    + tag,
                            domain : origin || document.domain,
                            uri : document.documentURI,
                            source : window,
                            tag : tag || null,
                            _fromHost : this
                        });
                return win.sendMessage ? win.sendMessage.call(null, message,
                        tag, origin) : null;
            }
            return null;

        },

        /** @private */
        _windowContext : null,

        /**
         * If sufficient privilege exists, returns the frame's current document
         * as an HTMLElement.
         *
         * @return {HTMLElement} The frame document or false if access to
         *         document object was denied.
         */
        getDocument : function() {
            var win = this.getWindow(), doc = null;
            try {
                doc = (Ext.isIE && win ? win.document : null)
                        || this.dom.contentDocument
                        || window.frames[this.id].document || null;
            } catch (gdEx) {
                return false; // signifies probable access restriction
            }
            return doc;
        },

        /**
         * If sufficient privilege exists, returns the frame's current document
         * body as an HTMLElement.
         *
         * @return {HTMLElement} The frame document body or Null if access to
         *         document object was denied.
         */
        getBody : function() {
            var d;
            return (d = this.getDocument()) ? d.body : null;
        },

        /**
         * Attempt to retrieve the frames current URI via frame's document object
         * @return {string} The frame document's current URI or the last know URI if permission was denied.
         */
        getDocumentURI : function() {
            var URI, d;
            try {
                URI = this.src && (d = this.getDocument()) ? d.location.href: null;
            } catch (ex) { // will fail on NON-same-origin domains
            }
            return URI || (typeof this.src == 'function' ? this.src() : this.src);
            // fallback to last known
        },

       /**
        * Attempt to retrieve the frames current URI via frame's Window object
        * @return {string} The frame document's current URI or the last know URI if permission was denied.
        */
        getWindowURI : function() {
            var URI, w;
            try {
                URI = (w = this.getWindow()) ? w.location.href : null;
            } catch (ex) {
            } // will fail on NON-same-origin domains
            return URI || (typeof this.src == 'function' ? this.src() : this.src);
            // fallback to last known
        },

        /**
         * Returns the frame's current window object.
         *
         * @return {Window} The frame Window object.
         */
        getWindow : function() {
            var dom = this.dom, win = null;
            try {
                win = dom.contentWindow || window.frames[dom.name] || null;
            } catch (gwEx) {
            }
            return win;
        },

        /**
         * Print the contents of the Iframes (if we own the document)
         */
        print : function() {
            var win;
            try {
                if( win = this.getWindow()){
                    if (Ext.isIE) {
                        win.focus();
                    }
                    win.print();
                }
            } catch (ex) {
                throw 'print exception: ' + (ex.description || ex.message || ex);
            }
        },
        /** @private */
        destroy : function() {
            this.removeAllListeners();
            if (this.loadMask) {
                this.hideMask(true);
                Ext.apply(this.loadMask, {
                            masker : null,
                            maskEl : null
                        });
            }

            if (this.dom) {

                Ext.ux.ManagedIFrame.Manager.deRegister(this);
                this.dom.ownerEl = this._windowContext = null;
                // IE Iframe cleanup
                if (Ext.isIE && this.dom.src) {
                    this.dom.src = 'javascript:false';
                }
                this._maskEl = null;
                this.remove();
            }



        },
        /**
         * Returns the general DOM modification capability of the frame. @return
         * {Boolean} If True, the frame's DOM can be manipulated, queried, and
         * Event Listeners set.
         */

        domWritable : function() {
            return !!this._windowContext;
        },
        /**
         * eval a javascript code block(string) within the context of the
         * Iframes window object.
         * @param {String} block A valid ('eval'able) script source block.
         * @param {Boolean} useDOM  if true, inserts the function
         * into a dynamic script tag, false does a simple eval on the function
         * definition. (useful for debugging) <p> Note: will only work after a
         * successful iframe.(Updater) update or after same-domain document has
         * been hooked, otherwise an exception is raised.
         */

        execScript : function(block, useDOM) {
            try {
                if (this.domWritable()) {
                    if (useDOM) {
                        this.writeScript(block);
                    } else {
                        return this._windowContext.eval(block);
                    }

                } else {
                    throw 'execScript:non-secure context'
                }
            } catch (ex) {
                this.fireEvent('exception', this, ex);
                return false;
            }
            return true;

        },

        /**
         * write a <script> block into the iframe's document
         * @param {String} block A valid (executable) script source block.
         * @param {object} attributes Additional Script tag attributes to apply to the script
         * Element (for other language specs [vbscript, Javascript] etc.) <p>
         * Note: writeScript will only work after a successful iframe.(Updater)
         * update or after same-domain document has been hooked, otherwise an
         * exception is raised.
         */

        writeScript : function(block, attributes) {
            attributes = Ext.apply({}, attributes || {}, {
                        type : "text/javascript",
                        text : block
                    });

            try {
                var head, script, doc = this.getDocument();
                if (doc && typeof doc.getElementsByTagName != 'undefined') {
                    if (!(head = doc.getElementsByTagName("head")[0])) {
                        // some browsers (Webkit, Safari) do not auto-create
                        // head elements during document.write
                        head = doc.createElement("head");
                        doc.getElementsByTagName("html")[0].appendChild(head);
                    }
                    if (head && (script = doc.createElement("script"))) {
                        for (var attrib in attributes) {
                            if (attributes.hasOwnProperty(attrib)
                                    && attrib in script) {
                                script[attrib] = attributes[attrib];
                            }
                        }
                        return !!head.appendChild(script);
                    }
                }
            } catch (ex) {

                this.fireEvent('exception', this, ex);
            }
            return false;
        },

        /**
         * Eval a function definition into the iframe window context.
         * @param {String/Object} fn Name of the function or function map
         * object: {name:'encodeHTML',fn:Ext.util.Format.htmlEncode}
         * @param {Boolean} useDOM  if true, inserts the fn into a dynamic script tag,
         * false does a simple eval on the function definition
         * @param {Boolean} invokeIt if true, the function specified is also executed in the
         * Window context of the frame. Function arguments are not supported.
         * @example <pre><code> var trim = function(s){ return s.replace(
         * /^\s+|\s+$/g,''); }; iframe.loadFunction('trim');
         * iframe.loadFunction({name:'myTrim',fn:String.prototype.trim ||
         * trim});</code></pre>
         */

        loadFunction : function(fn, useDOM, invokeIt) {

            var name = fn.name || fn;
            var fn = fn.fn || window[fn];
            this.execScript(name + '=' + fn, useDOM); // fn.toString coercion
            if (invokeIt) {
                this.execScript(name + '()'); // no args only
            }
        },

        /**
         * Forcefully show the defined loadMask
         * @param {String} msg Mask text to display during the mask operation, defaults to previous defined
         * loadMask config value.
         * @param {String} msgCls The CSS class to apply to the loading message element (defaults to "x-mask-loading")
         * @param {Boolean} forced True to show the mask regardless of document
         * ready/loaded state.
         */

        showMask : function(msg, msgCls, forced) {
            var lmask = this.loadMask;

            if (lmask && !lmask.disabled) {
                lmask.masker
                        || (lmask.masker = Ext.get(lmask.maskEl
                                || this.dom.parentNode || this.wrap({
                                            tag : 'div',
                                            style : {
                                                position : 'static'
                                            }
                                        })));
                (function   () {
                    //this.masker.repaint();
                    this._vis = !!this.masker.mask(msg || this.msg, msgCls
                                    || this.msgCls);
                }).defer(lmask.delay || 10, lmask)

            }
        },
        /**
         * Forcefully hide the defined loadMask @param {Boolean} forced True to
         * hide the mask regardless of document ready/loaded state.
         */

        hideMask : function(forced) {
            var tlm = this.loadMask;

            if (tlm && !tlm.disabled && tlm.masker) {
                if (forced || (tlm.hideOnReady && this._domReady)) {
                    tlm.masker.unmask();
                    tlm._vis = false;

                }
            }
        },

        /**
         * @private
         * Evaluate the Iframes readyState/load event to determine its
         * 'load' state, and raise the 'domready/documentloaded' event when
         * applicable.
         */

        loadHandler : function(e, target) {

            
            target || (target = {});
            var rstatus = (e && typeof e.type !== 'undefined' ? e.type: this.dom.readyState);
            //console.log('hanlder ',rstatus,this.frameInit , this._frameAction , this.eventsFollowFrameLinks);
            if (!this.frameInit || (!this._frameAction && !this.eventsFollowFrameLinks)) {
                return;
            }
            switch (rstatus) {

                case 'domready' : // MIF
                    if (this._domReady) { return; }
                    this._domReady = true;

                    if ((this._frameAction || this.eventsFollowFrameLinks) 
                            && this.getDocumentURI() != 'about:blank'
                            && (this._hooked = this._renderHook())) {
                                // Only raise if sandBox injection succeeded (same origin)
                        this._domFired = true;
                        this.fireEvent("domready", this);
                    }
                case 'domfail' : // MIF
                    this._domReady = true;
                    this.hideMask();

                    break;
                case 'load' : // Gecko, Opera, IE
                case 'complete' :

                    if (!this._domReady) { // one last try for slow DOMS.
                        this.loadHandler({
                                    type : 'domready',
                                    id : this.id
                                }, this.dom);
                    }
                    this.hideMask(true);
                    if (this._frameAction || this.eventsFollowFrameLinks) {
                        // not going to wait for the event chain, as it's not
                        // cancellable anyhow.
                        this.fireEvent.defer(1, this, ["documentloaded", this]);
                        // setSrc and update method (async) callbacks are called
                                            // ASAP.
                        if (this._callBack) {
                            this._callBack.defer(1, null, [this]);
                        }
                    }
                    this._frameAction = this._frameInit = false;

                    if (this.eventsFollowFrameLinks) { // reset for link
                                                        // tracking
                        this._domFired = this._domReady = false;
                    }

                    break;
                default :
            }

            this.frameState = rstatus;

        },
        /**
         * @private
         * Poll the Iframes document structure to determine DOM ready
         * state, and raise the 'domready' event when applicable.
         */

        checkDOM : function(win) {
            if (Ext.isOpera || Ext.isGecko || !this._frameAction) { return; }
            // initialise the counter
            var n = 0, manager = this, domReady = false,
                b, l, d, max = 300, polling = false,
                startLocation = (this.getDocument() || {location : {}}).location.href;

            (function() { // DOM polling for IE and others

                d = manager.getDocument() || {location : {}};

                // wait for location.href transition
                polling = (d.location.href !== startLocation || d.location.href === manager._targetURI);

                if (!manager._frameAction || manager._domReady) {
                    return;
                }

                domReady = polling && ((b = manager.getBody()) && !!(b.innerHTML || '').length) || false;

                // null href is a 'same-origin' document access violation,
                // so we assume the DOM is built when the browser updates it
                if (d.location.href && !domReady && (++n < max)) {
                    setTimeout(arguments.callee, 2); // try again
                    return;
                }

                manager.loadHandler({ type : domReady ? 'domready' : 'domfail'});

            })();
        }
    });

    /** @private
     * Stylesheet Frame interface object
     */
    var styleCamelRe = /(-[a-z])/gi;
    var styleCamelFn = function(m, a) {
        return a.charAt(1).toUpperCase();
    };
    /** @private */
    var CSSInterface = function(hostDocument) {
        var doc;
        if (hostDocument) {

            doc = hostDocument;

            return {
                rules : null,

                destroy  :  function(){  return doc = null; },
                /**
                 * Creates a stylesheet from a text blob of rules. These rules
                 * will be wrapped in a STYLE tag and appended to the HEAD of
                 * the document.
                 *
                 * @param {String}
                 *            cssText The text containing the css rules
                 * @param {String}
                 *            id An id to add to the stylesheet for later
                 *            removal
                 * @return {StyleSheet}
                 */
                createStyleSheet : function(cssText, id) {
                    var ss;

                    if (!doc)
                        return;
                    var head = doc.getElementsByTagName("head")[0];
                    var rules = doc.createElement("style");
                    rules.setAttribute("type", "text/css");
                    if (id) {
                        rules.setAttribute("id", id);
                    }
                    if (Ext.isIE) {
                        head.appendChild(rules);
                        ss = rules.styleSheet;
                        ss.cssText = cssText;
                    } else {
                        try {
                            rules.appendChild(doc.createTextNode(cssText));
                        } catch (e) {
                            rules.cssText = cssText;
                        }
                        head.appendChild(rules);
                        ss = rules.styleSheet
                                ? rules.styleSheet
                                : (rules.sheet || doc.styleSheets[doc.styleSheets.length
                                        - 1]);
                    }
                    this.cacheStyleSheet(ss);
                    return ss;
                },

                /**
                 * Removes a style or link tag by id
                 *
                 * @param {String}
                 *            id The id of the tag
                 */
                removeStyleSheet : function(id) {

                    if (!doc)
                        return;
                    var existing = doc.getElementById(id);
                    if (existing) {
                        existing.parentNode.removeChild(existing);
                    }
                },

                /**
                 * Dynamically swaps an existing stylesheet reference for a new
                 * one
                 *
                 * @param {String}
                 *            id The id of an existing link tag to remove
                 * @param {String}
                 *            url The href of the new stylesheet to include
                 */
                swapStyleSheet : function(id, url) {
                    this.removeStyleSheet(id);

                    if (!doc)
                        return;
                    var ss = doc.createElement("link");
                    ss.setAttribute("rel", "stylesheet");
                    ss.setAttribute("type", "text/css");
                    ss.setAttribute("id", id);
                    ss.setAttribute("href", url);
                    doc.getElementsByTagName("head")[0].appendChild(ss);
                },

                /**
                 * Refresh the rule cache if you have dynamically added
                 * stylesheets
                 *
                 * @return {Object} An object (hash) of rules indexed by
                 *         selector
                 */
                refreshCache : function() {
                    return this.getRules(true);
                },

                // private
                cacheStyleSheet : function(ss) {
                    if (this.rules) {
                        this.rules = {};
                    }
                    try {// try catch for cross domain access issue
                        var ssRules = ss.cssRules || ss.rules;
                        for (var j = ssRules.length - 1; j >= 0; --j) {
                            this.rules[ssRules[j].selectorText] = ssRules[j];
                        }
                    } catch (e) {
                    }
                },

                /**
                 * Gets all css rules for the document
                 *
                 * @param {Boolean}
                 *            refreshCache true to refresh the internal cache
                 * @return {Object} An object (hash) of rules indexed by
                 *         selector
                 */
                getRules : function(refreshCache) {
                    if (this.rules == null || refreshCache) {
                        this.rules = {};

                        if (doc) {
                            var ds = doc.styleSheets;
                            for (var i = 0, len = ds.length; i < len; i++) {
                                try {
                                    this.cacheStyleSheet(ds[i]);
                                } catch (e) {
                                }
                            }
                        }
                    }
                    return this.rules;
                },

                /**
                 * Gets an an individual CSS rule by selector(s)
                 *
                 * @param {String/Array}
                 *            selector The CSS selector or an array of selectors
                 *            to try. The first selector that is found is
                 *            returned.
                 * @param {Boolean}
                 *            refreshCache true to refresh the internal cache if
                 *            you have recently updated any rules or added
                 *            styles dynamically
                 * @return {CSSRule} The CSS rule or null if one is not found
                 */
                getRule : function(selector, refreshCache) {
                    var rs = this.getRules(refreshCache);
                    if (!Ext.isArray(selector)) {
                        return rs[selector];
                    }
                    for (var i = 0; i < selector.length; i++) {
                        if (rs[selector[i]]) {
                            return rs[selector[i]];
                        }
                    }
                    return null;
                },

                /**
                 * Updates a rule property
                 *
                 * @param {String/Array}
                 *            selector If it's an array it tries each selector
                 *            until it finds one. Stops immediately once one is
                 *            found.
                 * @param {String}
                 *            property The css property
                 * @param {String}
                 *            value The new value for the property
                 * @return {Boolean} true If a rule was found and updated
                 */
                updateRule : function(selector, property, value) {
                    if (!Ext.isArray(selector)) {
                        var rule = this.getRule(selector);
                        if (rule) {
                            rule.style[property.replace(styleCamelRe,
                                    styleCamelFn)] = value;
                            return true;
                        }
                    } else {
                        for (var i = 0; i < selector.length; i++) {
                            if (this.updateRule(selector[i], property, value)) {
                                return true;
                            }
                        }
                    }
                    return false;
                }
            };
        }
    };

    /**
     * @class Ext.ux.panel.ManagedIFrame
     * @extends Ext.Panel
     * @version: 1.2.4 (4/29/2009)
     * @license <a href="http://www.gnu.org/licenses/lgpl.html">LGPL 3.0</a>
     * @author: Doug Hendricks. Forum ID: <a
     * href="http://extjs.com/forum/member.php?u=8730">hendricd</a> Copyright
     * 2007-2008, Active Group, Inc. All rights reserved.
     *
     * @constructor Create a new Ext.ux.panel.ManagedIFrame @param {Object}
     * config The config object
     */
    Ext.ux.ManagedIframePanel = Ext.extend(Ext.Panel, {

        /**
         * Fires when the frame gets focus. Note: This event is only available
         * when overwriting the iframe document using the update method and to
         * pages retrieved from a "same domain". Returning false from the
         * eventHandler [MAY] NOT cancel the event, as this event is NOT ALWAYS
         * cancellable in all browsers.
         *
         * @event focus
         * @param {Ext.ux.ManagedIFrame} this.iframe
         * @param {Ext.Event}
         *
         */

        /**
         * Fires when the frame is blurred (loses focus).
         *
         * @event blur
         * @param {Ext.ux.ManagedIFrame}
         *            this.iframe
         * @param {Ext.Event}
         *            Note: This event is only available when overwriting the
         *            iframe document using the update method and to pages
         *            retrieved from a "same domain". Returning false from the
         *            eventHandler [MAY] NOT cancel the event, as this event is
         *            NOT ALWAYS cancellable in all browsers.
         */

        /**
         * Note: This event is only available when overwriting the iframe
         * document using the update method and to pages retrieved from a "same
         * domain". Note: Opera does not raise this event.
         *
         * @event unload * Fires when(if) the frames window object raises the
         *        unload event
         * @param {Ext.ux.ManagedIFrame}
         *            this.iframe
         * @param {Ext.Event}
         */

        /**
         * Note: This event is only available when overwriting the iframe
         * document using the update method and to pages retrieved from a "same
         * domain". Returning false from the eventHandler stops further event
         * (documentloaded) processing.
         *
         * @event domready Fires ONLY when an iFrame's Document(DOM) has reach a
         *        state where the DOM may be manipulated (ie same domain policy)
         * @param {Ext.ux.ManagedIFrame}
         *            this.iframe
         */

        /**
         * Fires when the iFrame has reached a loaded/complete state.
         *
         * @event documentloaded
         * @param {Ext.ux.ManagedIFrame}
         *            this.iframe
         */

        /**
         * Fires when the frame actions raise an error
         *
         * @event exception
         * @param {Ext.ux.ManagedIFrame}
         *            this.iframe
         * @param {Error/string}
         *            exception
         */

        /**
         * Fires upon receipt of a message generated by window.sendMessage
         * method of the embedded Iframe.window object
         *
         * @event message
         *
         * @param {Ext.ux.ManagedIFrame}
         *            this.iframe
         * @param {object}
         *            message (members: type: {string} literal "message", data
         *            {Mixed} [the message payload], domain [the document domain
         *            from which the message originated ], uri {string} the
         *            document URI of the message sender source (Object) the
         *            window context of the message sender tag {string} optional
         *            reference tag sent by the message sender
         */

        /**
         * Alternate event handler syntax for message:tag filtering Fires upon
         * receipt of a message generated by window.sendMessage method which
         * includes a specific tag value of the embedded Iframe.window object
         *
         * @event message:tag
         * @param {Ext.ux.ManagedIFrame}
         *            this.iframe
         * @param {object}
         *            message (members: type: {string} literal "message", data
         *            {Mixed} [the message payload], domain [the document domain
         *            from which the message originated ], uri {string} the
         *            document URI of the message sender source (Object) the
         *            window context of the message sender tag {string} optional
         *            reference tag sent by the message sender
         */
        // "message:tagName" is supported for X-frame messaging

        /**
         * @cfg {String/Function} defaultSrc Cached Iframe.src url (or Function
         *      that returns it) to use for initial rendering and refreshes.
         *      Overwritten every time {@link Ext.ux.panel.ManagedIframe#setSrc}
         *      is called unless "discardUrl" param is set to true.
         */
        defaultSrc : null,

        /**
         * @cfg {Object/String} bodyStyle Inline style rules applied to the
         *      Panel body prior to render.
         */
        bodyStyle : { position : 'relative' },


        /**
         * @cfg {Object} frameStyle Custom CSS styles to be applied to the
         *      Ext.ux.ManagedIframe frame element in the format expected by
         *      {@link Ext.Element#applyStyles} (defaults to CSS Rule
         *      {overflow:'auto'}).
         */
        frameStyle : { overflow : 'auto' },

        /**
         * @cfg {Object} frameConfig Custom DOMHelper config for iframe node
         *      specifications (eg. name, id, frameBorder, etc) Note: To
         *      specify/override with a unique Element id or name for the
         *      underlying iframe, use the autoCreate config option with it:
         *
         * @example
         * var MIF = new Ext.ux.ManagedIframePanel({
         *          frameConfig : {
         *              autoCreate : {
         *                  id : 'frameA',
         *                  name : 'frameA'
         *              },
         *              disableMessaging : false
         *          },
         *          defaultSrc : 'sites/customerList.html'
         *      });
         *
         */
        frameConfig : null,

        /**
         * @cfg {String} hideMode How this component should hidden. Supported
         *      values are "visibility" (css visibility), "offsets" (negative
         *      offset position), "display" (css display), and "nosize"
         *      (height/width set to zero (0px) - defaults to "display" for
         *      Internet Explorer and "nosize" for all other browsers (to
         *      prevent frame re-initialization after reflow of frame
         *      parentNodes).
         */
        hideMode : !Ext.isIE ? 'nosize' : 'display',

        shimCls : 'x-frame-shim',

        /**
         * @cfg {String} shimUrl The url of a transparent graphic image used to
         *      shim the frame (during drag or other) shimming operation.
         *      Defaults to Ext.BLANK_IMG_URL.
         */
        shimUrl : null,
        /**
         * @cfg {Object} loadMask An {@link Ext.LoadMask} config or true to mask
         *      the frame while loading (defaults to false). Additional loadMask
         *      configuration options: hideOnReady : {Boolean} False to hide the
         *      loadMask when the frame document is fully loaded rather than on
         *      domready.
         */
        loadMask : false,
        stateful : false,
        animCollapse : Ext.isIE && Ext.enableFx,
        /** @private class override */
        autoScroll : false,
        /**
         * @cfg {Boolean} closable Set True by default in the event a site
         * times-out while loadMasked
         */
        closable : true,
        /** @private */
        ctype : "Ext.ux.ManagedIframePanel",
        /** @private class override */
        showLoadIndicator : false,

        /**
         * @cfg {String/Object} unsupportedText Text (or Ext.DOMHelper config)
         *      to display within the rendered iframe tag to indicate the frame
         *      is not supported/enabled in the browser.
         */
        unsupportedText : 'Inline frames are NOT enabled\/supported by your browser.',

        /** @private */

        initComponent : function() {

            var f = this.frameConfig ? this.frameConfig.autoCreate || this.frameConfig : {};

            var frCfg = Ext.apply(f, { id : f.id || Ext.id()});
            frCfg.name = f.name || frCfg.id;

            if(Ext.isIE && Ext.isSecure){
                 frCfg.src = Ext.SSL_SECURE_URL;
            }

            var frameTag = Ext.apply({
                        tag : 'iframe',
                        frameborder : 0,
                        cls : 'x-managed-iframe',
                        style : this.frameStyle || f.style || {}
                    }, frCfg );

            var unsup = this.unsupportedText? {tag:'noframes',html:this.unsupportedText } : [];

            this.bodyCfg || (this.bodyCfg = {
                // shared masking DIV for hosting loadMask/dragMask
                cls : this.baseCls +'-body',
                children : this.contentEl? [] : [frameTag].concat(unsup)
            });

            this.autoScroll = false; // Force off as the Iframe manages this
            this.items = null;

            // setup stateful events if not defined
            if (this.stateful !== false) {
                this.stateEvents || (this.stateEvents = ['documentloaded']);
            }

            Ext.ux.ManagedIframePanel.superclass.initComponent.call(this);

            this.monitorResize || (this.monitorResize = !!this.fitToParent);

            this.addEvents({
                        documentloaded : true,
                        domready : true,
                        message : true,
                        exception : true,
                        blur : true,
                        focus : true
                    });

            // apply the addListener patch for 'message:tagging'
            this.addListener = this.on;

        },
        /** @private */
        doLayout : function() {
            // only resize (to Parent) if the panel is NOT in a layout.
            // parentNode should have {style:overflow:hidden;} applied.
            if (this.fitToParent && !this.ownerCt) {
                var pos = this.getPosition(), size = (Ext.get(this.fitToParent)
                        || this.getEl().parent()).getViewSize();
                this.setSize(size.width - pos[0], size.height - pos[1]);
            }
            Ext.ux.ManagedIframePanel.superclass.doLayout.apply(this, arguments);

        },

        /** @private */
        beforeDestroy : function() {

            if (this.rendered) {

                if (this.tools) {
                    for (var k in this.tools) {
                        Ext.destroy(this.tools[k]);
                    }
                }

                if (this.header && this.headerAsText) {
                    var s;
                    if (s = this.header.child('span'))s.remove(true,true);
                    this.header.update('');
                }

                Ext.each(['iframe', 'shim', 'header', 'topToolbar',
                                'bottomToolbar', 'footer', 'loadMask', 'body',
                                'bwrap'],
                       function(elName) {
                            if (this[elName]) {
                                if (typeof this[elName].destroy == 'function') {
                                    this[elName].destroy();
                                } else {
                                    Ext.destroy(this[elName]);
                                }

                                this[elName] = null;
                                delete this[elName];
                            }
                        }, this);
            }

            Ext.ux.ManagedIframePanel.superclass.beforeDestroy.call(this);
        },
        /** @private */
        onDestroy : function() {
            // Yes, Panel.super (Component), since we're doing Panel cleanup
            // beforeDestroy instead.
            Ext.Panel.superclass.onDestroy.call(this);
        },

        /** @private */
        afterRender : function(container) {

            var html = this.html; //preserve for frame-writing
            delete this.html;

            Ext.ux.ManagedIframePanel.superclass.afterRender.apply(this,arguments);

            if (this.iframe = this.body.child('iframe')) {

                this.iframe.ownerCt = this;

                if (this.loadMask) {
                    //resolve possible maskEl by Element name eg. 'body', 'bwrap', 'actionEl'
                    var mEl;
                    if(mEl = this.loadMask.maskEl){
                        this.loadMask.maskEl = this[mEl] || mEl || this.body;
                        this.loadMask.maskEl.addClass('x-managed-iframe-mask');
                    }

                    this.loadMask = Ext.apply({
                                disabled : false,
                                hideOnReady : false
                            }, this.loadMask);
                }

                this.getUpdater().showLoadIndicator = this.showLoadIndicator || false;

                // Enable auto-dragMask if the panel participates in (nested?)
                // border layout.
                // Setup event handlers on the SplitBars to enable the frame
                // dragMask when needed
                var ownerCt = this.ownerCt;
                while (ownerCt) {
                    ownerCt.on('afterlayout', function(container, layout) {
                                var MIM = Ext.ux.ManagedIFrame.Manager, st = false;
                                Ext.each(['north', 'south', 'east', 'west'],
                                        function(region) {
                                            var reg;
                                            if ((reg = layout[region])
                                                    && reg.splitEl) {
                                                st = true;
                                                if (!reg.split._splitTrapped) {
                                                    reg.split.on(
                                                            'beforeresize',
                                                            MIM.showShims, MIM);
                                                    reg.split._splitTrapped = true;
                                                }
                                            }
                                        }, this);
                                if (st && !this._splitTrapped) {
                                    this.on('resize', MIM.hideShims, MIM);
                                    this._splitTrapped = true;
                                }

                            }, this, { single : true}); // and discard

                    ownerCt = ownerCt.ownerCt; // nested layouts?
                }

                // create the shimming agent if not specified in markup
                this.shim = Ext.get(this.body.child('.' + this.shimCls))
                               || Ext.DomHelper.append(this.body,{
                                                tag : 'img',
                                                src : this.shimUrl || Ext.BLANK_IMAGE_URL,
                                                cls : this.shimCls,
                                                galleryimg : "no"
                                    }, true);
                // Set the Visibility Mode for el, bwrap for
                // collapse/expands/hide/show
                var El = Ext.Element;
                var mode = El[this.hideMode.toUpperCase()] || 'x-hide-nosize';
                Ext.each([this[this.collapseEl], this.floating ? null : this.getActionEl(),this.iframe],
                     function(el) {
                            if (el)
                                el.setVisibilityMode(mode);
                     }, this);

                if (this.iframe = new Ext.ux.ManagedIFrame(this.iframe, {
                            loadMask : this.loadMask,
                            showLoadIndicator: this.showLoadIndicator,
                            disableMessaging : this.disableMessaging,
                            style            : this.frameStyle,
                            src              : this.defaultSrc,
                            html             : html
                        }))
                   {
                    this.loadMask = this.iframe.loadMask;
                    this.iframe.ownerCt = this;
                    this.relayEvents(this.iframe, ["blur", "focus", "unload",
                                    "documentloaded", "domready", "exception",
                                    "message"].concat(this._msgTagHandlers || []));
                    delete this._msgTagHandlers;
                }

            }
        },

        /**
         * dispatch a message to the embedded frame-window context
         * @name sendMessage
         * @methodOf Ext.ux.panel.ManagedIframe
         * @param {Mixed} message The message payload
         * @param {String} tag Optional reference tag
         * @param {String} origin Optional domain designation of the sender
         * (defaults to document.domain).
         */

        sendMessage : function() {
            if (this.iframe) {
                this.iframe.sendMessage.apply(this.iframe, arguments);
            }
        },
        /**
        * @private 
        */
        filterOptRe: /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/,

        /** @private
         *  relay all defined 'message:tag' event handlers
         */
        on : function(name) {
            var tagRE = /^message\:/i, n = null;
            if (typeof name == 'object') {
                for (var na in name) {
                    if (!this.filterOptRe.test(na) && tagRE.test(na)) {
                        n || (n = []);
                        n.push(na.toLowerCase());
                    }
                }
            } else if (tagRE.test(name)) {
                n = [name.toLowerCase()];
            }

            if (this.getFrame() && n) {
                this.relayEvents(this.iframe, n);
            } else {
                this._msgTagHandlers || (this._msgTagHandlers = []);
                if (n)
                    this._msgTagHandlers = this._msgTagHandlers.concat(n);
                    // queued for onRender when iframe is available
            }
            Ext.ux.ManagedIframePanel.superclass.on.apply(this, arguments);
        },

        /**
         * Sets the embedded Iframe src property. Note: invoke the function with
         * no arguments to refresh the iframe based on the current src value.
         *
         * @param {String/Function} url (Optional) A string or reference to a Function that
         *            returns a URI string when called
         * @param {Boolean} discardUrl (Optional) If not passed as <tt>false</tt>
         *            the URL of this action becomes the default SRC attribute
         *            for this iframe, and will be subsequently used in future
         *            setSrc calls (emulates autoRefresh by calling setSrc
         *            without params).
         * @param {Function} callback (Optional) A callback function invoked when the
         *            frame document has been fully loaded.
         * @param {Object} scope (Optional) scope by which the callback function is
         *            invoked.
         */
        setSrc : function(url, discardUrl, callback, scope) {
            url = url || this.defaultSrc || false;

            if (url && this.rendered && this.iframe) {
                this.iframe.setSrc.call(this.iframe, url, discardUrl, callback, scope);
            }

            return this;
        },

        /**
         * Sets the embedded Iframe location using its replace method. Note: invoke the function with
         * no arguments to refresh the iframe based on the current src value.
         *
         * @param {String/Function} url (Optional) A string or reference to a Function that
         *            returns a URI string when called
         * @param {Boolean} discardUrl (Optional) If not passed as <tt>false</tt>
         *            the URL of this action becomes the default SRC attribute
         *            for this iframe, and will be subsequently used in future
         *            setSrc calls (emulates autoRefresh by calling setSrc
         *            without params).
         * @param {Function} callback (Optional) A callback function invoked when the
         *            frame document has been fully loaded.
         * @param {Object} scope (Optional) scope by which the callback function is
         *            invoked.
         */
        setLocation : function(url, discardUrl, callback, scope) {
           url = url || this.defaultSrc || false;

           if (url && this.rendered && this.iframe) {
               this.iframe.setLocation.call(this.iframe, url, discardUrl, callback, scope);
           }


            return this;
        },

        /**
         * @private //Make it state-aware
         */
        getState : function() {

            var URI = this.iframe ? this.iframe.getDocumentURI() || null : null;
            return Ext.apply(Ext.ux.ManagedIframePanel.superclass.getState.call(this)
                            || {}, URI ? {
                        defaultSrc : typeof URI == 'function' ? URI() : URI
                    } : null);

        },

        /**
         * Get the {@link Ext.Updater} for this panel's iframe/or body. Enables
         * Ajax-based document replacement of this panel's iframe document.
         *
         * @return {Ext.Updater} The Updater
         */
        getUpdater : function() {
            return this.rendered
                    ? (this.iframe || this.body).getUpdater()
                    : null;
        },
        /**
         * Get the embedded iframe Ext.Element for this panel
         *
         * @return {Ext.Element} The Panels Ext.ux.ManagedIFrame instance.
         */
        getFrame : function() {
            return this.rendered ? this.iframe : null
        },

        /**
         * Returns the frame's current window object.
         *
         * @return {Window} The frame Window object.
         */
        getFrameWindow : function() {
            return this.rendered && this.iframe
                    ? this.iframe.getWindow()
                    : null;
        },

        /**
         * If sufficient privilege exists, returns the frame's current document
         * as an HTMLElement.
         *
         * @return {HTMLElement} The frame document or false if access to
         *         document object was denied.
         */
        getFrameDocument : function() {
            return this.rendered && this.iframe
                    ? this.iframe.getDocument()
                    : null;
        },

        /**
         * Get the embedded iframe's document as an Ext.Element.
         *
         * @return {Ext.Element object} or null if unavailable
         */
        getFrameDoc : function() {
            return this.rendered && this.iframe ? this.iframe.getDoc() : null;
        },

        /**
         * If sufficient privilege exists, returns the frame's current document
         * body as an HTMLElement.
         *
         * @return {HTMLElement} The frame document body or Null if access to
         *         document object was denied.
         */
        getFrameBody : function() {
            return this.rendered && this.iframe ? this.iframe.getBody() : null;
        },

        /**
         * Loads this panel's iframe immediately with content returned from an
         * XHR call.
         *
         * @param {Object/String/Function}
         *            config A config object containing any of the following
         *            options:
         *
         * <pre><code>
         *      panel.load({
         *         url: &quot;your-url.php&quot;,
         *         params: {param1: &quot;foo&quot;, param2: &quot;bar&quot;}, // or a URL encoded string
         *         callback: yourFunction,
         *         scope: yourObject, // optional scope for the callback
         *         discardUrl: false,
         *         nocache: false,
         *         text: &quot;Loading...&quot;,
         *         timeout: 30,
         *         scripts: false,
         *         renderer:{render:function(el, response, updater, callback){....}}  //optional custom renderer
         *      });
         *
         * </code></pre>
         *
         * The only required property is url. The optional properties
         *            nocache, text and scripts are shorthand for
         *            disableCaching, indicatorText and loadScripts and are used
         *            to set their associated property on this panel Updater
         *            instance.
         * @return {Ext.Panel} this
         */
        load : function(loadCfg) {
            var um;
            if (um = this.getUpdater()) {
                if (loadCfg && loadCfg.renderer) {
                    um.setRenderer(loadCfg.renderer);
                    delete loadCfg.renderer;
                }
                um.update.apply(um, arguments);
            }
            return this;
        },

        /** @private */
       doAutoLoad : function() {
            this.load(typeof this.autoLoad == 'object' ? this.autoLoad : {
                        url : this.autoLoad
                    });
        }

    });

    Ext.ux.ManagedIFrame.Manager = MIM = function() {
        var frames = {};

        // private DOMFrameContentLoaded handler for browsers (Gecko, Webkit) that support it.


        var implementation = {
            readyHandler : function(e) {

                try {

                    var $frame = e.target.ownerEl;
                    if ($frame && $frame._frameAction){

                        $frame.loadHandler.call($frame,{type : 'domready'});

                    }

                } catch (rhEx) {return} //nested iframes will throw when accessing target.id

            },
            /**
             * @cfg {String} shimCls
             * @default "x-frame-shim"
             * The default CSS rule applied to ManagedIFrame image shims to toggle their visibility.
             */
            shimCls : 'x-frame-shim',

            /** @private */
            register : function(frame) {
                frame.manager = this;
                frames[frame.id] = frames[frame.dom.name] = {
                    ref : frame,
                    elCache : {}
                };

                // Hook the Iframes loaded state handler
                frame.dom[Ext.isIE?'onreadystatechange':'onload'] = frame.loadHandler.createDelegate(frame);
                return frame;
            },
            /** @private */
            deRegister : function(frame) {
                frame._unHook();
                frame.dom.onload = frame.dom.onreadystatechange = null;
                delete frames[frame.id];
                delete frames[frame.dom.name];

            },
            /**
             * Toggles the built-in MIF shim off on all visible ManagedIFrames
             * @methodOf Ext.ux.ManagedIFrame.Manager
             * @param none
             */
            hideShims : function() {

                if (!this.shimApplied)
                    return;
                Ext.select('.' + this.shimCls, true).removeClass(this.shimCls
                        + '-on');
                this.shimApplied = false;
            },

            /**
             * Mask ALL ManagedIframes (eg. when a region-layout.splitter is on the move.)
             * @methodOf Ext.ux.ManagedIFrame.Manager
             * @param none
             */
            showShims : function() {
                if (!this.shimApplied) {
                    this.shimApplied = true;
                    // Activate the shimCls globally
                    Ext.select('.' + this.shimCls, true).addClass(this.shimCls
                            + '-on');
                }

            },

            /**
             * Retrieve a ManagedIframe instance by its DOM ID
             * @methodOf Ext.ux.ManagedIFrame.Manager
             * @param {Ext.ux.ManagedIFrame/string} id
             */
            getFrameById : function(id) {
                return typeof id == 'string' ? (frames[id] ? frames[id].ref
                        || null : null) : null;
            },

            /**
             * Retrieve a ManagedIframe instance by its DOM name
             * @methodOf Ext.ux.ManagedIFrame.Manager
             * @param {Ext.ux.ManagedIFrame/string} name
             */
            getFrameByName : function(name) {
                return this.getFrameById(name);
            },
            /** @private */
            // retrieve the internal frameCache object
            getFrameHash : function(frame) {
                return frame.id ? frames[frame.id] : null;

            },

            /** @private */
            // to be called under the scope of the managing MIF
            eventProxy : function(e) {

                if (!e)
                    return;
                e = Ext.EventObject.setEvent(e);
                var be = e.browserEvent || e;

                // same-domain unloads should clear ElCache for use with the
                // next document rendering
                if (e.type == 'unload') {
                    this._unHook();
                }
                
                if (!be['eventPhase']
                        || (be['eventPhase'] == (be['AT_TARGET'] || 2))) {
                    return this.fireEvent(e.type, e);
                }
            },
            /** @private */
            _flyweights : {},

            /** @private */
            destroy : function() {

                if (document.addEventListener) {
                      window.removeEventListener("DOMFrameContentLoaded", this.readyHandler, true);
                }

            },

            // safe removal of embedded frame elements
            removeNode : Ext.isIE ? function(frame, n) {
                frame = MIM.getFrameHash(frame);
                if (frame && n && n.tagName != 'BODY') {
                    d = frame.scratchDiv
                            || (frame.scratchDiv = frame.getDocument().createElement('div'));
                    d.appendChild(n);
                    d.innerHTML = '';
                }
            } : function(frame, n) {
                if (n && n.parentNode && n.tagName != 'BODY') {
                    n.parentNode.removeChild(n);
                }
            }

        };
        if (document.addEventListener) { // for Gecko and Opera and any who
                                            // might support it later
                                            //Ext.EventManager.on

            window.addEventListener("DOMFrameContentLoaded", implementation.readyHandler, true);

        }

        Ext.EventManager.on(window, 'beforeunload', implementation.destroy,implementation);
        return implementation;

    }();

    MIM.showDragMask = MIM.showShims;
    MIM.hideDragMask = MIM.hideShims;

    // Provide an Ext.Element interface to frame document elements
    /** @private */
    MIM.El = function(frame, el, forceNew) {

        var frameObj;
        frame = (frameObj = MIM.getFrameHash(frame)) ? frameObj.ref : null;

        if (!frame) {
            return null;
        }
        var elCache = frameObj.elCache || (frameObj.elCache = {});

        var dom = frame.getDom(el);

        if (!dom) { // invalid id/element
            return null;
        }
        var id = dom.id;
        if (forceNew !== true && id && elCache[id]) { // element object
                                                        // already exists
            return elCache[id];
        }

        /**
         * The DOM element
         *
         * @type HTMLElement
         */
        this.dom = dom;

        /**
         * The DOM element ID
         *
         * @type String
         */
        this.id = id || Ext.id(dom);
    };
    /** @private */
    MIM.El.get = function(frame, el) {
        var ex, elm, id, doc;
        if (!frame || !el) {
            return null;
        }

        var frameObj;
        frame = (frameObj = MIM.getFrameHash(frame)) ? frameObj.ref : null;

        if (!frame) {
            return null;
        }

        var elCache = frameObj.elCache || (frameObj.elCache = {});

        if (!(doc = frame.getDocument())) {
            return null;
        }
        if (typeof el == "string") { // element id
            if (!(elm = frame.getDom(el))) {
                return null;
            }
            if (ex = elCache[el]) {
                ex.dom = elm;
            } else {
                ex = elCache[el] = new MIM.El(frame, elm);
            }
            return ex;
        } else if (el.tagName) { // dom element
            if (!(id = el.id)) {
                id = Ext.id(el);
            }
            if (ex = elCache[id]) {
                ex.dom = el;
            } else {
                ex = elCache[id] = new MIM.El(frame, el);
            }
            return ex;
        } else if (el instanceof MIM.El) {
            if (el != frameObj.docEl) {
                el.dom = frame.getDom(el.id) || el.dom; // refresh dom element
                                                        // in case no longer
                                                        // valid,
                // catch case where it hasn't been appended
                elCache[el.id] = el; // in case it was created directly with
                                        // Element(), let's cache it
            }
            return el;
        } else if (el.isComposite) {
            return el;
        } else if (Ext.isArray(el)) {
            return frame.select(el);
        } else if (el == doc) {
            // create a bogus element object representing the document object
            if (!frameObj.docEl) {
                var f = function() {
                };
                f.prototype = MIM.El.prototype;
                frameObj.docEl = new f();
                frameObj.docEl.dom = doc;
            }
            return frameObj.docEl;
        }
        return null;

    };

    Ext.apply(MIM.El.prototype, Ext.Element.prototype);

    Ext.ns('Ext.ux.panel', 'Ext.ux.portlet');
    Ext.reg('iframepanel', Ext.ux.panel.ManagedIframe = Ext.ux.ManagedIframePanel);

    /**
     * @class Ext.ux.portlet.ManagedIFrame
     * @extends Ext.ux.panel.ManagedIframe
     * @version: 1.2.4 (4/29/2009) 
     * @license <a
     * href="http://www.gnu.org/licenses/lgpl.html">LGPL 3.0</a> @author: Doug
     * Hendricks. Forum ID: <a
     * href="http://extjs.com/forum/member.php?u=8730">hendricd</a> Copyright
     * 2007-2008, Active Group, Inc. All rights reserved.
     *
     * @constructor Create a new Ext.ux.portlet.ManagedIFrame @param {Object}
     * config The config object
     */

    Ext.ux.ManagedIframePortlet = Ext.extend(Ext.ux.ManagedIframePanel, {
                anchor : '100%',
                frame : true,
                collapseEl : 'bwrap',
                collapsible : true,
                draggable : true,
                cls : 'x-portlet'
            });

    Ext.reg('iframeportlet',Ext.ux.portlet.ManagedIframe = Ext.ux.ManagedIframePortlet);

    /** @private
     * override adds a third visibility feature to Ext.Element: Now an elements'
     * visibility may be handled by application of a custom (hiding) CSS
     * className. The class is removed to make the Element visible again
     */

    Ext.apply(Ext.Element.prototype, {
        setVisible : function(visible, animate) {
            if (!animate || !Ext.lib.Anim) {
                if (this.visibilityMode == Ext.Element.DISPLAY) {
                    this.setDisplayed(visible);
                } else if (this.visibilityMode == Ext.Element.VISIBILITY) {
                    this.fixDisplay();
                    this.dom.style.visibility = visible ? "visible" : "hidden";
                } else {
                    this[visible ? 'removeClass' : 'addClass'](String(this.visibilityMode));
                }

            } else {
                // closure for composites
                var dom = this.dom;
                var visMode = this.visibilityMode;

                if (visible) {
                    this.setOpacity(.01);
                    this.setVisible(true);
                }
                this.anim({
                            opacity : {
                                to : (visible ? 1 : 0)
                            }
                        }, this.preanim(arguments, 1), null, .35, 'easeIn',
                        function() {

                            if (!visible) {
                                if (visMode == Ext.Element.DISPLAY) {
                                    dom.style.display = "none";
                                } else if (visMode == Ext.Element.VISIBILITY) {
                                    dom.style.visibility = "hidden";
                                } else {
                                    Ext.get(dom).addClass(String(visMode));
                                }
                                Ext.get(dom).setOpacity(1);
                            }
                        });
            }
            return this;
        },
        /** @private
         * Checks whether the element is currently visible using both visibility
         * and display properties.
         *
         * @param {Boolean}
         *            deep (optional) True to walk the dom and see if parent
         *            elements are hidden (defaults to false)
         * @return {Boolean} True if the element is currently visible, else
         *         false
         */
        isVisible : function(deep) {
            var vis = !(this.hasClass(this.visibilityMode) || this.getStyle("visibility") == "hidden"
                    || this.getStyle("display") == "none" );
            if (deep !== true || !vis) {
                return vis;
            }
            var p = this.dom.parentNode;
            while (p && p.tagName.toLowerCase() != "body") {
                if (!Ext.fly(p, '_isVisible').isVisible()) {
                    return false;
                }
                p = p.parentNode;
            }
            return true;
        }
    });
    /** @private */
    Ext.onReady(function() {
        // Generate CSS Rules but allow for overrides.
        var CSS = Ext.util.CSS, rules = [];

        CSS.getRule('.x-managed-iframe')|| (rules.push('.x-managed-iframe {height:100%;width:100%;overflow:auto;position:relative;}'));
        CSS.getRule('.x-managed-iframe-mask')|| (rules.push('.x-managed-iframe-mask{position:relative;zoom:1;}'));
        if (!CSS.getRule('.x-frame-shim')) {
            rules.push('.x-frame-shim {z-index:8500;position:absolute;top:0px;left:0px;background:transparent!important;overflow:hidden;display:none;}');
            rules.push('.x-frame-shim-on{width:100%;height:100%;display:block;zoom:1;}');
            rules.push('.ext-ie6 .x-frame-shim{margin-left:5px;margin-top:3px;}');
        }
        CSS.getRule('.x-hide-nosize')|| (rules.push('.x-hide-nosize,.x-hide-nosize *{height:0px!important;width:0px!important;border:none;}'));

        if (!!rules.length) {
            CSS.createStyleSheet(rules.join(' '));
        }
    });
})();
/** @sourceURL=<miframe.js> */
if (Ext.provide) {
    Ext.provide('miframe');
}