<commit_before>odoo.define('web.CrashManager', function (require) {
"use strict";

var ajax = require('web.ajax');
var core = require('web.core');
var Dialog = require('web.Dialog');

var QWeb = core.qweb;
var _t = core._t;
var _lt = core._lt;

var map_title ={
    user_error: _lt('Warning'),
    warning: _lt('Warning'),
    access_error: _lt('Access Error'),
    missing_error: _lt('Missing Record'),
    validation_error: _lt('Validation Error'),
    except_orm: _lt('Global Business Error'),
    access_denied: _lt('Access Denied'),
};

var CrashManager = core.Class.extend({
    init: function() {
        this.active = true;
    },
    enable: function () {
        this.active = true;
    },
    disable: function () {
        this.active = false;
    },
    rpc_error: function(error) {
        var self = this;
        if (!this.active) {
            return;
        }
        if (this.connection_lost) {
            return;
        }
        if (error.code == -32098) {
            core.bus.trigger('connection_lost');
            this.connection_lost = true;
            var timeinterval = setInterval(function() {
                ajax.jsonRpc('/web/webclient/version_info').then(function() {
                    clearInterval(timeinterval);
                    core.bus.trigger('connection_restored');
                    self.connection_lost = false;
                });
            }, 2000);
            return;
        }
        var handler = core.crash_registry.get(error.data.name, true);
        if (handler) {
            new (handler)(this, error).display();
            return;
        }
        if (error.data.name === "odoo.http.SessionExpiredException" || error.data.name === "werkzeug.exceptions.Forbidden") {
            this.show_warning({type: "Session Expired", data: { message: _t("Your Odoo session expired. Please refresh the current web page.") }});
            return;
        }
        if (_.has(map_title, error.data.exception_type)) {
            if(error.data.exception_type == 'except_orm'){
                if(error.data.arguments[1]) {
                    error = _.extend({}, error,
                                {
                                    data: _.extend({}, error.data,
                                        {
                                            message: error.data.arguments[1],
                                            title: error.data.arguments[0] !== 'Warning' ? (" - " + error.data.arguments[0]) : '',
                                        })
                                });
                }
                else {
                    error = _.extend({}, error,
                                {
                                    data: _.extend({}, error.data,
                                        {
                                            message: error.data.arguments[0],
                                            title:  '',
                                        })
                                });
                }
            }
            else {
                error = _.extend({}, error,
                            {
                                data: _.extend({}, error.data,
                                    {
                                        message: error.data.arguments[0],
                                        title: map_title[error.data.exception_type] !== 'Warning' ? (" - " + map_title[error.data.exception_type]) : '',
                                    })
                            });
            }

            this.show_warning(error);
        //InternalError

        } else {
            this.show_error(error);
        }
    },
    show_warning: function(error) {
        if (!this.active) {
            return;
        }
        new Dialog(this, {
            size: 'medium',
            title: "Odoo " + (_.str.capitalize(error.type) || _t("Warning")),
            subtitle: error.data.title,
            $content: $('<div>').html(QWeb.render('CrashManager.warning', {error: error}))
        }).open();
    },
    show_error: function(error) {
        if (!this.active) {
            return;
        }
        new Dialog(this, {
            title: "Odoo " + _.str.capitalize(error.type),
            $content: QWeb.render('CrashManager.error', {error: error})
        }).open();
    },
    show_message: function(exception) {
        this.show_error({
            type: _t("Client Error"),
            message: exception,
            data: {debug: ""}
        });
    },
});

/**
    An interface to implement to handle exceptions. Register implementation in instance.web.crash_manager_registry.
*/
var ExceptionHandler = {
    /**
        @param parent The parent.
        @param error The error object as returned by the JSON-RPC implementation.
    */
    init: function(parent, error) {},
    /**
        Called to inform to display the widget, if necessary. A typical way would be to implement
        this interface in a class extending instance.web.Dialog and simply display the dialog in this
        method.
    */
    display: function() {},
};

/**
 * Handle redirection warnings, which behave more or less like a regular
 * warning, with an additional redirection button.
 */
var RedirectWarningHandler = Dialog.extend(ExceptionHandler, {
    init: function(parent, error) {
        this._super(parent);
        this.error = error;
    },
    display: function() {
        var self = this;
        var error = this.error;
        error.data.message = error.data.arguments[0];

        new Dialog(this, {
            size: 'medium',
            title: "Odoo " + (_.str.capitalize(error.type) || "Warning"),
            buttons: [
                {text: error.data.arguments[2], classes : "btn-primary", click: function() {
                    window.location.href = '#action='+error.data.arguments[1];
                    self.destroy();
                }},
                {text: _t("Cancel"), click: function() { self.destroy(); }, close: true}
            ],
            $content: QWeb.render('CrashManager.warning', {error: error}),
        }).open();
    }
});

core.crash_registry.add('odoo.exceptions.RedirectWarning', RedirectWarningHandler);

return CrashManager;
});
<commit_msg>[FIX] web: add exponential backoff strategy for lost connection<commit_after>odoo.define('web.CrashManager', function (require) {
"use strict";

var ajax = require('web.ajax');
var core = require('web.core');
var Dialog = require('web.Dialog');

var QWeb = core.qweb;
var _t = core._t;
var _lt = core._lt;

var map_title ={
    user_error: _lt('Warning'),
    warning: _lt('Warning'),
    access_error: _lt('Access Error'),
    missing_error: _lt('Missing Record'),
    validation_error: _lt('Validation Error'),
    except_orm: _lt('Global Business Error'),
    access_denied: _lt('Access Denied'),
};

var CrashManager = core.Class.extend({
    init: function() {
        this.active = true;
        this.isConnected = true;
    },
    enable: function () {
        this.active = true;
    },
    disable: function () {
        this.active = false;
    },
    handleLostConnection: function () {
        var self = this;
        if (!this.isConnected) {
            // already handled, nothing to do.  This can happen when several
            // rpcs are done in parallel and fail because of a lost connection.
            return;
        }
        this.isConnected = false;
        var delay = 2000;
        core.bus.trigger('connection_lost');

        setTimeout(function checkConnection() {
            ajax.jsonRpc('/web/webclient/version_info', 'call', {}, {shadow:true}).then(function () {
                core.bus.trigger('connection_restored');
                self.isConnected = true;
            }).fail(function () {
                // exponential backoff, with some jitter
                delay = (delay * 1.5) + 500*Math.random();
                setTimeout(checkConnection, delay);
            });
        }, delay);
    },
    rpc_error: function(error) {
        if (!this.active) {
            return;
        }
        if (this.connection_lost) {
            return;
        }
        if (error.code == -32098) {
            this.handleLostConnection();
            return;
        }
        var handler = core.crash_registry.get(error.data.name, true);
        if (handler) {
            new (handler)(this, error).display();
            return;
        }
        if (error.data.name === "odoo.http.SessionExpiredException" || error.data.name === "werkzeug.exceptions.Forbidden") {
            this.show_warning({type: "Session Expired", data: { message: _t("Your Odoo session expired. Please refresh the current web page.") }});
            return;
        }
        if (_.has(map_title, error.data.exception_type)) {
            if(error.data.exception_type == 'except_orm'){
                if(error.data.arguments[1]) {
                    error = _.extend({}, error,
                                {
                                    data: _.extend({}, error.data,
                                        {
                                            message: error.data.arguments[1],
                                            title: error.data.arguments[0] !== 'Warning' ? (" - " + error.data.arguments[0]) : '',
                                        })
                                });
                }
                else {
                    error = _.extend({}, error,
                                {
                                    data: _.extend({}, error.data,
                                        {
                                            message: error.data.arguments[0],
                                            title:  '',
                                        })
                                });
                }
            }
            else {
                error = _.extend({}, error,
                            {
                                data: _.extend({}, error.data,
                                    {
                                        message: error.data.arguments[0],
                                        title: map_title[error.data.exception_type] !== 'Warning' ? (" - " + map_title[error.data.exception_type]) : '',
                                    })
                            });
            }

            this.show_warning(error);
        //InternalError

        } else {
            this.show_error(error);
        }
    },
    show_warning: function(error) {
        if (!this.active) {
            return;
        }
        new Dialog(this, {
            size: 'medium',
            title: "Odoo " + (_.str.capitalize(error.type) || _t("Warning")),
            subtitle: error.data.title,
            $content: $('<div>').html(QWeb.render('CrashManager.warning', {error: error}))
        }).open();
    },
    show_error: function(error) {
        if (!this.active) {
            return;
        }
        new Dialog(this, {
            title: "Odoo " + _.str.capitalize(error.type),
            $content: QWeb.render('CrashManager.error', {error: error})
        }).open();
    },
    show_message: function(exception) {
        this.show_error({
            type: _t("Client Error"),
            message: exception,
            data: {debug: ""}
        });
    },
});

/**
    An interface to implement to handle exceptions. Register implementation in instance.web.crash_manager_registry.
*/
var ExceptionHandler = {
    /**
        @param parent The parent.
        @param error The error object as returned by the JSON-RPC implementation.
    */
    init: function(parent, error) {},
    /**
        Called to inform to display the widget, if necessary. A typical way would be to implement
        this interface in a class extending instance.web.Dialog and simply display the dialog in this
        method.
    */
    display: function() {},
};

/**
 * Handle redirection warnings, which behave more or less like a regular
 * warning, with an additional redirection button.
 */
var RedirectWarningHandler = Dialog.extend(ExceptionHandler, {
    init: function(parent, error) {
        this._super(parent);
        this.error = error;
    },
    display: function() {
        var self = this;
        var error = this.error;
        error.data.message = error.data.arguments[0];

        new Dialog(this, {
            size: 'medium',
            title: "Odoo " + (_.str.capitalize(error.type) || "Warning"),
            buttons: [
                {text: error.data.arguments[2], classes : "btn-primary", click: function() {
                    window.location.href = '#action='+error.data.arguments[1];
                    self.destroy();
                }},
                {text: _t("Cancel"), click: function() { self.destroy(); }, close: true}
            ],
            $content: QWeb.render('CrashManager.warning', {error: error}),
        }).open();
    }
});

core.crash_registry.add('odoo.exceptions.RedirectWarning', RedirectWarningHandler);

return CrashManager;
});
<|endoftext|>


<commit_before>
var _gaq = _gaq || [];  // asynchronous stack used by google analytics

