<commit_before>/*
This file is part of the GhostDriver project from Neustar inc.

Copyright (c) 2012, Ivan De Marino <ivan.de.marino@gmail.com> - Neustar inc.
Copyright (c) 2012, Alex Anderson <@alxndrsn>
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright notice,
      this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

var ghostdriver = ghostdriver || {};

ghostdriver.WebElementReqHand = function(idOrElement, session) {
    // private:
    var
    _id = ((typeof(idOrElement) === "object") ? idOrElement["ELEMENT"] : idOrElement),
    _session = session,
    _locator = new ghostdriver.WebElementLocator(_session),
    _protoParent = ghostdriver.WebElementReqHand.prototype,
    _const = {
        ELEMENT             : "element",
        ELEMENTS            : "elements",
        VALUE               : "value",
        SUBMIT              : "submit",
        DISPLAYED           : "displayed",
        ENABLED             : "enabled",
        ATTRIBUTE           : "attribute",
        NAME                : "name",
        CLICK               : "click",
        SELECTED            : "selected",
        CLEAR               : "clear",
        CSS                 : "css",
        TEXT                : "text",
        EQUALS_DIR          : "equals",
        LOCATION            : "location",
        LOCATION_IN_VIEW    : "location_in_view",
        SIZE                : "size"
    },
    _errors = require("./errors.js"),

    _handle = function(req, res) {
        _protoParent.handle.call(this, req, res);

        // console.log("Request => " + JSON.stringify(req, null, '  '));

        // TODO lots to do...

        if (req.urlParsed.file === _const.ELEMENT && req.method === "POST") {
            _findElementCommand(req, res, _locator.locateElement);
            return;
        } else if (req.urlParsed.file === _const.ELEMENTS && req.method === "POST") {
            _findElementCommand(req, res, _locator.locateElements);
            return;
        } else if (req.urlParsed.file === _const.VALUE && req.method === "POST") {
            _valueCommand(req, res);
            return;
        } else if (req.urlParsed.file === _const.SUBMIT && req.method === "POST") {
            _submitCommand(req, res);
            return;
        } else if (req.urlParsed.file === _const.DISPLAYED && req.method === "GET") {
            _getDisplayedCommand(req, res);
            return;
        } else if (req.urlParsed.file === _const.ENABLED && req.method === "GET") {
            _getEnabledCommand(req, res);
            return;
        } else if (req.urlParsed.chunks[0] === _const.ATTRIBUTE && req.method === "GET") {
            _getAttributeCommand(req, res);
            return;
        } else if (req.urlParsed.file === _const.NAME && req.method === "GET") {
            _getNameCommand(req, res);
            return;
        } else if (req.urlParsed.file === _const.CLICK && req.method === "POST") {
            _postClickCommand(req, res);
            return;
        } else if (req.urlParsed.file === _const.SELECTED && req.method === "GET") {
            _getSelectedCommand(req, res);
            return;
        } else if (req.urlParsed.file === _const.CLEAR && req.method === "POST") {
            _postClearCommand(req, res);
            return;
        } else if (req.urlParsed.chunks[0] === _const.CSS && req.method === "GET") {
            _getCssCommand(req, res);
            return;
        } else if (req.urlParsed.file === _const.TEXT && req.method === "GET") {
            _getTextCommand(req, res);
            return;
        } else if (req.urlParsed.chunks[0] === _const.EQUALS && req.method === "GET") {
            _getEqualsCommand(req, res);
            return;
        } else if (req.urlParsed.file === _const.LOCATION && req.method === "GET") {
            _getLocationCommand(req, res);
            return;
        } else if (req.urlParsed.file === _const.LOCATION_IN_VIEW && req.method === "GET") {
            _getLocationInViewCommand(req, res);
            return;
        } else if (req.urlParsed.file === _const.SIZE && req.method === "GET") {
            _getSizeCommand(req, res);
            return;
        } else if (req.urlParsed.file === "" && req.method === "GET") {         //< GET "/session/:id/element/:id"
            // The response to this command is not defined in the specs:
            // here we just return the Element JSON ID.
            res.success(_session.getId(), _getJSON());
            return;
        } // else ...

        // TODO lots to do...

        throw _errors.createInvalidReqInvalidCommandMethodEH(req);
    },

    _getDisplayedCommand = function(req, res) {
        var displayed = _session.getCurrentWindow().evaluate(
            require("./webdriver_atoms.js").get("is_displayed"),
            _getJSON());
        res.respondBasedOnResult(_session, req, displayed);
    },

    _getEnabledCommand = function(req, res) {
        var enabled = _session.getCurrentWindow().evaluate(
            require("./webdriver_atoms.js").get("is_enabled"),
            _getJSON());
        res.respondBasedOnResult(_session, req, enabled);
    },

    _getLocationResult = function() {
        return _session.getCurrentWindow().evaluate(
            require("./webdriver_atoms.js").get("execute_script"),
            "return (" + require("./webdriver_atoms.js").get("get_location") + ")(arguments[0]);",
            [_getJSON()]);
    },

    _getLocationCommand = function(req, res) {
        var locationRes = _getLocationResult();
        res.respondBasedOnResult(_session, req, locationRes);
    },

    _getLocationInViewCommand = function(req, res) {
        var locationRes = _getLocationResult(),
            inViewLocationRes;

        if (locationRes.hasOwnProperty("status") && locationRes.status === 0) {
            // We got a location: let's scroll to it
            inViewLocationRes = _session.getCurrentWindow().evaluate(
                require("./webdriver_atoms.js").get("execute_script"),
                "return (" + require("./webdriver_atoms.js").get("get_in_view_location") + ")(arguments[0]);",
                [locationRes.value]);

            res.respondBasedOnResult(_session, req, inViewLocationRes);
        } else {
            // Result is an error: report it
            res.respondBasedOnResult(_session, req, locationRes);
        }
    },

    _getSizeCommand = function(req, res) {
        var size = _session.getCurrentWindow().evaluate(
            require("./webdriver_atoms.js").get("get_size"),
            _getJSON());
        res.respondBasedOnResult(_session, req, size);
    },

    _valueCommand = function(req, res) {
        var i, ilen,
            postObj = JSON.parse(req.post),
            typeAtom = require("./webdriver_atoms.js").get("type"),
            typeRes;

        // Ensure all required parameters are available
        if (typeof(postObj) === "object" && typeof(postObj.value) === "object") {
            // Execute the "type" atom
            typeRes = _getSession().getCurrentWindow().evaluate(typeAtom, _getJSON(), postObj.value);

            // TODO - Error handling based on the value of "typeRes"

            res.success(_session.getId());
            return;
        }

        throw _errors.createInvalidReqMissingCommandParameterEH(req);
    },

    _getNameCommand = function(req, res) {
        var result = _session.getCurrentWindow().evaluate(
                require("./webdriver_atoms.js").get("execute_script"),
                "return arguments[0].tagName;",
                [_getJSON()]);

        // Convert value to a lowercase string as per WebDriver JSONWireProtocol spec
        // @see http://code.google.com/p/selenium/wiki/JsonWireProtocol#/session/:sessionId/element/:id/name
        if(result.status === 0) {
            result.value = result.value.toLowerCase();
        }

        res.respondBasedOnResult(_session, req, result);
    },

    _getAttributeCommand = function(req, res) {
        var attributeValueAtom = require("./webdriver_atoms.js").get("get_attribute_value"),
            result;

        if (typeof(req.urlParsed.file) === "string" && req.urlParsed.file.length > 0) {
            // Read the attribute
            result = _session.getCurrentWindow().evaluate(
                attributeValueAtom,     // < Atom to read an attribute
                _getJSON(),             // < Element to read from
                req.urlParsed.file);    // < Attribute to read

            res.respondBasedOnResult(_session, req, result);
            return;
        }

        throw _errors.createInvalidReqMissingCommandParameterEH(req);
    },

    _getTextCommand = function(req, res) {
        var result = _session.getCurrentWindow().evaluate(
            require("./webdriver_atoms.js").get("get_text"),
            _getJSON());
        res.respondBasedOnResult(_session, req, result);
    },

    _getEqualsCommand = function(req, res) {
        var result;

        if (typeof(req.urlParsed.file) === "string" && req.urlParsed.file.length > 0) {
            result = _session.getCurrentWindow().evaluate(
                require("./webdriver_atoms.js").get("execute_script"),
                "return arguments[0].isSameNode(arguments[1]);",
                [_getJSON(), _getJSON(req.urlParsed.file)]);
            res.success(_session.getId(), result);
        }

        throw _errors.createInvalidReqMissingCommandParameterEH(req);
    },

    _submitCommand = function(req, res) {
        var submitRes;

        // Listen for the page to Finish Loading after the submit
        _getSession().getCurrentWindow().setOneShotCallback("onLoadFinished", function(status) {
            if (status === "success") {
                res.success(_session.getId());
            }

            // TODO - what do we do if this fails?
            // TODO - clear thing up after we are done waiting
        });

        submitRes = _getSession().getCurrentWindow().evaluate(
            require("./webdriver_atoms.js").get("submit"),
            _getJSON());

        // TODO - Error handling based on the value of "submitRes"
    },

    _postClickCommand = function(req, res) {
        var result = _session.getCurrentWindow().evaluate(
                require("./webdriver_atoms.js").get("click"),
                _getJSON());

        res.respondBasedOnResult(_session, req, result);
    },

    _getSelectedCommand = function(req, res) {
        var result = JSON.parse(_session.getCurrentWindow().evaluate(
                require("./webdriver_atoms.js").get("is_selected"),
                _getJSON()));

        res.respondBasedOnResult(_session, req, result);
    },

    _postClearCommand = function(req, res) {
        var result = _session.getCurrentWindow().evaluate(
                require("./webdriver_atoms.js").get("clear"),
                _getJSON());
        res.respondBasedOnResult(_session, req, result);
    },

    _getCssCommand = function(req, res) {
        var cssPropertyName = req.urlParsed.file,
            result;

        // Check that a property name was indeed provided
        if (typeof(cssPropertyName) === "string" || cssPropertyName.length > 0) {
            result = _session.getCurrentWindow().evaluate(
                require("./webdriver_atoms.js").get("execute_script"),
                "return window.getComputedStyle(arguments[0]).getPropertyValue(arguments[1]);",
                [_getJSON(), cssPropertyName]);

            res.respondBasedOnResult(_session, req, result);
            return;
        }

        throw _errors.createInvalidReqMissingCommandParameterEH(req);
    },

    _findElementCommand = function(req, res, locatorMethod) {
        // Search for a WebElement on the Page
        var elementOrElements,
            searchStartTime = new Date().getTime();

        // If a "locatorMethod" was not provided, default to "locateElement"
        if(typeof(locatorMethod) !== "function") {
            locatorMethod = _locator.locateElement;
        }

        // Try to find the element
        //  and retry if "startTime + implicitTimeout" is
        //  greater (or equal) than current time
        do {
            elementOrElements = locatorMethod("JSON", JSON.parse(req.post), _getJSON());
            if (elementOrElements) {
                res.success(_session.getId(), elementOrElements);
                return;
            }
        } while(searchStartTime + _session.getTimeout(_session.timeoutNames().IMPLICIT) >= new Date().getTime());

        throw _errors.createInvalidReqVariableResourceNotFoundEH(req);
    },

    /**
     * This method can generate any Element JSON: just provide an ID.
     * Will return the one of the current Element if no ID is provided.
     * @param elementId ID of the Element to describe in JSON format,
     *      or undefined to get the one fo the current Element.
     */
    _getJSON = function(elementId) {
        return {
            "ELEMENT" : elementId || _getId()
        };
    },

    _getId = function() {
        return _id;
    },
    _getSession = function() {
        return _session;
    };

    // public:
    return {
        handle : _handle,
        getId : _getId,
        getJSON : _getJSON,
        getSession : _getSession//,
        // isAttachedToDOM : _isAttachedToDOM,
        // isVisible : _isVisible
    };
};
// prototype inheritance:
ghostdriver.WebElementReqHand.prototype = new ghostdriver.RequestHandler();
<commit_msg>Sorting out some method naming in WebElementReqHand<commit_after>/*
This file is part of the GhostDriver project from Neustar inc.

Copyright (c) 2012, Ivan De Marino <ivan.de.marino@gmail.com> - Neustar inc.
Copyright (c) 2012, Alex Anderson <@alxndrsn>
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright notice,
      this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

var ghostdriver = ghostdriver || {};

ghostdriver.WebElementReqHand = function(idOrElement, session) {
    // private:
    var
    _id = ((typeof(idOrElement) === "object") ? idOrElement["ELEMENT"] : idOrElement),
    _session = session,
    _locator = new ghostdriver.WebElementLocator(_session),
    _protoParent = ghostdriver.WebElementReqHand.prototype,
    _const = {
        ELEMENT             : "element",
        ELEMENTS            : "elements",
        VALUE               : "value",
        SUBMIT              : "submit",
        DISPLAYED           : "displayed",
        ENABLED             : "enabled",
        ATTRIBUTE           : "attribute",
        NAME                : "name",
        CLICK               : "click",
        SELECTED            : "selected",
        CLEAR               : "clear",
        CSS                 : "css",
        TEXT                : "text",
        EQUALS_DIR          : "equals",
        LOCATION            : "location",
        LOCATION_IN_VIEW    : "location_in_view",
        SIZE                : "size"
    },
    _errors = require("./errors.js"),

    _handle = function(req, res) {
        _protoParent.handle.call(this, req, res);

        // console.log("Request => " + JSON.stringify(req, null, '  '));

        // TODO lots to do...

        if (req.urlParsed.file === _const.ELEMENT && req.method === "POST") {
            _postFindElementCommand(req, res, _locator.locateElement);
            return;
        } else if (req.urlParsed.file === _const.ELEMENTS && req.method === "POST") {
            _postFindElementCommand(req, res, _locator.locateElements);
            return;
        } else if (req.urlParsed.file === _const.VALUE && req.method === "POST") {
            _postValueCommand(req, res);
            return;
        } else if (req.urlParsed.file === _const.SUBMIT && req.method === "POST") {
            _postSubmitCommand(req, res);
            return;
        } else if (req.urlParsed.file === _const.DISPLAYED && req.method === "GET") {
            _getDisplayedCommand(req, res);
            return;
        } else if (req.urlParsed.file === _const.ENABLED && req.method === "GET") {
            _getEnabledCommand(req, res);
            return;
        } else if (req.urlParsed.chunks[0] === _const.ATTRIBUTE && req.method === "GET") {
            _getAttributeCommand(req, res);
            return;
        } else if (req.urlParsed.file === _const.NAME && req.method === "GET") {
            _getNameCommand(req, res);
            return;
        } else if (req.urlParsed.file === _const.CLICK && req.method === "POST") {
            _postClickCommand(req, res);
            return;
        } else if (req.urlParsed.file === _const.SELECTED && req.method === "GET") {
            _getSelectedCommand(req, res);
            return;
        } else if (req.urlParsed.file === _const.CLEAR && req.method === "POST") {
            _postClearCommand(req, res);
            return;
        } else if (req.urlParsed.chunks[0] === _const.CSS && req.method === "GET") {
            _getCssCommand(req, res);
            return;
        } else if (req.urlParsed.file === _const.TEXT && req.method === "GET") {
            _getTextCommand(req, res);
            return;
        } else if (req.urlParsed.chunks[0] === _const.EQUALS && req.method === "GET") {
            _getEqualsCommand(req, res);
            return;
        } else if (req.urlParsed.file === _const.LOCATION && req.method === "GET") {
            _getLocationCommand(req, res);
            return;
        } else if (req.urlParsed.file === _const.LOCATION_IN_VIEW && req.method === "GET") {
            _getLocationInViewCommand(req, res);
            return;
        } else if (req.urlParsed.file === _const.SIZE && req.method === "GET") {
            _getSizeCommand(req, res);
            return;
        } else if (req.urlParsed.file === "" && req.method === "GET") {         //< GET "/session/:id/element/:id"
            // The response to this command is not defined in the specs:
            // here we just return the Element JSON ID.
            res.success(_session.getId(), _getJSON());
            return;
        } // else ...

        // TODO lots to do...

        throw _errors.createInvalidReqInvalidCommandMethodEH(req);
    },

    _getDisplayedCommand = function(req, res) {
        var displayed = _session.getCurrentWindow().evaluate(
            require("./webdriver_atoms.js").get("is_displayed"),
            _getJSON());
        res.respondBasedOnResult(_session, req, displayed);
    },

    _getEnabledCommand = function(req, res) {
        var enabled = _session.getCurrentWindow().evaluate(
            require("./webdriver_atoms.js").get("is_enabled"),
            _getJSON());
        res.respondBasedOnResult(_session, req, enabled);
    },

    _getLocationResult = function() {
        return _session.getCurrentWindow().evaluate(
            require("./webdriver_atoms.js").get("execute_script"),
            "return (" + require("./webdriver_atoms.js").get("get_location") + ")(arguments[0]);",
            [_getJSON()]);
    },

    _getLocationCommand = function(req, res) {
        var locationRes = _getLocationResult();
        res.respondBasedOnResult(_session, req, locationRes);
    },

    _getLocationInViewCommand = function(req, res) {
        var locationRes = _getLocationResult(),
            inViewLocationRes;

        if (locationRes.hasOwnProperty("status") && locationRes.status === 0) {
            // We got a location: let's scroll to it
            inViewLocationRes = _session.getCurrentWindow().evaluate(
                require("./webdriver_atoms.js").get("execute_script"),
                "return (" + require("./webdriver_atoms.js").get("get_in_view_location") + ")(arguments[0]);",
                [locationRes.value]);

            res.respondBasedOnResult(_session, req, inViewLocationRes);
        } else {
            // Result is an error: report it
            res.respondBasedOnResult(_session, req, locationRes);
        }
    },

    _getSizeCommand = function(req, res) {
        var size = _session.getCurrentWindow().evaluate(
            require("./webdriver_atoms.js").get("get_size"),
            _getJSON());
        res.respondBasedOnResult(_session, req, size);
    },

    _postValueCommand = function(req, res) {
        var i, ilen,
            postObj = JSON.parse(req.post),
            typeAtom = require("./webdriver_atoms.js").get("type"),
            typeRes;

        // Ensure all required parameters are available
        if (typeof(postObj) === "object" && typeof(postObj.value) === "object") {
            // Execute the "type" atom
            typeRes = _getSession().getCurrentWindow().evaluate(
                typeAtom,
                _getJSON(),
                postObj.value);

            // TODO - Error handling based on the value of "typeRes"

            res.success(_session.getId());
            return;
        }

        throw _errors.createInvalidReqMissingCommandParameterEH(req);
    },

    _getNameCommand = function(req, res) {
        var result = _session.getCurrentWindow().evaluate(
                require("./webdriver_atoms.js").get("execute_script"),
                "return arguments[0].tagName;",
                [_getJSON()]);

        // Convert value to a lowercase string as per WebDriver JSONWireProtocol spec
        // @see http://code.google.com/p/selenium/wiki/JsonWireProtocol#/session/:sessionId/element/:id/name
        if(result.status === 0) {
            result.value = result.value.toLowerCase();
        }

        res.respondBasedOnResult(_session, req, result);
    },

    _getAttributeCommand = function(req, res) {
        var attributeValueAtom = require("./webdriver_atoms.js").get("get_attribute_value"),
            result;

        if (typeof(req.urlParsed.file) === "string" && req.urlParsed.file.length > 0) {
            // Read the attribute
            result = _session.getCurrentWindow().evaluate(
                attributeValueAtom,     // < Atom to read an attribute
                _getJSON(),             // < Element to read from
                req.urlParsed.file);    // < Attribute to read

            res.respondBasedOnResult(_session, req, result);
            return;
        }

        throw _errors.createInvalidReqMissingCommandParameterEH(req);
    },

    _getTextCommand = function(req, res) {
        var result = _session.getCurrentWindow().evaluate(
            require("./webdriver_atoms.js").get("get_text"),
            _getJSON());
        res.respondBasedOnResult(_session, req, result);
    },

    _getEqualsCommand = function(req, res) {
        var result;

        if (typeof(req.urlParsed.file) === "string" && req.urlParsed.file.length > 0) {
            result = _session.getCurrentWindow().evaluate(
                require("./webdriver_atoms.js").get("execute_script"),
                "return arguments[0].isSameNode(arguments[1]);",
                [_getJSON(), _getJSON(req.urlParsed.file)]);
            res.success(_session.getId(), result);
        }

        throw _errors.createInvalidReqMissingCommandParameterEH(req);
    },

    _postSubmitCommand = function(req, res) {
        var submitRes;

        // Listen for the page to Finish Loading after the submit
        _getSession().getCurrentWindow().setOneShotCallback("onLoadFinished", function(status) {
            if (status === "success") {
                res.success(_session.getId());
            }

            // TODO - what do we do if this fails?
            // TODO - clear thing up after we are done waiting
        });

        submitRes = _getSession().getCurrentWindow().evaluate(
            require("./webdriver_atoms.js").get("submit"),
            _getJSON());

        // TODO - Error handling based on the value of "submitRes"
    },

    _postClickCommand = function(req, res) {
        var result = _session.getCurrentWindow().evaluate(
                require("./webdriver_atoms.js").get("click"),
                _getJSON());

        res.respondBasedOnResult(_session, req, result);
    },

    _getSelectedCommand = function(req, res) {
        var result = JSON.parse(_session.getCurrentWindow().evaluate(
                require("./webdriver_atoms.js").get("is_selected"),
                _getJSON()));

        res.respondBasedOnResult(_session, req, result);
    },

    _postClearCommand = function(req, res) {
        var result = _session.getCurrentWindow().evaluate(
                require("./webdriver_atoms.js").get("clear"),
                _getJSON());
        res.respondBasedOnResult(_session, req, result);
    },

    _getCssCommand = function(req, res) {
        var cssPropertyName = req.urlParsed.file,
            result;

        // Check that a property name was indeed provided
        if (typeof(cssPropertyName) === "string" || cssPropertyName.length > 0) {
            result = _session.getCurrentWindow().evaluate(
                require("./webdriver_atoms.js").get("execute_script"),
                "return window.getComputedStyle(arguments[0]).getPropertyValue(arguments[1]);",
                [_getJSON(), cssPropertyName]);

            res.respondBasedOnResult(_session, req, result);
            return;
        }

        throw _errors.createInvalidReqMissingCommandParameterEH(req);
    },

    _postFindElementCommand = function(req, res, locatorMethod) {
        // Search for a WebElement on the Page
        var elementOrElements,
            searchStartTime = new Date().getTime();

        // If a "locatorMethod" was not provided, default to "locateElement"
        if(typeof(locatorMethod) !== "function") {
            locatorMethod = _locator.locateElement;
        }

        // Try to find the element
        //  and retry if "startTime + implicitTimeout" is
        //  greater (or equal) than current time
        do {
            elementOrElements = locatorMethod("JSON", JSON.parse(req.post), _getJSON());
            if (elementOrElements) {
                res.success(_session.getId(), elementOrElements);
                return;
            }
        } while(searchStartTime + _session.getTimeout(_session.timeoutNames().IMPLICIT) >= new Date().getTime());

        throw _errors.createInvalidReqVariableResourceNotFoundEH(req);
    },

    /**
     * This method can generate any Element JSON: just provide an ID.
     * Will return the one of the current Element if no ID is provided.
     * @param elementId ID of the Element to describe in JSON format,
     *      or undefined to get the one fo the current Element.
     */
    _getJSON = function(elementId) {
        return {
            "ELEMENT" : elementId || _getId()
        };
    },

    _getId = function() {
        return _id;
    },
    _getSession = function() {
        return _session;
    };

    // public:
    return {
        handle : _handle,
        getId : _getId,
        getJSON : _getJSON,
        getSession : _getSession//,
        // isAttachedToDOM : _isAttachedToDOM,
        // isVisible : _isVisible
    };
};
// prototype inheritance:
ghostdriver.WebElementReqHand.prototype = new ghostdriver.RequestHandler();
<|endoftext|>


