<commit_before>import React from 'react';
import { NavLink, navigateAction } from 'fluxible-router';
import UserPicture from '../common/UserPicture';
import { connectToStores } from 'fluxible-addons-react';
import userSignOut from '../../actions/user/userSignOut';
import loadNewUserNotificationsCount from '../../actions/user/notifications/loadNewUserNotificationsCount';
import UserProfileStore from '../../stores/UserProfileStore';
import UserNotificationsStore from '../../stores/UserNotificationsStore';
import fetchUser from '../../actions/user/userprofile/fetchUser';
import AriaMenuButton from 'react-aria-menubutton';

class UserMenuDropdown extends React.Component {
    constructor(props){
        super(props);
        this.userDropDown = undefined;
        this.state ={
            userMenuButtonExpanded : false
        };
        this.onHandleSelection = this.onHandleSelection.bind(this);
    /*    this.handleOnShowMenu = this.handleOnShowMenu.bind(this);
        this.handleOnHideMenu = this.handleOnHideMenu.bind(this);
*/
    }
    componentDidMount(){
        //$(this.refs.userDropDown).dropdown({action: this.onEnterAndClick.bind(this), selectOnKeydown: false}); //string refs are legacy
      //  $('#userButtonMenu').dropdown({action: this.onEnterAndClick, selectOnKeydown: false, onShow: this.handleOnShowMenu, onHide:this.handleOnHideMenu});
        if(this.props.UserProfileStore.userpicture === undefined)
            this.context.executeAction(fetchUser,{ params: {username: this.props.UserProfileStore.username}, onlyPicture: true});

        this.context.executeAction(loadNewUserNotificationsCount, { uid: this.props.UserProfileStore.userid });
    }

    componentDidUpdate() {
        //$(this.refs.userDropDown).dropdown({action: this.onEnterAndClick.bind(this), selectOnKeydown: false});
        //$('#userButtonMenu').dropdown({action: this.onEnterAndClick, selectOnKeydown: false, onShow: this.handleOnShowMenu, onHide:this.handleOnHideMenu});

        if(this.props.UserProfileStore.userpicture === undefined)
            this.context.executeAction(fetchUser, { params: {username: this.props.UserProfileStore.username}, onlyPicture: true});
    }

    onHandleSelection(value, event) {
        if(value === 'logout')
            this.context.executeAction(userSignOut, {username: this.props.UserProfileStore.username});
        else
            this.context.executeAction(navigateAction, {url: value});
        //$(this.refs.userDropDown).dropdown('hide'); //ref strings are legacy
        //$('#userButtonMenu').dropdown('hide');

      //  return false;
    }
    /*
    handleOnShowMenu(){
        if(process.env.BROWSER){ //ensure the component is mounted
            this.setState({
                userMenuButtonExpanded : true
            });
            $('#myDecksMenuItem').focus();
        }
    }
    handleOnHideMenu(){
        this.setState({
            userMenuButtonExpanded : false
        });

    }

*/

    render() {
        let pic = (this.props.UserProfileStore.userpicture === undefined) ? '' : this.props.UserProfileStore.userpicture;
        const alarmClassName = (this.props.UserNotificationsStore.newNotificationsCount > 0) ? 'alarm red icon' : 'alarm outline icon';
        const alarmIcon = (this.props.UserNotificationsStore.newNotificationsCount > 0) ? () : '';

        return(
            <AriaMenuButton.Wrapper
              onSelection={this.onHandleSelection}>
               <AriaMenuButton.Button >

                 <UserPicture picture={ pic } username={ this.props.UserProfileStore.username } avatar={ true } width= { 30 } />

                  {alarmIcon}

               </AriaMenuButton.Button>
               <AriaMenuButton.Menu className='ui menu'>
                  <AriaMenuButton.MenuItem
                   className='item'
                   key= {0}
                   tag='li'
                   value={'/user/' + this.props.UserProfileStore.username}
                   text='My Decks'>

                     My Decks
                  </AriaMenuButton.MenuItem>
                  <AriaMenuButton.MenuItem
                   className='item'
                   key= {1}
                   tag='li'
                   value={'/user/' + this.props.UserProfileStore.username + '/groups/overview'}
                   text='My Groups'>

                    My Groups
                  </AriaMenuButton.MenuItem>
                  <AriaMenuButton.MenuItem
                   className="item"
                   key= {2}
                   tag='li'
                   value={'/user/' + this.props.UserProfileStore.username + '/settings/profile'}
                   text=' My Settings'>

                    My Settings

                  </AriaMenuButton.MenuItem>
                  <AriaMenuButton.MenuItem
                   className="item"
                   key= {3}
                   tag='li'
                   value={'/notifications'}
                   text='My Notifications'>

                    My Notifications

                  </AriaMenuButton.MenuItem>
                  <AriaMenuButton.MenuItem
                   className="item"
                   key= {4}
                   tag='li'
                   value={'logout'}
                   text='Sign Out'>

                     Sign Out

                  </AriaMenuButton.MenuItem>
                </AriaMenuButton.Menu>
            </AriaMenuButton.Wrapper>
        );
    }
}

UserMenuDropdown.contextTypes = {
    executeAction: React.PropTypes.func.isRequired
};

UserMenuDropdown = connectToStores(UserMenuDropdown, [UserProfileStore, UserNotificationsStore], (context, props) => {
    return {
        UserProfileStore: context.getStore(UserProfileStore).getState(),
        UserNotificationsStore: context.getStore(UserNotificationsStore).getState()
    };
});
export default UserMenuDropdown;
<commit_msg>SWIK-1500 userMenuDropdown-->assignet ui menu vertical<commit_after>import React from 'react';
import { NavLink, navigateAction } from 'fluxible-router';
import UserPicture from '../common/UserPicture';
import { connectToStores } from 'fluxible-addons-react';
import userSignOut from '../../actions/user/userSignOut';
import loadNewUserNotificationsCount from '../../actions/user/notifications/loadNewUserNotificationsCount';
import UserProfileStore from '../../stores/UserProfileStore';
import UserNotificationsStore from '../../stores/UserNotificationsStore';
import fetchUser from '../../actions/user/userprofile/fetchUser';
import AriaMenuButton from 'react-aria-menubutton';

class UserMenuDropdown extends React.Component {
    constructor(props){
        super(props);
        this.userDropDown = undefined;
        this.state ={
            userMenuButtonExpanded : false
        };
        this.onHandleSelection = this.onHandleSelection.bind(this);
    /*    this.handleOnShowMenu = this.handleOnShowMenu.bind(this);
        this.handleOnHideMenu = this.handleOnHideMenu.bind(this);
*/
    }
    componentDidMount(){
        //$(this.refs.userDropDown).dropdown({action: this.onEnterAndClick.bind(this), selectOnKeydown: false}); //string refs are legacy
      //  $('#userButtonMenu').dropdown({action: this.onEnterAndClick, selectOnKeydown: false, onShow: this.handleOnShowMenu, onHide:this.handleOnHideMenu});
        if(this.props.UserProfileStore.userpicture === undefined)
            this.context.executeAction(fetchUser,{ params: {username: this.props.UserProfileStore.username}, onlyPicture: true});

        this.context.executeAction(loadNewUserNotificationsCount, { uid: this.props.UserProfileStore.userid });
    }

    componentDidUpdate() {
        //$(this.refs.userDropDown).dropdown({action: this.onEnterAndClick.bind(this), selectOnKeydown: false});
        //$('#userButtonMenu').dropdown({action: this.onEnterAndClick, selectOnKeydown: false, onShow: this.handleOnShowMenu, onHide:this.handleOnHideMenu});

        if(this.props.UserProfileStore.userpicture === undefined)
            this.context.executeAction(fetchUser, { params: {username: this.props.UserProfileStore.username}, onlyPicture: true});
    }

    onHandleSelection(value, event) {
        if(value === 'logout')
            this.context.executeAction(userSignOut, {username: this.props.UserProfileStore.username});
        else
            this.context.executeAction(navigateAction, {url: value});
        //$(this.refs.userDropDown).dropdown('hide'); //ref strings are legacy
        //$('#userButtonMenu').dropdown('hide');

      //  return false;
    }
    /*
    handleOnShowMenu(){
        if(process.env.BROWSER){ //ensure the component is mounted
            this.setState({
                userMenuButtonExpanded : true
            });
            $('#myDecksMenuItem').focus();
        }
    }
    handleOnHideMenu(){
        this.setState({
            userMenuButtonExpanded : false
        });

    }

*/

    render() {
        let pic = (this.props.UserProfileStore.userpicture === undefined) ? '' : this.props.UserProfileStore.userpicture;
        const alarmClassName = (this.props.UserNotificationsStore.newNotificationsCount > 0) ? 'alarm red icon' : 'alarm outline icon';
        const alarmIcon = (this.props.UserNotificationsStore.newNotificationsCount > 0) ? () : '';

        return(
            <AriaMenuButton.Wrapper
              onSelection={this.onHandleSelection}>
               <AriaMenuButton.Button >

                 <UserPicture picture={ pic } username={ this.props.UserProfileStore.username } avatar={ true } width= { 30 } />

                  {alarmIcon}

               </AriaMenuButton.Button>
               <AriaMenuButton.Menu className='ui menu vertical'>
                  <AriaMenuButton.MenuItem
                   className='item'
                   key= {0}
                   tag='li'
                   value={'/user/' + this.props.UserProfileStore.username}
                   text='My Decks'>

                     My Decks
                  </AriaMenuButton.MenuItem>
                  <AriaMenuButton.MenuItem
                   className='item'
                   key= {1}
                   tag='li'
                   value={'/user/' + this.props.UserProfileStore.username + '/groups/overview'}
                   text='My Groups'>

                    My Groups
                  </AriaMenuButton.MenuItem>
                  <AriaMenuButton.MenuItem
                   className="item"
                   key= {2}
                   tag='li'
                   value={'/user/' + this.props.UserProfileStore.username + '/settings/profile'}
                   text=' My Settings'>

                    My Settings

                  </AriaMenuButton.MenuItem>
                  <AriaMenuButton.MenuItem
                   className="item"
                   key= {3}
                   tag='li'
                   value={'/notifications'}
                   text='My Notifications'>

                    My Notifications

                  </AriaMenuButton.MenuItem>
                  <AriaMenuButton.MenuItem
                   className="item"
                   key= {4}
                   tag='li'
                   value={'logout'}
                   text='Sign Out'>

                     Sign Out

                  </AriaMenuButton.MenuItem>
                </AriaMenuButton.Menu>
            </AriaMenuButton.Wrapper>
        );
    }
}