openerp.web_analytics = function(instance) {

    /*
    *  The Web Analytics Module inserts the Google Analytics JS Snippet
    *  at the top of the page, and sends to google an url each time the
    *  openerp url is changed.
    *  The pushes of the urls is made by triggering the 'state_pushed' event in the
    *  web_client.do_push_state() method which is responsible of changing the openerp current url
    */

    // Google Analytics Code snippet
    (function() {
        var ga   = document.createElement('script');
        ga.type  = 'text/javascript';
        ga.async = true;
        ga.src   = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
        var s = document.getElementsByTagName('script')[0];
        s.parentNode.insertBefore(ga,s);
    })();

    instance.web_analytics.Tracker = instance.web.Class.extend({
        /*
        *  This method initializes the tracker
        */
        init: function() {
            /* Comment this lines when going on production, only used for testing on localhost */
            _gaq.push(['_setAccount', 'UA-35793871-1']);
            _gaq.push(['_setDomainName', 'none']);
            /**/

            /* Uncomment this lines when going on production
            _gaq.push(['_setAccount', 'UA-7333765-1']);
            _gaq.push(['_setDomainName', '.openerp.com']);  // Allow multi-domain
            */
        },
        /*
        * This method MUST be overriden by saas_demo and saas_trial in order to
        * set the correct user type. By default, the user connected is local to the DB.
        */
        _get_user_type: function() {
            return 'Local User';
        },
        _set_user_access_level: function() {
            if (instance.session.uid === 1) {
                return 'Admin User';
            // Make the difference between portal users and anonymous users
            } else if (instance.session.username.indexOf('@') !== -1) {
                if (instance.session.username.indexOf('anonymous') === -1) {
                    return 'Portal User';
                } else {
                    return 'Anonymous User';
                }
            } else if (instance.session.username.indexOf('anonymous') !== -1) {
                return 'Anonymous User';
            } else {
                return 'Normal User';
            }
        },
        /*
        * This method contains the initialization of all user-related custom variables
        * stored in GA. Also other modules can override it to add new custom variables
        */
        initialize_custom: function() {
            // Track User Access Level, Custom Variable 4 in GA with visitor level scope
            // Values: 'Admin User', 'Normal User', 'Portal User', 'Anonymous User'
            _gaq.push(['_setCustomVar', 4, 'User Access Level', this.user_access_level, 1]);

            // Track User Type Conversion, Custom Variable 3 in GA with session level scope
            // Values: 'Visitor', 'Demo', 'Online Trial', 'Online Paying', 'Local User'
            _gaq.push(['_setCustomVar', 1, 'User Type Conversion', this._get_user_type(), 2]);

            return instance.session.rpc("/web/webclient/version_info", {})
                .done(function(res) {
                    _gaq.push(['_setCustomVar', 5, 'Version', res.server_version, 3]);
                    return;
                });
        },
        /*
        *  This method contains the initialization of the object and view type
        *  as an event in GA.
        */
        on_state_pushed: function(state) {
            // Track only pages corresponding to a 'normal' view of OpenERP, views
            // related to client actions are tracked by the action manager
            if (state.model && state.view_type) {
                // Track the page
                var label = instance.web_analytics.generateUrl({'model': state.model, 'view_type': state.view_type});
                _gaq.push(['_trackEvent', state.model, state.view_type, label]);
            }
        },
        /*
        * This method includes the tracker into view and managers. It can be overriden
        * by other modules in order to extend tracking functionalities
        */
        include_tracker: function() {
            // Track the events related with the creation and the  modification of records,
            // the view type is always form
            instance.web.FormView.include({
                init: function(parent, dataset, view_id, options) {
                    this._super.apply(this, arguments);
                    var self = this;
                    this.on('record_created', self, function(r) {
                        var url = instance.web_analytics.generateUrl({'model': this.model, 'view_type': 'form'});
                        _gaq.push(['_trackEvent', this.model, 'on_button_create_save', url]);
                    });
                    this.on('record_saved', self, function(r) {
                        var url = instance.web_analytics.generateUrl({'model': this.model, 'view_type': 'form'});
                        _gaq.push(['_trackEvent', this.model, 'on_button_edit_save', url]);
                    });
                }
            });

            // Track client actions
            instance.web.ActionManager.include({
                ir_actions_client: function (action, options) {
                    var label = instance.web_analytics.generateUrl({'action': action.tag});
                    var category = action.res_model || action.type;
                    var ga_action = action.name || action.tag;
                    _gaq.push(['_trackEvent', category, ga_action, label]);
                    return this._super.apply(this, arguments);
                },
            });

            // Track button events
            instance.web.View.include({
                do_execute_action: function(action_data, dataset, record_id, on_closed) {
                    var category = this.model || dataset.model || '';
                    var action;
                    if (action_data.name && _.isNaN(action_data.name-0)) {
                        action = action_data.name;
                    } else {
                        action = action_data.string || action_data.special || '';
                    }
                    var label = instance.web_analytics.generateUrl({'model': category, 'view_type': this.view_type});
                    _gaq.push(['_trackEvent', category, action, label]);
                    return this._super.apply(this, arguments);
                },
            });

            // Track error events
            instance.web.CrashManager.include({
                show_error: function(error) {
                    var hash = window.location.hash;
                    var params = $.deparam(hash.substr(hash.indexOf('#')+1));
                    var options = {};
                    if (params.model && params.view_type) {
                        options = {'model': params.model, 'view_type': params.view_type};
                    } else {
                        options = {'action': params.action};
                    }
                    var label = instance.web_analytics.generateUrl(options);
                    if (error.code) {
                        _gaq.push(['_trackEvent', error.message, error.data.fault_code, label, ,true]);
                    } else {
                        _gaq.push(['_trackEvent', error.type, error.data.debug, label, ,true]);
                    }
                    this._super.apply(this, arguments);
                },
            });
        },
    });

    // ----------------------------------------------------------------
    // utility functions
    // ----------------------------------------------------------------

    instance.web_analytics.generateUrl = function(options) {
        var url = '';
        _.each(options, function(value, key) {
            url += '/' + key + '=' + value;
        });
        return url;
    };

    instance.web_analytics.setupTracker = function(wc) {
        var t = wc.tracker;
        return $.when(t._set_user_access_level()).then(function(r) {
            t.user_access_level = r;
            t.initialize_custom().then(function() {
                wc.on('state_pushed', wc, t.on_state_pushed);
                t.include_tracker();
            });
        });
    };

    // Set correctly the tracker in the current instance
    if (instance.client instanceof instance.web.WebClient) {        // not for embedded clients
        instance.webclient.tracker = new instance.web_analytics.Tracker();
        instance.web_analytics.setupTracker(instance.webclient);
    } else if (!instance.client) {
        // client does not already exists, we are in monodb mode
        instance.web.WebClient.include({
            start: function() {
                var d = this._super.apply(this, arguments);
                this.tracker = new instance.web_analytics.Tracker();
                return d;
            },
            show_application: function() {
                var self = this;
                instance.web_analytics.setupTracker(self).then(function() {
                    self._super();
                });
            },
        });
    }

};
<commit_msg>[IMP] Added _push_ecommerce function to web_analytics.Tracker. Minor naming fix<commit_after>
var _gaq = _gaq || [];  // asynchronous stack used by google analytics

openerp.web_analytics = function(instance) {

    /*
    *  The Web Analytics Module inserts the Google Analytics JS Snippet
    *  at the top of the page, and sends to google an url each time the
    *  openerp url is changed.
    *  The pushes of the urls is made by triggering the 'state_pushed' event in the
    *  web_client.do_push_state() method which is responsible of changing the openerp current url
    */

    // Google Analytics Code snippet
    (function() {
        var ga   = document.createElement('script');
        ga.type  = 'text/javascript';
        ga.async = true;
        ga.src   = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
        var s = document.getElementsByTagName('script')[0];
        s.parentNode.insertBefore(ga,s);
    })();

    instance.web_analytics.Tracker = instance.web.Class.extend({
        /*
        *  This method initializes the tracker
        */
        init: function() {
            /* Comment this lines when going on production, only used for testing on localhost */
            _gaq.push(['_setAccount', 'UA-35793871-1']);
            _gaq.push(['_setDomainName', 'none']);
            /**/

            /* Uncomment this lines when going on production
            _gaq.push(['_setAccount', 'UA-7333765-1']);
            _gaq.push(['_setDomainName', '.openerp.com']);  // Allow multi-domain
            */
        },
        /*
        * This method MUST be overriden by saas_demo and saas_trial in order to
        * set the correct user type. By default, the user connected is local to the DB.
        */
        _get_user_type: function() {
            return 'Local User';
        },
        _get_user_access_level: function() {
            if (instance.session.uid === 1) {
                return 'Admin User';
            // Make the difference between portal users and anonymous users
            } else if (instance.session.username.indexOf('@') !== -1) {
                if (instance.session.username.indexOf('anonymous') === -1) {
                    return 'Portal User';
                } else {
                    return 'Anonymous User';
                }
            } else if (instance.session.username.indexOf('anonymous') !== -1) {
                return 'Anonymous User';
            } else {
                return 'Normal User';
            }
        },
        /*
        * This method contains the initialization of all user-related custom variables
        * stored in GA. Also other modules can override it to add new custom variables
        */
        initialize_custom: function() {
            // Track User Access Level, Custom Variable 4 in GA with visitor level scope
            // Values: 'Admin User', 'Normal User', 'Portal User', 'Anonymous User'
            _gaq.push(['_setCustomVar', 4, 'User Access Level', this.user_access_level, 1]);

            // Track User Type Conversion, Custom Variable 3 in GA with session level scope
            // Values: 'Visitor', 'Demo', 'Online Trial', 'Online Paying', 'Local User'
            _gaq.push(['_setCustomVar', 1, 'User Type Conversion', this._get_user_type(), 2]);

            return instance.session.rpc("/web/webclient/version_info", {})
                .done(function(res) {
                    _gaq.push(['_setCustomVar', 5, 'Version', res.server_version, 3]);
                    return;
                });
        },
        /*
        *  This method contains the initialization of the object and view type
        *  as an event in GA.
        */
        on_state_pushed: function(state) {
            // Track only pages corresponding to a 'normal' view of OpenERP, views
            // related to client actions are tracked by the action manager
            if (state.model && state.view_type) {
                // Track the page
                var label = instance.web_analytics.generateUrl({'model': state.model, 'view_type': state.view_type});
                _gaq.push(['_trackEvent', state.model, state.view_type, label]);
            }
        },
        /*
        * This method includes the tracker into view and managers. It can be overriden
        * by other modules in order to extend tracking functionalities
        */
        include_tracker: function() {
            // Track the events related with the creation and the  modification of records,
            // the view type is always form
            instance.web.FormView.include({
                init: function(parent, dataset, view_id, options) {
                    this._super.apply(this, arguments);
                    var self = this;
                    this.on('record_created', self, function(r) {
                        var url = instance.web_analytics.generateUrl({'model': this.model, 'view_type': 'form'});
                        _gaq.push(['_trackEvent', this.model, 'on_button_create_save', url]);
                    });
                    this.on('record_saved', self, function(r) {
                        var url = instance.web_analytics.generateUrl({'model': this.model, 'view_type': 'form'});
                        _gaq.push(['_trackEvent', this.model, 'on_button_edit_save', url]);
                    });
                }
            });

            // Track client actions
            instance.web.ActionManager.include({
                ir_actions_client: function (action, options) {
                    var label = instance.web_analytics.generateUrl({'action': action.tag});
                    var category = action.res_model || action.type;
                    var ga_action = action.name || action.tag;
                    _gaq.push(['_trackEvent', category, ga_action, label]);
                    return this._super.apply(this, arguments);
                },
            });

            // Track button events
            instance.web.View.include({
                do_execute_action: function(action_data, dataset, record_id, on_closed) {
                    var category = this.model || dataset.model || '';
                    var action;
                    if (action_data.name && _.isNaN(action_data.name-0)) {
                        action = action_data.name;
                    } else {
                        action = action_data.string || action_data.special || '';
                    }
                    var label = instance.web_analytics.generateUrl({'model': category, 'view_type': this.view_type});
                    _gaq.push(['_trackEvent', category, action, label]);
                    return this._super.apply(this, arguments);
                },
            });

            // Track error events
            instance.web.CrashManager.include({
                show_error: function(error) {
                    var hash = window.location.hash;
                    var params = $.deparam(hash.substr(hash.indexOf('#')+1));
                    var options = {};
                    if (params.model && params.view_type) {
                        options = {'model': params.model, 'view_type': params.view_type};
                    } else {
                        options = {'action': params.action};
                    }
                    var label = instance.web_analytics.generateUrl(options);
                    if (error.code) {
                        _gaq.push(['_trackEvent', error.message, error.data.fault_code, label, ,true]);
                    } else {
                        _gaq.push(['_trackEvent', error.type, error.data.debug, label, ,true]);
                    }
                    this._super.apply(this, arguments);
                },
            });
        },
        _push_ecommerce: function(trans_data, item_list) {
            _gaq.push(['_addTrans',
                    trans_data.order_id,
                    trans_data.store_name,
                    trans_data.total,
                    trans_data.tax,
                    trans_data.shipping,
                    trans_data.city,
                    trans_data.state
                    trans_data.country,
            ]);
            _.each(item_list, function(item) {
                _gaq.push(['_addItem',
                    item.order_id,
                    item.sku,
                    item.name,
                    item.category,
                    item.price,
                    item.quantity,
                ]);
            });
            _gaq.push(['_trackTrans']);
        },
    });

    // ----------------------------------------------------------------
    // utility functions
    // ----------------------------------------------------------------

    instance.web_analytics.generateUrl = function(options) {
        var url = '';
        _.each(options, function(value, key) {
            url += '/' + key + '=' + value;
        });
        return url;
    };

    instance.web_analytics.setupTracker = function(wc) {
        var t = wc.tracker;
        return $.when(t._get_user_access_level()).then(function(r) {
            t.user_access_level = r;
            t.initialize_custom().then(function() {
                wc.on('state_pushed', wc, t.on_state_pushed);
                t.include_tracker();
            });
        });
    };

    // Set correctly the tracker in the current instance
    if (instance.client instanceof instance.web.WebClient) {        // not for embedded clients
        instance.webclient.tracker = new instance.web_analytics.Tracker();
        instance.web_analytics.setupTracker(instance.webclient);
    } else if (!instance.client) {
        // client does not already exists, we are in monodb mode
        instance.web.WebClient.include({
            start: function() {
                var d = this._super.apply(this, arguments);
                this.tracker = new instance.web_analytics.Tracker();
                return d;
            },
            show_application: function() {
                var self = this;
                instance.web_analytics.setupTracker(self).then(function() {
                    self._super();
                });
            },
        });
    }

};
<|endoftext|>