<commit_before>const styles = require.requireActual('../styles');

export const SPIN_STYLES = styles.SPIN_STYLES;

export const X_STYLES = styles.X_STYLES;

export const getListStyles = jest.fn(styles.getListStyles);
<commit_msg>remove js styles mock<commit_after><|endoftext|>


<commit_before>(function()
{
  // ML_ prefixes to avoid name clashes with other highlighters
  const
  CSS_AT_RULE                 = cls.CSSTokenizer.types.AT_RULE,
  CSS_SELECTOR                = cls.CSSTokenizer.types.SELECTOR,
  CSS_WHITESPACE              = cls.CSSTokenizer.types.WHITESPACE,
  CSS_PROPERTY                = cls.CSSTokenizer.types.PROPERTY,
  CSS_PROPERTY_SEPARATOR      = cls.CSSTokenizer.types.PROPERTY_SEPARATOR,
  CSS_PROPERTY_VALUE          = cls.CSSTokenizer.types.PROPERTY_VALUE,
  CSS_DECLARATION_TERMINATOR  = cls.CSSTokenizer.types.DECLARATION_TERMINATOR,
  CSS_DECLARATION_BLOCK_START = cls.CSSTokenizer.types.DECLARATION_BLOCK_START,
  CSS_DECLARATION_BLOCK_END   = cls.CSSTokenizer.types.DECLARATION_BLOCK_END,
  CSS_EOL_DATA                = cls.CSSTokenizer.types.EOL_DATA,
  CSS_COMMENT                 = cls.CSSTokenizer.types.COMMENT;
  CSS_EOF                     = cls.CSSTokenizer.types.EOF;

  var css_classes = [];

  css_classes[CSS_AT_RULE] = "css-at-rule";
  css_classes[CSS_SELECTOR] = "css-selector";
  css_classes[CSS_PROPERTY] = "css-property";
  css_classes[CSS_PROPERTY_SEPARATOR] = "css-property-separator";
  css_classes[CSS_PROPERTY_VALUE] = "css-property-value";
  css_classes[CSS_DECLARATION_BLOCK_START] = "css-declaration";
  css_classes[CSS_DECLARATION_BLOCK_END] = "css-declaration";
  css_classes[CSS_DECLARATION_TERMINATOR] = "declaration-terminator";
  css_classes[CSS_COMMENT] = "comment";

  const _escapes_re = /\\[0-9a-f]{1,6}/i;

  var normalize_token = function(token)
  {
    // check dom.js and helpers.js for trim.
    // There are some inherent limitations in fromCharCode wrt
    // multibyte sequences, but this should work for all CSS keywords.
    return token.replace(_escapes_re, function(s,p1,p2){
      return String.fromCharCode(parseInt(p1,16))
    });
  }

  // root handler, declaration handler

  var highlight_token = function(context, token_type, token)
  {
    if (!token) return;
    if (context.onnewline && (token_type == CSS_EOL_DATA))
    {
      context.onnewline();
    }

    switch (token_type)
    {
      case CSS_AT_RULE:
      case CSS_PROPERTY:
      case CSS_PROPERTY_VALUE:
      case CSS_SELECTOR:
      case CSS_COMMENT:
        context.template.push(context.text)
        context.text ="";
        context.template.push(["span",token,"class",css_classes[token_type]]);
        break;
      default:
        context.text += token;
        break;
    }
    return;
  }

  this.highlight_css = function(stylesheet, onnewline)
  {
    var css_tokenizer = new cls.CSSTokenizer();
    var context =
    {
      template: ["pre"],
      text: "",
      onnewline: onnewline,
      tag_template: null,
      self: this
    };

    // the js implementation of bind causes a noticable overhead here
    // when we get a native implementation we can adjust the code
    css_tokenizer.tokenize(script, function(token_type, token)
    {
        highlight_token(context, token_type, token);
    });

    if (context.text)
    {
      context.template.push(context.text);
    }

    return context.template;
  };

}).apply(window.templates || (window.templates = {}));