UserMenuDropdown.contextTypes = {
    executeAction: React.PropTypes.func.isRequired
};

UserMenuDropdown = connectToStores(UserMenuDropdown, [UserProfileStore, UserNotificationsStore], (context, props) => {
    return {
        UserProfileStore: context.getStore(UserProfileStore).getState(),
        UserNotificationsStore: context.getStore(UserNotificationsStore).getState()
    };
});
export default UserMenuDropdown;
<|endoftext|>


<commit_before>class HandlerManager {
	constructor() {
		this._handlers = {};
	}

	hasHandler(msg) {
		return this._handlers[msg] && this._handlers[msg].length > 0;
	}

	add(msg, handler) {
		if (!this._handlers[msg]) {
			this._handlers[msg] = [];
		}

		if (this._handlers[msg].some(existingHandler => existingHandler === handler)) {
			// This handler already exists
			return;
		}

		this._handlers[msg].push(handler);
	}

	emit(instance, msg, ...args) {
		let handlers = this._handlers[msg];
		if (!handlers || handlers.length == 0) {
			return;
		}

		handlers.forEach((handler) => {
			handler.apply(instance, args);
		});
	}
}
<commit_msg>Backwards-compatibility for legacy, unsupported third-party handlers<commit_after>class HandlerManager {
	constructor() {
		this._handlers = {};
	}

	hasHandler(msg) {
		return this._handlers[msg] && this._handlers[msg].length > 0;
	}

	add(msg, handler) {
		this.checkMsgForLegacyHandlers(msg);

		if (!this._handlers[msg]) {
			this._handlers[msg] = [];
		}

		if (this._handlers[msg].some(existingHandler => existingHandler === handler)) {
			// This handler already exists
			return;
		}

		this._handlers[msg].push(handler);
	}

	emit(instance, msg, ...args) {
		this.checkMsgForLegacyHandlers(msg);

		let handlers = this._handlers[msg];
		if (!handlers || handlers.length == 0) {
			return;
		}

		handlers.forEach((handler) => {
			handler.apply(instance, args);
		});
	}

	checkMsgForLegacyHandlers(msg) {
		const SteamUser = require('../../index.js');
		if (typeof SteamUser.prototype._handlers[msg] === 'function') {
			this.add(msg, SteamUser.prototype._handlers[msg]);
			delete SteamUser.prototype._handlers[msg];
		}
	}
}
<|endoftext|>


<commit_before>/* eslint max-len: 0 */
import React from 'react';
import PropTypes from 'prop-types';

import { Router } from 'routes';

// Components
import Layout from 'layout/layout/layout-app';

// Topic Detail Component
import TopicDetailHeader from 'layout/topics-detail/topics-detail-header';
import TopicDetailContent from 'layout/topics-detail/topics-detail-content';
import TopicThumbnailList from 'components/topics/thumbnail-list';

import Title from 'components/ui/Title';

class TopicDetailComponent extends React.Component {
  static propTypes = {
    topicsDetail: PropTypes.object
  };

  render() {
    const {
      topicsDetail
    } = this.props;

    const { data: topic } = topicsDetail;

    return (
      <Layout
        title={topic.name}
        description={topic.description || ''}
        category="Topic"
        pageHeader
      >

          {/* PAGE HEADER */}

                  <TopicDetailHeader />

                  <TopicDetailContent />

                  <Title className="-extrabig -secondary -p-secondary">
                    Other topics
                  </Title>

                  <TopicThumbnailList
                    onSelect={({ slug }) => {
                      // We need to make an amendment in the Wysiwyg to have this working
                      Router.pushRoute('topics_detail', { id: slug })
                        .then(() => {
                          window.scrollTo(0, 0);
                        });
                    }}
                  />

      </Layout>
    );
  }
}

export default TopicDetailComponent;
<commit_msg>Add Similar datasets to topic pages<commit_after>/* eslint max-len: 0 */
import React from 'react';
import PropTypes from 'prop-types';
import compact from 'lodash/compact';
import flatten from 'lodash/flatten';

import { Router } from 'routes';

// Components
import Layout from 'layout/layout/layout-app';
import SimilarDatasets from 'components/datasets/similar-datasets/similar-datasets';

// Topic Detail Component
import TopicDetailHeader from 'layout/topics-detail/topics-detail-header';
import TopicDetailContent from 'layout/topics-detail/topics-detail-content';
import TopicThumbnailList from 'components/topics/thumbnail-list';

import Title from 'components/ui/Title';

class TopicDetailComponent extends React.Component {
  static propTypes = {
    topicsDetail: PropTypes.object
  };

  getDatasetIds() {
    const { topicsDetail } = this.props;

    const content = JSON.parse(topicsDetail.data.content);

    const datasetIds = content.map((block) => {
      if (block.type === 'widget') {
        return block.content.datasetId;
      }

      if (block.type === 'grid') {
        return block.content.map((b) => {
          if (b.type === 'widget') {
            return b.content.datasetId;
          }

          return null;
        });
      }

      return null;
    });

    return compact(flatten(datasetIds));
  }

  render() {
    const {
      topicsDetail
    } = this.props;

    const { data: topic } = topicsDetail;

    return (
      <Layout
        title={topic.name}
        description={topic.description || ''}
        category="Topic"
        pageHeader
      >

          {/* PAGE HEADER */}

                  <TopicDetailHeader />

                  <TopicDetailContent />

                  <Title className="-extrabig -secondary -p-secondary">
                    Other topics
                  </Title>

                  <TopicThumbnailList
                    onSelect={({ slug }) => {
                      // We need to make an amendment in the Wysiwyg to have this working
                      Router.pushRoute('topics_detail', { id: slug })
                        .then(() => {
                          window.scrollTo(0, 0);
                        });
                    }}
                  />

                  <Title className="-extrabig -secondary -p-secondary">
                    Similar datasets
                  </Title>

                  <SimilarDatasets
                    datasetIds={this.getDatasetIds()}
                    onTagSelected={this.handleTagSelected}
                  />

      </Layout>
    );
  }
}

export default TopicDetailComponent;
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2013 The Johns Hopkins University/Applied Physics Laboratory
 *                             All rights reserved.
 *
 * This material may be used, modified, or reproduced by or for the U.S.
 * Government pursuant to the rights granted under the clauses at
 * DFARS 252.227-7013/7014 or FAR 52.227-14.
 *
 * 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
 *
 * NO WARRANTY.   THIS MATERIAL IS PROVIDED "AS IS."  JHU/APL DISCLAIMS ALL
 * WARRANTIES IN THE MATERIAL, WHETHER EXPRESS OR IMPLIED, INCLUDING (BUT NOT
 * LIMITED TO) ANY AND ALL IMPLIED WARRANTIES OF PERFORMANCE,
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT OF
 * INTELLECTUAL PROPERTY RIGHTS. ANY USER OF THE MATERIAL ASSUMES THE ENTIRE
 * RISK AND LIABILITY FOR USING THE MATERIAL.  IN NO EVENT SHALL JHU/APL BE
 * LIABLE TO ANY USER OF THE MATERIAL FOR ANY ACTUAL, INDIRECT,
 * CONSEQUENTIAL, SPECIAL OR OTHER DAMAGES ARISING FROM THE USE OF, OR
 * INABILITY TO USE, THE MATERIAL, INCLUDING, BUT NOT LIMITED TO, ANY DAMAGES
 * FOR LOST PROFITS.
 */

Ext.namespace("Ext.ux.grid", "Ext.ux.renderer");

Ext.ux.grid.ComboColumn = Ext.extend(Ext.grid.Column, {

    /**
     * The grids id
     */
    gridId: undefined,

    constructor: function (cfg) {
        Ext.ux.grid.ComboColumn.superclass.constructor.call(this, cfg);

        // Check for editor using custom renderer otherwise default
        this.renderer = (this.editor && this.editor.triggerAction) ? Ext.ux.renderer.ComboBoxRenderer(this.editor,
            this.gridId) : function (value) {
            return value; // TODO fix this formatting
        };
    }
});
Ext.grid.Column.types.combocolumn = Ext.ux.grid.ComboColumn;

/**
 *  A renderer to show the display value when using combo boxes in editor grids (instead of value/fk)
 */
Ext.ux.renderer.ComboBoxRenderer = function (combo, gridId) {
    // Get the value from displayfield, else value
    var getValue = function (value) {
        var record = combo.store.getAt(combo.store.find(combo.valueField, value));
        if (record) {
            return record.get(combo.displayField);
        }

        return value;
    };

    return function (value) {
        // Ensure combos store is loaded
        if (combo.store.getCount() === 0 && gridId) {
            combo.store.on('load', function () {
                    var grid = Ext.getCmp(gridId);
                    if (grid) {
                        grid.getView().refresh();
                    }
                }, {
                    single: true
                }
            );
            return value;
        }

        return getValue(value);
    };
};
<commit_msg>Use findExact on ComboColumn store<commit_after>/*
 * Copyright (c) 2013 The Johns Hopkins University/Applied Physics Laboratory
 *                             All rights reserved.
 *
 * This material may be used, modified, or reproduced by or for the U.S.
 * Government pursuant to the rights granted under the clauses at
 * DFARS 252.227-7013/7014 or FAR 52.227-14.
 *
 * 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
 *
 * NO WARRANTY.   THIS MATERIAL IS PROVIDED "AS IS."  JHU/APL DISCLAIMS ALL
 * WARRANTIES IN THE MATERIAL, WHETHER EXPRESS OR IMPLIED, INCLUDING (BUT NOT
 * LIMITED TO) ANY AND ALL IMPLIED WARRANTIES OF PERFORMANCE,
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT OF
 * INTELLECTUAL PROPERTY RIGHTS. ANY USER OF THE MATERIAL ASSUMES THE ENTIRE
 * RISK AND LIABILITY FOR USING THE MATERIAL.  IN NO EVENT SHALL JHU/APL BE
 * LIABLE TO ANY USER OF THE MATERIAL FOR ANY ACTUAL, INDIRECT,
 * CONSEQUENTIAL, SPECIAL OR OTHER DAMAGES ARISING FROM THE USE OF, OR
 * INABILITY TO USE, THE MATERIAL, INCLUDING, BUT NOT LIMITED TO, ANY DAMAGES
 * FOR LOST PROFITS.
 */

Ext.namespace("Ext.ux.grid", "Ext.ux.renderer");

