    /*

    Siesta 5.3.0
    Copyright(c) 2009-2019 Bryntum AB
    https://bryntum.com/contact
    https://bryntum.com/products/siesta/license

    */
    Class('Scope.Provider.Window', {

        isa     : Scope.Provider,

        does    : Scope.Provider.Role.WithDOM,

        has     : {
            popupWindow     : null
        },

        methods : {

            setViewportSize : function (width, height) {
                var popupWindow     = this.popupWindow

                if (!popupWindow) return

                // is not guaranteed to work
                popupWindow.resizeTo(width, height)
            },

            create : function (onLoadCallback) {
                var minViewportSize     = this.minViewportSize

                var width       = minViewportSize && minViewportSize.width || 1024
                var height      = minViewportSize && minViewportSize.height || 768

                var popup       = this.scope = this.popupWindow = this.parentWindow.open(
                    // left/top is set to > 0 value with intent to keep the mouse cursor outside of the popup
                    // its always recommened to set the mousecursor position to 0, 0 in the automation script
                    this.sourceURL || 'about:blank',
                    '_blank',
                    "left=10,top=10,width=" + width + ",height=" + height
                )

                if (!popup) {
                    alert('Please enable popups for the host with this test suite running: ' + this.parentWindow.location.host)
                    throw 'Please enable popups for the host with this test suite running: ' + this.parentWindow.location.host
                }

                var isIE = 'v' == '\v' || Boolean(this.parentWindow.msWriteProfilerMark)

                // dances with tambourine around the IE
                if (isIE && !this.sourceURL) {
                    var doc = this.getDocument()

                    doc.open()
                    doc.write('')
                    doc.close()
                }

                // trying to add the "early" onerror handler - will probably only work in FF
                if (this.cachedOnError) this.installOnErrorHandler(this.cachedOnError)

                /*!
                 * contentloaded.js
                 *
                 * Author: Diego Perini (diego.perini at gmail.com)
                 * Summary: cross-browser wrapper for DOMContentLoaded
                 * Updated: 20101020
                 * License: MIT
                 * Version: 1.2
                 *
                 * URL:
                 * http://javascript.nwbox.com/ContentLoaded/
                 * http://javascript.nwbox.com/ContentLoaded/MIT-LICENSE
                 *
                 */

                var me              = this

                // @win window reference
                // @fn function reference
                var contentLoaded = function (win, fn) {

                    var done = false, top = true,

                    doc = win.document, root = doc.documentElement,

                    add = doc.addEventListener ? 'addEventListener' : 'attachEvent',
                    rem = doc.addEventListener ? 'removeEventListener' : 'detachEvent',
                    pre = doc.addEventListener ? '' : 'on',

                    init = function(e) {
                        if (e.type == 'readystatechange' && doc.readyState != 'complete') return;

                        (e.type == 'load' ? win : doc)[ rem ](pre + e.type, init, false);

                        if (!done && (done = true)) fn.call(win, me);
                    },

                    poll = function () {
                        try { root.doScroll('left'); } catch(e) { setTimeout(poll, 50); return; }

                        init('poll');
                    };

                    if (doc.readyState == 'complete')
                        fn.call(win, me);
                    else {
                        if (doc.createEventObject && root.doScroll) {
                            try { top = !win.frameElement; } catch(e) { }
                            if (top) poll();
                        }
                        doc[add](pre + 'DOMContentLoaded', init, false);
                        doc[add](pre + 'readystatechange', init, false);
                        win[add](pre + 'load', init, false);
                    }
                }

                if (this.sourceURL)
                    // seems the "doc.readyState" is set before the DOM is created on the page
                    // if one will start interact with page immediately he can overwrite the page content
                    setTimeout(function () {
                        contentLoaded(popup, onLoadCallback || function () {})
                    }, 10)
                else
                    contentLoaded(popup, onLoadCallback || function () {})
            },

            getDocument : function () {
                return this.popupWindow.document
            },

            cleanup : function () {
                if (this.beforeCleanupCallback) this.beforeCleanupCallback()
                this.beforeCleanupCallback      = null

                this.popupWindow.close()

                this.popupWindow = null

                this.cleanupHandlers()
                if (this.cleanupCallback) this.cleanupCallback()
                this.cleanupCallback            = null
            }
        }
    })

    /**

    Name
    ====

    Scope.Provider.Window - scope provider, which uses the popup browser window.

    SYNOPSIS
    ========

            var provider = new Scope.Provider.Window()

            provider.setup(function () {

                if (provider.scope.SOME_GLOBAL == 'some_value') {
                    ...
                }

                provider.runCode(text, callback)

                ...

                provider.runScript(url, callback)

                ...

                provider.cleanup()
            })

    DESCRIPTION
    ===========

    `Scope.Provider.Window` is an implementation of the scope provider, which uses the popup browser window,
    to create a new scope.

    ISA
    ===

    [Scope.Provider](../Provider.html)

    DOES
    ====

    [Scope.Provider.Role.WithDOM](Role/WithDOM.html)

    GETTING HELP
    ============

    This extension is supported via github issues tracker: <http://github.com/SamuraiJack/Scope-Provider/issues>

    You can also ask questions at IRC channel : [#joose](http://webchat.freenode.net/?randomnick=1&channels=joose&prompt=1)

    Or the mailing list: <http://groups.google.com/group/joose-js>

    SEE ALSO
    ========

    Web page of this module: <http://github.com/SamuraiJack/Scope-Provider/>

    General documentation for Joose: <http://joose.github.com/Joose>

    BUGS
    ====

    All complex software has bugs lurking in it, and this module is no exception.

    Please report any bugs through the web interface at <http://github.com/SamuraiJack/Scope-Provider/issues>

    AUTHORS
    =======

    Nickolay Platonov <nplatonov@cpan.org>

    COPYRIGHT AND LICENSE
    =====================

    This software is Copyright (c) 2010 by Nickolay Platonov <nplatonov@cpan.org>.

    This is free software, licensed under:

      The GNU Lesser General Public License, Version 3, June 2007

    */