<commit_msg>Fixed undefined variable script<commit_after>(function()
{
  // ML_ prefixes to avoid name clashes with other highlighters
  const
  CSS_AT_RULE                 = cls.CSSTokenizer.types.AT_RULE,
  CSS_SELECTOR                = cls.CSSTokenizer.types.SELECTOR,
  CSS_WHITESPACE              = cls.CSSTokenizer.types.WHITESPACE,
  CSS_PROPERTY                = cls.CSSTokenizer.types.PROPERTY,
  CSS_PROPERTY_SEPARATOR      = cls.CSSTokenizer.types.PROPERTY_SEPARATOR,
  CSS_PROPERTY_VALUE          = cls.CSSTokenizer.types.PROPERTY_VALUE,
  CSS_DECLARATION_TERMINATOR  = cls.CSSTokenizer.types.DECLARATION_TERMINATOR,
  CSS_DECLARATION_BLOCK_START = cls.CSSTokenizer.types.DECLARATION_BLOCK_START,
  CSS_DECLARATION_BLOCK_END   = cls.CSSTokenizer.types.DECLARATION_BLOCK_END,
  CSS_EOL_DATA                = cls.CSSTokenizer.types.EOL_DATA,
  CSS_COMMENT                 = cls.CSSTokenizer.types.COMMENT;
  CSS_EOF                     = cls.CSSTokenizer.types.EOF;

  var css_classes = [];

  css_classes[CSS_AT_RULE] = "css-at-rule";
  css_classes[CSS_SELECTOR] = "css-selector";
  css_classes[CSS_PROPERTY] = "css-property";
  css_classes[CSS_PROPERTY_SEPARATOR] = "css-property-separator";
  css_classes[CSS_PROPERTY_VALUE] = "css-property-value";
  css_classes[CSS_DECLARATION_BLOCK_START] = "css-declaration";
  css_classes[CSS_DECLARATION_BLOCK_END] = "css-declaration";
  css_classes[CSS_DECLARATION_TERMINATOR] = "declaration-terminator";
  css_classes[CSS_COMMENT] = "comment";

  const _escapes_re = /\\[0-9a-f]{1,6}/i;

  var normalize_token = function(token)
  {
    // check dom.js and helpers.js for trim.
    // There are some inherent limitations in fromCharCode wrt
    // multibyte sequences, but this should work for all CSS keywords.
    return token.replace(_escapes_re, function(s,p1,p2){
      return String.fromCharCode(parseInt(p1,16))
    });
  }

  // root handler, declaration handler

  var highlight_token = function(context, token_type, token)
  {
    if (!token) return;
    if (context.onnewline && (token_type == CSS_EOL_DATA))
    {
      context.onnewline();
    }

    switch (token_type)
    {
      case CSS_AT_RULE:
      case CSS_PROPERTY:
      case CSS_PROPERTY_VALUE:
      case CSS_SELECTOR:
      case CSS_COMMENT:
        context.template.push(context.text)
        context.text ="";
        context.template.push(["span",token,"class",css_classes[token_type]]);
        break;
      default:
        context.text += token;
        break;
    }
    return;
  }

  this.highlight_css = function(stylesheet, onnewline)
  {
    var css_tokenizer = new cls.CSSTokenizer();
    var context =
    {
      template: ["pre"],
      text: "",
      onnewline: onnewline,
      tag_template: null,
      self: this
    };

    // the js implementation of bind causes a noticable overhead here
    // when we get a native implementation we can adjust the code
    css_tokenizer.tokenize(stylesheet, function(token_type, token)
    {
        highlight_token(context, token_type, token);
    });

    if (context.text)
    {
      context.template.push(context.text);
    }

    return context.template;
  };

}).apply(window.templates || (window.templates = {}));