Ext.ux.grid.ComboColumn = Ext.extend(Ext.grid.Column, {

    /**
     * The grids id
     */
    gridId: undefined,

    constructor: function (cfg) {
        Ext.ux.grid.ComboColumn.superclass.constructor.call(this, cfg);

        // Check for editor using custom renderer otherwise default
        this.renderer = (this.editor && this.editor.triggerAction) ? Ext.ux.renderer.ComboBoxRenderer(this.editor,
            this.gridId) : function (value) {
            return value; // TODO fix this formatting
        };
    }
});
Ext.grid.Column.types.combocolumn = Ext.ux.grid.ComboColumn;

/**
 *  A renderer to show the display value when using combo boxes in editor grids (instead of value/fk)
 */
Ext.ux.renderer.ComboBoxRenderer = function (combo, gridId) {
    // Get the value from displayfield, else value
    var getValue = function (value) {
        var record = combo.store.getAt(combo.store.findExact(combo.valueField, value));
        if (record) {
            return record.get(combo.displayField);
        }

        return value;
    };

    return function (value) {
        // Ensure combos store is loaded
        if (combo.store.getCount() === 0 && gridId) {
            if (!combo.onloadDefined) {
                // Ensure we are adding onLoad only once per combo column
                // This check was added because onLoad was added to the store 2^n times
                // where n is number of combo columns in this grid
                combo.onloadDefined = true;

                combo.store.on('load', function () {
                        var grid = Ext.getCmp(gridId);
                        if (grid) {
                            grid.getView().refresh();
                        }
                    }, {
                        single: true
                    }
                );
            }

            return value;
        }

        return getValue(value);
    };
};
<|endoftext|>


<commit_before>"use strict";

var
    esPhinx;

(function ($) {

    $.extend({

        prototype: {

            horizontalToggle: function (initialMargin = 0) {
                var
                    self = this,
                    width,
                    margin,
                    marginRight,
                    marginLeft;

                self.each(function (node) {
                    node = $(node);

                    width = Math.round(node.width());
                    marginLeft = Math.abs(node.css("margin-left"));
                    marginRight = Math.abs(node.css("margin-right"));

                    // discovering more criteria to know if align on right (||)
                    if (node.css("float") === "right") {
                        margin = Math.abs(Math.round(node.css("margin-right")));
                        if (margin !== (width + marginLeft)) {
                            node.css("margin-right", - (width + marginLeft) + "px");
                        } else {
                            node.css("margin-right", initialMargin + "px");
                        }
                    } else {
                        margin = Math.abs(Math.round(node.css("margin-left")));
                        if (margin !== (width + marginRight)) {
                            node.css("margin-left", - (width + marginRight) + "px");
                        } else {
                            node.css("margin-left", initialMargin + "px");
                        }
                    }

                });

                return self;
            },

            toggleClass: function (classList, changeTo) {
                var
                    self = this,
                    pattern;

                self.each(function (node) {
                    if ($(node).hasClass(classList)) {
                        $(node).removeClass(classList);
                        if (changeTo) {
                            $(node).addClass(changeTo);
                        }
                    } else if (changeTo) {
                        if ($(node).hasClass(changeTo)) {
                            $(node).removeClass(changeTo);
                            $(node).addClass(classList);
                        } else {
                            $(node).addClass(classList);
                        }
                    } else {
                        $(node).addClass(classList);
                    }
                });

                return self;
            },

            hide: function () {
                var
                    self = this;

                self.css("display", "none", true);

                return self;
            },

            show: function (displayValue) {
                displayValue = displayValue || "initial";

                var
                    self = this;

                self.css("display", displayValue);

                return self;
            },

            centralizeAt: function (nodeQuery) {
                var
                    self = this;

                self.css("position", "absolute");

                self.css({
                    top: ($(nodeQuery).height() / 2) - (self.height() / 2) + "px",
                    left: ($(nodeQuery).width() / 2) - (self.width() / 2) + "px"
                });

                return self;
            },

            minWidth: function () {
                var
                    self = this,
                    padding = self.css("padding-left")
                    + self.css("padding-right");

                return self.innerWidth() - padding;
            },

            innerWidth: function () {
                var
                    self = this,
                    border = self.css("border-left-width")
                    + self.css("border-right-width");

                return self.width() - border;
            },

            width: function (value) {
                var
                    self = this,
                    width = self.css("width"),
                    padding = self.css("padding-left")
                    + self.css("padding-right"),
                    border = self.css("border-left-width")
                    + self.css("border-right-width"),
                    difference;

                if (value || value === 0) {
                    self.each(function (node) {
                        node = $(node);
                        if (Number.isNaN(parseFloat(value))) {
                            node.css("width", value);
                        } else {
                            padding = self.css("padding-left")
                            + self.css("padding-right"),
                            border = node.css("border-left-width")
                            + node.css("border-right-width");
                            difference = parseFloat(value)
                            - (padding + border);
                            value  = node.width() + difference;
                            if (value < 0) {
                                value = 0;
                            }
                            $(node).css("width", value + "px");
                        }
                    });
                } else {
                    if (Number.isNaN(parseFloat(width))) {
                        return self.first().offsetWidth;
                    }
                    return width + padding + border;
                }
            },

            minHeight: function () {
                var
                    self = this,
                    padding = self.css("padding-top")
                    + self.css("padding-bottom");

                return self.innerHeight() - padding;
            },

            innerHeight: function () {
                var
                    self = this,
                    border = self.css("border-top-width")
                    + self.css("border-bottom-width");

                return self.height() - border;
            },

            height: function (value) {
                var
                    self = this,
                    height = self.css("height"),
                    padding = self.css("padding-top")
                    + self.css("padding-bottom"),
                    border = self.css("border-top-width")
                    + self.css("border-bottom-width"),
                    difference;

                if (value || value === 0) {
                    self.each(function (node) {
                        node = $(node);
                        if (Number.isNaN(parseFloat(value))) {
                            node.css("height", value);
                        } else {
                            padding = self.css("padding-top")
                            + self.css("padding-bottom");
                            border = node.css("border-top-width")
                            + node.css("border-bottom-width");
                            difference = parseFloat(value)
                            - (padding + border);
                            value  = node.height() + difference;
                            if (value < 0) {
                                value = 0;
                            }
                            $(node).css("height", value + "px");
                        }
                    });
                } else {
                    if (Number.isNaN(parseFloat(height))) {
                        return self.first().offsetHeight;
                    }
                    return self.innerHeight() + border;
                }

                return self;
            }

        }

    });

}(esPhinx));
<commit_msg>add support to callback in horizontalToggle method<commit_after>"use strict";

var
    esPhinx;

(function ($) {

    $.extend({

        prototype: {

            transitionDuration: function () {
                var
                    self = this;

                return self.css("transition-duration") * 1000;
            },

            horizontalToggle: function (initialMargin = 0, callback = function(){}) {

                if (typeof initialMargin === "function") {
                    callback = initialMargin;
                    initialMargin = 0;
                }

                var
                    self = this,
                    width,
                    margin,
                    marginRight,
                    marginLeft,
                    duration;

                self.each(function (node) {
                    node = $(node);

                    width = Math.round(node.width());
                    marginLeft = Math.abs(node.css("margin-left"));
                    marginRight = Math.abs(node.css("margin-right"));
                    duration = node.transitionDuration();

                    // discovering more criteria to know if align on right (||)
                    if (node.css("float") === "right") {
                        margin = Math.abs(Math.round(node.css("margin-right")));
                        if (margin !== (width + marginLeft)) {
                            node.css("margin-right", - (width + marginLeft) + "px");
                        } else {
                            node.css("margin-right", initialMargin + "px");
                        }
                    } else {
                        margin = Math.abs(Math.round(node.css("margin-left")));
                        if (margin !== (width + marginRight)) {
                            node.css("margin-left", - (width + marginRight) + "px");
                        } else {
                            node.css("margin-left", initialMargin + "px");
                        }
                    }

                    setTimeout(function () {
                        callback(node);
                    }, duration);

                });

                return self;
            },

            toggleClass: function (classList, changeTo) {
                var
                    self = this,
                    pattern;

                self.each(function (node) {
                    if ($(node).hasClass(classList)) {
                        $(node).removeClass(classList);
                        if (changeTo) {
                            $(node).addClass(changeTo);
                        }
                    } else if (changeTo) {
                        if ($(node).hasClass(changeTo)) {
                            $(node).removeClass(changeTo);
                            $(node).addClass(classList);
                        } else {
                            $(node).addClass(classList);
                        }
                    } else {
                        $(node).addClass(classList);
                    }
                });

                return self;
            },

            hide: function () {
                var
                    self = this;

                self.css("display", "none", true);

                return self;
            },

            show: function (displayValue) {
                displayValue = displayValue || "initial";

                var
                    self = this;

                self.css("display", displayValue);

                return self;
            },

            centralizeAt: function (nodeQuery) {
                var
                    self = this;

                self.css("position", "absolute");

                self.css({
                    top: ($(nodeQuery).height() / 2) - (self.height() / 2) + "px",
                    left: ($(nodeQuery).width() / 2) - (self.width() / 2) + "px"
                });

                return self;
            },

            minWidth: function () {
                var
                    self = this,
                    padding = self.css("padding-left")
                    + self.css("padding-right");

                return self.innerWidth() - padding;
            },

            innerWidth: function () {
                var
                    self = this,
                    border = self.css("border-left-width")
                    + self.css("border-right-width");

                return self.width() - border;
            },

            width: function (value) {
                var
                    self = this,
                    width = self.css("width"),
                    padding = self.css("padding-left")
                    + self.css("padding-right"),
                    border = self.css("border-left-width")
                    + self.css("border-right-width"),
                    difference;

                if (value || value === 0) {
                    self.each(function (node) {
                        node = $(node);
                        if (Number.isNaN(parseFloat(value))) {
                            node.css("width", value);
                        } else {
                            padding = self.css("padding-left")
                            + self.css("padding-right"),
                            border = node.css("border-left-width")
                            + node.css("border-right-width");
                            difference = parseFloat(value)
                            - (padding + border);
                            value  = node.width() + difference;
                            if (value < 0) {
                                value = 0;
                            }
                            $(node).css("width", value + "px");
                        }
                    });
                } else {
                    if (Number.isNaN(parseFloat(width))) {
                        return self.first().offsetWidth;
                    }
                    return width + padding + border;
                }
            },

            minHeight: function () {
                var
                    self = this,
                    padding = self.css("padding-top")
                    + self.css("padding-bottom");

                return self.innerHeight() - padding;
            },

            innerHeight: function () {
                var
                    self = this,
                    border = self.css("border-top-width")
                    + self.css("border-bottom-width");

                return self.height() - border;
            },

            height: function (value) {
                var
                    self = this,
                    height = self.css("height"),
                    padding = self.css("padding-top")
                    + self.css("padding-bottom"),
                    border = self.css("border-top-width")
                    + self.css("border-bottom-width"),
                    difference;

                if (value || value === 0) {
                    self.each(function (node) {
                        node = $(node);
                        if (Number.isNaN(parseFloat(value))) {
                            node.css("height", value);
                        } else {
                            padding = self.css("padding-top")
                            + self.css("padding-bottom");
                            border = node.css("border-top-width")
                            + node.css("border-bottom-width");
                            difference = parseFloat(value)
                            - (padding + border);
                            value  = node.height() + difference;
                            if (value < 0) {
                                value = 0;
                            }
                            $(node).css("height", value + "px");
                        }
                    });
                } else {
                    if (Number.isNaN(parseFloat(height))) {
                        return self.first().offsetHeight;
                    }
                    return self.innerHeight() + border;
                }

                return self;
            }

        }

    });

}(esPhinx));
<|endoftext|>