<commit_before>'use strict';

var $$item = function(opts) {
  var $opts = opts || {}, $rootScope = angular.element($('html')).scope(),
      $item_class = function(opts, prop) {
        var $opts = opts || {}, $prop = prop || [], i;
        var $parent =
          ($opts.type == 'owner') ?
            function() {return {type: 'owner', id: this.parent_id}}
          : ($opts.type == 'object') ?
              function() {return {type: 'group', id: this.group_id}}
          : ($opts.type == 'group')
            ? function() {
                return (this.parent_id != null)
                  ? {type: 'group', id: this.parent_id}
                  : {type: 'owner', id: this.owner_id}}
            : undefined;
        if (!$opts.type || !$opts.id) return null;
        $prop['type'] = {
          get: function() {return $opts['type'];}
        };
        $prop['parent'] = {
          get: $parent
        };
        $prop['toString'] = {
          get: function() {
            return this.type + '_' + this.id;
          }
        };

        for (i in $prop)
          Object.defineProperty(this, i, $prop[i]);

        for (i in $opts) if (!$prop[i]) this[i] = $opts[i];

        return this;
      };

  if ($opts.type == 'object') {
    return new $item_class($opts, {
      model: {
        get: function() {
          return $rootScope.object.model(this.model_id).title;}
      }
      ,title: {
        get: function() {return this.model + ' ' + this.no;}
      }
    });
  } else {
    return new $item_class($opts);
  }
};

var $directive = function($type, $childs) {
  console.warn($type + ': надо в сервисы/провайдеры перефигачить');
	$.contextMenu({
		selector: 'div[' + $type + ']',
		items: $.contextMenu.fromMenu('menu#' + $type)
	});
  return function($compile, $templateCache) {
    var def = {};

    def.link = function($scope, $element, $attrs) {
      var $obj = {};
      $obj[$type] = $scope.$root.$item({type: $type, id: $attrs[$type]});
      angular.extend($scope, $obj);
      $element.html($scope.$eval($type + '.title'));
      $compile($element.contents())($scope);
    };

    return def;
  }
};