<|endoftext|>


<commit_before>var mongoose =  require('./models'),
    Schema = mongoose.Schema;

var KeywordSchema = new Schema({
  text       : String,
  send_count : Number
});

var KeywordModel = mongoose.model('Keyword', KeywordSchema);

var Keyword = (function() {
  var _Keyword = {};

  _Keyword.findAll = function(success, fail) {
    var keywordsQuery = KeywordModel.where({});
    keywordsQuery.find().select('text send_count').lean().exec(function(err, result) {
      if (err) {
        fail(err, result);
        return;
      }
      success(result);
    });
  };

  _Keyword.addKeyword = function(keyword, success, fail) {
    var keywordsQuery = KeywordModel.where({ text: keyword.text});
    keywordsQuery.findOne().lean().exec(function(err, result) {
      if (err) {
        fail(err, result);
        return;
      }
      if (result.length !== 0) {
        fail({status: 400, message: "キーワードが存在しています"});
        return;
      }

      if (!keyword.send_count) {
        keyword.send_count = 0;
      }
      var newKeyword = new KeywordModel(keyword);
      newKeyword.save(function(err) {
        if (err) {
          fail({status: 500, message: err});
          return;
        }
        success();
      });
    });
  };

  _Keyword.countUpKeyword = function(keywordName, success, fail) {
    var keywordsQuery = KeywordModel.where({text: keywordName});
    keywordsQuery.findOneAndUpdate({$inc: { send_count: 1}}).lean().exec(function(err, result) {
      if (err) {
        fail(err, result);
        return;
      }
      success(result);
    });
  };

  return _Keyword;
})();

module.exports = Keyword;
<commit_msg>新規追加したいときにもエラーが出ていたので修正<commit_after>var mongoose =  require('./models'),
    Schema = mongoose.Schema;

var KeywordSchema = new Schema({
  text       : String,
  send_count : Number
});

var KeywordModel = mongoose.model('Keyword', KeywordSchema);

var Keyword = (function() {
  var _Keyword = {};

  _Keyword.findAll = function(success, fail) {
    var keywordsQuery = KeywordModel.where({});
    keywordsQuery.find().select('text send_count').lean().exec(function(err, result) {
      if (err) {
        fail(err, result);
        return;
      }
      success(result);
    });
  };

  _Keyword.addKeyword = function(keyword, success, fail) {
    var keywordsQuery = KeywordModel.where({ text: keyword.text});
    keywordsQuery.findOne().lean().exec(function(err, result) {
      if (err) {
        fail(err, result);
        return;
      }
      console.log(result);
      if (result && result.length !== 0) {
        fail({status: 400, message: "キーワードが存在しています"});
        return;
      }

      if (!keyword.send_count) {
        keyword.send_count = 0;
      }
      var newKeyword = new KeywordModel(keyword);
      newKeyword.save(function(err) {
        if (err) {
          fail({status: 500, message: err});
          return;
        }
        success();
      });
    });
  };

  _Keyword.countUpKeyword = function(keywordName, success, fail) {
    var keywordsQuery = KeywordModel.where({text: keywordName});
    keywordsQuery.findOneAndUpdate({$inc: { send_count: 1}}).lean().exec(function(err, result) {
      if (err) {
        fail(err, result);
        return;
      }
      success(result);
    });
  };

  return _Keyword;
})();

module.exports = Keyword;
<|endoftext|>


<commit_before>import PopperJS from './popper';
import { PopupManager } from 'vue-popup';

/**
 * @param {HTMLElement} [reference=$refs.reference] - The reference element used to position the popper.
 * @param {HTMLElement} [popper=$refs.popper] - The HTML element used as popper, or a configuration used to generate the popper.
 * @param {String} [placement=button] - Placement of the popper accepted values: top(-start, -end), right(-start, -end), bottom(-start, -right), left(-start, -end)
 * @param {Number} [offset=0] - Amount of pixels the popper will be shifted (can be negative).
 * @param {Boolean} [visible=false] Visibility of the popup element.
 * @param {Boolean} [visible-arrow=false] Visibility of the arrow, no style.
 */
export default {
  props: {
    placement: {
      type: String,
      default: 'bottom'
    },
    boundariesPadding: {
      type: Number,
      default: 5
    },
    reference: Object,
    popper: Object,
    offset: {
      default: 0
    },
    value: Boolean,
    visibleArrow: Boolean,
    transition: String,
    appendToBody: {
      type: Boolean,
      default: true
    },
    options: {
      type: Object,
      default() {
        return {
          gpuAcceleration: false
        };
      }
    }
  },

  data() {
    return {
      showPopper: false
    };
  },

  watch: {
    value: {
      immediate: true,
      handler(val) {
        this.showPopper = val;
        this.$emit('input', val);
      }
    },

    showPopper(val) {
      val ? this.updatePopper() : this.destroyPopper();
      this.$emit('input', val);
    }
  },

  methods: {
    createPopper() {
      if (!/^(top|bottom|left|right)(-start|-end)?$/g.test(this.placement)) {
        return;
      }

      const options = this.options;
      const popper = this.popperElm = this.popperElm || this.popper || this.$refs.popper;
      const reference = this.referenceElm = this.referenceElm || this.reference || this.$refs.reference || this.$slots.reference[0].elm;

      if (!popper || !reference) return;

      if (this.visibleArrow) this.appendArrow(popper);
      if (this.appendToBody) document.body.appendChild(this.popperElm);
      if (this.popperJS && this.popperJS.hasOwnProperty('destroy')) {
        this.popperJS.destroy();
      }

      options.placement = this.placement;
      options.offset = this.offset;
      this.popperJS = new PopperJS(reference, popper, options);
      this.popperJS.onCreate(_ => {
        this.$emit('created', this);
        this.resetTransformOrigin();
      });
      this.popperJS._popper.style.zIndex = PopupManager.nextZIndex();
    },

    updatePopper() {
      this.popperJS ? this.popperJS.update() : this.createPopper();
    },

    doDestroy() {
      if (this.showPopper || !this.popperJS) return;
      this.popperJS.destroy();
      this.popperJS = null;
    },

    destroyPopper() {
      if (this.popperJS) {
        this.resetTransformOrigin();
      }
    },

    resetTransformOrigin() {
      let placementMap = { top: 'bottom', bottom: 'top', left: 'right', right: 'left' };
      let placement = this.popperJS._popper.getAttribute('x-placement').split('-')[0];
      let origin = placementMap[placement];
      this.popperJS._popper.style.transformOrigin = ['top', 'bottom'].indexOf(placement) > -1 ? `center ${ origin }` : `${ origin } center`;
    },

    appendArrow(element) {
      let hash;
      if (this.appended) {
        return;
      }

      this.appended = true;

      for (let item in element.attributes) {
        if (/^_v-/.test(element.attributes[item].name)) {
          hash = element.attributes[item].name;
          break;
        }
      }

      const arrow = document.createElement('div');

      if (hash) {
        arrow.setAttribute(hash, '');
      }
      arrow.setAttribute('x-arrow', '');
      arrow.className = 'popper__arrow';
      element.appendChild(arrow);
    }
  },

  beforeDestroy() {
    this.doDestroy();
    this.popperElm &&
    document.body.contains(this.popperElm) &&
    document.body.removeChild(this.popperElm);
  }
};
<commit_msg>Popover: fix the arrow appears, fixed #412<commit_after>import PopperJS from './popper';
import { PopupManager } from 'vue-popup';

/**
 * @param {HTMLElement} [reference=$refs.reference] - The reference element used to position the popper.
 * @param {HTMLElement} [popper=$refs.popper] - The HTML element used as popper, or a configuration used to generate the popper.
 * @param {String} [placement=button] - Placement of the popper accepted values: top(-start, -end), right(-start, -end), bottom(-start, -right), left(-start, -end)
 * @param {Number} [offset=0] - Amount of pixels the popper will be shifted (can be negative).
 * @param {Boolean} [visible=false] Visibility of the popup element.
 * @param {Boolean} [visible-arrow=false] Visibility of the arrow, no style.
 */