<commit_before>var module = module || {};
module.exports = module.exports || {};

module.exports.runner = async (onInitialized, onPageLoaded, isFrameworkLoaded, onFrameworkLoaded, isTestingDone) => {

    const chutzpahCommon = require('../chutzpahFunctions.js');
    const chutzpahFunctions = chutzpahCommon.getCommonFunctions(process.exit, updateEventTime);

    var testFrameworkLoaded = false,
        attemptingToSetupTestFramework = false,
        testFile = null,
        testMode = null,
        timeOut = null,
        startTime = null,
        userAgent = null,
        ignoreResourceLoadingError = false,
        finalResult = 0,
        isRunningElevated = false,
        chromePath = null,
        browserArgs = null;

    startTime = new Date().getTime();

    testFile = process.argv[2];
    testMode = process.argv[3] || "execution";
    timeOut = parseInt(process.argv[4]) || 5001;

    if (process.argv.length > 5) {
        isRunningElevated = "true" === process.argv[5].toLowerCase();
    }

    if (process.argv.length > 6) {
        ignoreResourceLoadingError = "true" === process.argv[6].toLowerCase();
    }

    if (process.argv.length > 7) {
        chromePath = process.argv[7];
    }

    if (process.argv.length > 8) {
        userAgent = process.argv[8];
    }

    if (process.argv.length > 9) {
        browserArgs = process.argv[9];
    }

    function debugLog(msg) {
        //chutzpahFunctions.rawLog("!!_!! " + msg);
    }

    function updateEventTime() {
        startTime = new Date().getTime();
    }

    async function trySetupTestFramework(evaluate) {
        debugLog("trySetupTestFramework");
        if (!testFrameworkLoaded && !attemptingToSetupTestFramework) {
            attemptingToSetupTestFramework = true;
            debugLog("checking isFrameworkLoaded ");
            var loaded = await evaluate(isFrameworkLoaded);
            if (loaded && (typeof loaded !== "string" || loaded === "true")) {
                testFrameworkLoaded = true;
                debugLog("calling onFrameworkLoaded");
                await evaluate(onFrameworkLoaded);
            }

            attemptingToSetupTestFramework = false;
        }

    }

    async function wait(delay) {
        return new Promise(function (resolve, reject) {
            setTimeout(resolve, delay);
        });
    }

    async function waitFor(testIfDone, timeOutMillis) {
        let maxtimeOutMillis = timeOutMillis,
            isDone = false,
            result = -1;

        async function intervalHandler() {
            debugLog("intervalHandler");
            var now = new Date().getTime();

            if (!isDone && ((now - startTime) < maxtimeOutMillis)) {
                isDone = await testIfDone();
                return -1; // Not done, try again
            } else {
                if (!isDone) {
                    return 3; // Timeout
                } else {
                    return 0; // Done succesfully
                }
            }
        }

        while (result < 0) {
            debugLog("@@@ wait...: " + result);
            await wait(100);
            result = await intervalHandler();

            if (result >= 0) {
                debugLog("Positive result, fin! " + result);
                return result;
            }
        }
    }

    async function pageOpenHandler(evaluate) {
        debugLog("pageOpenHandler");

        var waitCondition = async () => {
            let rawResult = await evaluate(isTestingDone);
            let result = rawResult && (typeof rawResult !== "string" || rawResult === "true");
            debugLog("@@@ waitCondition result: " + JSON.stringify(result));
            return result;
        };

        debugLog("Promise in pageOpenHandler");
        // Initialize startTime, this will get updated every time we receive
        // content from the test framework
        updateEventTime();
        debugLog("First trySetupTestFramework");
        await trySetupTestFramework(evaluate);

        debugLog("Evaluate onPageLoaded");
        await evaluate(onPageLoaded);

        debugLog("Calling waitFor...");
        return await waitFor(waitCondition, timeOut);
    }

    async function pageInitializedHandler(evaluate) {
        debugLog("pageInitializedHandler");
        await evaluate(onInitialized);
    }

    function getPageInitializationScript() {
        if (testMode === 'discovery') {
            return "window.chutzpah = { testMode: 'discovery', phantom: true };";
        }
        else {
            return "window.chutzpah = { testMode: 'execution', phantom: true };";
        }
    }

    function wrapFunctionForEvaluation(func) {
        let str = '(' + func.toString() + ')()'

        // If the result is an instanceof of Promise, It's resolved in context of nodejs later.
        return `
        {
          let result = ${str};
          if (result instanceof Promise) {
            result;
          }
          else {
            let json = JSON.stringify(result);
            json;
          }
        }
      `.trim();
    }

    const puppeteer = require('puppeteer-core');
    const fs = require('fs');
    const path = require('path');

    function resolveChromePath() {
        if (canAccess(`${process.env.CHROME_PATH}`)) {
            return process.env.CHROME_PATH;
        }
        return undefined;
    }

    function getChromePaths() {
        const installations = [];
        const suffixes = [
            `${path.sep}Google${path.sep}Chrome SxS${path.sep}Application${path.sep}chrome.exe`,
            `${path.sep}Google${path.sep}Chrome${path.sep}Application${path.sep}chrome.exe`
        ];
        const prefixes = [
            process.env.LOCALAPPDATA, process.env.PROGRAMFILES, process.env['PROGRAMFILES(X86)']
        ].filter(Boolean);

        const customChromePath = resolveChromePath();
        if (customChromePath) {
            installations.push(customChromePath);
        }

        prefixes.forEach(prefix => suffixes.forEach(suffix => {
            const chromePath = path.join(prefix, suffix);
            if (canAccess(chromePath)) {
                installations.push(chromePath);
            }
        }));
        return installations;
    }

    function canAccess(file) {
        if (!file) {
            return false;
        }

        try {
            fs.accessSync(file);
            return true;
        } catch (e) {
            return false;
        }
    }

    function handleError(error) {
        var error;
        if (typeof (error) === 'object') {
            chutzpahFunctions.onError(error.message, error.stack);
        }
        else {
            chutzpahFunctions.onError(error);
        }
    }

    // Capture all uncaught exceptions and wrap before logging
    process.on('uncaughtException', handleError);

    try {
        let chromeExecutable = null;

        if (!chromePath) {
            const chromePaths = getChromePaths();
            if (chromePaths.length <= 0) {
                debugLog("Could not find chrome paths");
            }
            chromeExecutable = chromePaths[0];
        }
        else {
            chromeExecutable = chromePath;
        }

        chutzpahFunctions.rawLog("!!_!! Using Chrome Install : " + chromeExecutable);
        debugLog("Launch Chrome (" + chromeExecutable + "): Elevated= " + isRunningElevated);

        // If isRunningElevated, we need to turn off sandbox since it does not work with admin users
        var launchBrowserArges = isRunningElevated ? ["--no-sandbox"] : [];
        if (browserArgs) {
            launchBrowserArges.push(...browserArgs.trim().split(" "));
        }
        chutzpahFunctions.rawLog("!!_!! puppeteer browser args: " + JSON.stringify(launchBrowserArges));

        // If isRunningElevated, we need to turn off sandbox since it does not work with admin users
        const browser = await puppeteer.launch({
                headless: true, args: launchBrowserArges, executablePath: chromeExecutable
            });

        const page = await browser.newPage();

        try {
            await page.setBypassCSP(true);
        } catch (error) {
            // Older chromes won't support this so just ignore...
        }

        if (userAgent) {
            page.setUserAgent(userAgent);
        }

        const evaluate = async (func) => { return await page.evaluate(wrapFunctionForEvaluation(func)); };

        page.on('requestfinished', (async (request) => {
            chutzpahFunctions.rawLog("!!_!! Resource Received: " + request.url());
            await trySetupTestFramework(evaluate);
        }));

        page.on('requestfailed', ((request) => {
            let errorText = request.failure().errorText;
            if (!ignoreResourceLoadingError) {
                chutzpahFunctions.onError(errorText);
            }
            chutzpahFunctions.rawLog("!!_!! Resource Error for " + request.url() + " with error " + errorText);

        }));

        page.on('console', message => {
            if (message.type === 'error') {
                chutzpahFunctions.onError(message.text(), message.text());
            }
            else {
                chutzpahFunctions.captureLogMessage(message.text());
            }
        });

        page.on('error', error => {
            handleError(error);
        });

        page.on('pageerror', error => {
            handleError(error);
        });

        await page.evaluateOnNewDocument(getPageInitializationScript());

        debugLog("### Navigate..." + testFile);
        await page.goto(testFile, { waitUntil: "load" });

        debugLog("### loadEventFired");

        debugLog("### calling pageInitializedHandler");
        await pageInitializedHandler(evaluate);

        debugLog("### calling pageOpenHandler");
        finalResult = await pageOpenHandler(evaluate);
        debugLog("Just about done: " + finalResult);

    } catch (err) {
        chutzpahFunctions.rawLog("!!_!! Error: " + err);

        debugLog("Closing client");
        if (browser) {
            await browser.close();
        }

        process.exit(2);
    }

    debugLog("Closing client");
    if (browser) {
        await browser.close();
    }

    debugLog("Closed client");

    process.exit(finalResult);

};<commit_msg>Disable CORS by default<commit_after>var module = module || {};
module.exports = module.exports || {};