angular.module('skuapso', ['mgcrea.ngStrap', 'skuapso.test'])
.run(function($http, $rootScope, $templateCache, $filter, $modal, $log) {
  var $preload = function(file) {
    var $file = '/static/tpl/' + file.replace(/\./g, '/') + '.tpl.html';
    $log.debug('$http: %o', $http.pendingRequests);
    $http.get($file)
    .success(function(data) {
      $templateCache.put($file, data);
    });
  };
  $preload('skuapso.owner');
  $preload('skuapso.group');
  $preload('skuapso.object');

  $rootScope['callbacks'] = {};
  $rootScope['callbacks']['object'] = {};
  $rootScope['sensor'] = true;
  $rootScope['$scopes'] = {};
  $rootScope['toDateTime'] = new Date();
  $rootScope['fromDateTime'] = new Date();
  $rootScope['fromDateTime'].setDate($rootScope['toDateTime'].getDate() - 1);
  $rootScope['paths'];

  function check_dest(arr, el) {
    if (arr.length == 0) return null;
    var p = arr.shift();
    if (arr.length == 0) {
      if (!el[p]) el[p] = function(i) {
        return el[p].filter(function(ele) {return ele.id == i}).pop();
      }
      p += 's';
      if (!el[p]) el[p] = [];
      return el[p];
    } else {
      if (!el[p]) el[p] = {};
      return check_dest(arr, el[p]);
    }
  };
  check_dest(['owner'], $rootScope);
  check_dest(['group'], $rootScope);
  check_dest(['object'], $rootScope);

  $rootScope['t1'] = {t1: "hello"};
  $rootScope['t2'] = {t: "t2"};
  $rootScope['callbacks']['object']['show_track'] = function($obj) {
    if ($obj.type != 'object') return;
    if (!$rootScope.$item($obj)) return;
    var $from = $filter('date')($rootScope['fromDateTime'], 'psql');
    var $to   = $filter('date')($rootScope['toDateTime'], 'psql');
    var $url = '/object/' + $obj.id + '/track/'
              + $from + '/' + $to;
    if ($rootScope['sensor']) $url += '/sensor/1/>/70';
    $http.get($url).success(function(data) {
      var i, line, lines;
      for (i = 0; i < data.length; i++) {
        line = L.polyline(data[i].track);
        line.bindPopup(data[i].object_id + '
' + data[i].min + '>>' + data[i].max);
        line.addTo(map);
      }
      //          map.fitBounds(lines.getBounds());
    });
  };
  $rootScope['callbacks']['object']['edit'] = function(opts) {
    if (opts.type != 'object') return;
    var object = $rootScope.$item(opts);
    if (!object) return;
    if (!$rootScope.edit) $rootScope.edit = {};
    $rootScope.edit.object = object;
    var modalOpts = {
      template: '/static/tpl/skuapso/object.edit.tpl.html',
      scope: $rootScope,
      show: true
    };
    var modal = $modal(modalOpts);
  };

  $rootScope['$item'] = function(el) {
    return $rootScope[el['type'] + 's'].filter(function(element) {
      return element.id == el['id'];
    })[0];
  };

  $rootScope['$'] = function(el) {
    return $(el && el.type && el.id) ? $('[' + el.type + '="' + el.id +'"]') : undefined;
  };

  $rootScope['$childs'] = function(filter) {
    var i, arr = [], $sub_types = (filter.type == 'owner') ? ['owner', 'group'] :
      (filter.type == 'group') ? ['group', 'object'] : [];

    for (i = 0; i < $sub_types.length; i++) {
      var fun = (filter.type == $sub_types[i])
        ? function(el) {return el.parent_id == filter.id;}
        : function(el) {return (el[filter.type + '_id'] == filter.id) && (el.parent_id == null);};
      arr = arr.concat(this[$sub_types[i] + 's'].filter(fun));
    }
    return arr;
  };

  $rootScope['add'] = function(el) {
    var e = $$item(el), $type, $dest, $str;
    if (e) {
      $type = e.type
        .split('_')
        .filter(function(el) {return el != '';});
      $dest = check_dest($type, $rootScope);

      $dest.push(e);
      if (e.parent) {
        $str = e.parent.type + '_' + e.parent.id;
        $dest = $rootScope.$scopes[$str];
        if ($dest == undefined)
          $dest = $rootScope.$scopes[$str] = new Array();
        $dest.push(e);
      }
    } else $log.error('rejected %o', data[i]);
    if ($rootScope.$loaded) {
      if (e.parent) {
        if ($dest) {
          $rootScope.$scopes[$str] = $filter('orderBy')($dest, 'title');
        }
//        angular.element($rootScope.$(e.parent)).scope().$digest();
      }
    }
  };

  $http.get('/items').success(function(data) {
    var i;
    for (i = 0; i < data.length; i++)
      $rootScope.add(data[i]);
    $rootScope.$loaded = true;
    for (i in $rootScope.$scopes) {
      $rootScope.$scopes[i] = $filter('orderBy')($rootScope.$scopes[i], 'title');
    }
		$('body').fadeIn('slow');
		map.invalidateSize();
  });
})
.filter('is_null', function() {
  return function(input, expression) {
    var out = new Array(), i = 0;
    for (i; input != undefined && i < input.length; i++) {
      if (input[i][expression] == null) {
        out.push(input[i]);
      }
    }
    return out;
  }
})
.directive('management', function() {
  var def = {};
  return def;
})
.directive('list', function($compile) {
  var def = {};

  def.$scope = {collapsed: '@collapsed'};

  def.controller = function($scope, $rootScope, $attrs) {
    var $type = $attrs.list, $id = $attrs.listParentId || null;

    Object.defineProperty($scope, '$childs', {
      get: function() {
        return $rootScope.$scopes[$type + '_' + $id];
      }
    });

    $scope.collapsed = false;

    $scope.$toggle = function() {
      $scope.collapsed = !$scope.collapsed;
    }
  };

  def.compile = function($element, $attrs) {
    var c = {};
    var $type = $attrs.list , $id = $attrs.listParentId;
		var $div = function($t, $i) {
			return '

';
		}

    c['pre'] = function($scope) {
      $element.html('');
      if ($scope.$root.$item({type: $type, id: $id})) {
        $element.append($div($type, $id));
      }
      $compile($element.addClass('list').contents())($scope);
    };

    c['post'] = function($scope) {
      var rebuildChilds = function(newValue, oldValue) {
        var i;
        var $newScope, $newElem;
        var $ul;
        // вероятно можно сделать побыстрее, если не пересоздавать все элементы
        $element.find('>ul').remove();
        if ($scope.$childs != null && $scope.$childs.length > 0 && !$scope.collapsed) {
          $ul = $element.append('

').find('>ul');
          for (i = 0; i < $scope.$childs.length; i++) {
            $type = $scope.$childs[i].type, $id = $scope.$childs[i].id;
            if ($scope.$root.$scopes[$type + '_' + $id]) {
              $newScope = $scope.$new(true);
              $newElem = $compile('

')($newScope);
            } else {
							$newElem = '
' + $div($type, $id) + '
';
              $newElem = $compile($newElem)($scope);
            }
            $newElem.addClass('list-item').addClass($type);
            $ul.append($newElem);
          }
        }
      };

      var toggleChilds = function(newValue, oldValue) {
        if (newValue !== oldValue)
          $element.find('>ul').toggle(100);
        $element.find('>img').attr('src',
            newValue ? '/static/img/button-closed.png' : '/static/img/button-open.png');
      };

      var noChilds = function(newValue, oldValue) {
				var $div, $newElem;
        if (newValue) {
          $element.find('>img').remove();
        } else if($scope.$root.$item({type: $type, id: $id})) {
          $div = $element.find('>div');
          $newElem = ($scope.collapsed) ? 'button-closed.png' : 'button-open.png';
          $newElem = '';
          $element.prepend($compile($newElem)($scope));
        }
      };

      $scope.$watch('$childs', rebuildChilds, angular.equals);
      $scope.$watch('$childs.length==0', noChilds, angular.equals);
      $scope.$watch('collapsed', toggleChilds, angular.equals);
    }

    return c;
  };

  def.link = function($scope, $element, $attrs) {
  };

  return def;
})
.directive('owner', $directive('owner', ['owner', 'group']))
.directive('group', $directive('group', ['group', 'object']))
.directive('object', $directive('object', []))
;
<commit_msg>removed $scope.eval from $directive<commit_after>'use strict';

var $$item = function(opts) {
  var $opts = opts || {}, $rootScope = angular.element($('html')).scope(),
      $item_class = function(opts, prop) {
        var $opts = opts || {}, $prop = prop || [], i;
        var $parent =
          ($opts.type == 'owner') ?
            function() {return {type: 'owner', id: this.parent_id}}
          : ($opts.type == 'object') ?
              function() {return {type: 'group', id: this.group_id}}
          : ($opts.type == 'group')
            ? function() {
                return (this.parent_id != null)
                  ? {type: 'group', id: this.parent_id}
                  : {type: 'owner', id: this.owner_id}}
            : undefined;
        if (!$opts.type || !$opts.id) return null;
        $prop['type'] = {
          get: function() {return $opts['type'];}
        };
        $prop['parent'] = {
          get: $parent
        };
        $prop['toString'] = {
          get: function() {
            return this.type + '_' + this.id;
          }
        };

        for (i in $prop)
          Object.defineProperty(this, i, $prop[i]);

        for (i in $opts) if (!$prop[i]) this[i] = $opts[i];

        return this;
      };

  if ($opts.type == 'object') {
    return new $item_class($opts, {
      model: {
        get: function() {
          return $rootScope.object.model(this.model_id).title;}
      }
      ,title: {
        get: function() {return this.model + ' ' + this.no;}
      }
    });
  } else {
    return new $item_class($opts);
  }
};

var $directive = function($type, $childs) {
  console.warn($type + ': надо в сервисы/провайдеры перефигачить');
	$.contextMenu({
		selector: 'div[' + $type + ']',
		items: $.contextMenu.fromMenu('menu#' + $type)
	});
  return function($compile, $templateCache) {
    var def = {};

    def.link = function($scope, $element, $attrs) {
      var $obj = {};
      $obj[$type] = $scope.$root.$item({type: $type, id: $attrs[$type]});
      angular.extend($scope, $obj);
      $element.html('{{' + $type + '.title}}');
      $compile($element.contents())($scope);
    };

    return def;
  }
};

angular.module('skuapso', ['mgcrea.ngStrap', 'skuapso.test'])
.run(function($http, $rootScope, $templateCache, $filter, $modal, $log) {
  var $preload = function(file) {
    var $file = '/static/tpl/' + file.replace(/\./g, '/') + '.tpl.html';
    $log.debug('$http: %o', $http.pendingRequests);
    $http.get($file)
    .success(function(data) {
      $templateCache.put($file, data);
    });
  };
  $preload('skuapso.owner');
  $preload('skuapso.group');
  $preload('skuapso.object');

  $rootScope['callbacks'] = {};
  $rootScope['callbacks']['object'] = {};
  $rootScope['sensor'] = true;
  $rootScope['$scopes'] = {};
  $rootScope['toDateTime'] = new Date();
  $rootScope['fromDateTime'] = new Date();
  $rootScope['fromDateTime'].setDate($rootScope['toDateTime'].getDate() - 1);
  $rootScope['paths'];

  function check_dest(arr, el) {
    if (arr.length == 0) return null;
    var p = arr.shift();
    if (arr.length == 0) {
      if (!el[p]) el[p] = function(i) {
        return el[p].filter(function(ele) {return ele.id == i}).pop();
      }
      p += 's';
      if (!el[p]) el[p] = [];
      return el[p];
    } else {
      if (!el[p]) el[p] = {};
      return check_dest(arr, el[p]);
    }
  };
  check_dest(['owner'], $rootScope);
  check_dest(['group'], $rootScope);
  check_dest(['object'], $rootScope);

  $rootScope['t1'] = {t1: "hello"};
  $rootScope['t2'] = {t: "t2"};
  $rootScope['callbacks']['object']['show_track'] = function($obj) {
    if ($obj.type != 'object') return;
    if (!$rootScope.$item($obj)) return;
    var $from = $filter('date')($rootScope['fromDateTime'], 'psql');
    var $to   = $filter('date')($rootScope['toDateTime'], 'psql');
    var $url = '/object/' + $obj.id + '/track/'
              + $from + '/' + $to;
    if ($rootScope['sensor']) $url += '/sensor/1/>/70';
    $http.get($url).success(function(data) {
      var i, line, lines;
      for (i = 0; i < data.length; i++) {
        line = L.polyline(data[i].track);
        line.bindPopup(data[i].object_id + '
' + data[i].min + '>>' + data[i].max);
        line.addTo(map);
      }
      //          map.fitBounds(lines.getBounds());
    });
  };
  $rootScope['callbacks']['object']['edit'] = function(opts) {
    if (opts.type != 'object') return;
    var object = $rootScope.$item(opts);
    if (!object) return;
    if (!$rootScope.edit) $rootScope.edit = {};
    $rootScope.edit.object = object;
    var modalOpts = {
      template: '/static/tpl/skuapso/object.edit.tpl.html',
      scope: $rootScope,
      show: true
    };
    var modal = $modal(modalOpts);
  };

  $rootScope['$item'] = function(el) {
    return $rootScope[el['type'] + 's'].filter(function(element) {
      return element.id == el['id'];
    })[0];
  };

  $rootScope['$'] = function(el) {
    return $(el && el.type && el.id) ? $('[' + el.type + '="' + el.id +'"]') : undefined;
  };

  $rootScope['$childs'] = function(filter) {
    var i, arr = [], $sub_types = (filter.type == 'owner') ? ['owner', 'group'] :
      (filter.type == 'group') ? ['group', 'object'] : [];

    for (i = 0; i < $sub_types.length; i++) {
      var fun = (filter.type == $sub_types[i])
        ? function(el) {return el.parent_id == filter.id;}
        : function(el) {return (el[filter.type + '_id'] == filter.id) && (el.parent_id == null);};
      arr = arr.concat(this[$sub_types[i] + 's'].filter(fun));
    }
    return arr;
  };

  $rootScope['add'] = function(el) {
    var e = $$item(el), $type, $dest, $str;
    if (e) {
      $type = e.type
        .split('_')
        .filter(function(el) {return el != '';});
      $dest = check_dest($type, $rootScope);

      $dest.push(e);
      if (e.parent) {
        $str = e.parent.type + '_' + e.parent.id;
        $dest = $rootScope.$scopes[$str];
        if ($dest == undefined)
          $dest = $rootScope.$scopes[$str] = new Array();
        $dest.push(e);
      }
    } else $log.error('rejected %o', data[i]);
    if ($rootScope.$loaded) {
      if (e.parent) {
        if ($dest) {
          $rootScope.$scopes[$str] = $filter('orderBy')($dest, 'title');
        }
//        angular.element($rootScope.$(e.parent)).scope().$digest();
      }
    }
  };

  $http.get('/items').success(function(data) {
    var i;
    for (i = 0; i < data.length; i++)
      $rootScope.add(data[i]);
    $rootScope.$loaded = true;
    for (i in $rootScope.$scopes) {
      $rootScope.$scopes[i] = $filter('orderBy')($rootScope.$scopes[i], 'title');
    }
		$('body').fadeIn('slow');
		map.invalidateSize();
  });
})
.filter('is_null', function() {
  return function(input, expression) {
    var out = new Array(), i = 0;
    for (i; input != undefined && i < input.length; i++) {
      if (input[i][expression] == null) {
        out.push(input[i]);
      }
    }
    return out;
  }
})
.directive('management', function() {
  var def = {};
  return def;
})
.directive('list', function($compile) {
  var def = {};

  def.$scope = {collapsed: '@collapsed'};

  def.controller = function($scope, $rootScope, $attrs) {
    var $type = $attrs.list, $id = $attrs.listParentId || null;

    Object.defineProperty($scope, '$childs', {
      get: function() {
        return $rootScope.$scopes[$type + '_' + $id];
      }
    });

    $scope.collapsed = false;

    $scope.$toggle = function() {
      $scope.collapsed = !$scope.collapsed;
    }
  };

  def.compile = function($element, $attrs) {
    var c = {};
    var $type = $attrs.list , $id = $attrs.listParentId;
		var $div = function($t, $i) {
			return '

';
		}

    c['pre'] = function($scope) {
      $element.html('');
      if ($scope.$root.$item({type: $type, id: $id})) {
        $element.append($div($type, $id));
      }
      $compile($element.addClass('list').contents())($scope);
    };

    c['post'] = function($scope) {
      var rebuildChilds = function(newValue, oldValue) {
        var i;
        var $newScope, $newElem;
        var $ul;
        // вероятно можно сделать побыстрее, если не пересоздавать все элементы
        $element.find('>ul').remove();
        if ($scope.$childs != null && $scope.$childs.length > 0 && !$scope.collapsed) {
          $ul = $element.append('

').find('>ul');
          for (i = 0; i < $scope.$childs.length; i++) {
            $type = $scope.$childs[i].type, $id = $scope.$childs[i].id;
            if ($scope.$root.$scopes[$type + '_' + $id]) {
              $newScope = $scope.$new(true);
              $newElem = $compile('

')($newScope);
            } else {
							$newElem = '
' + $div($type, $id) + '
';
              $newElem = $compile($newElem)($scope);
            }
            $newElem.addClass('list-item').addClass($type);
            $ul.append($newElem);
          }
        }
      };

      var toggleChilds = function(newValue, oldValue) {
        if (newValue !== oldValue)
          $element.find('>ul').toggle(100);
        $element.find('>img').attr('src',
            newValue ? '/static/img/button-closed.png' : '/static/img/button-open.png');
      };

      var noChilds = function(newValue, oldValue) {
				var $div, $newElem;
        if (newValue) {
          $element.find('>img').remove();
        } else if($scope.$root.$item({type: $type, id: $id})) {
          $div = $element.find('>div');
          $newElem = ($scope.collapsed) ? 'button-closed.png' : 'button-open.png';
          $newElem = '';
          $element.prepend($compile($newElem)($scope));
        }
      };

      $scope.$watch('$childs', rebuildChilds, angular.equals);
      $scope.$watch('$childs.length==0', noChilds, angular.equals);
      $scope.$watch('collapsed', toggleChilds, angular.equals);
    }

    return c;
  };

  def.link = function($scope, $element, $attrs) {
  };

  return def;
})
.directive('owner', $directive('owner', ['owner', 'group']))
.directive('group', $directive('group', ['group', 'object']))
.directive('object', $directive('object', []))
;
<|endoftext|>


<commit_before>odoo.define('website_slides.slides_share', function (require) {
'use strict';

var Widget = require('web.Widget');
var sAnimations = require('website.content.snippets.animation');
require('website_slides.slides');

var ShareMail = Widget.extend({
    events: {
        'click button': '_sendMail',
    },

    //--------------------------------------------------------------------------
    // Private
    //--------------------------------------------------------------------------

    /**
     * @private
     */
    _sendMail: function () {
        var self = this;
        var input = this.$('input');
        var slideID = this.$('button').data('slide-id');
        if (input.val() && input[0].checkValidity()) {
            this.$el.removeClass('o_has_error').find('.form-control, .custom-select').removeClass('is-invalid');
            this._rpc({
                route: '/slides/slide/send_share_email',
                params: {
                    slide_id: slideID,
                    email: input.val(),
                },
            }).then(function () {
                self.$el.html($('
Thank you! Mail has been sent.
'));
            });
        } else {
            this.$el.addClass('o_has_error').find('.form-control, .custom-select').addClass('is-invalid');
            input.focus();
        }
    },
});

sAnimations.registry.websiteSlidesShare = sAnimations.Class.extend({
    selector: '#wrapwrap',
    read_events: {
        'click a.o_slides_social_share': '_onSlidesSocialShare',
    },

    /**
     * @override
     * @param {Object} parent
     */
    start: function (parent) {
        var self = this;
        var defs = [this._super.apply(this, arguments)];
        defs.push(new ShareMail(this).attachTo($('.oe_slide_js_share_email')));

        if ($('div#statistic').length) {
            var slideURL = $('div#statistic').attr('slide-url');
            var socialURLs = {
                linkedin: 'https://www.linkedin.com/countserv/count/share?url=',
                twitter: 'https://cdn.api.twitter.com/1/urls/count.json?url=',
                facebook: 'https://graph.facebook.com/?id=',
                gplus: 'https://clients6.google.com/rpc',
            };
        }

        _.each(socialURLs, function (value, key) {
            self._updateStatistics(key, slideURL);
        });

        return $.when.apply($, defs);
    },

    //--------------------------------------------------------------------------
    // Private
    //--------------------------------------------------------------------------

    /**
     * @private
     * @param {string} socialSite
     * @param {string} slide_url
     */
    _updateStatistics: function (socialSite, slideURL) {
        if (socialSite === 'gplus') {
            $.ajax({
                url: this.social_urls['gplus'],
                type: 'POST',
                dataType: 'json',
                contentType: 'application/json',
                data: JSON.stringify([{
                    method: 'pos.plusones.get',
                    id: 'p',
                    params: {
                        nolog: true,
                        id: slideURL,
                        source: 'widget',
                        userId: '@viewer',
                        groupId: '@self'
                    },
                    // TDE NOTE: should there be a key here ?
                    jsonrpc: '2.0',
                    apiVersion: 'v1'
                }]),
                success: function (data) {
                    $('#google-badge').text(data[0].result.metadata.globalCounts.count || 0);
                    $('#total-share').text(parseInt($('#total-share').text()) + parseInt($('#google-badge').text()));
                },
            });
        } else {
            $.ajax({
                url: this.social_urls[socialSite] + slideURL,
                dataType: 'jsonp',
                success: function (data) {
                    var shareCount = (socialSite === 'facebook' ? data.shares : data.count) || 0;
                    $('#' + socialSite + '-badge').text(shareCount);
                    $('#total-share').text(parseInt($('#total-share').text()) + parseInt($('#' + socialSite + '-badge').text()));
                },
            });
        }
    },

    //--------------------------------------------------------------------------
    // Handlers
    //--------------------------------------------------------------------------

    /**
     * @override
     * @param {Object} ev
     */
    _onSlidesSocialShare: function (ev) {
        ev.preventDefault();
        var key = $(ev.currentTarget).attr('social-key');
        var popUpURL = $(ev.currentTarget).attr('href');
        var popUp = window.open(popUpURL, 'Share Dialog', 'width=626,height=436');
        $(window).on('focus', function () {
            if (popUp.closed) {
                this._updateStatistics(key, this.slide_url);
                $(window).off('focus');
            }
        });
    },
});
});
<commit_msg>[FIX] website_slides: fix statistics computation<commit_after>odoo.define('website_slides.slides_share', function (require) {
'use strict';

var Widget = require('web.Widget');
var sAnimations = require('website.content.snippets.animation');
require('website_slides.slides');

var ShareMail = Widget.extend({
    events: {
        'click button': '_sendMail',
    },

    //--------------------------------------------------------------------------
    // Private
    //--------------------------------------------------------------------------

    /**
     * @private
     */
    _sendMail: function () {
        var self = this;
        var input = this.$('input');
        var slideID = this.$('button').data('slide-id');
        if (input.val() && input[0].checkValidity()) {
            this.$el.removeClass('o_has_error').find('.form-control, .custom-select').removeClass('is-invalid');
            this._rpc({
                route: '/slides/slide/send_share_email',
                params: {
                    slide_id: slideID,
                    email: input.val(),
                },
            }).then(function () {
                self.$el.html($('
Thank you! Mail has been sent.
'));
            });
        } else {
            this.$el.addClass('o_has_error').find('.form-control, .custom-select').addClass('is-invalid');
            input.focus();
        }
    },
});

sAnimations.registry.websiteSlidesShare = sAnimations.Class.extend({
    selector: '#wrapwrap',
    read_events: {
        'click a.o_slides_social_share': '_onSlidesSocialShare',
    },

    /**
     * @override
     * @param {Object} parent
     */
    start: function (parent) {
        var self = this;
        var defs = [this._super.apply(this, arguments)];
        defs.push(new ShareMail(this).attachTo($('.oe_slide_js_share_email')));

        if ($('div#statistic').length) {
            this.slideURL = $('div#statistic').attr('slide-url');
            this.socialURLs = {
                linkedin: 'https://www.linkedin.com/countserv/count/share?url=',
                twitter: 'https://cdn.api.twitter.com/1/urls/count.json?url=',
                facebook: 'https://graph.facebook.com/?id=',
                gplus: 'https://clients6.google.com/rpc',
            };
        }

            _.each(this.socialURLs, function (value, key) {
                self._updateStatistics(key, self.slideURL);
            });

        return $.when.apply($, defs);
    },

    //--------------------------------------------------------------------------
    // Private
    //--------------------------------------------------------------------------

    /**
     * @private
     * @param {string} socialSite
     * @param {string} slide_url
     */
    _updateStatistics: function (socialSite, slideURL) {
        var self = this;
        if (socialSite === 'gplus') {
            $.ajax({
                url: self.socialURLs['gplus'],
                type: 'POST',
                dataType: 'json',
                contentType: 'application/json',
                data: JSON.stringify([{
                    method: 'pos.plusones.get',
                    id: 'p',
                    params: {
                        nolog: true,
                        id: slideURL,
                        source: 'widget',
                        userId: '@viewer',
                        groupId: '@self'
                    },
                    // TDE NOTE: should there be a key here ?
                    jsonrpc: '2.0',
                    apiVersion: 'v1'
                }]),
                success: function (data) {
                    $('#google-badge').text(data[0].result.metadata.globalCounts.count || 0);
                    $('#total-share').text(parseInt($('#total-share').text()) + parseInt($('#google-badge').text()));
                },
            });
        } else {
            $.ajax({
                url: self.socialURLs[socialSite] + slideURL,
                dataType: 'jsonp',
                success: function (data) {
                    var shareCount = (socialSite === 'facebook' ? data.shares : data.count) || 0;
                    $('#' + socialSite + '-badge').text(shareCount);
                    $('#total-share').text(parseInt($('#total-share').text()) + parseInt($('#' + socialSite + '-badge').text()));
                },
            });
        }
    },

    //--------------------------------------------------------------------------
    // Handlers
    //--------------------------------------------------------------------------

    /**
     * @override
     * @param {Object} ev
     */
    _onSlidesSocialShare: function (ev) {
        ev.preventDefault();
        var key = $(ev.currentTarget).attr('social-key');
        var popUpURL = $(ev.currentTarget).attr('href');
        var popUp = window.open(popUpURL, 'Share Dialog', 'width=626,height=436');
        $(window).on('focus', function () {
            if (popUp.closed) {
                this._updateStatistics(key, this.slide_url);
                $(window).off('focus');
            }
        });
    },
});
});
<|endoftext|>


<commit_before>import React, {PureComponent, PropTypes} from 'react';
import autobind from 'autobind-decorator';
import KeyValueEditor from '../key-value-editor/editor';
import Editor from '../codemirror/code-editor';
import {trackEvent} from '../../../analytics/index';
import * as allHeaderNames from '../../../datasets/header-names';
import * as allCharsets from '../../../datasets/charsets';
import * as allMimeTypes from '../../../datasets/content-types';
import * as allEncodings from '../../../datasets/encodings';

@autobind
class RequestHeadersEditor extends PureComponent {
  _handleBulkUpdate (headersString) {
    this.props.onChange(this._getHeadersFromString(headersString));
  }

  _handleTrackToggle (pair) {
    trackEvent('Headers Editor', 'Toggle', pair.disabled ? 'Disable' : 'Enable');
  }

  _handleTrackCreate () {
    trackEvent('Headers Editor', 'Create');
  }

  _handleTrackDelete () {
    trackEvent('Headers Editor', 'Delete');
  }

  _getHeadersFromString (headersString) {
    const headers = [];
    const rows = headersString.split(/[\n,]+/);

    for (const row of rows) {
      const items = row.split(':');

      if (items.length !== 2) {
        // Need a colon to be valid
        continue;
      }

      const name = items[0].trim();
      const value = items[1].trim();

      if (!name || !value) {
        // Need name and value to be valid
        continue;
      }

      headers.push({name, value});
    }

    return headers;
  }

  _getHeadersString () {
    const {headers} = this.props;

    let headersString = '';

    for (const header of headers) {
      // Make sure it's not disabled
      if (header.disabled) {
        continue;
      }

      // Make sure it's a valid header (key + value)
      if (!header.name || !header.value) {
        continue;
      }

      headersString += `${header.name}: ${header.value}\n`;
    }

    return headersString;
  }

  _getCommonHeaderValues (pair) {
    switch (pair.name.toLowerCase()) {
      case 'content-type':
      case 'accept':
        return allMimeTypes;
      case 'accept-charset':
        return allCharsets;
      case 'accept-encoding':
        return allEncodings;
      default:
        return [];
    }
  }

  _getCommonHeaderNames (pair) {
    return allHeaderNames;
  }

  render () {
    const {
      bulk,
      headers,
      editorFontSize,
      editorLineWrapping,
      onChange,
      handleRender,
      handleGetRenderContext
    } = this.props;

    return bulk ? (

          <Editor
            getRenderContext={handleGetRenderContext}
            render={handleRender}
            fontSize={editorFontSize}
            lineWrapping={editorLineWrapping}
            onChange={this._handleBulkUpdate}
            defaultValue={this._getHeadersString()}
          />

      ) : (

            <KeyValueEditor
              sortable
              namePlaceholder="My-Header"
              valuePlaceholder="Value"
              pairs={headers}
              handleRender={handleRender}
              handleGetRenderContext={handleGetRenderContext}
              handleGetAutocompleteNameConstants={this._getCommonHeaderNames}
              handleGetAutocompleteValueConstants={this._getCommonHeaderValues}
              onToggleDisable={this._handleTrackToggle}
              onCreate={this._handleTrackCreate}
              onDelete={this._handleTrackDelete}
              onChange={onChange}
            />

      );
  }
}

RequestHeadersEditor.propTypes = {
  onChange: PropTypes.func.isRequired,
  bulk: PropTypes.bool.isRequired,
  editorFontSize: PropTypes.number.isRequired,
  editorLineWrapping: PropTypes.bool.isRequired,
  handleRender: PropTypes.func.isRequired,
  handleGetRenderContext: PropTypes.func.isRequired,
  headers: PropTypes.arrayOf(PropTypes.shape({
    name: PropTypes.string.isRequired,
    value: PropTypes.string.isRequired
  })).isRequired
};

export default RequestHeadersEditor;
<commit_msg>Fixed autocomplete imports (#121)<commit_after>import React, {PureComponent, PropTypes} from 'react';
import autobind from 'autobind-decorator';
import KeyValueEditor from '../key-value-editor/editor';
import Editor from '../codemirror/code-editor';
import {trackEvent} from '../../../analytics/index';
import allHeaderNames from '../../../datasets/header-names';
import allCharsets from '../../../datasets/charsets';
import allMimeTypes from '../../../datasets/content-types';
import allEncodings from '../../../datasets/encodings';

@autobind
class RequestHeadersEditor extends PureComponent {
  _handleBulkUpdate (headersString) {
    this.props.onChange(this._getHeadersFromString(headersString));
  }

  _handleTrackToggle (pair) {
    trackEvent('Headers Editor', 'Toggle', pair.disabled ? 'Disable' : 'Enable');
  }

  _handleTrackCreate () {
    trackEvent('Headers Editor', 'Create');
  }

  _handleTrackDelete () {
    trackEvent('Headers Editor', 'Delete');
  }

  _getHeadersFromString (headersString) {
    const headers = [];
    const rows = headersString.split(/[\n,]+/);

    for (const row of rows) {
      const items = row.split(':');

      if (items.length !== 2) {
        // Need a colon to be valid
        continue;
      }

      const name = items[0].trim();
      const value = items[1].trim();

      if (!name || !value) {
        // Need name and value to be valid
        continue;
      }

      headers.push({name, value});
    }

    return headers;
  }

  _getHeadersString () {
    const {headers} = this.props;

    let headersString = '';

    for (const header of headers) {
      // Make sure it's not disabled
      if (header.disabled) {
        continue;
      }

      // Make sure it's a valid header (key + value)
      if (!header.name || !header.value) {
        continue;
      }

      headersString += `${header.name}: ${header.value}\n`;
    }

    return headersString;
  }

  _getCommonHeaderValues (pair) {
    switch (pair.name.toLowerCase()) {
      case 'content-type':
      case 'accept':
        return allMimeTypes;
      case 'accept-charset':
        return allCharsets;
      case 'accept-encoding':
        return allEncodings;
      default:
        return [];
    }
  }

  _getCommonHeaderNames (pair) {
    return allHeaderNames;
  }

  render () {
    const {
      bulk,
      headers,
      editorFontSize,
      editorLineWrapping,
      onChange,
      handleRender,
      handleGetRenderContext
    } = this.props;

    return bulk ? (

          <Editor
            getRenderContext={handleGetRenderContext}
            render={handleRender}
            fontSize={editorFontSize}
            lineWrapping={editorLineWrapping}
            onChange={this._handleBulkUpdate}
            defaultValue={this._getHeadersString()}
          />

      ) : (

            <KeyValueEditor
              sortable
              namePlaceholder="My-Header"
              valuePlaceholder="Value"
              pairs={headers}
              handleRender={handleRender}
              handleGetRenderContext={handleGetRenderContext}
              handleGetAutocompleteNameConstants={this._getCommonHeaderNames}
              handleGetAutocompleteValueConstants={this._getCommonHeaderValues}
              onToggleDisable={this._handleTrackToggle}
              onCreate={this._handleTrackCreate}
              onDelete={this._handleTrackDelete}
              onChange={onChange}
            />

      );
  }
}

RequestHeadersEditor.propTypes = {
  onChange: PropTypes.func.isRequired,
  bulk: PropTypes.bool.isRequired,
  editorFontSize: PropTypes.number.isRequired,
  editorLineWrapping: PropTypes.bool.isRequired,
  handleRender: PropTypes.func.isRequired,
  handleGetRenderContext: PropTypes.func.isRequired,
  headers: PropTypes.arrayOf(PropTypes.shape({
    name: PropTypes.string.isRequired,
    value: PropTypes.string.isRequired
  })).isRequired
};

export default RequestHeadersEditor;
<|endoftext|>


<commit_before>/*
 * #%L
 * AEM Chrome Plug-in
 * %%
 * Copyright (C) 2016 Adobe
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

(function(){
    var s = document.createElement('script');
    s.src = chrome.extension.getURL('aem-chrome-plugin--adaptive-form--custom-script.js');
    (document.head || document.documentElement).appendChild(s);

    window.addEventListener('af-editor-loaded.afPlugin', function () {
        chrome.runtime.sendMessage({url: window.location.href, action: "af-editor-loaded"}, function (response) {
            console.log(response);
        });
    });
})();
<commit_msg>Reduce console.log clutter<commit_after>/*
 * #%L
 * AEM Chrome Plug-in
 * %%
 * Copyright (C) 2016 Adobe
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

(function(){
    var s = document.createElement('script');
    s.src = chrome.extension.getURL('aem-chrome-plugin--adaptive-form--custom-script.js');
    (document.head || document.documentElement).appendChild(s);

    window.addEventListener('af-editor-loaded.afPlugin', function () {
        chrome.runtime.sendMessage({url: window.location.href, action: "af-editor-loaded"}, function (response) {
            // Reduce console.log clutter
            // console.log(response);
        });
    });
})();
<|endoftext|>


<commit_before>"use strict";

const utils = require("./utils.js");
const Visitor = require("./visitor.js");

class AssignmentVisitor extends Visitor {
  reset(rootPath, options) {
    this.exportedLocalNames = options.exportedLocalNames;
    this.magicString = options.magicString;
    this.modifyAST = !! options.modifyAST;
    this.moduleAlias = options.moduleAlias;

    if (this.exportedLocalNames === void 0) {
      this.exportedLocalNames = Object.create(null);
    }

    if (this.magicString === void 0) {
      this.magicString = null;
    }
  }

  visitAssignmentExpression(path) {
    return assignmentHelper(this, path, "left");
  }

  visitCallExpression(path) {
    this.visitChildren(path);

    const callee = path.getValue().callee;
    if (callee.type === "Identifier" &&
        callee.name === "eval") {
      wrap(this, path);
    }
  }

  visitUpdateExpression(path) {
    return assignmentHelper(this, path, "argument");
  }
};

function assignmentHelper(visitor, path, childName) {
  visitor.visitChildren(path);

  const child = path.getValue()[childName];
  const assignedNames = utils.getNamesFromPattern(child);
  const nameCount = assignedNames.length;

  // Wrap assignments to exported identifiers with `module.runSetters`.
  for (let i = 0; i < nameCount; ++i) {
    if (visitor.exportedLocalNames[assignedNames[i]] === true) {
      wrap(visitor, path);
      break;
    }
  }
}

function wrap(visitor, path) {
  const value = path.getValue();

  if (visitor.magicString !== null) {
    visitor.magicString.prependRight(
      value.start,
      visitor.moduleAlias + ".runSetters("
    ).appendLeft(value.end, ")");
  }

  if (visitor.modifyAST) {
    path.replace({
      type: "CallExpression",
      callee: {
        type: "MemberExpression",
        object: {
          type: "Identifier",
          name: "module"
        },
        property: {
          type: "Identifier",
          name: "runSetters"
        }
      },
      arguments: [value]
    });
  }
}

module.exports = AssignmentVisitor;
<commit_msg>Also use possibleIndexes to guide AssignmentVisitor traversal.<commit_after>"use strict";

const utils = require("./utils.js");
const Visitor = require("./visitor.js");

class AssignmentVisitor extends Visitor {
  reset(rootPath, options) {
    this.exportedLocalNames = options.exportedLocalNames;
    this.magicString = options.magicString;
    this.modifyAST = !! options.modifyAST;
    this.moduleAlias = options.moduleAlias;

    if (this.exportedLocalNames === void 0) {
      this.exportedLocalNames = Object.create(null);
    }

    if (this.magicString === void 0) {
      this.magicString = null;
    }

    if (this.magicString) {
      const identifiers = Object.keys(this.exportedLocalNames);

      // In addition to any exported local identifiers, this visitor needs
      // to visit `eval(...)` expressions, so it's important to search for
      // any possible indexes of the `eval` identifier, too.
      identifiers.push("eval");

      // When this.possibleIndexes is defined, the AST traversal can
      // abandon any subtrees that do not contain any possible indexes.
      this.possibleIndexes = utils.findPossibleIndexes(
        this.magicString.original,
        identifiers
      );
    }
  }

  visitAssignmentExpression(path) {
    return assignmentHelper(this, path, "left");
  }

  visitCallExpression(path) {
    this.visitChildren(path);

    const callee = path.getValue().callee;
    if (callee.type === "Identifier" &&
        callee.name === "eval") {
      wrap(this, path);
    }
  }

  visitUpdateExpression(path) {
    return assignmentHelper(this, path, "argument");
  }
};

function assignmentHelper(visitor, path, childName) {
  visitor.visitChildren(path);

  const child = path.getValue()[childName];
  const assignedNames = utils.getNamesFromPattern(child);
  const nameCount = assignedNames.length;

  // Wrap assignments to exported identifiers with `module.runSetters`.
  for (let i = 0; i < nameCount; ++i) {
    if (visitor.exportedLocalNames[assignedNames[i]] === true) {
      wrap(visitor, path);
      break;
    }
  }
}

function wrap(visitor, path) {
  const value = path.getValue();

  if (visitor.magicString !== null) {
    visitor.magicString.prependRight(
      value.start,
      visitor.moduleAlias + ".runSetters("
    ).appendLeft(value.end, ")");
  }

  if (visitor.modifyAST) {
    path.replace({
      type: "CallExpression",
      callee: {
        type: "MemberExpression",
        object: {
          type: "Identifier",
          name: "module"
        },
        property: {
          type: "Identifier",
          name: "runSetters"
        }
      },
      arguments: [value]
    });
  }
}

module.exports = AssignmentVisitor;
<|endoftext|>


<commit_before>/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with this
 * work for additional information regarding copyright ownership. The ASF
 * licenses this file to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

var App = require('app');
var date = require('utils/date');
var numberUtils = require('utils/number_utils');

App.MainDashboardServiceYARNView = App.MainDashboardServiceView.extend({
  templateName: require('templates/main/dashboard/service/yarn'),
  serviceName: 'YARN',

  nodeHeap: function () {
    var memUsed = this.get('service').get('jvmMemoryHeapUsed');
    var memCommitted = this.get('service').get('jvmMemoryHeapCommitted');
    var percent = memCommitted > 0 ? ((100 * memUsed) / memCommitted) : 0;
    return this.t('dashboard.services.hdfs.nodes.heapUsed').format(
        numberUtils.bytesToSize(memUsed, 1, 'parseFloat', 1024 * 1024),
        numberUtils.bytesToSize(memCommitted, 1, 'parseFloat', 1024 * 1024),
        percent.toFixed(1));

  }.property('service.jvmMemoryHeapUsed', 'service.jvmMemoryHeapCommitted'),

  summaryHeader: function () {
    var text = this.t("dashboard.services.yarn.summary");
    var svc = this.get('service');
    var totalCount = svc.get('nodeManagerNodes').get('length');
    return text.format(totalCount, totalCount);
  }.property('service.nodeManagerNodes'),

  nodeManagerComponent: function () {
    return App.HostComponent.find().findProperty('componentName', 'NODEMANAGER');
  }.property(),

  yarnClientComponent: function () {
    return App.HostComponent.find().findProperty('componentName', 'YARN_CLIENT');
  }.property(),

  hasManyYarnClients: function () {
    if(this.get('service.yarnClientNodes') > 1){
      return true;
    }else{
      return false;
    }
  }.property('service.yarnClientNodes'),

  nodeUptime: function () {
    var uptime = this.get('service').get('resourceManagerStartTime');
    if (uptime && uptime > 0){
      var diff = (new Date()).getTime() - uptime;
      if (diff < 0) {
        diff = 0;
      }
      var formatted = date.timingFormat(diff);
      return this.t('dashboard.services.uptime').format(formatted);
    }
    return this.t('services.service.summary.notRunning');
  }.property("service.resourceManagerStartTime"),

  nodeManagersLive: function () {
    return this.get('service.nodeManagerLiveNodes.length');
  }.property('service.nodeManagerNodes', 'service.nodeManagerLiveNodes'),

  nodeManagerText: function () {
    if(this.get("service.nodeManagerNodes") > 1){
      return Em.I18n.t('services.service.summary.viewHosts');
    }else{
      return Em.I18n.t('services.service.summary.viewHost');
    }
  }.property("service.nodeManagerNodes"),

  nodeManagersLiveTextView: App.ComponentLiveTextView.extend({
    liveComponents: function() {
      return this.get("service.nodeManagerLiveNodes.length");
    }.property('service.nodeManagerNodes', 'service.nodeManagerLiveNodes', 'service.nodeManagerLiveNodes.length'),
    totalComponents: function() {
      return this.get("service.nodeManagerNodes.length");
    }.property("service.nodeManagerNodes.length")
  }),

  nodeManagersStatus: function () {
    var nmActive = this.get('service.nodeManagersCountActive');
    var nmLost = this.get('service.nodeManagersCountLost');
    var nmUnhealthy = this.get('service.nodeManagersCountUnhealthy');
    var nmRebooted = this.get('service.nodeManagersCountRebooted');
    var nmDecom = this.get('service.nodeManagersCountDecommissioned');
    return this.t('dashboard.services.yarn.nodeManagers.status.msg').format(nmActive, nmLost, nmUnhealthy, nmRebooted, nmDecom);
  }.property('service.nodeManagersCountActive', 'service.nodeManagersCountLost',
      'service.nodeManagersCountUnhealthy', 'service.nodeManagersCountRebooted', 'service.nodeManagersCountDecommissioned'),

  containers: function () {
    var allocated = this.get('service.containersAllocated');
    var pending = this.get('service.containersPending');
    var reserved = this.get('service.containersReserved');
    return this.t('dashboard.services.yarn.containers.msg').format(allocated, pending, reserved);
  }.property('service.containersAllocated', 'service.containersPending', 'service.containersReserved'),

  apps: function () {
    var appsSubmitted = this.get('service.appsSubmitted');
    var appsRunning = this.get('service.appsRunning');
    var appsPending = this.get('service.appsPending');
    var appsCompleted = this.get('service.appsCompleted');
    var appsKilled = this.get('service.appsKilled');
    var appsFailed = this.get('service.appsFailed');
    return this.t('dashboard.services.yarn.apps.msg').format(appsSubmitted, appsRunning, appsPending, appsCompleted, appsKilled, appsFailed);
  }.property('service.appsSubmitted', 'service.appsRunning', 'service.appsPending', 'service.appsCompleted', 'service.appsKilled', 'service.appsFailed'),

  memory: function () {
    return Em.I18n.t('dashboard.services.yarn.memory.msg').format(
        numberUtils.bytesToSize(this.get('service.allocatedMemory'), 1, 'parseFloat', 1024 * 1024),
        numberUtils.bytesToSize(this.get('service.reservedMemory'), 1, 'parseFloat', 1024 * 1024),
        numberUtils.bytesToSize(this.get('service.availableMemory'), 1, 'parseFloat', 1024 * 1024));
  }.property('service.allocatedMemory', 'service.reservedMemory', 'service.availableMemory'),

  queues: function() {
    return Em.I18n.t('dashboard.services.yarn.queues.msg').format(this.get('service.queuesCount'));
  }.property('service.queuesCount'),

  didInsertElement: function(){
    $("[rel='queue-tooltip']").tooltip({html: true, placement: "right"});
  }

});
<commit_msg>AMBARI-2912. YARN summary values show up as null when service stopped. (onechiporenko via yusaku)<commit_after>/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with this
 * work for additional information regarding copyright ownership. The ASF
 * licenses this file to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

var App = require('app');
var date = require('utils/date');
var numberUtils = require('utils/number_utils');

App.MainDashboardServiceYARNView = App.MainDashboardServiceView.extend({
  templateName: require('templates/main/dashboard/service/yarn'),
  serviceName: 'YARN',

  nodeHeap: function () {
    var memUsed = this.get('service').get('jvmMemoryHeapUsed');
    var memCommitted = this.get('service').get('jvmMemoryHeapCommitted');
    var percent = memCommitted > 0 ? ((100 * memUsed) / memCommitted) : 0;
    return this.t('dashboard.services.hdfs.nodes.heapUsed').format(
        numberUtils.bytesToSize(memUsed, 1, 'parseFloat', 1024 * 1024),
        numberUtils.bytesToSize(memCommitted, 1, 'parseFloat', 1024 * 1024),
        percent.toFixed(1));

  }.property('service.jvmMemoryHeapUsed', 'service.jvmMemoryHeapCommitted'),

  summaryHeader: function () {
    var text = this.t("dashboard.services.yarn.summary");
    var svc = this.get('service');
    var totalCount = svc.get('nodeManagerNodes').get('length');
    return text.format(totalCount, totalCount);
  }.property('service.nodeManagerNodes'),

  nodeManagerComponent: function () {
    return App.HostComponent.find().findProperty('componentName', 'NODEMANAGER');
  }.property(),

  yarnClientComponent: function () {
    return App.HostComponent.find().findProperty('componentName', 'YARN_CLIENT');
  }.property(),

  hasManyYarnClients: function () {
    return (this.get('service.yarnClientNodes') > 1);
  }.property('service.yarnClientNodes'),

  nodeUptime: function () {
    var uptime = this.get('service').get('resourceManagerStartTime');
    if (uptime && uptime > 0){
      var diff = (new Date()).getTime() - uptime;
      if (diff < 0) {
        diff = 0;
      }
      var formatted = date.timingFormat(diff);
      return this.t('dashboard.services.uptime').format(formatted);
    }
    return this.t('services.service.summary.notRunning');
  }.property("service.resourceManagerStartTime"),

  nodeManagersLive: function () {
    return this.get('service.nodeManagerLiveNodes.length');
  }.property('service.nodeManagerNodes', 'service.nodeManagerLiveNodes'),

  nodeManagerText: function () {
    if(this.get("service.nodeManagerNodes") > 1){
      return Em.I18n.t('services.service.summary.viewHosts');
    }else{
      return Em.I18n.t('services.service.summary.viewHost');
    }
  }.property("service.nodeManagerNodes"),

  nodeManagersLiveTextView: App.ComponentLiveTextView.extend({
    liveComponents: function() {
      return this.get("service.nodeManagerLiveNodes.length");
    }.property('service.nodeManagerNodes', 'service.nodeManagerLiveNodes', 'service.nodeManagerLiveNodes.length'),
    totalComponents: function() {
      return this.get("service.nodeManagerNodes.length");
    }.property("service.nodeManagerNodes.length")
  }),

  nodeManagersStatus: function () {
    var nmActive = this.get('service.nodeManagersCountActive');
    var nmLost = this.get('service.nodeManagersCountLost');
    var nmUnhealthy = this.get('service.nodeManagersCountUnhealthy');
    var nmRebooted = this.get('service.nodeManagersCountRebooted');
    var nmDecom = this.get('service.nodeManagersCountDecommissioned');
    return this.t('dashboard.services.yarn.nodeManagers.status.msg').format(
      this.formatUnavailable(nmActive),
      this.formatUnavailable(nmLost),
      this.formatUnavailable(nmUnhealthy),
      this.formatUnavailable(nmRebooted),
      this.formatUnavailable(nmDecom)
    );
  }.property('service.nodeManagersCountActive', 'service.nodeManagersCountLost',
      'service.nodeManagersCountUnhealthy', 'service.nodeManagersCountRebooted', 'service.nodeManagersCountDecommissioned'),

  containers: function () {
    var allocated = this.get('service.containersAllocated');
    var pending = this.get('service.containersPending');
    var reserved = this.get('service.containersReserved');
    return this.t('dashboard.services.yarn.containers.msg').format(
      this.formatUnavailable(allocated),
      this.formatUnavailable(pending),
      this.formatUnavailable(reserved)
    );
  }.property('service.containersAllocated', 'service.containersPending', 'service.containersReserved'),

  apps: function () {
    var appsSubmitted = this.get('service.appsSubmitted');
    var appsRunning = this.get('service.appsRunning');
    var appsPending = this.get('service.appsPending');
    var appsCompleted = this.get('service.appsCompleted');
    var appsKilled = this.get('service.appsKilled');
    var appsFailed = this.get('service.appsFailed');
    return this.t('dashboard.services.yarn.apps.msg').format(
      this.formatUnavailable(appsSubmitted),
      this.formatUnavailable(appsRunning),
      this.formatUnavailable(appsPending),
      this.formatUnavailable(appsCompleted),
      this.formatUnavailable(appsKilled),
      this.formatUnavailable(appsFailed));
  }.property('service.appsSubmitted', 'service.appsRunning', 'service.appsPending', 'service.appsCompleted', 'service.appsKilled', 'service.appsFailed'),

  memory: function () {
    return Em.I18n.t('dashboard.services.yarn.memory.msg').format(
        numberUtils.bytesToSize(this.get('service.allocatedMemory'), 1, 'parseFloat', 1024 * 1024),
        numberUtils.bytesToSize(this.get('service.reservedMemory'), 1, 'parseFloat', 1024 * 1024),
        numberUtils.bytesToSize(this.get('service.availableMemory'), 1, 'parseFloat', 1024 * 1024));
  }.property('service.allocatedMemory', 'service.reservedMemory', 'service.availableMemory'),

  queues: function() {
    return Em.I18n.t('dashboard.services.yarn.queues.msg').format(this.formatUnavailable(this.get('service.queuesCount')));
  }.property('service.queuesCount'),

  didInsertElement: function(){
    $("[rel='queue-tooltip']").tooltip({html: true, placement: "right"});
  }

});
<|endoftext|>


<commit_before>var socket = io();

socket.on('lightStatus', function(data) {
  if (data=="on") {
    $("#lights").css("background","yellow");
     $("#lights").css("color","#666666");
     $("#lights").css("border-style","solid");
  } else {
    $("#lights").css("background","#666666");
     $("#lights").css("color","white");
     $("#lights").css("border-style","none");
  }

});

socket.on('news', function (data) {
	alert (data.width+"x"+data.height)
});

socket.on('liveStream', function(url) {
  var stream = document.getElementById('stream');
  stream.src=url;
  //alert(url)
});

function sendCommand(c,x) {
  if (c=="t") {
    x=x-50
    document.getElementById("thrust_out").innerHTML = "Thrust: "+x;
  }
  if (c=="v") {
    x=Math.round(x*50);
    document.getElementById("vert_out").innerHTML = "Vertical: "+x;
  }
  if (c=="r") {
    x=Math.round(x*50);
    document.getElementById("rotate_out").innerHTML = "Rotate: "+x;
  }
  socket.emit(c,x);

}

window.addEventListener("load", function(){
  var StartStreamButton = document.getElementById('StartStreamButton');
  var StopButton = document.getElementById('StopButton');
  var LightButton = document.getElementById('lights');
  StopButton.addEventListener('click', function() {
    document.getElementById('thrust').value=50;
    sendCommand('t',50);
  });
  LightButton.addEventListener('click', function() {
    sendCommand('l','toggle');
  });

  StartStreamButton.addEventListener('click', function() {
    var sW = document.getElementById("streamcontainer").offsetWidth
    var sH = document.getElementById("streamcontainer").offsetHeight
    socket.emit('start-stream', { width : sW, height : sH });
  });
  var joystickView = new JoystickView(150, function(callbackView){
      $("#joystickContent").append(callbackView.render().el);
      setTimeout(function(){
          callbackView.renderSprite();
      }, 0);
  });
  joystickView.bind("verticalMove", function(y){
      $("#yVal").html(y);
      //Call Socket.io function to emit vertical move y
      sendCommand("v",y);
  });
  joystickView.bind("horizontalMove", function(x){
      $("#xVal").html(x);
      //Call Socket.io function to emit horizontal move x
      sendCommand("r",x);
  });

});
<commit_msg>test to see if stream output is present<commit_after>var socket = io();

socket.on('lightStatus', function(data) {
  if (data=="on") {
    $("#lights").css("background","yellow");
     $("#lights").css("color","#666666");
     $("#lights").css("border-style","solid");
  } else {
    $("#lights").css("background","#666666");
     $("#lights").css("color","white");
     $("#lights").css("border-style","none");
  }

});

socket.on('news', function (data) {
	alert (data.width+"x"+data.height)
});

socket.on('liveStream', function(Stream_url) {
  $.ajax({
      url:Stream_url,
      type:'HEAD',
      error: function()
      {
          alert("no file yet")
      },
      success: function()
      {
          alert("file exists")
          var stream = document.getElementById('stream');
          stream.src=Stream_url;
      }
  });
  //alert(url)
});

function sendCommand(c,x) {
  if (c=="t") {
    x=x-50
    document.getElementById("thrust_out").innerHTML = "Thrust: "+x;
  }
  if (c=="v") {
    x=Math.round(x*50);
    document.getElementById("vert_out").innerHTML = "Vertical: "+x;
  }
  if (c=="r") {
    x=Math.round(x*50);
    document.getElementById("rotate_out").innerHTML = "Rotate: "+x;
  }
  socket.emit(c,x);

}

window.addEventListener("load", function(){
  var StartStreamButton = document.getElementById('StartStreamButton');
  var StopButton = document.getElementById('StopButton');
  var LightButton = document.getElementById('lights');
  StopButton.addEventListener('click', function() {
    document.getElementById('thrust').value=50;
    sendCommand('t',50);
  });
  LightButton.addEventListener('click', function() {
    sendCommand('l','toggle');
  });

  StartStreamButton.addEventListener('click', function() {
    var sW = document.getElementById("streamcontainer").offsetWidth
    var sH = document.getElementById("streamcontainer").offsetHeight
    socket.emit('start-stream', { width : sW, height : sH });
  });
  var joystickView = new JoystickView(150, function(callbackView){
      $("#joystickContent").append(callbackView.render().el);
      setTimeout(function(){
          callbackView.renderSprite();
      }, 0);
  });
  joystickView.bind("verticalMove", function(y){
      $("#yVal").html(y);
      //Call Socket.io function to emit vertical move y
      sendCommand("v",y);
  });
  joystickView.bind("horizontalMove", function(x){
      $("#xVal").html(x);
      //Call Socket.io function to emit horizontal move x
      sendCommand("r",x);
  });

});
<|endoftext|>


<commit_before>(function () {
    "use strict";
    var Tornado = function(cities,windGust,type) {
        this.cities = cities;
        this.windGust = windGust;
        this.type = type;
    };

    var cities = [["New York", 1234], ["California", 234]];
    var katrina = new Tornado(cities, '120mph', 'F12');

    console.log("Tornado "+ katrina);

    Tornado.prototype.valueOf = function () {
        var sum = 0;
        for(var i=0; i <= this.cities.length-1; i++) {
            console.log("..."+ cities);
            sum += this.cities[i][1];
        }
        return sum;
    }

    var twister = new Tornado(cities, '34mph', 'F23');
    cities.push(["London", 2000]);
    console.log("Tornado "+ katrina.valueOf());
    console.log("twister" + twister.constructor);
    console.log("twister" + twister.constructor.prototype);

}());<commit_msg>tidy code<commit_after>(function () {
    "use strict";
    var Tornado = function(cities,windGust,type) {
        this.cities = cities;
        this.windGust = windGust;
        this.type = type;
    };

    var cities = [["New York", 1234], ["California", 234]];
    var katrina = new Tornado(cities, '120mph', 'F12');

    console.log("Tornado "+ katrina);

    Tornado.prototype.valueOf = function () {
        var sum = 0;
        for(var i=0; i <= this.cities.length-1; i++) {
            console.log("..."+ cities);
            sum += this.cities[i][1];
        }
        return sum;
    };

    var twister = new Tornado(cities, '34mph', 'F23');
    cities.push(["London", 2000]);
    console.log("Tornado "+ katrina.valueOf());
    console.log("twister" + twister.constructor);
    console.log("twister" + twister.constructor.prototype);

}());<|endoftext|>


<commit_before>import Ember from 'ember';
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';

export default Ember.Route.extend(AuthenticatedRouteMixin, {
  model: function(){
    return this.store.findAll('article');
  }
});
<commit_msg>update the model function definition to es6 in admin.articles route<commit_after>import Ember from 'ember';
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';

export default Ember.Route.extend(AuthenticatedRouteMixin, {
  model() {
    return this.store.findAll('article');
  }
});
<|endoftext|>