export default {
  props: {
    placement: {
      type: String,
      default: 'bottom'
    },
    boundariesPadding: {
      type: Number,
      default: 5
    },
    reference: Object,
    popper: Object,
    offset: {
      default: 0
    },
    value: Boolean,
    visibleArrow: Boolean,
    transition: String,
    appendToBody: {
      type: Boolean,
      default: true
    },
    options: {
      type: Object,
      default() {
        return {
          gpuAcceleration: false
        };
      }
    }
  },

  data() {
    return {
      showPopper: false
    };
  },

  watch: {
    value: {
      immediate: true,
      handler(val) {
        this.showPopper = val;
        this.$emit('input', val);
      }
    },

    showPopper(val) {
      val ? this.updatePopper() : this.destroyPopper();
      this.$emit('input', val);
    }
  },

  methods: {
    createPopper() {
      if (!/^(top|bottom|left|right)(-start|-end)?$/g.test(this.placement)) {
        return;
      }

      const options = this.options;
      const popper = this.popperElm = this.popperElm || this.popper || this.$refs.popper;
      const reference = this.referenceElm = this.referenceElm || this.reference || this.$refs.reference || this.$slots.reference[0].elm;

      if (!popper || !reference) return;

      if (this.visibleArrow) this.appendArrow(popper);
      if (this.appendToBody) document.body.appendChild(this.popperElm);
      if (this.popperJS && this.popperJS.hasOwnProperty('destroy')) {
        this.popperJS.destroy();
      }

      options.placement = this.placement;
      options.offset = this.offset;
      this.popperJS = new PopperJS(reference, popper, options);
      this.popperJS.onCreate(_ => {
        this.$emit('created', this);
        this.resetTransformOrigin();
        this.$nextTick(this.updatePopper);
      });
      this.popperJS._popper.style.zIndex = PopupManager.nextZIndex();
    },

    updatePopper() {
      this.popperJS ? this.popperJS.update() : this.createPopper();
    },

    doDestroy() {
      if (this.showPopper || !this.popperJS) return;
      this.popperJS.destroy();
      this.popperJS = null;
    },

    destroyPopper() {
      if (this.popperJS) {
        this.resetTransformOrigin();
      }
    },

    resetTransformOrigin() {
      let placementMap = { top: 'bottom', bottom: 'top', left: 'right', right: 'left' };
      let placement = this.popperJS._popper.getAttribute('x-placement').split('-')[0];
      let origin = placementMap[placement];
      this.popperJS._popper.style.transformOrigin = ['top', 'bottom'].indexOf(placement) > -1 ? `center ${ origin }` : `${ origin } center`;
    },

    appendArrow(element) {
      let hash;
      if (this.appended) {
        return;
      }

      this.appended = true;

      for (let item in element.attributes) {
        if (/^_v-/.test(element.attributes[item].name)) {
          hash = element.attributes[item].name;
          break;
        }
      }

      const arrow = document.createElement('div');

      if (hash) {
        arrow.setAttribute(hash, '');
      }
      arrow.setAttribute('x-arrow', '');
      arrow.className = 'popper__arrow';
      element.appendChild(arrow);
    }
  },

  beforeDestroy() {
    this.doDestroy();
    this.popperElm &&
    document.body.contains(this.popperElm) &&
    document.body.removeChild(this.popperElm);
  }
};
<|endoftext|>


<commit_before>'use strict';

var Db        = require('../config/database');
var mongoose  = require('mongoose');
var crypto    = require('crypto');

// 7 days in milliseconds
var TTL = 604800000;

var ObjectId  = mongoose.Schema.ObjectId;

// Generates a random string to use as a session token
function generateToken() {
  return crypto.randomBytes(256).toString('base64');
}

function createExpirationDate() {
  return (Date.now() + TTL);
}

// Creates the schema for a session
var SessionSchema = mongoose.Schema({
  token     : { type : String, default : generateToken },
  createdAt : { type : Date, default : Date.now, expires : TTL/1000 },
  expireAt  : { type : Date, default : createExpirationDate },
  userId    : { type : ObjectId, required : true}
});

// Creates a collection named sessions in MongoDB
var SessionMongoModel = Db.model('sessions', SessionSchema);

// Takes a userId as an argument and returns the token string to the callback
function findSessionByUserId(userId, callback) {
  SessionMongoModel.findOne({ userId: userId },
                            function(err, session) {
    if (err) {
      // TODO: Error message?
      callback(err);
    } else if (!session) {
      callback({
        code    : 400,
        message : 'Session not found.'
      });
    } else {
      callback(null, session.token);
    }
  });
}

// Takes a token string as an argument and returns ths userId to the callback
function findUserByToken(clientToken, callback) {
  SessionMongoModel.findOne({ token: clientToken }, function(err, session) {
    if (err) {

      // TODO: Error message?
      callback(err, null);
    } else if (!session) {
      callback({
        code    : 400,
        message : 'Session not found.'
      });
    } else {
      callback(null, session.userId);
    }
  });
}

// Creates a new session and attach user ObjectId to it
function createSession(userId, callback) {
 SessionMongoModel.create({ userId: userId }, callback);
}

// Takes a token string and deletes the session with that string from MongoDB
function destroySession(clientToken, callback) {
  SessionMongoModel.findOneAndRemove({ token: clientToken },
    function(err, session) {
      if (err) {

        // TODO: Error message?
        callback(err, null);
      } else if (!session) {
        callback({
          code    : 400,
          message : 'Session not found.'
        });
      } else {
        callback(null);
      }
    }
  );
}

function destroyAllSessions(userId, callback) {
  SessionMongoModel.remove({ userId: userId }, callback);
}

var SessionModel = {
  findSession : findSessionByUserId,
  findUser    : findUserByToken,
  create      : createSession,
  destroy     : destroySession,
  destroyAll  : destroyAllSessions
};

module.exports = SessionModel;
<commit_msg>Removed expiring data from the database because it's too unstable<commit_after>'use strict';

var Db        = require('../config/database');
var mongoose  = require('mongoose');
var crypto    = require('crypto');

// 7 days in milliseconds
var TTL = 604800000;

var ObjectId  = mongoose.Schema.ObjectId;

// Generates a random string to use as a session token
function generateToken() {
  return crypto.randomBytes(256).toString('base64');
}

function createExpirationDate() {
  return (Date.now() + TTL);
}

// Creates the schema for a session
var SessionSchema = mongoose.Schema({
  token     : { type : String, default : generateToken },
  createdAt : { type : Date, default : Date.now},
  userId    : { type : ObjectId, required : true}
});

// Creates a collection named sessions in MongoDB
var SessionMongoModel = Db.model('sessions', SessionSchema);

// Takes a userId as an argument and returns the token string to the callback
function findSessionByUserId(userId, callback) {
  SessionMongoModel.findOne({ userId: userId },
                            function(err, session) {
    if (err) {
      // TODO: Error message?
      callback(err);
    } else if (!session) {
      callback({
        code    : 400,
        message : 'Session not found.'
      });
    } else {
      callback(null, session.token);
    }
  });
}

// Takes a token string as an argument and returns ths userId to the callback
function findUserByToken(clientToken, callback) {
  SessionMongoModel.findOne({ token: clientToken }, function(err, session) {
    if (err) {

      // TODO: Error message?
      callback(err, null);
    } else if (!session) {
      callback({
        code    : 400,
        message : 'Session not found.'
      });
    } else {
      callback(null, session.userId);
    }
  });
}

// Creates a new session and attach user ObjectId to it
function createSession(userId, callback) {
 SessionMongoModel.create({ userId: userId }, callback);
}

// Takes a token string and deletes the session with that string from MongoDB
function destroySession(clientToken, callback) {
  SessionMongoModel.findOneAndRemove({ token: clientToken },
    function(err, session) {
      if (err) {

        // TODO: Error message?
        callback(err, null);
      } else if (!session) {
        callback({
          code    : 400,
          message : 'Session not found.'
        });
      } else {
        callback(null);
      }
    }
  );
}

function destroyAllSessions(userId, callback) {
  SessionMongoModel.remove({ userId: userId }, callback);
}

var SessionModel = {
  findSession : findSessionByUserId,
  findUser    : findUserByToken,
  create      : createSession,
  destroy     : destroySession,
  destroyAll  : destroyAllSessions
};

module.exports = SessionModel;
<|endoftext|>


<commit_before>/*!
 * Forked from vdom-virtualize@0.5.1 by Marcel Klehr <mklehr@gmx.net>
 *
 * (MIT LICENSE)
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the 'Software'), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
'use strict';

var _ = require('underscore');
var VNode = require('virtual-dom/vnode/vnode');
var VText = require('virtual-dom/vnode/vtext');

/**
 * DOMNode property white list
 * Taken from https://github.com/Raynos/react/blob/dom-property-config/src/browser/ui/dom/DefaultDOMPropertyConfig.js
 */
var props = [
  'accept', 'accessKey', 'action', 'alt', 'async', 'autoComplete', 'autoPlay', 'cellPadding',
  'cellSpacing', 'checked', 'className', 'colSpan', 'content', 'contentEditable', 'controls',
  'crossOrigin', 'data', 'dataset', 'defer', 'dir', 'download', 'draggable', 'encType', 'formNoValidate',
  'href', 'hrefLang', 'htmlFor', 'httpEquiv', 'icon', 'id', 'label', 'lang', 'list', 'loop', 'max',
  'mediaGroup', 'method', 'min', 'multiple', 'muted', 'name', 'noValidate', 'pattern', 'placeholder',
  'poster', 'preload', 'radioGroup', 'readOnly', 'rel', 'required', 'rowSpan', 'sandbox', 'scope',
  'scrollLeft', 'scrolling', 'scrollTop', 'selected', 'span', 'spellCheck', 'src', 'srcDoc', 'srcSet',
  'start', 'step', 'style', 'tabIndex', 'target', 'title', 'type', 'value',

  // Non-standard Properties
  'autoCapitalize', 'autoCorrect', 'property', 'attributes'
];

function getElementAttributes(el) {
  var attrs = el.attributes;
  var result = {};
  for (var i = 0; i < attrs.length; i++) {
    result[attrs[i].name] = attrs[i].value;
  }

  return {attributes: result};
}