module.exports.runner = async (onInitialized, onPageLoaded, isFrameworkLoaded, onFrameworkLoaded, isTestingDone) => {

    const chutzpahCommon = require('../chutzpahFunctions.js');
    const chutzpahFunctions = chutzpahCommon.getCommonFunctions(process.exit, updateEventTime);

    var testFrameworkLoaded = false,
        attemptingToSetupTestFramework = false,
        testFile = null,
        testMode = null,
        timeOut = null,
        startTime = null,
        userAgent = null,
        ignoreResourceLoadingError = false,
        finalResult = 0,
        isRunningElevated = false,
        chromePath = null,
        browserArgs = null;

    startTime = new Date().getTime();

    testFile = process.argv[2];
    testMode = process.argv[3] || "execution";
    timeOut = parseInt(process.argv[4]) || 5001;

    if (process.argv.length > 5) {
        isRunningElevated = "true" === process.argv[5].toLowerCase();
    }

    if (process.argv.length > 6) {
        ignoreResourceLoadingError = "true" === process.argv[6].toLowerCase();
    }

    if (process.argv.length > 7) {
        chromePath = process.argv[7];
    }

    if (process.argv.length > 8) {
        userAgent = process.argv[8];
    }

    if (process.argv.length > 9) {
        browserArgs = process.argv[9];
    }

    function debugLog(msg) {
        //chutzpahFunctions.rawLog("!!_!! " + msg);
    }

    function updateEventTime() {
        startTime = new Date().getTime();
    }

    async function trySetupTestFramework(evaluate) {
        debugLog("trySetupTestFramework");
        if (!testFrameworkLoaded && !attemptingToSetupTestFramework) {
            attemptingToSetupTestFramework = true;
            debugLog("checking isFrameworkLoaded ");
            var loaded = await evaluate(isFrameworkLoaded);
            if (loaded && (typeof loaded !== "string" || loaded === "true")) {
                testFrameworkLoaded = true;
                debugLog("calling onFrameworkLoaded");
                await evaluate(onFrameworkLoaded);
            }

            attemptingToSetupTestFramework = false;
        }

    }

    async function wait(delay) {
        return new Promise(function (resolve, reject) {
            setTimeout(resolve, delay);
        });
    }

    async function waitFor(testIfDone, timeOutMillis) {
        let maxtimeOutMillis = timeOutMillis,
            isDone = false,
            result = -1;

        async function intervalHandler() {
            debugLog("intervalHandler");
            var now = new Date().getTime();

            if (!isDone && ((now - startTime) < maxtimeOutMillis)) {
                isDone = await testIfDone();
                return -1; // Not done, try again
            } else {
                if (!isDone) {
                    return 3; // Timeout
                } else {
                    return 0; // Done succesfully
                }
            }
        }

        while (result < 0) {
            debugLog("@@@ wait...: " + result);
            await wait(100);
            result = await intervalHandler();

            if (result >= 0) {
                debugLog("Positive result, fin! " + result);
                return result;
            }
        }
    }

    async function pageOpenHandler(evaluate) {
        debugLog("pageOpenHandler");

        var waitCondition = async () => {
            let rawResult = await evaluate(isTestingDone);
            let result = rawResult && (typeof rawResult !== "string" || rawResult === "true");
            debugLog("@@@ waitCondition result: " + JSON.stringify(result));
            return result;
        };

        debugLog("Promise in pageOpenHandler");
        // Initialize startTime, this will get updated every time we receive
        // content from the test framework
        updateEventTime();
        debugLog("First trySetupTestFramework");
        await trySetupTestFramework(evaluate);

        debugLog("Evaluate onPageLoaded");
        await evaluate(onPageLoaded);

        debugLog("Calling waitFor...");
        return await waitFor(waitCondition, timeOut);
    }

    async function pageInitializedHandler(evaluate) {
        debugLog("pageInitializedHandler");
        await evaluate(onInitialized);
    }

    function getPageInitializationScript() {
        if (testMode === 'discovery') {
            return "window.chutzpah = { testMode: 'discovery', phantom: true };";
        }
        else {
            return "window.chutzpah = { testMode: 'execution', phantom: true };";
        }
    }

    function wrapFunctionForEvaluation(func) {
        let str = '(' + func.toString() + ')()'

        // If the result is an instanceof of Promise, It's resolved in context of nodejs later.
        return `
        {
          let result = ${str};
          if (result instanceof Promise) {
            result;
          }
          else {
            let json = JSON.stringify(result);
            json;
          }
        }
      `.trim();
    }

    const puppeteer = require('puppeteer-core');
    const fs = require('fs');
    const path = require('path');

    function resolveChromePath() {
        if (canAccess(`${process.env.CHROME_PATH}`)) {
            return process.env.CHROME_PATH;
        }
        return undefined;
    }

    function getChromePaths() {
        const installations = [];
        const suffixes = [
            `${path.sep}Google${path.sep}Chrome SxS${path.sep}Application${path.sep}chrome.exe`,
            `${path.sep}Google${path.sep}Chrome${path.sep}Application${path.sep}chrome.exe`
        ];
        const prefixes = [
            process.env.LOCALAPPDATA, process.env.PROGRAMFILES, process.env['PROGRAMFILES(X86)']
        ].filter(Boolean);

        const customChromePath = resolveChromePath();
        if (customChromePath) {
            installations.push(customChromePath);
        }

        prefixes.forEach(prefix => suffixes.forEach(suffix => {
            const chromePath = path.join(prefix, suffix);
            if (canAccess(chromePath)) {
                installations.push(chromePath);
            }
        }));
        return installations;
    }

    function canAccess(file) {
        if (!file) {
            return false;
        }

        try {
            fs.accessSync(file);
            return true;
        } catch (e) {
            return false;
        }
    }

    function handleError(error) {
        var error;
        if (typeof (error) === 'object') {
            chutzpahFunctions.onError(error.message, error.stack);
        }
        else {
            chutzpahFunctions.onError(error);
        }
    }

    // Capture all uncaught exceptions and wrap before logging
    process.on('uncaughtException', handleError);

    try {
        let chromeExecutable = null;

        if (!chromePath) {
            const chromePaths = getChromePaths();
            if (chromePaths.length <= 0) {
                debugLog("Could not find chrome paths");
            }
            chromeExecutable = chromePaths[0];
        }
        else {
            chromeExecutable = chromePath;
        }

        chutzpahFunctions.rawLog("!!_!! Using Chrome Install : " + chromeExecutable);
        debugLog("Launch Chrome (" + chromeExecutable + "): Elevated= " + isRunningElevated);

        // Disable CORS by default
        var launchBrowserArges = ["--disable-web-security"];
        // If isRunningElevated, we need to turn off sandbox since it does not work with admin users
        if (isRunningElevated) {
            launchBrowserArges.push("--no-sandbox");
        }
        if (browserArgs) {
            launchBrowserArges.push(...browserArgs.trim().split(" "));
        }
        chutzpahFunctions.rawLog("!!_!! puppeteer browser args: " + JSON.stringify(launchBrowserArges));

        // If isRunningElevated, we need to turn off sandbox since it does not work with admin users
        const browser = await puppeteer.launch({
                headless: true, args: launchBrowserArges, executablePath: chromeExecutable
            });

        const page = await browser.newPage();

        try {
            await page.setBypassCSP(true);
        } catch (error) {
            // Older chromes won't support this so just ignore...
        }

        if (userAgent) {
            page.setUserAgent(userAgent);
        }

        const evaluate = async (func) => { return await page.evaluate(wrapFunctionForEvaluation(func)); };

        page.on('requestfinished', (async (request) => {
            chutzpahFunctions.rawLog("!!_!! Resource Received: " + request.url());
            await trySetupTestFramework(evaluate);
        }));

        page.on('requestfailed', ((request) => {
            let errorText = request.failure().errorText;
            if (!ignoreResourceLoadingError) {
                chutzpahFunctions.onError(errorText);
            }
            chutzpahFunctions.rawLog("!!_!! Resource Error for " + request.url() + " with error " + errorText);

        }));

        page.on('console', message => {
            if (message.type === 'error') {
                chutzpahFunctions.onError(message.text(), message.text());
            }
            else {
                chutzpahFunctions.captureLogMessage(message.text());
            }
        });

        page.on('error', error => {
            handleError(error);
        });

        page.on('pageerror', error => {
            handleError(error);
        });

        await page.evaluateOnNewDocument(getPageInitializationScript());

        debugLog("### Navigate..." + testFile);
        await page.goto(testFile, { waitUntil: "load" });

        debugLog("### loadEventFired");

        debugLog("### calling pageInitializedHandler");
        await pageInitializedHandler(evaluate);

        debugLog("### calling pageOpenHandler");
        finalResult = await pageOpenHandler(evaluate);
        debugLog("Just about done: " + finalResult);

    } catch (err) {
        chutzpahFunctions.rawLog("!!_!! Error: " + err);

        debugLog("Closing client");
        if (browser) {
            await browser.close();
        }

        process.exit(2);
    }

    debugLog("Closing client");
    if (browser) {
        await browser.close();
    }

    debugLog("Closed client");

    process.exit(finalResult);

};<|endoftext|>