function getElementProperties(el) {
  var obj = {};

  _.forEach(props, function(propName) {
    if (!el[propName]) {
      return;
    }

    // Special case: style
    // .style is a DOMStyleDeclaration, thus we need to iterate over all
    // rules to create a hash of applied css properties.
    //
    // You can directly set a specific .style[prop] = value so patching with vdom
    // is possible.
    if ('style' == propName) {
      var css = {}
        , styleProp;
      for (var i = 0; i < el.style.length; i++) {
        styleProp = el.style[i];
        css[styleProp] = el.style.getPropertyValue(styleProp); // XXX: add support for '!important' via getPropertyPriority()!
      }

      obj[propName] = css;
      return
    }

    // Special case: dataset
    // we can iterate over .dataset with a simple for..in loop.
    // The all-time foo with data-* attribs is the dash-snake to camelCase
    // conversion.
    // However, I'm not sure if this is compatible with h()
    //
    // .dataset properties are directly accessible as transparent getters/setters, so
    // patching with vdom is possible.
    if ('dataset' == propName) {
      var data = {};
      for (var p in el.dataset) {
        data[p] = el.dataset[p]
      }

      obj[propName] = data;
      return
    }

    // Special case: attributes
    // some properties are only accessible via .attributes, so
    // that's what we'd do, if vdom-create-element could handle this.
    if ('attributes' == propName) {
      return;
    }
    if ('tabIndex' == propName && el.tabIndex === -1) {
      return;
    }

    // default: just copy the property
    obj[propName] = el[propName];
    return;
  });

  return obj
}

function createFromTextNode(tNode) {
  return new VText(tNode.nodeValue);
}

function createFromElement(el, attributesOnly) {
  var tagName = el.tagName;
  var namespace = el.namespaceURI === 'http://www.w3.org/1999/xhtml' ? null : el.namespaceURI;
  var properties = attributesOnly ? getElementAttributes(el) : getElementProperties(el);
  var children = [];

  for (var i = 0; i < el.childNodes.length; i++) {
    children.push(createVNode(el.childNodes[i], attributesOnly));
  }

  var vnode = new VNode(tagName, properties, children, null, namespace);
  return vnode;
}

function createVNode(domNode, attributesOnly) {
  if (domNode.nodeType === 1) {
    return createFromElement(domNode, attributesOnly);
  }
  if (domNode.nodeType === 3) {
    return createFromTextNode(domNode);
  }
}

module.exports = createVNode;
<commit_msg>Add maxlength to whitelisted props<commit_after>/*!
 * Forked from vdom-virtualize@0.5.1 by Marcel Klehr <mklehr@gmx.net>
 *
 * (MIT LICENSE)
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the 'Software'), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
'use strict';

var _ = require('underscore');
var VNode = require('virtual-dom/vnode/vnode');
var VText = require('virtual-dom/vnode/vtext');

/**
 * DOMNode property white list
 * Forked from https://github.com/Raynos/react/blob/dom-property-config/src/browser/ui/dom/DefaultDOMPropertyConfig.js
 */
var props = [
  'accept', 'accessKey', 'action', 'alt', 'async', 'autoComplete', 'autoPlay', 'cellPadding',
  'cellSpacing', 'checked', 'className', 'colSpan', 'content', 'contentEditable', 'controls',
  'crossOrigin', 'data', 'dataset', 'defer', 'dir', 'download', 'draggable', 'encType', 'formNoValidate',
  'href', 'hrefLang', 'htmlFor', 'httpEquiv', 'icon', 'id', 'label', 'lang', 'list', 'loop', 'max', 'maxlength',
  'mediaGroup', 'method', 'min', 'multiple', 'muted', 'name', 'noValidate', 'pattern', 'placeholder',
  'poster', 'preload', 'radioGroup', 'readOnly', 'rel', 'required', 'rowSpan', 'sandbox', 'scope',
  'scrollLeft', 'scrolling', 'scrollTop', 'selected', 'span', 'spellCheck', 'src', 'srcDoc', 'srcSet',
  'start', 'step', 'style', 'tabIndex', 'target', 'title', 'type', 'value',

  // Non-standard Properties
  'autoCapitalize', 'autoCorrect', 'property', 'attributes'
];

function getElementAttributes(el) {
  var attrs = el.attributes;
  var result = {};
  for (var i = 0; i < attrs.length; i++) {
    result[attrs[i].name] = attrs[i].value;
  }

  return {attributes: result};
}

function getElementProperties(el) {
  var obj = {};

  _.forEach(props, function(propName) {
    if (!el[propName]) {
      return;
    }

    // Special case: style
    // .style is a DOMStyleDeclaration, thus we need to iterate over all
    // rules to create a hash of applied css properties.
    //
    // You can directly set a specific .style[prop] = value so patching with vdom
    // is possible.
    if ('style' == propName) {
      var css = {}
        , styleProp;
      for (var i = 0; i < el.style.length; i++) {
        styleProp = el.style[i];
        css[styleProp] = el.style.getPropertyValue(styleProp); // XXX: add support for '!important' via getPropertyPriority()!
      }

      obj[propName] = css;
      return
    }

    // Special case: dataset
    // we can iterate over .dataset with a simple for..in loop.
    // The all-time foo with data-* attribs is the dash-snake to camelCase
    // conversion.
    // However, I'm not sure if this is compatible with h()
    //
    // .dataset properties are directly accessible as transparent getters/setters, so
    // patching with vdom is possible.
    if ('dataset' == propName) {
      var data = {};
      for (var p in el.dataset) {
        data[p] = el.dataset[p]
      }

      obj[propName] = data;
      return
    }

    // Special case: attributes
    // some properties are only accessible via .attributes, so
    // that's what we'd do, if vdom-create-element could handle this.
    if ('attributes' == propName) {
      return;
    }
    if ('tabIndex' == propName && el.tabIndex === -1) {
      return;
    }

    // default: just copy the property
    obj[propName] = el[propName];
    return;
  });

  return obj
}

function createFromTextNode(tNode) {
  return new VText(tNode.nodeValue);
}

function createFromElement(el, attributesOnly) {
  var tagName = el.tagName;
  var namespace = el.namespaceURI === 'http://www.w3.org/1999/xhtml' ? null : el.namespaceURI;
  var properties = attributesOnly ? getElementAttributes(el) : getElementProperties(el);
  var children = [];

  for (var i = 0; i < el.childNodes.length; i++) {
    children.push(createVNode(el.childNodes[i], attributesOnly));
  }

  var vnode = new VNode(tagName, properties, children, null, namespace);
  return vnode;
}

function createVNode(domNode, attributesOnly) {
  if (domNode.nodeType === 1) {
    return createFromElement(domNode, attributesOnly);
  }
  if (domNode.nodeType === 3) {
    return createFromTextNode(domNode);
  }
}

module.exports = createVNode;
<|endoftext|>


<commit_before>import mongoose from "mongoose"

async function createConnection() {
  mongoose.Promise = Promise

  // Don't forget to add a user for this connection
  const connection = await mongoose.connect("mongodb://localhost/twi-test", {
    useMongoClient: true,
    promiseLibrary: Promise
  })

  return connection
}

async function closeConnection() {
  return await mongoose.disconnect()
}

export {
  createConnection,
  closeConnection
}
<commit_msg>Fix db connection in tests helper<commit_after>import mongoose from "mongoose"

async function createConnection() {
  mongoose.Promise = Promise

  // Don't forget to add a user for this connection
  const connection = await mongoose.connect("mongodb://localhost/twi-test", {
    promiseLibrary: Promise
  })

  return connection
}

async function closeConnection() {
  return await mongoose.disconnect()
}

export {
  createConnection,
  closeConnection
}
<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react'
import ReactCSSTransitionGroup from 'react-addons-css-transition-group'

export default class extends Component {

  static propTypes = {
    children: PropTypes.any.isRequired,
    animationEnter: PropTypes.string.isRequired,
    animationLeave: PropTypes.string.isRequired,
    durationEnter: PropTypes.number.isRequired,
    durationLeave: PropTypes.number.isRequired
  };

  render() {
    const { children, animationEnter, animationLeave, durationEnter, durationLeave, ...others } = this.props

    return (


<commit_before>/* global APP */
var EventEmitter = require("events");
var RTCBrowserType = require("./RTCBrowserType");
var RTCUtils = require("./RTCUtils.js");
var LocalStream = require("./LocalStream.js");
var DataChannels = require("./DataChannels");
var MediaStream = require("./MediaStream.js");
var DesktopSharingEventTypes
    = require("../../service/desktopsharing/DesktopSharingEventTypes");
var MediaStreamType = require("../../service/RTC/MediaStreamTypes");
var StreamEventTypes = require("../../service/RTC/StreamEventTypes.js");
var RTCEvents = require("../../service/RTC/RTCEvents.js");
var XMPPEvents = require("../../service/xmpp/XMPPEvents");
var UIEvents = require("../../service/UI/UIEvents");

var eventEmitter = new EventEmitter();

function getMediaStreamUsage()
{
    var result = {
        audio: true,
        video: true
    };

    /** There are some issues with the desktop sharing
     * when this property is enabled.
     * WARNING: We must change the implementation to start video/audio if we
     * receive from the focus that the peer is not muted.

     var isSecureConnection = window.location.protocol == "https:";

    if(config.disableEarlyMediaPermissionRequests || !isSecureConnection)
    {
        result = {
            audio: false,
            video: false
        };

    }
    **/

    return result;
}

var RTC = {
    // Exposes DataChannels to public consumption (e.g. jitsi-meet-torture)
    // without the necessity to require the module.
    "DataChannels": DataChannels,

    rtcUtils: null,
    devices: {
        audio: true,
        video: true
    },
    remoteStreams: {},
    localAudio: null,
    localVideo: null,
    addStreamListener: function (listener, eventType) {
        eventEmitter.on(eventType, listener);
    },
    addListener: function (type, listener) {
        eventEmitter.on(type, listener);
    },
    removeStreamListener: function (listener, eventType) {
        if(!(eventType instanceof StreamEventTypes))
            throw "Illegal argument";

        eventEmitter.removeListener(eventType, listener);
    },
    createLocalStream: function (stream, type, change, videoType,
                                 isMuted, isGUMStream) {

        var localStream =
            new LocalStream(stream, type, eventEmitter, videoType, isGUMStream);
        if(isMuted === true)
            localStream.setMute(true);

        if (MediaStreamType.AUDIO_TYPE === type) {
            this.localAudio = localStream;
        } else {
            this.localVideo = localStream;
        }
        var eventType = StreamEventTypes.EVENT_TYPE_LOCAL_CREATED;
        if(change)
            eventType = StreamEventTypes.EVENT_TYPE_LOCAL_CHANGED;

        eventEmitter.emit(eventType, localStream, isMuted);
        return localStream;
    },
    createRemoteStream: function (data, ssrc) {
        var jid = data.peerjid || APP.xmpp.myJid();

        // check the video muted state from last stored presence if any
        var muted = false;
        var pres = APP.xmpp.getLastPresence(jid);
        if (pres && pres.videoMuted) {
            muted = pres.videoMuted;
        }

        var self = this;
        [MediaStreamType.AUDIO_TYPE, MediaStreamType.VIDEO_TYPE].forEach(
            function (type) {
            var tracks =
                type == MediaStreamType.AUDIO_TYPE
                ? data.stream.getAudioTracks() : data.stream.getVideoTracks();
            if (!tracks || !Array.isArray(tracks) || !tracks.length) {
                console.log("Not creating a(n) " + type + " stream: no tracks");
                return;
            }

            var remoteStream = new MediaStream(data, ssrc,
                RTCBrowserType.getBrowserType(), eventEmitter, muted, type);

            if (!self.remoteStreams[jid]) {
                self.remoteStreams[jid] = {};
            }
            self.remoteStreams[jid][type] = remoteStream;
            eventEmitter.emit(StreamEventTypes.EVENT_TYPE_REMOTE_CREATED,
                remoteStream);
        });
    },
    getPCConstraints: function () {
        return this.rtcUtils.pc_constraints;
    },
    getUserMediaWithConstraints:function(um, success_callback,
                                         failure_callback, resolution,
                                         bandwidth, fps, desktopStream)
    {
        return this.rtcUtils.getUserMediaWithConstraints(um, success_callback,
            failure_callback, resolution, bandwidth, fps, desktopStream);
    },
    attachMediaStream:  function (elSelector, stream) {
        this.rtcUtils.attachMediaStream(elSelector, stream);
    },
    getStreamID:  function (stream) {
        return this.rtcUtils.getStreamID(stream);
    },
    getVideoSrc: function (element) {
        return this.rtcUtils.getVideoSrc(element);
    },
    setVideoSrc: function (element, src) {
        this.rtcUtils.setVideoSrc(element, src);
    },
    getVideoElementName: function () {
        return RTCBrowserType.isTemasysPluginUsed() ? 'object' : 'video';
    },
    dispose: function() {
        if (this.rtcUtils) {
            this.rtcUtils = null;
        }
    },
    stop:  function () {
        this.dispose();
    },
    start: function () {
        var self = this;
        APP.desktopsharing.addListener(
            DesktopSharingEventTypes.NEW_STREAM_CREATED,
            function (stream, isUsingScreenStream, callback) {
                self.changeLocalVideo(stream, isUsingScreenStream, callback);
        });
        APP.xmpp.addListener(XMPPEvents.CALL_INCOMING, function(event) {
            DataChannels.init(event.peerconnection, eventEmitter);
        });
        APP.UI.addListener(UIEvents.SELECTED_ENDPOINT,
            DataChannels.handleSelectedEndpointEvent);
        APP.UI.addListener(UIEvents.PINNED_ENDPOINT,
            DataChannels.handlePinnedEndpointEvent);

        // In case of IE we continue from 'onReady' callback
        // passed to RTCUtils constructor. It will be invoked by Temasys plugin
        // once it is initialized.
        var onReady = function () {
            eventEmitter.emit(RTCEvents.RTC_READY, true);
            self.rtcUtils.obtainAudioAndVideoPermissions(
                null, null, getMediaStreamUsage());
        };

        this.rtcUtils = new RTCUtils(this, eventEmitter, onReady);

        // Call onReady() if Temasys plugin is not used
        if (!RTCBrowserType.isTemasysPluginUsed()) {
            onReady();
        }
    },
    muteRemoteVideoStream: function (jid, value) {
        var stream;

        if(this.remoteStreams[jid] &&
            this.remoteStreams[jid][MediaStreamType.VIDEO_TYPE]) {
            stream = this.remoteStreams[jid][MediaStreamType.VIDEO_TYPE];
        }

        if(!stream)
            return true;

        if (value != stream.muted) {
            stream.setMute(value);
            return true;
        }
        return false;
    },
    changeLocalVideo: function (stream, isUsingScreenStream, callback) {
        var oldStream = this.localVideo.getOriginalStream();
        var type = (isUsingScreenStream ? "screen" : "camera");
        var localCallback = callback;
        if(this.localVideo.isMuted() && this.localVideo.videoType !== type) {
            localCallback = function() {
                APP.xmpp.setVideoMute(false, function(mute) {
                    eventEmitter.emit(RTCEvents.VIDEO_MUTE, mute);
                });

                callback();
            };
        }
        // FIXME: Workaround for FF/IE/Safari
        if (stream && stream.videoStream) {
            stream = stream.videoStream;
        }
        var videoStream = this.rtcUtils.createStream(stream, true);
        this.localVideo =
            this.createLocalStream(videoStream, "video", true, type);
        // Stop the stream
        this.stopMediaStream(oldStream);

        APP.xmpp.switchStreams(videoStream, oldStream,localCallback);
    },
    changeLocalAudio: function (stream, callback) {
        var oldStream = this.localAudio.getOriginalStream();
        var newStream = this.rtcUtils.createStream(stream);
        this.localAudio
            = this.createLocalStream(
                    newStream, MediaStreamType.AUDIO_TYPE, true);
        // Stop the stream
        this.stopMediaStream(oldStream);
        APP.xmpp.switchStreams(newStream, oldStream, callback, true);
    },
    isVideoMuted: function (jid) {
        if (jid === APP.xmpp.myJid()) {
            var localVideo = APP.RTC.localVideo;
            return (!localVideo || localVideo.isMuted());
        } else {
            if (!APP.RTC.remoteStreams[jid] ||
                !APP.RTC.remoteStreams[jid][MediaStreamType.VIDEO_TYPE]) {
                return null;
            }
            return APP.RTC.remoteStreams[jid][MediaStreamType.VIDEO_TYPE].muted;
        }
    },
    setVideoMute: function (mute, callback, options) {
        if (!this.localVideo)
            return;

        if (mute == APP.RTC.localVideo.isMuted())
        {
            APP.xmpp.sendVideoInfoPresence(mute);
            if (callback)
                callback(mute);
        }
        else
        {
            APP.RTC.localVideo.setMute(mute);
            APP.xmpp.setVideoMute(
                mute,
                callback,
                options);
        }
    },
    setDeviceAvailability: function (devices) {
        if(!devices)
            return;
        if(devices.audio === true || devices.audio === false)
            this.devices.audio = devices.audio;
        if(devices.video === true || devices.video === false)
            this.devices.video = devices.video;
        eventEmitter.emit(RTCEvents.AVAILABLE_DEVICES_CHANGED, this.devices);
    },
    /**
     * A method to handle stopping of the stream.
     * One point to handle the differences in various implementations.
     * @param mediaStream MediaStream object to stop.
     */
    stopMediaStream: function (mediaStream) {
        mediaStream.getTracks().forEach(function (track) {
            // stop() not supported with IE
            if (track.stop) {
                track.stop();
            }
        });

        // leave stop for implementation still using it
        if (mediaStream.stop) {
            mediaStream.stop();
        }
    },
    /**
     * Adds onended/inactive handler to a MediaStream.
     * @param mediaStream a MediaStream to attach onended/inactive handler
     * @param handler the handler
     */
    addMediaStreamInactiveHandler: function (mediaStream, handler) {
        if (mediaStream.addEventListener) {
            // chrome
            if(typeof mediaStream.active !== "undefined")
                mediaStream.oninactive = handler;
            else
                mediaStream.onended = handler;
        } else {
            // themasys
            mediaStream.attachEvent('ended', function () {
                handler(mediaStream);
            });
        }
    },
    /**
     * Removes onended/inactive handler.
     * @param mediaStream the MediaStream to remove the handler from.
     * @param handler the handler to remove.
     */
    removeMediaStreamInactiveHandler: function (mediaStream, handler) {
        if (mediaStream.removeEventListener) {
            // chrome
            if(typeof mediaStream.active !== "undefined")
                mediaStream.oninactive = null;
            else
                mediaStream.onended = null;
        } else {
            // themasys
            mediaStream.detachEvent('ended', handler);
        }
    }
};

module.exports = RTC;
<commit_msg>Fixes Uncaught TypeError: mediaStream.detachEvent on stopping desktop sharing.<commit_after>/* global APP */
var EventEmitter = require("events");
var RTCBrowserType = require("./RTCBrowserType");
var RTCUtils = require("./RTCUtils.js");
var LocalStream = require("./LocalStream.js");
var DataChannels = require("./DataChannels");
var MediaStream = require("./MediaStream.js");
var DesktopSharingEventTypes
    = require("../../service/desktopsharing/DesktopSharingEventTypes");
var MediaStreamType = require("../../service/RTC/MediaStreamTypes");
var StreamEventTypes = require("../../service/RTC/StreamEventTypes.js");
var RTCEvents = require("../../service/RTC/RTCEvents.js");
var XMPPEvents = require("../../service/xmpp/XMPPEvents");
var UIEvents = require("../../service/UI/UIEvents");

var eventEmitter = new EventEmitter();

function getMediaStreamUsage()
{
    var result = {
        audio: true,
        video: true
    };

    /** There are some issues with the desktop sharing
     * when this property is enabled.
     * WARNING: We must change the implementation to start video/audio if we
     * receive from the focus that the peer is not muted.

     var isSecureConnection = window.location.protocol == "https:";

    if(config.disableEarlyMediaPermissionRequests || !isSecureConnection)
    {
        result = {
            audio: false,
            video: false
        };

    }
    **/

    return result;
}

var RTC = {
    // Exposes DataChannels to public consumption (e.g. jitsi-meet-torture)
    // without the necessity to require the module.
    "DataChannels": DataChannels,

    rtcUtils: null,
    devices: {
        audio: true,
        video: true
    },
    remoteStreams: {},
    localAudio: null,
    localVideo: null,
    addStreamListener: function (listener, eventType) {
        eventEmitter.on(eventType, listener);
    },
    addListener: function (type, listener) {
        eventEmitter.on(type, listener);
    },
    removeStreamListener: function (listener, eventType) {
        if(!(eventType instanceof StreamEventTypes))
            throw "Illegal argument";

        eventEmitter.removeListener(eventType, listener);
    },
    createLocalStream: function (stream, type, change, videoType,
                                 isMuted, isGUMStream) {

        var localStream =
            new LocalStream(stream, type, eventEmitter, videoType, isGUMStream);
        if(isMuted === true)
            localStream.setMute(true);

        if (MediaStreamType.AUDIO_TYPE === type) {
            this.localAudio = localStream;
        } else {
            this.localVideo = localStream;
        }
        var eventType = StreamEventTypes.EVENT_TYPE_LOCAL_CREATED;
        if(change)
            eventType = StreamEventTypes.EVENT_TYPE_LOCAL_CHANGED;

        eventEmitter.emit(eventType, localStream, isMuted);
        return localStream;
    },
    createRemoteStream: function (data, ssrc) {
        var jid = data.peerjid || APP.xmpp.myJid();

        // check the video muted state from last stored presence if any
        var muted = false;
        var pres = APP.xmpp.getLastPresence(jid);
        if (pres && pres.videoMuted) {
            muted = pres.videoMuted;
        }

        var self = this;
        [MediaStreamType.AUDIO_TYPE, MediaStreamType.VIDEO_TYPE].forEach(
            function (type) {
            var tracks =
                type == MediaStreamType.AUDIO_TYPE
                ? data.stream.getAudioTracks() : data.stream.getVideoTracks();
            if (!tracks || !Array.isArray(tracks) || !tracks.length) {
                console.log("Not creating a(n) " + type + " stream: no tracks");
                return;
            }

            var remoteStream = new MediaStream(data, ssrc,
                RTCBrowserType.getBrowserType(), eventEmitter, muted, type);

            if (!self.remoteStreams[jid]) {
                self.remoteStreams[jid] = {};
            }
            self.remoteStreams[jid][type] = remoteStream;
            eventEmitter.emit(StreamEventTypes.EVENT_TYPE_REMOTE_CREATED,
                remoteStream);
        });
    },
    getPCConstraints: function () {
        return this.rtcUtils.pc_constraints;
    },
    getUserMediaWithConstraints:function(um, success_callback,
                                         failure_callback, resolution,
                                         bandwidth, fps, desktopStream)
    {
        return this.rtcUtils.getUserMediaWithConstraints(um, success_callback,
            failure_callback, resolution, bandwidth, fps, desktopStream);
    },
    attachMediaStream:  function (elSelector, stream) {
        this.rtcUtils.attachMediaStream(elSelector, stream);
    },
    getStreamID:  function (stream) {
        return this.rtcUtils.getStreamID(stream);
    },
    getVideoSrc: function (element) {
        return this.rtcUtils.getVideoSrc(element);
    },
    setVideoSrc: function (element, src) {
        this.rtcUtils.setVideoSrc(element, src);
    },
    getVideoElementName: function () {
        return RTCBrowserType.isTemasysPluginUsed() ? 'object' : 'video';
    },
    dispose: function() {
        if (this.rtcUtils) {
            this.rtcUtils = null;
        }
    },
    stop:  function () {
        this.dispose();
    },
    start: function () {
        var self = this;
        APP.desktopsharing.addListener(
            DesktopSharingEventTypes.NEW_STREAM_CREATED,
            function (stream, isUsingScreenStream, callback) {
                self.changeLocalVideo(stream, isUsingScreenStream, callback);
        });
        APP.xmpp.addListener(XMPPEvents.CALL_INCOMING, function(event) {
            DataChannels.init(event.peerconnection, eventEmitter);
        });
        APP.UI.addListener(UIEvents.SELECTED_ENDPOINT,
            DataChannels.handleSelectedEndpointEvent);
        APP.UI.addListener(UIEvents.PINNED_ENDPOINT,
            DataChannels.handlePinnedEndpointEvent);

        // In case of IE we continue from 'onReady' callback
        // passed to RTCUtils constructor. It will be invoked by Temasys plugin
        // once it is initialized.
        var onReady = function () {
            eventEmitter.emit(RTCEvents.RTC_READY, true);
            self.rtcUtils.obtainAudioAndVideoPermissions(
                null, null, getMediaStreamUsage());
        };

        this.rtcUtils = new RTCUtils(this, eventEmitter, onReady);

        // Call onReady() if Temasys plugin is not used
        if (!RTCBrowserType.isTemasysPluginUsed()) {
            onReady();
        }
    },
    muteRemoteVideoStream: function (jid, value) {
        var stream;

        if(this.remoteStreams[jid] &&
            this.remoteStreams[jid][MediaStreamType.VIDEO_TYPE]) {
            stream = this.remoteStreams[jid][MediaStreamType.VIDEO_TYPE];
        }

        if(!stream)
            return true;

        if (value != stream.muted) {
            stream.setMute(value);
            return true;
        }
        return false;
    },
    changeLocalVideo: function (stream, isUsingScreenStream, callback) {
        var oldStream = this.localVideo.getOriginalStream();
        var type = (isUsingScreenStream ? "screen" : "camera");
        var localCallback = callback;
        if(this.localVideo.isMuted() && this.localVideo.videoType !== type) {
            localCallback = function() {
                APP.xmpp.setVideoMute(false, function(mute) {
                    eventEmitter.emit(RTCEvents.VIDEO_MUTE, mute);
                });

                callback();
            };
        }
        // FIXME: Workaround for FF/IE/Safari
        if (stream && stream.videoStream) {
            stream = stream.videoStream;
        }
        var videoStream = this.rtcUtils.createStream(stream, true);
        this.localVideo =
            this.createLocalStream(videoStream, "video", true, type);
        // Stop the stream
        this.stopMediaStream(oldStream);

        APP.xmpp.switchStreams(videoStream, oldStream,localCallback);
    },
    changeLocalAudio: function (stream, callback) {
        var oldStream = this.localAudio.getOriginalStream();
        var newStream = this.rtcUtils.createStream(stream);
        this.localAudio
            = this.createLocalStream(
                    newStream, MediaStreamType.AUDIO_TYPE, true);
        // Stop the stream
        this.stopMediaStream(oldStream);
        APP.xmpp.switchStreams(newStream, oldStream, callback, true);
    },
    isVideoMuted: function (jid) {
        if (jid === APP.xmpp.myJid()) {
            var localVideo = APP.RTC.localVideo;
            return (!localVideo || localVideo.isMuted());
        } else {
            if (!APP.RTC.remoteStreams[jid] ||
                !APP.RTC.remoteStreams[jid][MediaStreamType.VIDEO_TYPE]) {
                return null;
            }
            return APP.RTC.remoteStreams[jid][MediaStreamType.VIDEO_TYPE].muted;
        }
    },
    setVideoMute: function (mute, callback, options) {
        if (!this.localVideo)
            return;

        if (mute == APP.RTC.localVideo.isMuted())
        {
            APP.xmpp.sendVideoInfoPresence(mute);
            if (callback)
                callback(mute);
        }
        else
        {
            APP.RTC.localVideo.setMute(mute);
            APP.xmpp.setVideoMute(
                mute,
                callback,
                options);
        }
    },
    setDeviceAvailability: function (devices) {
        if(!devices)
            return;
        if(devices.audio === true || devices.audio === false)
            this.devices.audio = devices.audio;
        if(devices.video === true || devices.video === false)
            this.devices.video = devices.video;
        eventEmitter.emit(RTCEvents.AVAILABLE_DEVICES_CHANGED, this.devices);
    },
    /**
     * A method to handle stopping of the stream.
     * One point to handle the differences in various implementations.
     * @param mediaStream MediaStream object to stop.
     */
    stopMediaStream: function (mediaStream) {
        mediaStream.getTracks().forEach(function (track) {
            // stop() not supported with IE
            if (track.stop) {
                track.stop();
            }
        });

        // leave stop for implementation still using it
        if (mediaStream.stop) {
            mediaStream.stop();
        }
    },
    /**
     * Adds onended/inactive handler to a MediaStream.
     * @param mediaStream a MediaStream to attach onended/inactive handler
     * @param handler the handler
     */
    addMediaStreamInactiveHandler: function (mediaStream, handler) {
        if(RTCBrowserType.isTemasysPluginUsed()) {
            // themasys
            mediaStream.attachEvent('ended', function () {
                handler(mediaStream);
            });
        }
        else {
            if(typeof mediaStream.active !== "undefined")
                mediaStream.oninactive = handler;
            else
                mediaStream.onended = handler;
        }
    },
    /**
     * Removes onended/inactive handler.
     * @param mediaStream the MediaStream to remove the handler from.
     * @param handler the handler to remove.
     */
    removeMediaStreamInactiveHandler: function (mediaStream, handler) {
        if(RTCBrowserType.isTemasysPluginUsed()) {
            // themasys
            mediaStream.detachEvent('ended', handler);
        }
        else {
            if(typeof mediaStream.active !== "undefined")
                mediaStream.oninactive = null;
            else
                mediaStream.onended = null;
        }
    }
};

module.exports = RTC;
<|endoftext|>


<commit_before>const request = require("request")

exports.name = "Cat"

exports.regexes = [
	/chats?/i,
	/cats?/i
]

exports.onMessage = (message) => {
	request("http://random.cat/meow",(err,response,body) => {
		if(err){
			message.channel.sendMessage(message.author+" Je n'ai pas pu récupèrer l'image de chat :(")
			return
		}
		var body = JSON.parse(response.body)
		message.channel.sendMessage(message.author+" "+body.file)
	});
}<commit_msg>Minor bugfixes<commit_after>const request = require("request")

exports.name = "Cat"

exports.regexes = [
	/ chats?/i,
	/ cats?/i
]

exports.onMessage = (message) => {
	request("http://random.cat/meow",(err,response,body) => {
		if(err){
			message.channel.sendMessage(message.author+" Je n'ai pas pu récupèrer l'image de chat :(")
			return
		}
		var body = JSON.parse(response.body)
		message.channel.sendMessage(message.author+" "+body.file)
	});
}<|endoftext|>


<commit_before>import {PadColumn} from '@grid/core/column-type';

export default function pin(columns, pin) {
	return columns.filter(c => c.model.pin === pin);
}<commit_msg>fix header layout on pin<commit_after>export default function pin(columns, pin) {
	return columns.filter(c => c.model.pin === pin);
}<|endoftext|>