<commit_before>Miogen.require(['Component.BaseComponent',
                'Component.Textbox',
                'Component.ComboBox',
                'Component.Checkbox'], function () {

    Miogen.define('Component.DataField', Miogen.Component.BaseComponent.extend({

        field: null,
        overrideDefaultCheckbox: null,
        data: null,

        construct: function (cfg) {
            var config = {
                data: null
            };

            Miogen.mixIn(config, cfg);

            this.data = cfg.data;

            this._super(config);
        },

        build: function (cb) {
            var label, t = this, dataType, dataQuery, required, localValue;

            this.el = $('

');
            required = this.data.isRequired();
            dataType = this.data.getType();

            if (dataType !== 'boolean' || !required) {
                // Checkboxes doesn't have separate labels as it's in the control
                label = $('');
                label.text(this.data.getPrompt());
                this.el.append(label);
            }

            // If it's not a boolean and not required, set the override default checkbox
            if (dataType !== 'boolean' && !required) {
                this.overrideDefaultCheckbox = new Miogen.Component.Checkbox({
                    label: 'Override default',
                    checked: this.data.getValue() !== null
                });
                this.addComponent(this.overrideDefaultCheckbox);
            }

            switch (dataType) {
                case 'boolean': {
                    if (required) {
                        this.field = new Miogen.Component.Checkbox({
                            label: this.data.getPrompt(),
                            checked: this.data.getValue()
                        });
                    }
                    else {
                        // It's not required, so we have 3 states, Default, Yes, No
                        this.field = new Miogen.Component.ComboBox({
                            value: this.data.getValue() === null ? '' : (this.data.getValue() ? 'true' : 'false'), // Null means Default
                            options: [
                                {value: '', label: 'Default (' + (this.data.getInheritedValue(false) ? 'Yes' : 'No') + ')'},
                                {value: 'true', label: 'Yes'},
                                {value: 'false', label: 'No'}
                            ]
                        });
                    }
                    break;
                }
                case 'text': {
                    this.field = new Miogen.Component.Textbox({
                        value: this.data.getValue(),
                        disabled: this.data.isReadOnly()
                    });
                    break;
                }
                case 'uri': {
                    this.field = new Miogen.Component.ComboBox({
                        value: this.data.getValue()
                    });
                    break;
                }
                default: {
                    this.field = new Miogen.Component.Textbox({
                        value: this.data.getValue(),
                        disabled: true
                    });
                }
            }

            Miogen.bind(t, this.field, 'onChange', function (value) {
                if (dataType === 'boolean' && !required) {
                    // It can be null, true, false
                    if (value === '') {
                        value = null;
                    }
                    else {
                        value = value === 'true';
                    }
                }
                localValue = value;
                t.data.setValue(value);
            });

            // Watch for changes to the field
            Miogen.bind(t, this.data.getItem(), 'onValueChange', function (attribute, value) {
                if (attribute === t.data.getAttribute() + '.value') {
                    if (dataType === 'boolean' && !required) {
                        // Handle the special case for booleans
                        if (value === null) {
                            value = '';
                        }
                        else {
                            value = value ? 'true' : 'false';
                        }
                    }

                    // If we have an override checkbox, make sure that is enabled before we update the display value
                    if (t.overrideDefaultCheckbox !== null) {
                        if (value === null && t.overrideDefaultCheckbox.getValue() === true) {
                            t.overrideDefaultCheckbox.setValue(false); // We are going back to the not overriding
                            t.field.disable();
                            t.field.setValue(t.data.getInheritedValue());
                        }
                        else {
                            if (value !== null && !t.overrideDefaultCheckbox.getValue()) {
                                // We are overriding the value
                                t.field.enable();
                                t.overrideDefaultCheckbox.setValue(true);
                            }

                            // Only set the value if it's different and is not null (as the text box value will be the inherited one)
                            if (t.field.getValue() !== value && (t.overrideDefaultCheckbox.getValue() !== false && value !== null)) {
                                t.field.setValue(value);
                            }
                        }
                    }
                    else {
                        if (t.field.getValue() !== value) {
                            t.field.setValue(value);
                        }
                    }
                }
            });

            // Bind to the override default checkbox to set the real data field to the appropriate states
            if (this.overrideDefaultCheckbox !== null) {
                localValue = this.data.getValue();
                if (this.data.getValue() === null) {
                    // Disable the field
                    this.field.disable();
                    this.field.setValue(t.data.getInheritedValue());
                }

                Miogen.bind(t, this.overrideDefaultCheckbox, 'onChange', function (value) {
                    if (value) {
                        if (localValue === null) {
                            localValue = t.data.getDefaultValue(''); // Get the default value
                        }

                        t.field.enable();
                        t.field.setValue(localValue);
                        t.data.setValue(localValue);
                    }
                    else {
                        t.field.disable();
                        t.field.setValue(t.data.getInheritedValue());
                        t.data.setValue(null);
                    }
                });
            }

            this.addComponent(this.field);

            // See if we need to load the data
            dataQuery = this.data.getQuery();
            if (dataQuery !== null) {
                // Lookup the data
                Miogen.getViewModel().get({
                    url: dataQuery,
                    success: function (doc) {
                        $.each(doc.getItems(), function (index, item) {
                            t.field.addOption(item.getUri(), item.getField(t.data.getPromptField()).getValue());
                        });

                        t.field.build(function () {
                            cb.call(t);
                        });
                    },
                    error: function () {
                        console.log('Unable to load data', arguments);
                    }
                });
            }
            else {
                // No query lookup, just build it
                this.field.build(function () {
                    if (t.overrideDefaultCheckbox !== null) {
                        t.overrideDefaultCheckbox.build(function () {
                            cb.call(t);
                        });
                    }
                    else {
                        cb.call(t);
                    }
                });
            }
        },

        destroy: function () {
            Miogen.unbind(this, this.field, 'onChange');
            Miogen.unbind(this, this.data.getItem(), 'onValueChange');
            this._super();
        }

    }));

});<commit_msg>Basic support for numeric types<commit_after>Miogen.require(['Component.BaseComponent',
                'Component.Textbox',
                'Component.ComboBox',
                'Component.Checkbox'], function () {

    Miogen.define('Component.DataField', Miogen.Component.BaseComponent.extend({

        field: null,
        overrideDefaultCheckbox: null,
        data: null,

        construct: function (cfg) {
            var config = {
                data: null
            };

            Miogen.mixIn(config, cfg);

            this.data = cfg.data;

            this._super(config);
        },

        build: function (cb) {
            var label, t = this, dataType, dataQuery, required, localValue;

            this.el = $('

');
            required = this.data.isRequired();
            dataType = this.data.getType();

            if (dataType !== 'boolean' || !required) {
                // Checkboxes doesn't have separate labels as it's in the control
                label = $('');
                label.text(this.data.getPrompt());
                this.el.append(label);
            }

            // If it's not a boolean and not required, set the override default checkbox
            if (dataType !== 'boolean' && !required) {
                this.overrideDefaultCheckbox = new Miogen.Component.Checkbox({
                    label: 'Override default',
                    checked: this.data.getValue() !== null
                });
                this.addComponent(this.overrideDefaultCheckbox);
            }

            switch (dataType) {
                case 'boolean': {
                    if (required) {
                        this.field = new Miogen.Component.Checkbox({
                            label: this.data.getPrompt(),
                            checked: this.data.getValue()
                        });
                    }
                    else {
                        // It's not required, so we have 3 states, Default, Yes, No
                        this.field = new Miogen.Component.ComboBox({
                            value: this.data.getValue() === null ? '' : (this.data.getValue() ? 'true' : 'false'), // Null means Default
                            options: [
                                {value: '', label: 'Default (' + (this.data.getInheritedValue(false) ? 'Yes' : 'No') + ')'},
                                {value: 'true', label: 'Yes'},
                                {value: 'false', label: 'No'}
                            ]
                        });
                    }
                    break;
                }
                case 'text': {
                    this.field = new Miogen.Component.Textbox({
                        value: this.data.getValue(),
                        disabled: this.data.isReadOnly()
                    });
                    break;
                }
                case 'numeric': {
                    // TODO: Use a number stepper and have numeric validation
                    this.field = new Miogen.Component.Textbox({
                        value: this.data.getValue(),
                        disabled: this.data.isReadOnly()
                    });
                    break;
                }
                case 'uri': {
                    this.field = new Miogen.Component.ComboBox({
                        value: this.data.getValue()
                    });
                    break;
                }
                default: {
                    this.field = new Miogen.Component.Textbox({
                        value: this.data.getValue(),
                        disabled: true
                    });
                }
            }

            Miogen.bind(t, this.field, 'onChange', function (value) {
                if (dataType === 'boolean' && !required) {
                    // It can be null, true, false
                    if (value === '') {
                        value = null;
                    }
                    else {
                        value = value === 'true';
                    }
                }
                localValue = value;
                t.data.setValue(value);
            });

            // Watch for changes to the field
            Miogen.bind(t, this.data.getItem(), 'onValueChange', function (attribute, value) {
                if (attribute === t.data.getAttribute() + '.value') {
                    if (dataType === 'boolean' && !required) {
                        // Handle the special case for booleans
                        if (value === null) {
                            value = '';
                        }
                        else {
                            value = value ? 'true' : 'false';
                        }
                    }

                    // If we have an override checkbox, make sure that is enabled before we update the display value
                    if (t.overrideDefaultCheckbox !== null) {
                        if (value === null && t.overrideDefaultCheckbox.getValue() === true) {
                            t.overrideDefaultCheckbox.setValue(false); // We are going back to the not overriding
                            t.field.disable();
                            t.field.setValue(t.data.getInheritedValue());
                        }
                        else {
                            if (value !== null && !t.overrideDefaultCheckbox.getValue()) {
                                // We are overriding the value
                                t.field.enable();
                                t.overrideDefaultCheckbox.setValue(true);
                            }

                            // Only set the value if it's different and is not null (as the text box value will be the inherited one)
                            if (t.field.getValue() !== value && (t.overrideDefaultCheckbox.getValue() !== false && value !== null)) {
                                t.field.setValue(value);
                            }
                        }
                    }
                    else {
                        if (t.field.getValue() !== value) {
                            t.field.setValue(value);
                        }
                    }
                }
            });

            // Bind to the override default checkbox to set the real data field to the appropriate states
            if (this.overrideDefaultCheckbox !== null) {
                localValue = this.data.getValue();
                if (this.data.getValue() === null) {
                    // Disable the field
                    this.field.disable();
                    this.field.setValue(t.data.getInheritedValue());
                }

                Miogen.bind(t, this.overrideDefaultCheckbox, 'onChange', function (value) {
                    if (value) {
                        if (localValue === null) {
                            localValue = t.data.getDefaultValue(''); // Get the default value
                        }

                        t.field.enable();
                        t.field.setValue(localValue);
                        t.data.setValue(localValue);
                    }
                    else {
                        t.field.disable();
                        t.field.setValue(t.data.getInheritedValue());
                        t.data.setValue(null);
                    }
                });
            }

            this.addComponent(this.field);

            // See if we need to load the data
            dataQuery = this.data.getQuery();
            if (dataQuery !== null) {
                // Lookup the data
                Miogen.getViewModel().get({
                    url: dataQuery,
                    success: function (doc) {
                        $.each(doc.getItems(), function (index, item) {
                            t.field.addOption(item.getUri(), item.getField(t.data.getPromptField()).getValue());
                        });

                        t.field.build(function () {
                            cb.call(t);
                        });
                    },
                    error: function () {
                        console.log('Unable to load data', arguments);
                    }
                });
            }
            else {
                // No query lookup, just build it
                this.field.build(function () {
                    if (t.overrideDefaultCheckbox !== null) {
                        t.overrideDefaultCheckbox.build(function () {
                            cb.call(t);
                        });
                    }
                    else {
                        cb.call(t);
                    }
                });
            }
        },

        destroy: function () {
            Miogen.unbind(this, this.field, 'onChange');
            Miogen.unbind(this, this.data.getItem(), 'onValueChange');
            this._super();
        }

    }));

});<|endoftext|>


<commit_before>'use strict';

const webpack = require('webpack');
const { resolve } = require('path');

const buildPath = resolve(__dirname, 'dist', 'dll');

module.exports = {
  // TODO: needs to update the context value to link to the app folder
  context: __dirname,

  entry: {
    vendors: [resolve('config', 'dll', 'vendors.js')],
  },

  output: {
    path: buildPath,
    filename: '[name].js',
    library: '[name]__[hash]',
  },

  resolve: {
    modules: ['node_modules'],
  },

  plugins: [
    new webpack.DllPlugin({
      path: resolve(buildPath, 'manifest.json'),
      name: '[name]__[hash]',
    }),

    new webpack.optimize.UglifyJsPlugin(),
  ],
};
<commit_msg>Deleted unused webpack dll config<commit_after><|endoftext|>


<commit_before>'use strict';

GetOption( { 'enhancement-friendsthatown': true }, function( items )
{
	if( !items[ 'enhancement-friendsthatown' ] )
	{
		return;
	}

	var xhrfriends = new XMLHttpRequest();
	var xhr = new XMLHttpRequest();
	var appid = GetCurrentAppID();
	var bDoneAsync = false;

	var HTTPCallback = function()
	{
		if( xhr.readyState !== 4 || xhr.status !== 200 )
		{
			return;
		}

		if( !bDoneAsync )
		{
			bDoneAsync = true;

			return;
		}

		if( !xhr.response[ appid ].success )
		{
			return;
		}

		var friendsown = xhr.response[ appid ].data.friendsown;
		if( !friendsown.length )
		{
			return;
		}

		var friends = xhrfriends.response.querySelector( '.profile_friends' ).children;
		var i, steamID, miniprofiles = {};

		for( i = 0; i < friends.length; ++i )
		{
			steamID = friends[ i ].getAttribute( 'data-miniprofile' );

			miniprofiles[ steamID ] = friends[ i ];
		}

		var fragment = document.createDocumentFragment();

		var div = document.createElement( 'div' );
		div.className = 'mainSectionHeader friendListSectionHeader';
		div.appendChild( document.createTextNode( friendsown.length + ' friends who own this game ' ) );

		var span = document.createElement( 'span' );
		span.className = 'underScoreColor';
		span.appendChild( document.createTextNode( '_' ) );
		div.appendChild( span );

		fragment.appendChild( div );

		div = document.createElement( 'div' );
		div.className = 'profile_friends';

		for( i = 0; i < friendsown.length; ++i )
		{
			steamID = friendsown[ i ].steamid.slice( 4 ) - 1197960265728;

			var newText = document.createElement( 'div' );
			newText.className = 'friendSmallText';

			var hours = Math.round( friendsown[ i ].playtime_twoweeks / 60 * 10 ) / 10 + ' hrs';
			hours += ' / ' + Math.round( friendsown[ i ].playtime_total / 60 * 10 ) / 10 + ' hrs';
			newText.appendChild( document.createTextNode( hours ) );

			newText.appendChild( document.createElement( 'br' ) );

			var compareLink = document.createElement( 'a' );
			compareLink.className = 'whiteLink friendBlockInnerLink';
			compareLink.href = miniprofiles[ steamID ].querySelector( '.friendBlockLinkOverlay' ).href + '/stats/' + appid + '/compare';
			compareLink.appendChild( document.createTextNode( 'View stats' ) );

			newText.appendChild( compareLink );

			var originalText = miniprofiles[ steamID ].querySelector( '.friendSmallText' );
			originalText.parentNode.replaceChild( newText, originalText );

			div.appendChild( miniprofiles[ steamID ] );
		}

		var clearleftdiv = document.createElement( 'div' );
		clearleftdiv.style.clear = 'left';
		div.appendChild( clearleftdiv );

		fragment.appendChild( div );

		document.getElementById( 'memberList' ).appendChild( fragment );

		// We need to reinitialize miniprofile hovers
		var script = document.createElement( 'script' );
		script.id = 'steamdb_init_miniprofiles';
		script.type = 'text/javascript';
		script.appendChild( document.createTextNode( 'InitMiniprofileHovers();' ) );

		document.head.appendChild( script );
	};

	xhrfriends.onreadystatechange = HTTPCallback;
	xhrfriends.open( 'GET', '//steamcommunity.com/my/friends/', true );
	xhrfriends.responseType = 'document';
	xhrfriends.send();

	xhr.onreadystatechange = HTTPCallback;
	xhr.open( 'GET', '//store.steampowered.com/api/appuserdetails/?appids=' + appid, true );
	xhr.responseType = 'json';
	xhr.send();
} );
<commit_msg>Make friendsthatplay work more reliably, add loading indicator<commit_after>'use strict';

GetOption( { 'enhancement-friendsthatown': true }, function( items )
{
	if( !items[ 'enhancement-friendsthatown' ] )
	{
		return;
	}

	var div = document.createElement( 'div' );
	div.className = 'mainSectionHeader friendListSectionHeader';

	var friendsOwnNumber = document.createElement( 'span' );
	friendsOwnNumber.appendChild( document.createTextNode( 'Loading' ) );
	div.appendChild( friendsOwnNumber );
	div.appendChild( document.createTextNode( ' friends who own this game ' ) );

	var span = document.createElement( 'span' );
	span.className = 'underScoreColor';
	span.appendChild( document.createTextNode( '_' ) );
	div.appendChild( span );

	document.getElementById( 'memberList' ).appendChild( div );

	var xhrfriends = new XMLHttpRequest();
	var xhr = new XMLHttpRequest();
	var appid = GetCurrentAppID();

	var HTTPCallback = function()
	{
		if( xhr.readyState !== 4 || xhr.status !== 200 || xhrfriends.readyState !== 4 || xhrfriends.status !== 200 )
		{
			if( xhr.readyState === 4 && xhrfriends.readyState === 4 )
			{
				friendsOwnNumber.style.color = 'red';
				friendsOwnNumber.textContent = 'Failed to load';
			}

			return;
		}

		if( !xhr.response[ appid ].success )
		{
			friendsOwnNumber.style.color = 'red';
			friendsOwnNumber.textContent = 'Failed to load';

			return;
		}

		var friendsown = xhr.response[ appid ].data.friendsown;

		if( !friendsown || !friendsown.length )
		{
			friendsOwnNumber.textContent = '0';

			return;
		}

		friendsOwnNumber.textContent = friendsown.length;

		var friends = xhrfriends.response.querySelector( '.profile_friends' ).children;
		var i, steamID, miniprofiles = {};

		for( i = 0; i < friends.length; ++i )
		{
			steamID = friends[ i ].getAttribute( 'data-miniprofile' );

			miniprofiles[ steamID ] = friends[ i ];
		}

		var fragment = document.createDocumentFragment();

		div = document.createElement( 'div' );
		div.className = 'profile_friends';

		for( i = 0; i < friendsown.length; ++i )
		{
			steamID = friendsown[ i ].steamid.slice( 4 ) - 1197960265728;

			var newText = document.createElement( 'div' );
			newText.className = 'friendSmallText';

			var hours = Math.round( friendsown[ i ].playtime_twoweeks / 60 * 10 ) / 10 + ' hrs';
			hours += ' / ' + Math.round( friendsown[ i ].playtime_total / 60 * 10 ) / 10 + ' hrs';
			newText.appendChild( document.createTextNode( hours ) );

			newText.appendChild( document.createElement( 'br' ) );

			var compareLink = document.createElement( 'a' );
			compareLink.className = 'whiteLink friendBlockInnerLink';
			compareLink.href = miniprofiles[ steamID ].querySelector( '.friendBlockLinkOverlay' ).href + '/stats/' + appid + '/compare';
			compareLink.appendChild( document.createTextNode( 'View stats' ) );

			newText.appendChild( compareLink );

			var originalText = miniprofiles[ steamID ].querySelector( '.friendSmallText' );
			originalText.parentNode.replaceChild( newText, originalText );

			div.appendChild( miniprofiles[ steamID ] );
		}

		var clearleftdiv = document.createElement( 'div' );
		clearleftdiv.style.clear = 'left';
		div.appendChild( clearleftdiv );

		fragment.appendChild( div );

		document.getElementById( 'memberList' ).appendChild( fragment );

		// We need to reinitialize miniprofile hovers
		var script = document.createElement( 'script' );
		script.id = 'steamdb_init_miniprofiles';
		script.type = 'text/javascript';
		script.appendChild( document.createTextNode( 'InitMiniprofileHovers();' ) );

		document.head.appendChild( script );
	};

	xhrfriends.onreadystatechange = HTTPCallback;
	xhrfriends.open( 'GET', '//steamcommunity.com/my/friends/', true );
	xhrfriends.responseType = 'document';
	xhrfriends.send();

	xhr.onreadystatechange = HTTPCallback;
	xhr.open( 'GET', '//store.steampowered.com/api/appuserdetails/?appids=' + appid, true );
	xhr.responseType = 'json';
	xhr.send();
} );
<|endoftext|>


<commit_before>Components.utils.import("resource:///modules/gloda/log4moz.js");

// Rules:
//
// onDragEnter: Reset timer
//              Set current row to null
//              Set cached view to null
// onDragExit:  Cancel timer
//              Switch to cached folder view, if any
// onDragOver:  In all folders view?
//              Yes: Do nothing
//              No: Has current row changed?
//                  Yes: Reset timer
//                  No: Do nothing
// notify:      Cache old folder view
//              Switch to all folders view
// resetTimer:  In all folders view?
//              Yes: Do nothing
//              No: Start timer

var FolderPaneSwitcher = {
  showHideArrowsObserver: {
    observe: function() {
      var prefBranch = Components.classes["@mozilla.org/preferences-service;1"]
          .getService(Components.interfaces.nsIPrefBranch);
      var show = prefBranch.getBoolPref("extensions.FolderPaneSwitcher.arrows");
      FolderPaneSwitcher.logger.debug("show="+show);
      document.getElementById("folderPaneHeader").hidden = !show;
    }
  },

  onLoad: function() {
    if (! this.logger) {
      this.logger = Log4Moz.getConfiguredLogger("extensions.FolderPaneSwitcher",
						Log4Moz.Level.Trace,
						Log4Moz.Level.Info,
						Log4Moz.Level.Debug);
    }
    var me = FolderPaneSwitcher;
    var folderTree = document.getElementById("folderTree");
    var treechildren = folderTree.getElementsByTagName("treechildren")[0];
    treechildren.addEventListener("dragenter", me.onDragEnter, false);
    treechildren.addEventListener("dragexit", me.onDragExit, false);
    treechildren.addEventListener("dragover", me.onDragOver, false);
    FolderPaneSwitcher.showHideArrowsObserver.observe();
    var prefBranch = Components.classes["@mozilla.org/preferences-service;1"]
        .getService(Components.interfaces.nsIPrefBranch);
    prefBranch.addObserver("extensions.FolderPaneSwitcher.arrows",
			   FolderPaneSwitcher.showHideArrowsObserver, false);
  },

  onDragEnter: function() {
    FolderPaneSwitcher.logger.debug("onDragEnter");
    FolderPaneSwitcher.resetTimer();
    FolderPaneSwitcher.currentRow = null;
    FolderPaneSwitcher.cachedView = null;
  },

  onDragExit: function() {
    FolderPaneSwitcher.logger.debug("onDragExit");
    if (FolderPaneSwitcher.timer) {
      FolderPaneSwitcher.timer.cancel();
      FolderPaneSwitcher.timer = null;
    }
    if (FolderPaneSwitcher.cachedView) {
      gFolderTreeView.mode = FolderPaneSwitcher.cachedView;
    }
  },

  onDragOver: function(aEvent) {
    FolderPaneSwitcher.logger.debug("onDragOver");
    if (gFolderTreeView.mode == "all") {
      return;
    }
    var row = gFolderTreeView.getFolderAtCoords(aEvent.clientX, aEvent.clientY);
    if (row != FolderPaneSwitcher.currentRow) {
      FolderPaneSwitcher.resetTimer();
      FolderPaneSwitcher.currentRow = row;
    }
  },

  timer: null,
  timerCallback: {
    notify: function() {
      FolderPaneSwitcher.logger.debug("timerCallback.notify");
      FolderPaneSwitcher.cachedView = gFolderTreeView.mode;
      gFolderTreeView.mode = "all";
      FolderPaneSwitcher.timer = null;
    },
  },

  resetTimer: function() {
    if (FolderPaneSwitcher.timer) {
      FolderPaneSwitcher.timer.cancel();
    }
    var prefBranch = Components.classes["@mozilla.org/preferences-service;1"]
        .getService(Components.interfaces.nsIPrefBranch);
    var delay = prefBranch.getIntPref("extensions.FolderPaneSwitcher.delay");
    var t = Components.classes["@mozilla.org/timer;1"]
	.createInstance(Components.interfaces.nsITimer);
    t.initWithCallback(FolderPaneSwitcher.timerCallback, delay,
		       Components.interfaces.nsITimer.TYPE_ONE_SHOT);
    FolderPaneSwitcher.timer = t;
  },
};

window.addEventListener("load", function () { FolderPaneSwitcher.onLoad(); }, false);
<commit_msg>Remove unneeded debugging. Work around the fact that dragexit and dragdrop don't get sent when user actually does a legitimate drop.<commit_after>Components.utils.import("resource:///modules/gloda/log4moz.js");

// Rules:
//
// onDragEnter: Reset timer
//              Set current row to null
//              Set cached view to null
// onDragExit:  Cancel timer
//              Switch to cached folder view, if any
// onDragDrop:  Same as onDragExit
// onDragOver:  In all folders view?
//              Yes: Do nothing
//              No: Has current row changed?
//                  Yes: Reset timer
//                  No: Do nothing
// notify:      Cache old folder view
//              Switch to all folders view
// resetTimer:  In all folders view?
//              Yes: Do nothing
//              No: Start timer

var FolderPaneSwitcher = {
  showHideArrowsObserver: {
    observe: function() {
      var prefBranch = Components.classes["@mozilla.org/preferences-service;1"]
          .getService(Components.interfaces.nsIPrefBranch);
      var show = prefBranch.getBoolPref("extensions.FolderPaneSwitcher.arrows");
      document.getElementById("folderPaneHeader").hidden = !show;
    }
  },

  onLoad: function() {
    if (! this.logger) {
      this.logger = Log4Moz.getConfiguredLogger("extensions.FolderPaneSwitcher",
						Log4Moz.Level.Trace,
						Log4Moz.Level.Info,
						Log4Moz.Level.Debug);
    }
    var me = FolderPaneSwitcher;
    var folderTree = document.getElementById("folderTree");
    var treechildren = folderTree.getElementsByTagName("treechildren")[0];
    treechildren.addEventListener("dragenter", me.onDragEnter, false);
    treechildren.addEventListener("dragover", me.onDragOver, false);
    // Dragexit and dragdrop don't actually get sent when the user
    // drops a message into a folder. This is arguably a bug in
    // Thunderbird (see bz#674807). To work around it, I register a
    // folder listener to detect when a move or copy is
    // completed. This is gross, but appears to work well enough.
    treechildren.addEventListener("dragexit", me.onDragExit, false);
    treechildren.addEventListener("dragdrop", me.onDragExit, false);
    var ns =
	Components.classes["@mozilla.org/messenger/msgnotificationservice;1"]
	.getService(Components.interfaces.nsIMsgFolderNotificationService);
    ns.addListener(me.folderListener, ns.msgsMoveCopyCompleted|
		   ns.folderMoveCopyCompleted);
    FolderPaneSwitcher.showHideArrowsObserver.observe();
    var prefBranch = Components.classes["@mozilla.org/preferences-service;1"]
        .getService(Components.interfaces.nsIPrefBranch);
    prefBranch.addObserver("extensions.FolderPaneSwitcher.arrows",
			   FolderPaneSwitcher.showHideArrowsObserver, false);
  },

  folderListener: {
    msgsMoveCopyCompleted: function(aMove, aSrcMsgs, aDestFolder, aDestMsgs) {
      if (aDestFolder == FolderPaneSwitcher.currentFolder) {
	// Still remotely possible that someone else could be copying
	// into the same folder at the same time as us, but this is
	// the best we can do until they fix the event bug.
	FolderPaneSwitcher.onDragExit({type:"msgsMoveCopyCompleted"});
      }
    },
    folderMoveCopyCompleted: function(aMove, aSrcFolder, aDestFolder) {
      if (aDestFolder == FolderPaneSwitcher.currentFolder) {
	// Still remotely possible that someone else could be copying
	// into the same folder at the same time as us, but this is
	// the best we can do until they fix the event bug.
	FolderPaneSwitcher.onDragExit({type:"folderMoveCopyCompleted"});
      }
    }
  },

  onDragEnter: function() {
    FolderPaneSwitcher.logger.debug("onDragEnter");
    FolderPaneSwitcher.resetTimer();
    FolderPaneSwitcher.cachedView = null;
    FolderPaneSwitcher.currentFolder = null;
  },

  onDragExit: function(aEvent) {
    FolderPaneSwitcher.logger.debug("onDragExit("+aEvent.type+")");
    if (FolderPaneSwitcher.timer) {
      FolderPaneSwitcher.timer.cancel();
      FolderPaneSwitcher.timer = null;
    }
    if (FolderPaneSwitcher.cachedView) {
      gFolderTreeView.mode = FolderPaneSwitcher.cachedView;
      FolderPaneSwitcher.cachedView = null;
    }
    FolderPaneSwitcher.currentFolder = null;
  },

  onDragOver: function(aEvent) {
    FolderPaneSwitcher.logger.trace("onDragOver"); // too verbose for debug
    var old = FolderPaneSwitcher.currentFolder;
    FolderPaneSwitcher.currentFolder =
	gFolderTreeView.getFolderAtCoords(aEvent.clientX, aEvent.clientY);
    if (gFolderTreeView.mode == "all") {
      return;
    }
    if (old != FolderPaneSwitcher.currentFolder) {
      FolderPaneSwitcher.resetTimer();
      FolderPaneSwitcher.currentFolder = folder;
    }
  },

  timer: null,
  timerCallback: {
    notify: function() {
      FolderPaneSwitcher.logger.debug("timerCallback.notify");
      FolderPaneSwitcher.cachedView = gFolderTreeView.mode;
      gFolderTreeView.mode = "all";
      FolderPaneSwitcher.timer = null;
    },
  },

  resetTimer: function() {
    if (FolderPaneSwitcher.timer) {
      FolderPaneSwitcher.timer.cancel();
    }
    var prefBranch = Components.classes["@mozilla.org/preferences-service;1"]
        .getService(Components.interfaces.nsIPrefBranch);
    var delay = prefBranch.getIntPref("extensions.FolderPaneSwitcher.delay");
    var t = Components.classes["@mozilla.org/timer;1"]
	.createInstance(Components.interfaces.nsITimer);
    t.initWithCallback(FolderPaneSwitcher.timerCallback, delay,
		       Components.interfaces.nsITimer.TYPE_ONE_SHOT);
    FolderPaneSwitcher.timer = t;
  },
};

window.addEventListener("load", function () { FolderPaneSwitcher.onLoad(); }, false);
<|endoftext|>


<commit_before>import React, { PureComponent } from 'react'
import { connect } from 'react-redux'
import clearErrors from '../../actions/interface/clear-errors'

import closebutton from '../../assets/images/close.svg'

class ErrorComp extends PureComponent {
  render() {
    const { error } = this.props
    if (!!error) {
      return (

{ error.type }

{ error.message }

      )
    } else {
      return null
    }
  }
}

const mapStateToProps = ({ error }) => ({ error })
export default connect(mapStateToProps, { clearErrors })(ErrorComp)
<commit_msg>Add PropTypes to Error<commit_after>import React, { PureComponent, PropTypes } from 'react'
import { connect } from 'react-redux'
import clearErrors from '../../actions/interface/clear-errors'

import closebutton from '../../assets/images/close.svg'

class ErrorComp extends PureComponent {
  static propTypes = {
    error: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]).isRequired,
    clearErrors: PropTypes.func.isRequired
  }

  render() {
    const { error, clearErrors } = this.props
    if (!!error) {
      return (

{ error.type }

{ error.message }

      )
    } else {
      return null
    }
  }
}

const mapStateToProps = ({ error }) => ({ error })
export default connect(mapStateToProps, { clearErrors })(ErrorComp)
<|endoftext|>