<commit_before>var EventSourcedAggregate = require('./EventSourcedAggregate').EventSourcedAggregate;
var Event = require('./Event').Event;
var util = require('util');
var when = require('when');

function SagaStage(name, accumulatorFunction){
	this.name = name;
	this.transitions = {};
}
SagaStage.prototype.addTransition = function addTransition(transition){
	this.transitions[transition.name] = transition;
	// Allow method chaining.
	return this;
};
SagaStage.prototype.handleEvent = function handleEvent(event, commit, queuedEvents, accumulator){
	var specificMethodName = 'on' + event.eventType;
	if(typeof(this[specificMethodName]) === 'function'){
		this[specificMethodName](event, commit, queuedEvents, accumulator);
	}
	else{
		if(typeof(this.defaultEventHandler) === 'function'){
			this.defaultEventHandler(event, commit, queuedEvents, accumulator);
		}
	}
};

function SagaTransition(name, eventAcceptorFunction, actionFunction, transitionEventType, eventPayloadGenerator){
	this.destination = null;
	this.eventEndsTransition = eventAcceptorFunction;
	this.performAction = actionFunction;
	this.transitionEventType = transitionEventType;
	this.eventPayloadGenerator = (typeof(eventPayloadGenerator) === 'function') ? eventPayloadGenerator : function(event, commit, queuedEvents, accumulator){};
}

SagaTransition.prototype.setDestination = function setDestination(destination){
	this.destination = destination;
	// Allow method chaining.
	return this;
};

function Saga(){

}
util.inherits(Saga, EventSourcedAggregate);

Saga.prototype._init = function _init(initialStage){
	this._currentStage = initialStage;
	this._currentStagePath = 'init';
	this._stageAccumulator = {};
	this._enqueuedEvents = [];
	this._seenEventIDs = {};
	this._error = null;
	this._allowMissingEventHandlers = true;
};

Saga.prototype.processEvent = function processEvent(event, commit){
	var self = this;
	// Guard clause: do not process duplicate events.
	if(this._seenEventIDs[event.eventID]){
		return when.resolve();
	}
	// Gather all transitions that are to occur. We use each transition's supplied decision function.
	var transitionIntents = [];
	for(var transitionKey in this._currentStage.transitions){
		var currentTransition = this._currentStage.transitions[transitionKey];
		var transitionDecision = currentTransition.eventEndsTransition(event, commit, this._enqueuedEvents, this._stageAccumulator);
		if(transitionDecision){
			transitionIntents.push(currentTransition);
		}
	}
	// Check if any transitions have been marked for passing.
	if(transitionIntents.length > 0){
		// There is at least one nominated transition.
		// Check for conflicts.
		if(transitionIntents.length > 1){
			//TODO: define the event payload below in a better way.
			this._stageEvent('TransitionConflictDetected', {currentStage: this._currentStage.name, currentEventType: event.eventType});
			return when.reject(new TransitionConflictError('Transition conflict detected - will not proceed with state transition'));
		}
		var transition = transitionIntents[0];
		return when(transition.performAction(event, commit, this._enqueuedEvents, this._stageAccumulator),
		function _finalizeTransition(actionResult){
			self._stageEvent(new Event(transition.transitionEventType, transition.eventPayloadGenerator(event, commit, self._enqueuedEvents, self._stageAccumulator, actionResult)));
			self._stageEvent(new Event('TransitionCompleted', {transitionName: transition.name}));
			return when.resolve(actionResult);
		},
		function _cancelTransition(reason){
			return when.reject(reason);
		});
	}
	else{
		// No transitions - simply enqueue the event.
		this._stageEvent(new Event('EventEnqueued', {event: event}));
		return when.resolve();
	}
};

Saga.prototype.onEventEnqueued = function onEventEnqueued(event, commit){
	this._enqueuedEvents.push(event);
	this._currentStage.handleEvent(event, commit, this._enqueuedEvents, this._stageAccumulator);
};

Saga.prototype.onTransitionCompleted = function onTransitionCompleted(event, commit){
	var transitionName = event.eventPayload.transitionName;
	this._currentStage = this._currentStage.transitions[transitionName].destination;
	this._currentStagePath += '.' + transitionName;
	this._enqueuedEvents = [];
	this._stageAccumulator = {};
};

Saga.prototype._getSnapshotData = function _getSnapshotData(){
	return {
		stagePath: this._currentStagePath,
		enqueuedEvents: this._enqueuedEvents,
		stageAccumulator: this._stageAccumulator,
		seenEventIDs: Object.keys(this._seenEventIDs)
	};
};

module.exports.SagaStage = SagaStage;
module.exports.SagaTransition = SagaTransition;
module.exports.Saga = Saga;<commit_msg>Saga now supports passing an environment object whose purpose is to provide runtime services and dependencies to the transition function. Also, a saga may now filter the events that it processes, rejecting those which it is not ready to handle (yet).<commit_after>var EventSourcedAggregate = require('./EventSourcedAggregate').EventSourcedAggregate;
var Event = require('./Event').Event;
var util = require('util');
var when = require('when');

function SagaStage(name, acceptedEventTypes){
	this.name = name;
	this.transitions = {};
	this.acceptedEventTypes = acceptedEventTypes;
}
SagaStage.prototype.addTransition = function addTransition(transition){
	this.transitions[transition.name] = transition;
	// Allow method chaining.
	return this;
};
SagaStage.prototype.handleEvent = function handleEvent(event, commit, queuedEvents, accumulator, sagaAccumulator){
	var specificMethodName = 'on' + event.eventType;
	if(typeof(this[specificMethodName]) === 'function'){
		this[specificMethodName](event, commit, queuedEvents, accumulator, sagaAccumulator);
	}
	else{
		if(typeof(this.defaultEventHandler) === 'function'){
			this.defaultEventHandler(event, commit, queuedEvents, accumulator, sagaAccumulator);
		}
	}
};

function SagaTransition(name, eventAcceptorFunction, actionFunction, transitionEventType, eventPayloadGenerator){
	this.destination = null;
	this.eventEndsTransition = eventAcceptorFunction;
	this.performAction = actionFunction || function(event, commit, queuedEvents, stageAccumulator, sagaAccumulator, environment){};
	this.transitionEventType = transitionEventType;
	this.eventPayloadGenerator = (typeof(eventPayloadGenerator) === 'function') ? eventPayloadGenerator : function(event, commit, queuedEvents, accumulator, globalAccumulator, actionResult){
		return {};
	};
}

SagaTransition.prototype.setDestination = function setDestination(destination){
	this.destination = destination;
	// Allow method chaining.
	return this;
};

function Saga(){

}
util.inherits(Saga, EventSourcedAggregate);

Saga.prototype._init = function _init(initialStage){
	this._currentStage = initialStage;
	this._currentStagePath = initialStage.name;
	this._stageAccumulator = {};
	this._globalAccumulator = {};
	this._enqueuedEvents = [];
	this._seenEventIDs = {};
	this._error = null;
	this._allowMissingEventHandlers = true;
};

Saga.prototype.processEvent = function processEvent(event, commit, environment){
	var self = this;
	// Guard clause: do not process duplicate events.
	if(this._seenEventIDs[event.eventID]){
		return when.resolve();
	}
	if(this.currentStage.acceptedEventTypes.indexOf(event.eventType) < 0){
		return when.reject(new EventTypeNotAccepted('The saga does not accept this type of events at this stage - perhaps try processing at a later stage?'));
	}
	// Gather all transitions that are to occur. We use each transition's supplied decision function.
	var transitionIntents = [];
	for(var transitionKey in this._currentStage.transitions){
		var currentTransition = this._currentStage.transitions[transitionKey];
		var transitionDecision = currentTransition.eventEndsTransition(event, commit, this._enqueuedEvents, this._stageAccumulator, this._globalAccumulator);
		if(transitionDecision){
			transitionIntents.push(currentTransition);
		}
	}
	// Check if any transitions have been marked for passing.
	if(transitionIntents.length > 0){
		// There is at least one nominated transition.
		// Check for conflicts.
		if(transitionIntents.length > 1){
			//TODO: define the event payload below in a better way.
			this._stageEvent('TransitionConflictDetected', {currentStage: this._currentStage.name, currentEventType: event.eventType});
			return when.reject(new TransitionConflictError('Transition conflict detected - will not proceed with state transition'));
		}
		var transition = transitionIntents[0];
		return when(transition.performAction(event, commit, this._enqueuedEvents, this._stageAccumulator, this._globalAccumulator, environment),
		function _finalizeTransition(actionResult){
			if(transition.transitionEventType){
				self._stageEvent(new Event(transition.transitionEventType, transition.eventPayloadGenerator(event, commit, self._enqueuedEvents, self._stageAccumulator, self._globalAccumulator, actionResult)));
			}
			self._stageEvent(new Event('TransitionCompleted', {transitionName: transition.name, event: event, commit: commit}));
			return when.resolve(actionResult);
		},
		function _cancelTransition(reason){
			return when.reject(reason);
		});
	}
	else{
		// No transitions - simply enqueue the event.
		this._stageEvent(new Event('EventEnqueued', {event: event}));
		return when.resolve();
	}
};

Saga.prototype.onEventEnqueued = function onEventEnqueued(event, commit){
	this._enqueuedEvents.push(event);
	this._currentStage.handleEvent(event, commit, this._enqueuedEvents, this._stageAccumulator, this._globalAccumulator);
};

Saga.prototype.onTransitionCompleted = function onTransitionCompleted(event, commit){
	var transitionName = event.eventPayload.transitionName;
	this._currentStage.handleEvent(event.eventPayload.event, event.eventPayload.commit, this._enqueuedEvents, this._stageAccumulator, this._globalAccumulator);
	this._currentStage = this._currentStage.transitions[transitionName].destination;
	this._currentStagePath += '.' + transitionName;
	this._enqueuedEvents = [];
	this._stageAccumulator = {};
};

Saga.prototype._getSnapshotData = function _getSnapshotData(){
	return {
		stagePath: this._currentStagePath,
		enqueuedEvents: this._enqueuedEvents,
		stageAccumulator: this._stageAccumulator,
		globalAccumulator: this._globalAccumulator,
		seenEventIDs: Object.keys(this._seenEventIDs)
	};
};

// Helper functions for Saga users.
Saga.eventTypesSeen = function eventTypesSeen(requiredEventTypes){
	function isContainedIn(containee, container){
		return containee.every(function(element){
			return container.indexOf(element) >= 0;
		});
	}
	return function _eventTypesSeen(event, commit, queuedEvents){
		var seenEventTypes = queuedEvents.concat(event).map(function(ev){
			return ev.eventType;
		});
		return isContainedIn(requiredEventTypes, seenEventTypes);
	};
};

module.exports.SagaStage = SagaStage;
module.exports.SagaTransition = SagaTransition;
module.exports.Saga = Saga;<|endoftext|>


<commit_before>/**
 * Map组件
 * @author yellow date 2017/7/24
 * -由于此组件包含input,button。可以根据需要拆分组件
 *
 */
import React, { Component } from 'react';
import { connect } from 'react-redux';
import RootReducer from './../../redux/RootReducer';
import PropTypes from 'prop-types';
import * as maptalks from 'maptalks';

//引入地图组件
import MapToolBar from './MapToolBar';
/**
 * @type {maptalks.Map}
 * 全局的地图对象和方法
 */
let map;

/**
 * 地图组件
 * @class
 */
class Map extends Component {

    componentDidMount() {
        const mapDiv = this.refs.map;
        map = new maptalks.Map(mapDiv, {
            center: [-0.113049, 51.498568],
            zoom: 14,
            baseLayer: new maptalks.TileLayer('base', {
                urlTemplate: 'http://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}.png',//'http://{s}.tile.osm.org/{z}/{x}/{y}.png',
                subdomains: ['a', 'b', 'c', 'd', 'e']
            }),
            layers: [
                new maptalks.VectorLayer('point'),
                new maptalks.VectorLayer('line'),
                new maptalks.VectorLayer('polygon')
            ]
        });
        map.setZoom(20);
    }

    render() {

        const { onMenuItemClick } = this.props;

        return (

                <div ref='map' style={{ color: "#000", width: '100%', height: `${window.innerHeight}px` }} />
                <MapToolBar onClick={onMenuItemClick} text="zoom_in" />

        )
    }

}

/**
 * 限定组件的一些属性
 */
Map.propTypes = {
    //onClick: PropTypes.func.isRequired
}

//加入reducer(mapReduce)
const mapReduce = (state = 0, action) => {
    //获取当前定位
    if (action.type === "menuClick" && action.payload.command === "get_location") {
        //获取定位,由于无GPS返回固定坐标
        const center = new maptalks.Coordinate(114.360734, 30.541093);
        map.setCenter(center);
        const circle = new maptalks.Circle(center, 20, {
            symbol: {
                lineColor: '#34495e',
                lineWidth: 2,
                polygonFill: '#1bbc9b',
                polygonOpacity: 0.4
            }
        });
        const marker = new maptalks.Marker(
            center, {
                symbol: {
                    'textFaceName': 'sans-serif',
                    'textName': 'your location',
                    'textFill': '#34495e',
                    'textHorizontalAlignment': 'right',
                    'textSize': 25
                }
            }
        );
        const line = new maptalks.LineString([
            center.add(-0.018, 0.005),
            center.add(0.006, 0.005)
        ], {
                symbol: {
                    'lineColor': '#1bbc9b',
                    'lineWidth': 3
                }
            });
        //将对象添加至图层
        map.getLayer('point').addGeometry(circle);
        map.getLayer('polygon').addGeometry(marker);
        map.getLayer('line').addGeometry(line);
    }
    //地图放大
    if (action.type === "menuClick" && action.payload.command === "zoom_in") {
        map.zoomIn();
    }
    //地图缩小
    if (action.type === "menuClick" && action.payload.command === "zoom_out") {
        map.zoomOut();
    }
    return state;
}

RootReducer.merge(mapReduce);

//加入reducer(layerControlReduce)
const layerControlReduce = (
    state = {
        pointIsChecked: true,
        linetIsChecked: true,
        polygonIsChecked: true
    }, action) => {
    //点选point图层控制其显示
    if (action.type === "handlePointIsChecked") {
        const pointIsChecked = {
            pointIsChecked: !state.pointIsChecked
        }
        if (pointIsChecked.pointIsChecked) {
            map.getLayer("point").show();
        } else {
            map.getLayer("point").hide();
        }
        console.log(pointIsChecked);
        return Object.assign({}, state, { ...pointIsChecked })
    }
    //点选line图层控制其显示
    if (action.type === "handleLineIsChecked") {
        const linetIsChecked = {
            linetIsChecked: !state.linetIsChecked
        }
        if (linetIsChecked.linetIsChecked) {
            map.getLayer("line").show();
        } else {
            map.getLayer("line").hide();
        }
        console.log(linetIsChecked);
        return Object.assign({}, state, { ...linetIsChecked })
    }
    //点选polygon图层控制其显示
    if (action.type === "handlePolygonIsChecked") {
        const polygonIsChecked = {
            polygonIsChecked: !state.polygonIsChecked
        }
        if (polygonIsChecked.polygonIsChecked) {
            map.getLayer("polygon").show();
        } else {
            map.getLayer("polygon").hide();
        }
        console.log(polygonIsChecked);
        return Object.assign({}, state, { ...polygonIsChecked })
    }
    return { ...state };
}

RootReducer.merge(layerControlReduce);

//加入reducer(realtimeMapping)
const realtimeMappingReduce = (
    state = { realtimeMappingIsChecked: false }, action) => {

    if (action.type === "handleRealtimeMapping") {
        const realtimeMappingIsChecked = {
            realtimeMappingIsChecked: !state.realtimeMappingIsChecked
        }
        if (realtimeMappingIsChecked.realtimeMappingIsChecked) {
            console.log('打开了');
        } else {
            console.log('没打开');
        }
        console.log(realtimeMappingIsChecked);
        return { ...realtimeMappingIsChecked }
    }
    return { ...state };
}
RootReducer.merge(realtimeMappingReduce);

//加入Reducer(sketchReduce)
//初始化相关量
let drawPoint,drawLine,drawPolygon,deleteObj,
     point,line,polygon,target,
     getPoint,clearPoiArr,getObj,
     clickEventBind;
let objIsClicked= false;
//初始化线面的点集数组
let poiArr=new Array(),
    poiId=new Array(),
    poiCoor=new Array(),
    points=new Array();
const sketchReduce = (state = {
    pointNum: 0,
    drawPointIsChecked: false,
    drawLineIsChecked: false,
    drawPolygonIsChecked:false,
    deleteIsChecked:false,
    undoIsChecked:false,
    redoIsChecked:false,
    saveIsChecked:false}, action) => {
//用于连线和构面时获取被选中的点并存放在poiArr数组中
        getPoint=getPoint ||function(e){
            target=e.target;
            poiArr.push(target);
            poiCoor.push(target._coordinates);
            const id=target._id;
            poiId.push(id);
            //map.getLayer('point').getGeometryById(id).
            target.updateSymbol([{ 'polygonFill': '#f00'}]);
        }
//用于清空点集
        clearPoiArr=clearPoiArr || function(){

            for(var i=0;i<poiId.length;i++){
                map.getLayer('point').getGeometryById(poiId[i]).updateSymbol([{ 'polygonFill': '#0000FF'}]);
            }
            poiArr=[];
            poiId=[];
            poiCoor=[];
            console.log('cleared array');}
//用于获取线面对象
        getObj = getObj ||function(e){
            target=e.target;
            objIsClicked=!objIsClicked;
            if(objIsClicked){
                target.updateSymbol([{ 'lineColor': '#f00'}]);
            }else{
                target.updateSymbol([{ 'lineColor': '#FF0000'}]);
            }
        }
//用于判断click事件的绑定
       clickEventBind=clickEventBind || function(status){
            if(status==='drawPoint'){
                console.log(status)
                if(!state.drawLineIsChecked){
                    map.off('click',drawLine);
                    map.off('dblclick',clearPoiArr)
                }
                if(!state.drawPolygonIsChecked){
                    map.off('dblclick',drawPolygon)
                }
                if(!state.deleteIsChecked){
                    map.off('click',deleteObj)
                }
            }
            if(status==='drawLine'){
                console.log(status)
                if(!state.drawPointIsChecked){
                    map.off('click',drawPoint)
                }
                if(!state.drawPolygonIsChecked){
                    map.off('dblclick',drawPolygon)
                }
                if(!state.deleteIsChecked){
                    map.off('click',deleteObj)
                }
            }
            if(status==='drawPolygon'){
                console.log(status)
                if(!state.drawPointIsChecked){
                    map.off('click',drawPoint)
                }
                if(!state.drawLineIsChecked){
                    map.off('click',drawLine)
                    map.off('dblclick',clearPoiArr)
                }
                if(!state.deleteIsChecked){
                    map.off('click',deleteObj)
                }
            }
            if(status==='delete'){
                console.log(status)
                if(!state.drawPointIsChecked){
                    map.off('click',drawPoint)
                }
                if(!state.drawLineIsChecked){
                    map.off('click',drawLine)
                    map.off('dblclick',clearPoiArr)
                }
                if(!state.drawPolygonIsChecked){
                    map.off('dblclick',drawPolygon)
                }
            }
        }
//用于画点
        drawPoint = drawPoint ||function (e) {
                state.pointNum++;
                point = new maptalks.Circle(e.coordinate,2,
                    {
                        'id':state.pointNum,
                        'draggable':true,
                        'symbol':[
                            {
                                'lineColor': '#0000FF',
                                'lineWidth': 2,
                                'polygonFill': '#0000FF',
                                'polygonOpacity': 1},

                            {
                                'textFaceName': 'sans-serif',
                                'textName': state.pointNum,
                                'textFill': '#FFFFFF',
                                'textHorizontalAlignment': 'right',
                                'textSize': 20}
                            ]
                    }
                );
                points.push(point);
                point.on('click',getPoint)
                map.getLayer('point').addGeometry(point);
            };
//用于画线
        drawLine = drawLine ||function () {
            console.log(poiArr.length);
            if(poiArr.length===2){
                line = new maptalks.ConnectorLine(poiArr[0], poiArr[1], {
                    'showOn' : 'always',
                    'arrowStyle' : 'classic',
                    'arrowPlacement' : null,
                    'symbol': {
                        'lineColor': '#FF0000',
                        'ineWidth': 2
                    }
                });
                line.on('click',getObj);
                map.getLayer('line').addGeometry(line);
            }
            if(poiArr.length>2){
                const i=poiArr.length-2;
                    line = new maptalks.ConnectorLine(poiArr[i], poiArr[i+1], {
                        showOn : 'always',
                        arrowStyle : 'classic',
                        arrowPlacement : null,
                        symbol: {
                            lineColor: '#FF0000',
                            lineWidth: 2
                        }
                    });
                    line.on('click',getObj);
                    map.getLayer('line').addGeometry(line);
            }
        };
//用于画地块
        drawPolygon = drawPolygon ||function () {
             console.log(poiCoor.length);
             if(poiCoor.length>=3){
                 polygon = new maptalks.Polygon(poiCoor, {
                    symbol: {
                    'lineColor' : '#FF0000',
                    'lineWidth' : 2,
                    'polygonFill' : '#FFFFFF',
                    'polygonOpacity' : 0.6
                    }
                });
                polygon.on('click',getObj);
                map.getLayer('polygon').addGeometry(polygon);
             }
            clearPoiArr();
        }
//用于删除对象
        deleteObj = deleteObj ||function (){
            console.log(target);
            target.remove();
        }
///////
        switch (action.type) {

            case 'drawPointClick':
                clickEventBind('drawPoint');
                !state.drawPointIsChecked ? map.on('click', drawPoint):map.off('click',drawPoint);
                const newState1={
                    pointNum:state.pointNum,
                    drawPointIsChecked:!state.drawPointIsChecked,
                    drawLineIsChecked:false,
                    drawPolygonIsChecked:false,
                    deleteIsChecked:false,
                    undoIsChecked:false,
                    redoIsChecked:false,
                    saveIsChecked:false
                }
                return {...state,...newState1};

            case 'drawLineClick':
                clickEventBind('drawLine');
                !state.drawLineIsChecked ? map.on('click', drawLine):map.off('click',drawLine);
                !state.drawLineIsChecked ? map.on('dblclick', clearPoiArr):map.off('dblclick',clearPoiArr);
                const newState2={
                    pointNum:state.pointNum,
                    drawPointIsChecked:false,
                    drawLineIsChecked:!state.drawLineIsChecked,
                    drawPolygonIsChecked:false,
                    deleteIsChecked:false,
                    undoIsChecked:false,
                    redoIsChecked:false,
                    saveIsChecked:false
                }
                return {...state,...newState2};

            case  'drawPolygonClick':
                clickEventBind('drawPolygon');
                !state.drawPolygonIsChecked ? map.on('dblclick', drawPolygon):map.off('dblclick',drawPolygon);
                const newState3={
                    pointNum:state.pointNum,
                    drawPointIsChecked:false,
                    drawLineIsChecked:false,
                    drawPolygonIsChecked:!state.drawPolygonIsChecked,
                    deleteIsChecked:false,
                    undoIsChecked:false,
                    redoIsChecked:false,
                    saveIsChecked:false
                }
                return {...state,...newState3};

            case 'deleteClick':
                clickEventBind('delete');
                !state.deleteIsChecked ? map.on('click', deleteObj):map.off('click',deleteObj);
                const newState4={
                    pointNum:state.pointNum,
                    drawPointIsChecked:false,
                    drawLineIsChecked:false,
                    drawPolygonIsChecked:false,
                    deleteIsChecked:!state.deleteIsChecked,
                    undoIsChecked:false,
                    redoIsChecked:false,
                    saveIsChecked:false
                }
                return {...state,...newState4};

            case 'undoClick':
                console.log('撤销');

                return { ...state }

            case 'redoClick':
                console.log('重做');

                return { ...state }

            case 'saveClick':
                console.log('保存');

                return { ...state }

            default:
                return { ...state }

        }
}
RootReducer.merge(sketchReduce);
/**
*
* @param {*} state
* @param {*} ownProps
*/
const mapStateToProps = (state, ownProps) => {

    const props = ownProps;

    return {
        text: ownProps.ownProps,
    }
}
/**
 * 只对顶层view可见
 * @param {*} dispatch
 * @param {*} ownProps
 */
const mapDispatchToProps = (dispatch, ownProps) => {
    return {

        onMenuItemClick: (text) => {
            dispatch({
                type: 'menuClick',
                payload: {
                    command: text
                }
            });
        },

    }
}

export default connect(mapStateToProps, mapDispatchToProps)(Map)<commit_msg>线面对象点击变色失败=。=<commit_after>/**
 * Map组件
 * @author yellow date 2017/7/24
 * -由于此组件包含input,button。可以根据需要拆分组件
 *
 */
import React, { Component } from 'react';
import { connect } from 'react-redux';
import RootReducer from './../../redux/RootReducer';
import PropTypes from 'prop-types';
import * as maptalks from 'maptalks';

//引入地图组件
import MapToolBar from './MapToolBar';
/**
 * @type {maptalks.Map}
 * 全局的地图对象和方法
 */
let map;

/**
 * 地图组件
 * @class
 */
class Map extends Component {

    componentDidMount() {
        const mapDiv = this.refs.map;
        map = new maptalks.Map(mapDiv, {
            center: [-0.113049, 51.498568],
            zoom: 14,
            baseLayer: new maptalks.TileLayer('base', {
                urlTemplate: 'http://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}.png',//'http://{s}.tile.osm.org/{z}/{x}/{y}.png',
                subdomains: ['a', 'b', 'c', 'd', 'e']
            }),
            layers: [
                new maptalks.VectorLayer('point'),
                new maptalks.VectorLayer('line'),
                new maptalks.VectorLayer('polygon')
            ]
        });
        map.setZoom(20);
    }

    render() {

        const { onMenuItemClick } = this.props;

        return (

                <div ref='map' style={{ color: "#000", width: '100%', height: `${window.innerHeight}px` }} />
                <MapToolBar onClick={onMenuItemClick} text="zoom_in" />

        )
    }

}

/**
 * 限定组件的一些属性
 */
Map.propTypes = {
    //onClick: PropTypes.func.isRequired
}

//加入reducer(mapReduce)
const mapReduce = (state = 0, action) => {
    //获取当前定位
    if (action.type === "menuClick" && action.payload.command === "get_location") {
        //获取定位,由于无GPS返回固定坐标
        const center = new maptalks.Coordinate(114.360734, 30.541093);
        map.setCenter(center);
        const circle = new maptalks.Circle(center, 20, {
            symbol: {
                lineColor: '#34495e',
                lineWidth: 2,
                polygonFill: '#1bbc9b',
                polygonOpacity: 0.4
            }
        });
        const marker = new maptalks.Marker(
            center, {
                symbol: {
                    'textFaceName': 'sans-serif',
                    'textName': 'your location',
                    'textFill': '#34495e',
                    'textHorizontalAlignment': 'right',
                    'textSize': 25
                }
            }
        );
        const line = new maptalks.LineString([
            center.add(-0.018, 0.005),
            center.add(0.006, 0.005)
        ], {
                symbol: {
                    'lineColor': '#1bbc9b',
                    'lineWidth': 3
                }
            });
        //将对象添加至图层
        map.getLayer('point').addGeometry(circle);
        map.getLayer('polygon').addGeometry(marker);
        map.getLayer('line').addGeometry(line);
    }
    //地图放大
    if (action.type === "menuClick" && action.payload.command === "zoom_in") {
        map.zoomIn();
    }
    //地图缩小
    if (action.type === "menuClick" && action.payload.command === "zoom_out") {
        map.zoomOut();
    }
    return state;
}

RootReducer.merge(mapReduce);

//加入reducer(layerControlReduce)
const layerControlReduce = (
    state = {
        pointIsChecked: true,
        linetIsChecked: true,
        polygonIsChecked: true
    }, action) => {
    //点选point图层控制其显示
    if (action.type === "handlePointIsChecked") {
        const pointIsChecked = {
            pointIsChecked: !state.pointIsChecked
        }
        if (pointIsChecked.pointIsChecked) {
            map.getLayer("point").show();
        } else {
            map.getLayer("point").hide();
        }
        console.log(pointIsChecked);
        return Object.assign({}, state, { ...pointIsChecked })
    }
    //点选line图层控制其显示
    if (action.type === "handleLineIsChecked") {
        const linetIsChecked = {
            linetIsChecked: !state.linetIsChecked
        }
        if (linetIsChecked.linetIsChecked) {
            map.getLayer("line").show();
        } else {
            map.getLayer("line").hide();
        }
        console.log(linetIsChecked);
        return Object.assign({}, state, { ...linetIsChecked })
    }
    //点选polygon图层控制其显示
    if (action.type === "handlePolygonIsChecked") {
        const polygonIsChecked = {
            polygonIsChecked: !state.polygonIsChecked
        }
        if (polygonIsChecked.polygonIsChecked) {
            map.getLayer("polygon").show();
        } else {
            map.getLayer("polygon").hide();
        }
        console.log(polygonIsChecked);
        return Object.assign({}, state, { ...polygonIsChecked })
    }
    return { ...state };
}

RootReducer.merge(layerControlReduce);

//加入reducer(realtimeMapping)
const realtimeMappingReduce = (
    state = { realtimeMappingIsChecked: false }, action) => {

    if (action.type === "handleRealtimeMapping") {
        const realtimeMappingIsChecked = {
            realtimeMappingIsChecked: !state.realtimeMappingIsChecked
        }
        if (realtimeMappingIsChecked.realtimeMappingIsChecked) {
            console.log('打开了');
        } else {
            console.log('没打开');
        }
        console.log(realtimeMappingIsChecked);
        return { ...realtimeMappingIsChecked }
    }
    return { ...state };
}
RootReducer.merge(realtimeMappingReduce);

//加入Reducer(sketchReduce)
//初始化相关量
let drawPoint,drawLine,drawPolygon,deleteObj,
     point,line,polygon,target,
     getPoint,clearPoiArr,getObj,
     clickEventBind;
let objIsClicked= false;
//初始化线面的点集数组
let poiArr=new Array(),
    poiId=new Array(),
    poiCoor=new Array(),
    points=new Array();
const sketchReduce = (state = {
    pointNum: 0,
    drawPointIsChecked: false,
    drawLineIsChecked: false,
    drawPolygonIsChecked:false,
    deleteIsChecked:false,
    undoIsChecked:false,
    redoIsChecked:false,
    saveIsChecked:false}, action) => {
//用于连线和构面时获取被选中的点并存放在poiArr数组中
        getPoint=getPoint ||function(e){
            target=e.target;
            poiArr.push(target);
            poiCoor.push(target._coordinates);
            const id=target._id;
            poiId.push(id);
            target.updateSymbol([{ 'polygonFill': '#f00'}]);
        }
//用于清空点集
        clearPoiArr=clearPoiArr || function(){

            for(var i=0;i<poiId.length;i++){
                map.getLayer('point').getGeometryById(poiId[i]).updateSymbol([{ 'polygonFill': '#0000FF'}]);
            }
            poiArr=[];
            poiId=[];
            poiCoor=[];
            console.log('cleared array');}
//用于获取线面对象
        getObj = getObj ||function(e){
            target=e.target;
            console.log(target);
            objIsClicked=!objIsClicked;
            console.log(objIsClicked);
            if(objIsClicked){
                target.updateSymbol({ 'lineColor': '#f00'});
            }else{
                target.updateSymbol({ 'lineColor': '#FF0000'});
            }
        }
//用于判断click事件的绑定
       clickEventBind=clickEventBind || function(status){
            if(status==='drawPoint'){
                console.log(status)
                if(!state.drawLineIsChecked){
                    map.off('click',drawLine);
                    map.off('dblclick',clearPoiArr)
                }
                if(!state.drawPolygonIsChecked){
                    map.off('dblclick',drawPolygon)
                }
                if(!state.deleteIsChecked){
                    map.off('click',deleteObj)
                }
            }
            if(status==='drawLine'){
                console.log(status)
                if(!state.drawPointIsChecked){
                    map.off('click',drawPoint)
                }
                if(!state.drawPolygonIsChecked){
                    map.off('dblclick',drawPolygon)
                }
                if(!state.deleteIsChecked){
                    map.off('click',deleteObj)
                }
            }
            if(status==='drawPolygon'){
                console.log(status)
                if(!state.drawPointIsChecked){
                    map.off('click',drawPoint)
                }
                if(!state.drawLineIsChecked){
                    map.off('click',drawLine)
                    map.off('dblclick',clearPoiArr)
                }
                if(!state.deleteIsChecked){
                    map.off('click',deleteObj)
                }
            }
            if(status==='delete'){
                console.log(status)
                if(!state.drawPointIsChecked){
                    map.off('click',drawPoint)
                }
                if(!state.drawLineIsChecked){
                    map.off('click',drawLine)
                    map.off('dblclick',clearPoiArr)
                }
                if(!state.drawPolygonIsChecked){
                    map.off('dblclick',drawPolygon)
                }
            }
        }
//用于画点
        drawPoint = drawPoint ||function (e) {
                state.pointNum++;
                point = new maptalks.Circle(e.coordinate,2,
                    {
                        'id':state.pointNum,
                        'draggable':true,
                        'symbol':[
                            {
                                'lineColor': '#0000FF',
                                'lineWidth': 2,
                                'polygonFill': '#0000FF',
                                'polygonOpacity': 1},

                            {
                                'textFaceName': 'sans-serif',
                                'textName': state.pointNum,
                                'textFill': '#FFFFFF',
                                'textHorizontalAlignment': 'right',
                                'textSize': 20}
                            ]
                    }
                );
                points.push(point);
                point.on('click',getPoint)
                map.getLayer('point').addGeometry(point);
            };
//用于画线
        drawLine = drawLine ||function () {
            console.log(poiArr.length);
            if(poiArr.length===2){
                line = new maptalks.ConnectorLine(poiArr[0], poiArr[1], {
                    'showOn' : 'always',
                    'arrowStyle' : 'classic',
                    'arrowPlacement' : null,
                    'symbol': {
                        'lineColor': '#FF0000',
                        'ineWidth': 2
                    }
                });
                line.on('click',getObj);
                map.getLayer('line').addGeometry(line);
            }
            if(poiArr.length>2){
                const i=poiArr.length-2;
                    line = new maptalks.ConnectorLine(poiArr[i], poiArr[i+1], {
                        showOn : 'always',
                        arrowStyle : 'classic',
                        arrowPlacement : null,
                        symbol: {
                            lineColor: '#FF0000',
                            lineWidth: 2
                        }
                    });
                    line.on('click',getObj);
                    map.getLayer('line').addGeometry(line);
            }
        };
//用于画地块
        drawPolygon = drawPolygon ||function () {
             console.log(poiCoor.length);
             if(poiCoor.length>=3){
                 polygon = new maptalks.Polygon(poiCoor, {
                    symbol: {
                    'lineColor' : '#FF0000',
                    'lineWidth' : 2,
                    'polygonFill' : '#FFFFFF',
                    'polygonOpacity' : 0.6
                    }
                });
                polygon.on('click',getObj);
                map.getLayer('polygon').addGeometry(polygon);
             }
            clearPoiArr();
        }
//用于删除对象
        deleteObj = deleteObj ||function (){
            console.log(target);
            target.remove();
        }
///////
        switch (action.type) {

            case 'drawPointClick':
                clickEventBind('drawPoint');
                !state.drawPointIsChecked ? map.on('click', drawPoint):map.off('click',drawPoint);
                const newState1={
                    pointNum:state.pointNum,
                    drawPointIsChecked:!state.drawPointIsChecked,
                    drawLineIsChecked:false,
                    drawPolygonIsChecked:false,
                    deleteIsChecked:false,
                    undoIsChecked:false,
                    redoIsChecked:false,
                    saveIsChecked:false
                }
                return {...state,...newState1};

            case 'drawLineClick':
                clickEventBind('drawLine');
                !state.drawLineIsChecked ? map.on('click', drawLine):map.off('click',drawLine);
                !state.drawLineIsChecked ? map.on('dblclick', clearPoiArr):map.off('dblclick',clearPoiArr);
                const newState2={
                    pointNum:state.pointNum,
                    drawPointIsChecked:false,
                    drawLineIsChecked:!state.drawLineIsChecked,
                    drawPolygonIsChecked:false,
                    deleteIsChecked:false,
                    undoIsChecked:false,
                    redoIsChecked:false,
                    saveIsChecked:false
                }
                return {...state,...newState2};

            case  'drawPolygonClick':
                clickEventBind('drawPolygon');
                !state.drawPolygonIsChecked ? map.on('dblclick', drawPolygon):map.off('dblclick',drawPolygon);
                const newState3={
                    pointNum:state.pointNum,
                    drawPointIsChecked:false,
                    drawLineIsChecked:false,
                    drawPolygonIsChecked:!state.drawPolygonIsChecked,
                    deleteIsChecked:false,
                    undoIsChecked:false,
                    redoIsChecked:false,
                    saveIsChecked:false
                }
                return {...state,...newState3};

            case 'deleteClick':
                clickEventBind('delete');
                !state.deleteIsChecked ? map.on('click', deleteObj):map.off('click',deleteObj);
                const newState4={
                    pointNum:state.pointNum,
                    drawPointIsChecked:false,
                    drawLineIsChecked:false,
                    drawPolygonIsChecked:false,
                    deleteIsChecked:!state.deleteIsChecked,
                    undoIsChecked:false,
                    redoIsChecked:false,
                    saveIsChecked:false
                }
                return {...state,...newState4};

            case 'undoClick':
                console.log('撤销');

                return { ...state }

            case 'redoClick':
                console.log('重做');

                return { ...state }

            case 'saveClick':
                console.log('保存');

                return { ...state }

            default:
                return { ...state }

        }
}
RootReducer.merge(sketchReduce);
/**
*
* @param {*} state
* @param {*} ownProps
*/
const mapStateToProps = (state, ownProps) => {

    const props = ownProps;

    return {
        text: ownProps.ownProps,
    }
}
/**
 * 只对顶层view可见
 * @param {*} dispatch
 * @param {*} ownProps
 */
const mapDispatchToProps = (dispatch, ownProps) => {
    return {

        onMenuItemClick: (text) => {
            dispatch({
                type: 'menuClick',
                payload: {
                    command: text
                }
            });
        },

    }
}

export default connect(mapStateToProps, mapDispatchToProps)(Map)<|endoftext|>


<commit_before>/**
 * Module dependencies.
 */

var EventEmitter = require('events').EventEmitter;
var small_screen = require('../is-small-screen');
var ocreate = require('../object-create');
var authParams = require('./auth-params');
var whitelist = require('./whitelist');
var regex = require('../regex');
var i18n = require('../i18n');
var bind = require('../bind');
var _ = require('underscore');
var xtend = _.extend;
var okeys = _.keys;

/**
 * Expose `OptionsManager`
 */

module.exports = OptionsManager;

/**
 * Create an `OptionsManager` from
 * instanceOptions and displayOptions
 *
 * @param {Auth0Lock} widget
 * @param {Object} displayOptions
 * @constructor
 */

function OptionsManager(widget, options) {
  if (!(this instanceof OptionsManager)) {
    return new OptionsManager(widget, options);
  }

  // Initiate `EventEmitter`
  EventEmitter.call(this);

  // Flag OptionsManager as `unloaded`
  this.state('loading');

  // holds widget as reference
  this.$widget = widget;

  // save widget's $client object reference
  this.$client = widget.$client;

  // save copy of widget's valid strategies
  this.$strategies = widget.$strategies;

  // save widget's `auth0-js` instance object
  this.$auth0 = widget.$auth0;

  // Options moved from constructor and hacked into `auth0-js` instance
  this.$auth0._useJSONP = options.forceJSONP || this.$auth0._useJSONP;
  this.$auth0._callbackURL = options.callbackURL || this.$auth0._callbackURL;
  this.$auth0._callbackOnLocationHash = 'token' === options.responseType || !!this.$auth0._callbackOnLocationHash;

  // save widget instance options with `$` prepended
  _.each(okeys(widget.$options), function(key) {
    this["$" + key] = widget.$options[key];
  }, this);

  // copies all provided options to instance
  // filtering by allowed options `whitelist`
  _.each(okeys(options), function(key) {
    // we should whitelist options
    // so no OptionsManager method gets overriden
    // by user configurable object
    // XXX: Broken, fix it!
    // if (!~whitelist.indexOf(key) && !~supportedParams.indexOf(key)) return;
    this[key] = options[key];
  }, this);

  // Set `i18n` dictionary for templates
  this.i18n = i18n.getDict(this.dict);

  // default authParams to empty object
  this.authParams = _.extend({}, options.authParams);

  // save default responseType
  this.responseType = options.responseType ? options.responseType : 'code';

  // enable/disable last login and AD discovery
  this.rememberLastLogin = options.rememberLastLogin ? options.rememberLastLogin : true;
  this.integratedWindowsLogin = options.integratedWindowsLogin ? options.integratedWindowsLogin : true;

  // If popupCallback, enable popup mode
  if ('function' === typeof options.popupCallback) {
    this.popup = true;
    // XXX: the following to should already come with
    // the options from constructor... right?
    this.popupOptions = _.extend({}, options.popupOptions);
    this.popupCallback = options.popupCallback;
  }

  // force `closable` when provided with `container`
  this.closable = options.closable ? options.closable : !this.container;

  // Delay options requiring $client configuration
  this.$widget.getClientConfiguration(bind(this._onclientloaded, this));
}

/**
 * Inherit from `EventEmitter`
 */

OptionsManager.prototype = ocreate(EventEmitter.prototype);

/**
 * Get or Set `$_state` for track
 * `OptionsManager`s ready state
 *
 * @param {String} state
 * @param {String} message
 * @return {OptionsManager}
 * @public
 */

OptionsManager.prototype.state = function(state, message) {
  if (0 === arguments.length) {
    return this.$_state;
  }

  // debug('state is now %s', state);
  this.$_state = state;
  this.emit(state, message);
  return this;
};

/**
 * Register `fn` for when `OptionsManager`
 * is ready (or `loaded`)
 *
 * @param {Function} fn
 * @return {OptionsManager}
 * @public
 */

OptionsManager.prototype.ready = function(fn) {
  function done() {
    if ('loaded' === this.state()) {
      return fn();
    }
  }

  if ('loaded' === this.state()) {
    setTimeout(bind(done, this), 0);
  } else {
    this.once('loaded', bind(done, this));
  }

  return this;
};

/**
 * Continue setup once client's configuration
 * is retrieved from assets url or S3
 *
 * @param {Object} client
 * @return {OptionsManager}
 * @private
 */

OptionsManager.prototype._onclientloaded = function(client) {

  // Refresh clients configuration with what's stored
  // on the Auth0's hash
  this.$client = _.extend(this.$client, client);

  // Enrich $client.strategies
  // then, continue setting up the mode
  if (this.connections) {
    this.$client.strategies = _.chain(this.$client.strategies)
      .map(strategiesConnectionsMapper(this.connections))
      .filter(hasConnectionsFilter)
      .value();
  }

  // merge strategies info
  for (var i = 0; i < this.$client.strategies.length; i++) {
    var sname = this.$client.strategies[i].name;
    this.$client.strategies[i] = _.extend({}, this.$client.strategies[i], this.$strategies[sname]);
  }

  // Holds auth0 strategies only
  this.auth0Strategies = _.chain(this.$client.strategies)
    .filter(auth0StrategiesFilter)
    .value();

  // show signup/forgot links
  var auth0Conn = this._getAuth0Connection() || {};

  // if booted on `signup` or `reset`, but not configured
  // on connection => override mode with `signin`
  if (this.mode === 'signup' && !auth0Conn.showSignup) this.mode = 'signin';
  if (this.mode === 'reset' && !auth0Conn.showForgot) this.mode = 'signin';

  // Resolve show action buttons or not
  this.showSignupAction = (this.disableSignupAction !== true) && ((auth0Conn && auth0Conn.showSignup) || this.signupLink);
  this.showResetAction = (this.disableResetAction !== true) && ((auth0Conn && auth0Conn.showForgot) || this.resetLink);

  // usernameStyle
  var auth0ConnStrategy = this._getClientStrategyByConnectionName(auth0Conn.name) || {};

  if (!this.usernameStyle && (auth0ConnStrategy.name === 'ad' || auth0ConnStrategy.name === 'auth0-adldap')) {
    this.usernameStyle = 'username';
  }

  this.state('loaded');

  return this;
};

/**
 * Resolve whether are there or not any
 * social connections within client
 * strategies
 *
 * @return {Boolean}
 * @private
 */

OptionsManager.prototype._isThereAnySocialConnection = function () {
  var client = this.$client;
  var filter = { social: true };
  return !!_.findWhere(client.strategies, filter);
};

/**
 * Resolve whether are there or not any
 * enterprise or Databse connection within
 * client strategies
 *
 * @return {Boolean}
 * @private
 */

OptionsManager.prototype._isThereAnyEnterpriseOrDbConnection = function() {
  var client = this.$client;
  var filter = { social: false };
  return !!_.findWhere(client.strategies, filter);
};

/**
 * Resolve whether are there or not any
 * database connection within client strategies
 *
 * @return {Boolean}
 * @private
 */

OptionsManager.prototype._isThereAnyDBConnection = function() {
  var client = this.$client;
  var filter = { userAndPass: true };
  return !!_.findWhere(client.strategies, filter);
};

/**
 * Resolve whether are there or not any
 * Active Directory connection within client
 * strategies
 *
 * @return {Boolean}
 * @private
 */

OptionsManager.prototype._isThereAnyADConnection = function() {
  return _.some(this.$client.strategies, function (s) {
    return (s.name === 'ad' || s.name === 'auth0-adldap') && s.connections.length > 0;
  });
};

/**
 * Resolves wether `email`'s domain belongs to
 * an enterprise connection or not, and alters
 * `output` object in the way...
 *
 * @param {String} email
 * @param {Object} output
 * @return {Boolean}
 * @private
 */

OptionsManager.prototype._isEnterpriseConnection = function (email, output) {
  var client = this.$client;
  var parser = regex.email_parser;
  var emailM = parser.exec(email.toLowerCase());
  var email_domain = null != emailM ? emailM.slice(-2)[0] : null;
  var sfilter = { userAndPass: undefined };
  var cfilter = { domain: email_domain };

  if (!email_domain) return false;

  var conn = _.chain(client.strategies)
    .where(sfilter)
    .pluck('connections')
    .flatten()
    .findWhere(cfilter)
    .value();

  if (conn && output) {
    output.domain = conn.domain;
  }

  return !!conn;
};

OptionsManager.prototype._isFreeSubscription = function() {
  return this.$client.subscription && !~['free', 'dev'].indexOf(this.$client.subscription);
};

/**
 * Get resolved Auth0 connection to signin by `userName`
 * XXX: No idea what logic this follows...
 *
 * @param {String} userName
 * @return {Object}
 * @private
 */

OptionsManager.prototype._getAuth0Connection = function(username) {

  // if specified, use it, otherwise return first
  if (this.defaultUserPasswordConnection) {
    return _.chain(this.auth0Strategies)
      .pluck('connections')
      .flatten()
      .findWhere({ name: this.defaultUserPasswordConnection })
      .value();
  }

  var domain = username && ~username.indexOf('@') ? username.split('@')[1] : '';

  if (username && domain && this.$client.strategies) {
    //there is still a chance that the connection might be
    //adldap and with domain
    var conn = _.chain(this.$client.strategies)
                .pluck('connections')
                .flatten()
                .findWhere({domain: domain})
                .value();
    if (conn) {
      return conn;
    }
  }

  // By default, if exists, return auth0 connection (db-conn) or first
  var defaultStrategy = _.findWhere(this.auth0Strategies, { name: 'auth0' });
  defaultStrategy = defaultStrategy || (this.auth0Strategies.length > 0 ? this.auth0Strategies[0] : null);

  return defaultStrategy && defaultStrategy.connections.length > 0 ? defaultStrategy.connections[0] : null;
};

/**
 * Get Loggedin auth parameters from `strategy` and `ssoData`
 *
 * @param {String} strategy
 * @param {Object} ssoData
 * @return {Object}
 * @private
 */

OptionsManager.prototype._getLoggedInAuthParams = function (strategy, ssoData) {
  switch (strategy) {
    case 'google-oauth2':
      return { login_hint: ssoData.lastUsedUsername };
    default:
      return {};
  }
};

/**
 * Get client strategy by connection `connName`
 * XXX: Check that there may exist 2 connection with same name
 * but at different strategies... in that case this is wrong,
 * and it should also accept a strategy name as second parameter
 *
 * @param {String} connName
 * @return {Object}
 * @private
 */

OptionsManager.prototype._getClientStrategyByConnectionName = function (connName) {
  return _.chain(this.$client.strategies)
    .filter(function (s) {
      return _.findWhere(s.connections, { name: connName });
    }).value()[0];
};

/**
 * Get configured client strategy by strategy `name`
 *
 * @param {String} name
 * @return {Object}
 * @private
 */

OptionsManager.prototype._getClientStrategyByName = function (name) {
  return _.findWhere(this.$client.strategies, { name: name });
};

/**
 * Resolve whether use or don't use big social buttons
 *
 * @return {Boolean}
 * @public
 */

OptionsManager.prototype._useBigSocialButtons = function() {
  return this.socialBigButtons !== undefined ?  this.socialBigButtons : !this._isThereAnyEnterpriseOrDbConnection();
};

/**
 * Retrieve `$client` strategies by `social: true`
 *
 * @return {Array}
 * @public
 */

OptionsManager.prototype._getSocialStrategies = function() {
  return _.where(this.$client.strategies, { social: true });
};

/**
 * Resolve disable the focus on `is_small_screen`
 * or at embeded mode in `container`. Or override
 * by user preferences
 *
 * @return {Boolean}
 * @public
 */

OptionsManager.prototype._focusDisabled = function() {
  return this.focusInput !== undefined ? !this.focusInput : small_screen() || !!this.container;
};

/**
 * Private helpers
 */

function auth0StrategiesFilter(strategy) {
  return strategy.userAndPass && strategy.connections.length > 0;
}

function hasConnectionsFilter(strategy) {
  return strategy.connections.length > 0;
}

function strategiesConnectionsMapper(connections) {
  return function (strategy) {
    // XXX: We need to replace with Lodash
    // no deep clone/extend is a pain for referential objects...
    strategy = _.extend({}, strategy);
    strategy.connections = _.filter(strategy.connections, function (connection) {
      return _.contains(connections, connection.name);
    });
    return strategy;
  };
}
<commit_msg>Fixes minor style updates breaking defaults<commit_after>/**
 * Module dependencies.
 */

var EventEmitter = require('events').EventEmitter;
var small_screen = require('../is-small-screen');
var ocreate = require('../object-create');
var authParams = require('./auth-params');
var whitelist = require('./whitelist');
var regex = require('../regex');
var i18n = require('../i18n');
var bind = require('../bind');
var _ = require('underscore');
var xtend = _.extend;
var okeys = _.keys;

/**
 * Expose `OptionsManager`
 */

module.exports = OptionsManager;

/**
 * Create an `OptionsManager` from
 * instanceOptions and displayOptions
 *
 * @param {Auth0Lock} widget
 * @param {Object} displayOptions
 * @constructor
 */

function OptionsManager(widget, options) {
  if (!(this instanceof OptionsManager)) {
    return new OptionsManager(widget, options);
  }

  // Initiate `EventEmitter`
  EventEmitter.call(this);

  // Flag OptionsManager as `unloaded`
  this.state('loading');

  // holds widget as reference
  this.$widget = widget;

  // save widget's $client object reference
  this.$client = widget.$client;

  // save copy of widget's valid strategies
  this.$strategies = widget.$strategies;

  // save widget's `auth0-js` instance object
  this.$auth0 = widget.$auth0;

  // Options moved from constructor and hacked into `auth0-js` instance
  this.$auth0._useJSONP = options.forceJSONP || this.$auth0._useJSONP;
  this.$auth0._callbackURL = options.callbackURL || this.$auth0._callbackURL;
  this.$auth0._callbackOnLocationHash = 'token' === options.responseType || !!this.$auth0._callbackOnLocationHash;

  // save widget instance options with `$` prepended
  _.each(okeys(widget.$options), function(key) {
    this["$" + key] = widget.$options[key];
  }, this);

  // copies all provided options to instance
  // filtering by allowed options `whitelist`
  _.each(okeys(options), function(key) {
    // we should whitelist options
    // so no OptionsManager method gets overriden
    // by user configurable object
    // XXX: Broken, fix it!
    // if (!~whitelist.indexOf(key) && !~supportedParams.indexOf(key)) return;
    this[key] = options[key];
  }, this);

  // Set `i18n` dictionary for templates
  this.i18n = i18n.getDict(this.dict);

  // default authParams to empty object
  this.authParams = _.extend({}, options.authParams);

  // save default responseType
  this.responseType = options.responseType ? options.responseType : 'code';

  // enable/disable last login and AD discovery
  this.rememberLastLogin = null != options.rememberLastLogin ? !!options.rememberLastLogin : true;
  this.integratedWindowsLogin = null != options.integratedWindowsLogin ? !!options.integratedWindowsLogin : true;

  // If popupCallback, enable popup mode
  if ('function' === typeof options.popupCallback) {
    this.popup = true;
    // XXX: the following to should already come with
    // the options from constructor... right?
    this.popupOptions = _.extend({}, options.popupOptions);
    this.popupCallback = options.popupCallback;
  }

  // force `closable` when provided with `container`
  this.closable = null != options.closable ? !!options.closable : !this.container;

  // Delay options requiring $client configuration
  this.$widget.getClientConfiguration(bind(this._onclientloaded, this));
}

/**
 * Inherit from `EventEmitter`
 */

OptionsManager.prototype = ocreate(EventEmitter.prototype);

/**
 * Get or Set `$_state` for track
 * `OptionsManager`s ready state
 *
 * @param {String} state
 * @param {String} message
 * @return {OptionsManager}
 * @public
 */

OptionsManager.prototype.state = function(state, message) {
  if (0 === arguments.length) {
    return this.$_state;
  }

  // debug('state is now %s', state);
  this.$_state = state;
  this.emit(state, message);
  return this;
};

/**
 * Register `fn` for when `OptionsManager`
 * is ready (or `loaded`)
 *
 * @param {Function} fn
 * @return {OptionsManager}
 * @public
 */

OptionsManager.prototype.ready = function(fn) {
  function done() {
    if ('loaded' === this.state()) {
      return fn();
    }
  }

  if ('loaded' === this.state()) {
    setTimeout(bind(done, this), 0);
  } else {
    this.once('loaded', bind(done, this));
  }

  return this;
};

/**
 * Continue setup once client's configuration
 * is retrieved from assets url or S3
 *
 * @param {Object} client
 * @return {OptionsManager}
 * @private
 */

OptionsManager.prototype._onclientloaded = function(client) {

  // Refresh clients configuration with what's stored
  // on the Auth0's hash
  this.$client = _.extend(this.$client, client);

  // Enrich $client.strategies
  // then, continue setting up the mode
  if (this.connections) {
    this.$client.strategies = _.chain(this.$client.strategies)
      .map(strategiesConnectionsMapper(this.connections))
      .filter(hasConnectionsFilter)
      .value();
  }

  // merge strategies info
  for (var i = 0; i < this.$client.strategies.length; i++) {
    var sname = this.$client.strategies[i].name;
    this.$client.strategies[i] = _.extend({}, this.$client.strategies[i], this.$strategies[sname]);
  }

  // Holds auth0 strategies only
  this.auth0Strategies = _.chain(this.$client.strategies)
    .filter(auth0StrategiesFilter)
    .value();

  // show signup/forgot links
  var auth0Conn = this._getAuth0Connection() || {};

  // if booted on `signup` or `reset`, but not configured
  // on connection => override mode with `signin`
  if (this.mode === 'signup' && !auth0Conn.showSignup) this.mode = 'signin';
  if (this.mode === 'reset' && !auth0Conn.showForgot) this.mode = 'signin';

  // Resolve show action buttons or not
  this.showSignupAction = (this.disableSignupAction !== true) && ((auth0Conn && auth0Conn.showSignup) || this.signupLink);
  this.showResetAction = (this.disableResetAction !== true) && ((auth0Conn && auth0Conn.showForgot) || this.resetLink);

  // usernameStyle
  var auth0ConnStrategy = this._getClientStrategyByConnectionName(auth0Conn.name) || {};

  if (!this.usernameStyle && (auth0ConnStrategy.name === 'ad' || auth0ConnStrategy.name === 'auth0-adldap')) {
    this.usernameStyle = 'username';
  }

  this.state('loaded');

  return this;
};

/**
 * Resolve whether are there or not any
 * social connections within client
 * strategies
 *
 * @return {Boolean}
 * @private
 */

OptionsManager.prototype._isThereAnySocialConnection = function () {
  var client = this.$client;
  var filter = { social: true };
  return !!_.findWhere(client.strategies, filter);
};

/**
 * Resolve whether are there or not any
 * enterprise or Databse connection within
 * client strategies
 *
 * @return {Boolean}
 * @private
 */

OptionsManager.prototype._isThereAnyEnterpriseOrDbConnection = function() {
  var client = this.$client;
  var filter = { social: false };
  return !!_.findWhere(client.strategies, filter);
};

/**
 * Resolve whether are there or not any
 * database connection within client strategies
 *
 * @return {Boolean}
 * @private
 */

OptionsManager.prototype._isThereAnyDBConnection = function() {
  var client = this.$client;
  var filter = { userAndPass: true };
  return !!_.findWhere(client.strategies, filter);
};

/**
 * Resolve whether are there or not any
 * Active Directory connection within client
 * strategies
 *
 * @return {Boolean}
 * @private
 */

OptionsManager.prototype._isThereAnyADConnection = function() {
  return _.some(this.$client.strategies, function (s) {
    return (s.name === 'ad' || s.name === 'auth0-adldap') && s.connections.length > 0;
  });
};

/**
 * Resolves wether `email`'s domain belongs to
 * an enterprise connection or not, and alters
 * `output` object in the way...
 *
 * @param {String} email
 * @param {Object} output
 * @return {Boolean}
 * @private
 */

OptionsManager.prototype._isEnterpriseConnection = function (email, output) {
  var client = this.$client;
  var parser = regex.email_parser;
  var emailM = parser.exec(email.toLowerCase());
  var email_domain = null != emailM ? emailM.slice(-2)[0] : null;
  var sfilter = { userAndPass: undefined };
  var cfilter = { domain: email_domain };

  if (!email_domain) return false;

  var conn = _.chain(client.strategies)
    .where(sfilter)
    .pluck('connections')
    .flatten()
    .findWhere(cfilter)
    .value();

  if (conn && output) {
    output.domain = conn.domain;
  }

  return !!conn;
};

OptionsManager.prototype._isFreeSubscription = function() {
  return this.$client.subscription && !~['free', 'dev'].indexOf(this.$client.subscription);
};

/**
 * Get resolved Auth0 connection to signin by `userName`
 * XXX: No idea what logic this follows...
 *
 * @param {String} userName
 * @return {Object}
 * @private
 */

OptionsManager.prototype._getAuth0Connection = function(username) {

  // if specified, use it, otherwise return first
  if (null != this.defaultUserPasswordConnection) {
    return _.chain(this.auth0Strategies)
      .pluck('connections')
      .flatten()
      .findWhere({ name: this.defaultUserPasswordConnection })
      .value();
  }

  var domain = username && ~username.indexOf('@') ? username.split('@')[1] : '';

  if (username && domain && this.$client.strategies) {
    //there is still a chance that the connection might be
    //adldap and with domain
    var conn = _.chain(this.$client.strategies)
                .pluck('connections')
                .flatten()
                .findWhere({domain: domain})
                .value();
    if (conn) {
      return conn;
    }
  }

  // By default, if exists, return auth0 connection (db-conn) or first
  var defaultStrategy = _.findWhere(this.auth0Strategies, { name: 'auth0' });
  defaultStrategy = defaultStrategy || (this.auth0Strategies.length > 0 ? this.auth0Strategies[0] : null);

  return defaultStrategy && defaultStrategy.connections.length > 0 ? defaultStrategy.connections[0] : null;
};

/**
 * Get Loggedin auth parameters from `strategy` and `ssoData`
 *
 * @param {String} strategy
 * @param {Object} ssoData
 * @return {Object}
 * @private
 */

OptionsManager.prototype._getLoggedInAuthParams = function (strategy, ssoData) {
  switch (strategy) {
    case 'google-oauth2':
      return { login_hint: ssoData.lastUsedUsername };
    default:
      return {};
  }
};

/**
 * Get client strategy by connection `connName`
 * XXX: Check that there may exist 2 connection with same name
 * but at different strategies... in that case this is wrong,
 * and it should also accept a strategy name as second parameter
 *
 * @param {String} connName
 * @return {Object}
 * @private
 */

OptionsManager.prototype._getClientStrategyByConnectionName = function (connName) {
  return _.chain(this.$client.strategies)
    .filter(function (s) {
      return _.findWhere(s.connections, { name: connName });
    }).value()[0];
};

/**
 * Get configured client strategy by strategy `name`
 *
 * @param {String} name
 * @return {Object}
 * @private
 */

OptionsManager.prototype._getClientStrategyByName = function (name) {
  return _.findWhere(this.$client.strategies, { name: name });
};

/**
 * Resolve whether use or don't use big social buttons
 *
 * @return {Boolean}
 * @public
 */

OptionsManager.prototype._useBigSocialButtons = function() {
  return null != this.socialBigButtons ? !!this.socialBigButtons : !this._isThereAnyEnterpriseOrDbConnection();
};

/**
 * Retrieve `$client` strategies by `social: true`
 *
 * @return {Array}
 * @public
 */

OptionsManager.prototype._getSocialStrategies = function() {
  return _.where(this.$client.strategies, { social: true });
};

/**
 * Resolve disable the focus on `is_small_screen`
 * or at embeded mode in `container`. Or override
 * by user preferences
 *
 * @return {Boolean}
 * @public
 */

OptionsManager.prototype._focusDisabled = function() {
  return null != this.focusInput ? !this.focusInput : (small_screen() || !!this.container);
};

/**
 * Private helpers
 */

function auth0StrategiesFilter(strategy) {
  return strategy.userAndPass && strategy.connections.length > 0;
}

function hasConnectionsFilter(strategy) {
  return strategy.connections.length > 0;
}

function strategiesConnectionsMapper(connections) {
  return function (strategy) {
    // XXX: We need to replace with Lodash
    // no deep clone/extend is a pain for referential objects...
    var cloned = _.extend({}, strategy);
    cloned.connections = _.filter(cloned.connections, function (connection) {
      return _.contains(connections, connection.name);
    });
    return cloned;
  };
}
<|endoftext|>


<commit_before>/*!
 * Module dependencies.
 */

var fs = require('fs'),
    path = require('path');

/*!
 * Global constants.
 */

var HOME = process.env[(process.platform == 'win32') ? 'USERPROFILE' : 'HOME'];

/**
 * Change Process to Project Root.
 *
 * Options:
 *
 *   - `delegate` {Object} error delegate.
 *     - `emitter` {EventEmitter} will emit an `error` event on error.
 *     - `callback` {Function} will be called on an error.
 *       - `e` {Error} describes the error.
 *
 * Returns:
 *
 *   - `null` {Object} if the project root is not found.
 *   - `path` {String} is the full path to the project root.
 */

module.exports.cd = function(delegate) {
    var currentPath = process.cwd();

    // is the current working directory the PhoneGap project?
    if (module.exports.isProject(currentPath)) {
        return currentPath;
    }

    // if not, step back a directory
    process.chdir(path.join(currentPath, '..'));

    // recursively try again, unless we're not at the system root (/ or C:/ or whatever)
    if (process.cwd() !== currentPath) {
        return module.exports.cd(delegate);
    }

    // notify delegate of error because we are at the system root
    var e = new Error('project directory could not be found');
    delegate.emitter.emit('error', e);
    delegate.callback(e);

    return null;
};

/**
 * Check Path to be a Cordova Project.
 *
 * Options:
 *
 *   - `projectPath` {String} is path checked.
 *
 * Returns:
 *
 *   - {Boolean} true if valid Cordova project.
 */

module.exports.isProject = function(projectPath) {
    var cordovaPath = path.join(projectPath, '.cordova');

    return (fs.existsSync(cordovaPath) &&
            !module.exports.isHome(projectPath));
};

/**
 * Check Path to be User Home Directory.
 *
 * Options:
 *
 *   - `homePath` {String} is path checked.
 *
 * Returns:
 *
 *   - {Boolean} true if path is user's home directory.
 */

module.exports.isHome = function(homePath) {
    return (homePath === HOME);
};

module.exports.clobberProjectConfig = function(configPath,clobbertargets) {
    var fs = require('fs');

    fs.open(configPath,'r+', function(err,fd) {
        if (err) {
            return;
        }
        fs.readFile(configPath, function(err, data) {
            if(err) {
                return;
            }
            for (each in clobbertargets) {
                data.replace(each, clobbertargets[each]);
            }
        });
    });
    return configPath;
};
<commit_msg>[#255][#303] created package parsing function in project utils<commit_after>/*!
 * Module dependencies.
 */

var fs = require('fs'),
    path = require('path');

/*!
 * Global constants.
 */

var HOME = process.env[(process.platform == 'win32') ? 'USERPROFILE' : 'HOME'];

/**
 * Change Process to Project Root.
 *
 * Options:
 *
 *   - `delegate` {Object} error delegate.
 *     - `emitter` {EventEmitter} will emit an `error` event on error.
 *     - `callback` {Function} will be called on an error.
 *       - `e` {Error} describes the error.
 *
 * Returns:
 *
 *   - `null` {Object} if the project root is not found.
 *   - `path` {String} is the full path to the project root.
 */

module.exports.cd = function(delegate) {
    var currentPath = process.cwd();

    // is the current working directory the PhoneGap project?
    if (module.exports.isProject(currentPath)) {
        return currentPath;
    }

    // if not, step back a directory
    process.chdir(path.join(currentPath, '..'));

    // recursively try again, unless we're not at the system root (/ or C:/ or whatever)
    if (process.cwd() !== currentPath) {
        return module.exports.cd(delegate);
    }

    // notify delegate of error because we are at the system root
    var e = new Error('project directory could not be found');
    delegate.emitter.emit('error', e);
    delegate.callback(e);

    return null;
};

/**
 * Check Path to be a Cordova Project.
 *
 * Options:
 *
 *   - `projectPath` {String} is path checked.
 *
 * Returns:
 *
 *   - {Boolean} true if valid Cordova project.
 */

/**
 *  Read Phonegap's package.json file and return as an object
 *
 *  Options:
 *
 *    -  none
 *
 *  Returns
 *
 *    - {object} containing package.json data
 */
module.exports.readNpmPackgae = function() {
    // load package.json
    var packagePath = path.join(__dirname, '..', '..', '..', 'package.json');

    return packageJSON = JSON.parse(fs.readFileSync(packagePath), 'utf8');
};

module.exports.isProject = function(projectPath) {
    var cordovaPath = path.join(projectPath, '.cordova');

    return (fs.existsSync(cordovaPath) &&
            !module.exports.isHome(projectPath));
};

/**
 * Check Path to be User Home Directory.
 *
 * Options:
 *
 *   - `homePath` {String} is path checked.
 *
 * Returns:
 *
 *   - {Boolean} true if path is user's home directory.
 */

module.exports.isHome = function(homePath) {
    return (homePath === HOME);
};

module.exports.clobberProjectConfig = function(configPath,clobbertargets) {
    var fs = require('fs');

    fs.open(configPath,'r+', function(err,fd) {
        if (err) {
            return;
        }
        fs.readFile(configPath, function(err, data) {
            if(err) {
                return;
            }
            for (each in clobbertargets) {
                data.replace(each, clobbertargets[each]);
            }
        });
    });
    return configPath;
};
<|endoftext|>


<commit_before>dojo.provide("dijit.Tooltip");

dojo.require("dijit.base.Widget");
dojo.require("dijit.base.TemplatedWidget");
dojo.require("dijit.util.place");
dojo.require("dijit.util.BackgroundIframe");

dojo.declare(
	"dijit._MasterTooltip",
	[dijit.base.Widget, dijit.base.TemplatedWidget],
	{
		// summary
		//		Internal widget that holds the actual tooltip markup,
		//		which occurs once per page.
		//		Called by Tooltip widgets which are just containers to hold
		//		the markup

		// duration: Integer
		//		Milliseconds to fade in/fade out
		duration: 200,

		// opacity: Number
		//		Final opacity tooltips are shown at, after fade in
		opacity: 0.9,

		templatePath: dojo.moduleUrl("dijit", "templates/Tooltip.html"),

		postCreate: function(){
			dojo.body().appendChild(this.domNode);

			this.bgIframe = new dijit.util.BackgroundIframe();
			this.bgIframe.setZIndex(dojo.style(this.domNode, "zIndex")-1);

			this.fadeIn = dojo._fade({node: this.domNode, duration: this.duration, end: this.opacity});
			dojo.connect(this.fadeIn, "onEnd", this, "_onShow");
			this.fadeOut = dojo._fade({node: this.domNode, duration: this.duration, end: 0});
			dojo.connect(this.fadeOut, "onEnd", this, "_onHide");

		},

		show: function(/*String*/ innerHTML, /*DomNode*/ aroundNode){
			// summary: display tooltip w/specified contents underneath specified node

			if(this.fadeOut.status() == "playing"){
				// previous tooltip is being hidden; wait until the hide completes then show new one
				this._onDeck=arguments;
				return;
			}
			this.containerNode.innerHTML=innerHTML;
			dijit.util.placeOnScreenAroundElement(this.domNode, aroundNode, [0,0],
				{'BL': 'TL', 'TL': 'BL'});
			dojo.style(this.domNode, "opacity", 0);
			this.fadeIn.play();
			this.isShowingNow = true;
		},

		_onShow: function(){
			this.bgIframe.size(this.domNode);
			this.bgIframe.show();
		},

		hide: function(){
			// summary: hide the tooltip
			if(this._onDeck){
				// this hide request is for a show() that hasn't even started yet;
				// just cancel the pending show()
				this._onDeck=null;
				return;
			}
			this.fadeIn.stop();
			this.isShowingNow = false;
			this.fadeOut.play();
		},

		_onHide: function(){
			this.domNode.style.cssText="";	// to position offscreen again
			this.bgIframe.hide();
			if(this._onDeck){
				// a show request has been queue up; do it now
				this.show.apply(this, this._onDeck);
				this._onDeck=null;
			}
		}

	}
);

// Make a single tooltip markup on the page that is reused as appropriate
dojo.addOnLoad(function(){
	dijit.MasterTooltip = new dijit._MasterTooltip();
});

dojo.declare(
	"dijit.Tooltip",
	dijit.base.Widget,
	{
		// summary
		//		Pops up a tooltip (a help message) when you hover over a node.

		// caption: String
		//		Text to display in the tooltip.
		//		Can also be specified as innerHTML (when creating the widget from markup).
		caption: "",

		// showDelay: Integer
		//		Number of milliseconds to wait after hovering over/focusing on the object, before
		//		the tooltip is displayed.
		showDelay: 400,

		// connectId: String
		//		Id of domNode to attach the tooltip to.
		//		(When user hovers over specified dom node, the tooltip will appear.)
		connectId: "",

		postCreate: function(){
			// An array to hold connect handles for cleanup (per instance)
			this._connections = [];

			this._connectNode = dojo.byId(this.connectId);

			dojo.forEach(["onMouseOver", "onHover", "onMouseOut", "onUnHover"], function(event){
				this._connections.push(dojo.connect(this._connectNode, event.toLowerCase(), this, "_"+event));
			}, this);
		},

		//PORT from dojo.dom.isDescendantOf
		_isDescendantOf: function(/*Node*/node, /*Node*/ancestor){
			//	summary
			//	Returns boolean if node is a descendant of ancestor
			// guaranteeDescendant allows us to be a "true" isDescendantOf function

			while(node){
				if(node === ancestor){
					return true; // boolean
				}
				try{
					node = node.parentNode;
				}catch(e){
					return true;
				}
			}
			return false; // boolean
		},

		_onMouseOver: function(/*Event*/ e){
			if(this._isDescendantOf(e.relatedTarget, this._connectNode)){
				// false event; just moved from target child to target; ignore.
				return;
			}
			this._onHover(e);
		},

		_onMouseOut: function(/*Event*/ e){
			if(this._isDescendantOf(e.relatedTarget, this._connectNode)){
				// false event; just moved from target to target child; ignore.
				return;
			}
			this._onUnHover(e);
		},

		_onHover: function(/*Event*/ e){
			if(this._hover){ return; }
			this._hover=true;

			// If tooltip not showing yet then set a timer to show it shortly
			if(!this.isShowingNow && !this._showTimer){
				this._showTimer = setTimeout(dojo.hitch(this, "open"), this.showDelay);
			}
		},

		_onUnHover: function(/*Event*/ e){
			if(!this._hover){ return; }
			this._hover=false;

			if(this._showTimer){
				clearTimeout(this._showTimer);
				delete this._showTimer;
			}else{
				this.close();
			}
		},

		open: function(){
			// summary: display the tooltip; usually not called directly.
			if(this.isShowingNow){ return; }
			if(this._showTimer){
				clearTimeout(this._showTimer);
				delete this._showTimer;
			}
			delete this._showTimer;
			dijit.MasterTooltip.show(this.caption || this.domNode.innerHTML, this._connectNode);
			this.isShowingNow = true;
		},

		close: function(){
			// summary: hide the tooltip; usually not called directly.
			if(!this.isShowingNow){ return; }
			dijit.MasterTooltip.hide();
			this.isShowingNow = false;
		},

		uninitialize: function(){
			this.close();
			dojo.forEach(this._connections, dojo.disconnect);
			this._connections = {};
		}
	}
);
<commit_msg>Refs #2727<commit_after>dojo.provide("dijit.Tooltip");

dojo.require("dijit.base.Widget");
dojo.require("dijit.base.TemplatedWidget");
dojo.require("dijit.util.place");
dojo.require("dijit.util.BackgroundIframe");

dojo.declare(
	"dijit._MasterTooltip",
	[dijit.base.Widget, dijit.base.TemplatedWidget],
	{
		// summary
		//		Internal widget that holds the actual tooltip markup,
		//		which occurs once per page.
		//		Called by Tooltip widgets which are just containers to hold
		//		the markup

		// duration: Integer
		//		Milliseconds to fade in/fade out
		duration: 200,

		// opacity: Number
		//		Final opacity tooltips are shown at, after fade in
		opacity: 0.9,

		templatePath: dojo.moduleUrl("dijit", "templates/Tooltip.html"),

		postCreate: function(){
			dojo.body().appendChild(this.domNode);

			this.bgIframe = new dijit.util.BackgroundIframe();
			this.bgIframe.setZIndex(dojo.style(this.domNode, "zIndex")-1);

			this.fadeIn = dojo._fade({node: this.domNode, duration: this.duration, end: this.opacity});
			dojo.connect(this.fadeIn, "onEnd", this, "_onShow");
			this.fadeOut = dojo._fade({node: this.domNode, duration: this.duration, end: 0});
			dojo.connect(this.fadeOut, "onEnd", this, "_onHide");

		},

		show: function(/*String*/ innerHTML, /*DomNode*/ aroundNode){
			// summary: display tooltip w/specified contents underneath specified node

			if(this.fadeOut.status() == "playing"){
				// previous tooltip is being hidden; wait until the hide completes then show new one
				this._onDeck=arguments;
				return;
			}
			this.containerNode.innerHTML=innerHTML;
			dijit.util.placeOnScreenAroundElement(this.domNode, aroundNode, [0,0],
				{'BL': 'TL', 'TL': 'BL'});
			dojo.style(this.domNode, "opacity", 0);
			this.fadeIn.play();
			this.isShowingNow = true;
		},

		_onShow: function(){
			this.bgIframe.size(this.domNode);
			this.bgIframe.show();
		},

		hide: function(){
			// summary: hide the tooltip
			if(this._onDeck){
				// this hide request is for a show() that hasn't even started yet;
				// just cancel the pending show()
				this._onDeck=null;
				return;
			}
			this.fadeIn.stop();
			this.isShowingNow = false;
			this.fadeOut.play();
		},

		_onHide: function(){
			this.domNode.style.cssText="";	// to position offscreen again
			this.bgIframe.hide();
			if(this._onDeck){
				// a show request has been queue up; do it now
				this.show.apply(this, this._onDeck);
				this._onDeck=null;
			}
		}

	}
);

// Make a single tooltip markup on the page that is reused as appropriate
dojo.addOnLoad(function(){
	dijit.MasterTooltip = new dijit._MasterTooltip();
});

dojo.declare(
	"dijit.Tooltip",
	dijit.base.Widget,
	{
		// summary
		//		Pops up a tooltip (a help message) when you hover over a node.

		// caption: String
		//		Text to display in the tooltip.
		//		Can also be specified as innerHTML (when creating the widget from markup).
		caption: "",

		// showDelay: Integer
		//		Number of milliseconds to wait after hovering over/focusing on the object, before
		//		the tooltip is displayed.
		showDelay: 400,

		// connectId: String
		//		Id of domNode to attach the tooltip to.
		//		(When user hovers over specified dom node, the tooltip will appear.)
		connectId: "",

		postCreate: function(){
			// An array to hold connect handles for cleanup (per instance)
			this._connections = [];

			this._connectNode = dojo.byId(this.connectId);

			dojo.forEach(["onMouseOver", "onHover", "onMouseOut", "onUnHover"], function(event){
				this._connections.push(dojo.connect(this._connectNode, event.toLowerCase(), this, "_"+event));
			}, this);
		},

		//PORT #2804
		_isDescendantOf: function(/*Node*/node, /*Node*/ancestor){
			//	summary
			//	Returns boolean if node is a descendant of ancestor
			// guaranteeDescendant allows us to be a "true" isDescendantOf function

			while(node){
				if(node === ancestor){
					return true; // boolean
				}
				try{
					node = node.parentNode;
				}catch(e){
					return true;
				}
			}
			return false; // boolean
		},

		_onMouseOver: function(/*Event*/ e){
			if(this._isDescendantOf(e.relatedTarget, this._connectNode)){
				// false event; just moved from target child to target; ignore.
				return;
			}
			this._onHover(e);
		},

		_onMouseOut: function(/*Event*/ e){
			if(this._isDescendantOf(e.relatedTarget, this._connectNode)){
				// false event; just moved from target to target child; ignore.
				return;
			}
			this._onUnHover(e);
		},

		_onHover: function(/*Event*/ e){
			if(this._hover){ return; }
			this._hover=true;

			// If tooltip not showing yet then set a timer to show it shortly
			if(!this.isShowingNow && !this._showTimer){
				this._showTimer = setTimeout(dojo.hitch(this, "open"), this.showDelay);
			}
		},

		_onUnHover: function(/*Event*/ e){
			if(!this._hover){ return; }
			this._hover=false;

			if(this._showTimer){
				clearTimeout(this._showTimer);
				delete this._showTimer;
			}else{
				this.close();
			}
		},

		open: function(){
			// summary: display the tooltip; usually not called directly.
			if(this.isShowingNow){ return; }
			if(this._showTimer){
				clearTimeout(this._showTimer);
				delete this._showTimer;
			}
			delete this._showTimer;
			dijit.MasterTooltip.show(this.caption || this.domNode.innerHTML, this._connectNode);
			this.isShowingNow = true;
		},

		close: function(){
			// summary: hide the tooltip; usually not called directly.
			if(!this.isShowingNow){ return; }
			dijit.MasterTooltip.hide();
			this.isShowingNow = false;
		},

		uninitialize: function(){
			this.close();
			dojo.forEach(this._connections, dojo.disconnect);
			this._connections = {};
		}
	}
);
<|endoftext|>


<commit_before>dojo.provide("dijit.Tooltip");

dojo.require("dijit._Widget");
dojo.require("dijit._Templated");

dojo.declare(
	"dijit._MasterTooltip",
	[dijit._Widget, dijit._Templated],
	{
		// summary
		//		Internal widget that holds the actual tooltip markup,
		//		which occurs once per page.
		//		Called by Tooltip widgets which are just containers to hold
		//		the markup

		// duration: Integer
		//		Milliseconds to fade in/fade out
		duration: 200,

		templatePath: dojo.moduleUrl("dijit", "templates/Tooltip.html"),

		postCreate: function(){
			dojo.body().appendChild(this.domNode);

			this.bgIframe = new dijit.BackgroundIframe(this.domNode);

			// Setup fade-in and fade-out functions.  An IE bug prevents the arrow from showing up
			// unless opacity==1, because it's displayed via overflow: visible on the main div.
			var opacity = dojo.isIE ? 1 : dojo.style(this.domNode, "opacity");
			this.fadeIn = dojo._fade({node: this.domNode, duration: this.duration, end: opacity});
			dojo.connect(this.fadeIn, "onEnd", this, "_onShow");
			this.fadeOut = dojo._fade({node: this.domNode, duration: this.duration, end: 0});
			dojo.connect(this.fadeOut, "onEnd", this, "_onHide");

		},

		show: function(/*String*/ innerHTML, /*DomNode*/ aroundNode){
			// summary:
			//	Display tooltip w/specified contents to right specified node
			//	(To left if there's no space on the right, or if LTR==right)

			if(this.fadeOut.status() == "playing"){
				// previous tooltip is being hidden; wait until the hide completes then show new one
				this._onDeck=arguments;
				return;
			}
			this.containerNode.innerHTML=innerHTML;

			// Firefox bug. when innerHTML changes to be shorter than previous
			// one, the node size will not be updated until it moves.
			this.domNode.style.top = (this.domNode.offsetTop + 1) + "px";

			// position the element and change CSS according to position
			var align = this.isLeftToRight() ? {'BR': 'BL', 'BL': 'BR'} : {'BL': 'BR', 'BR': 'BL'};
			var pos = dijit.placeOnScreenAroundElement(this.domNode, aroundNode, align);
			this.domNode.className="dijitTooltip dijitTooltip" + (pos.corner=='BL' ? "Right" : "Left");

			// show it
			dojo.style(this.domNode, "opacity", 0);
			this.fadeIn.play();
			this.isShowingNow = true;
		},

		_onShow: function(){
			if(dojo.isIE){
				// the arrow won't show up on a node w/an opacity filter
				this.domNode.style.filter="";
			}
		},

		hide: function(){
			// summary: hide the tooltip
			if(this._onDeck){
				// this hide request is for a show() that hasn't even started yet;
				// just cancel the pending show()
				this._onDeck=null;
				return;
			}
			this.fadeIn.stop();
			this.isShowingNow = false;
			this.fadeOut.play();
		},

		_onHide: function(){
			this.domNode.style.cssText="";	// to position offscreen again
			if(this._onDeck){
				// a show request has been queued up; do it now
				this.show.apply(this, this._onDeck);
				this._onDeck=null;
			}
		}

	}
);

// Make a single tooltip markup on the page that is reused as appropriate
dojo.addOnLoad(function(){
	dijit.MasterTooltip = new dijit._MasterTooltip();
});

dojo.declare(
	"dijit.Tooltip",
	dijit._Widget,
	{
		// summary
		//		Pops up a tooltip (a help message) when you hover over a node.

		// label: String
		//		Text to display in the tooltip.
		//		Specified as innerHTML when creating the widget from markup.
		label: "",

		// showDelay: Integer
		//		Number of milliseconds to wait after hovering over/focusing on the object, before
		//		the tooltip is displayed.
		showDelay: 400,

		// connectId: String
		//		Id of domNode to attach the tooltip to.
		//		(When user hovers over specified dom node, the tooltip will appear.)
		connectId: "",

		postCreate: function(){
			this.srcNodeRef.style.display="none";

			this._connectNode = dojo.byId(this.connectId);

			dojo.forEach(["onMouseOver", "onHover", "onMouseOut", "onUnHover"], function(event){
				this.connect(this._connectNode, event.toLowerCase(), "_"+event);
			}, this);
		},

		_onMouseOver: function(/*Event*/ e){
			this._onHover(e);
		},

		_onMouseOut: function(/*Event*/ e){
			if(dojo.isDescendant(e.relatedTarget, this._connectNode)){
				// false event; just moved from target to target child; ignore.
				return;
			}
			this._onUnHover(e);
		},

		_onHover: function(/*Event*/ e){
			if(this._hover){ return; }
			this._hover=true;
			// If tooltip not showing yet then set a timer to show it shortly
			if(!this.isShowingNow && !this._showTimer){
				this._showTimer = setTimeout(dojo.hitch(this, "open"), this.showDelay);
			}
		},

		_onUnHover: function(/*Event*/ e){
			if(!this._hover){ return; }
			this._hover=false;

			if(this._showTimer){
				clearTimeout(this._showTimer);
				delete this._showTimer;
			}else{
				this.close();
			}
		},

		open: function(){
			// summary: display the tooltip; usually not called directly.
			if(this.isShowingNow){ return; }
			if(this._showTimer){
				clearTimeout(this._showTimer);
				delete this._showTimer;
			}
			dijit.MasterTooltip.show(this.label || this.domNode.innerHTML, this._connectNode);
			this.isShowingNow = true;
		},

		close: function(){
			// summary: hide the tooltip; usually not called directly.
			if(!this.isShowingNow){ return; }
			dijit.MasterTooltip.hide();
			this.isShowingNow = false;
		},

		uninitialize: function(){
			this.close();
		}
	}
);
<commit_msg>Fixes #4081.  Changed dojo_fade to dojo.fadeIn and dojo.fadeOut<commit_after>dojo.provide("dijit.Tooltip");

dojo.require("dijit._Widget");
dojo.require("dijit._Templated");

dojo.declare(
	"dijit._MasterTooltip",
	[dijit._Widget, dijit._Templated],
	{
		// summary
		//		Internal widget that holds the actual tooltip markup,
		//		which occurs once per page.
		//		Called by Tooltip widgets which are just containers to hold
		//		the markup

		// duration: Integer
		//		Milliseconds to fade in/fade out
		duration: 200,

		templatePath: dojo.moduleUrl("dijit", "templates/Tooltip.html"),

		postCreate: function(){
			dojo.body().appendChild(this.domNode);

			this.bgIframe = new dijit.BackgroundIframe(this.domNode);

			// Setup fade-in and fade-out functions.
			this.fadeIn = dojo.fadeIn({ node: this.domNode, duration: this.duration, onEnd: dojo.hitch(this, "_onShow") }),
			this.fadeOut = dojo.fadeOut({ node: this.domNode, duration: this.duration, onEnd: dojo.hitch(this, "_onHide") });

		},

		show: function(/*String*/ innerHTML, /*DomNode*/ aroundNode){
			// summary:
			//	Display tooltip w/specified contents to right specified node
			//	(To left if there's no space on the right, or if LTR==right)

			if(this.fadeOut.status() == "playing"){
				// previous tooltip is being hidden; wait until the hide completes then show new one
				this._onDeck=arguments;
				return;
			}
			this.containerNode.innerHTML=innerHTML;

			// Firefox bug. when innerHTML changes to be shorter than previous
			// one, the node size will not be updated until it moves.
			this.domNode.style.top = (this.domNode.offsetTop + 1) + "px";

			// position the element and change CSS according to position
			var align = this.isLeftToRight() ? {'BR': 'BL', 'BL': 'BR'} : {'BL': 'BR', 'BR': 'BL'};
			var pos = dijit.placeOnScreenAroundElement(this.domNode, aroundNode, align);
			this.domNode.className="dijitTooltip dijitTooltip" + (pos.corner=='BL' ? "Right" : "Left");

			// show it
			dojo.style(this.domNode, "opacity", 0);
			this.fadeIn.play();
			this.isShowingNow = true;
		},

		_onShow: function(){
			if(dojo.isIE){
				// the arrow won't show up on a node w/an opacity filter
				this.domNode.style.filter="";
			}
		},

		hide: function(){
			// summary: hide the tooltip
			if(this._onDeck){
				// this hide request is for a show() that hasn't even started yet;
				// just cancel the pending show()
				this._onDeck=null;
				return;
			}
			this.fadeIn.stop();
			this.isShowingNow = false;
			this.fadeOut.play();
		},

		_onHide: function(){
			this.domNode.style.cssText="";	// to position offscreen again
			if(this._onDeck){
				// a show request has been queued up; do it now
				this.show.apply(this, this._onDeck);
				this._onDeck=null;
			}
		}

	}
);

// Make a single tooltip markup on the page that is reused as appropriate
dojo.addOnLoad(function(){
	dijit.MasterTooltip = new dijit._MasterTooltip();
});

dojo.declare(
	"dijit.Tooltip",
	dijit._Widget,
	{
		// summary
		//		Pops up a tooltip (a help message) when you hover over a node.

		// label: String
		//		Text to display in the tooltip.
		//		Specified as innerHTML when creating the widget from markup.
		label: "",

		// showDelay: Integer
		//		Number of milliseconds to wait after hovering over/focusing on the object, before
		//		the tooltip is displayed.
		showDelay: 400,

		// connectId: String
		//		Id of domNode to attach the tooltip to.
		//		(When user hovers over specified dom node, the tooltip will appear.)
		connectId: "",

		postCreate: function(){
			this.srcNodeRef.style.display="none";

			this._connectNode = dojo.byId(this.connectId);

			dojo.forEach(["onMouseOver", "onHover", "onMouseOut", "onUnHover"], function(event){
				this.connect(this._connectNode, event.toLowerCase(), "_"+event);
			}, this);
		},

		_onMouseOver: function(/*Event*/ e){
			this._onHover(e);
		},

		_onMouseOut: function(/*Event*/ e){
			if(dojo.isDescendant(e.relatedTarget, this._connectNode)){
				// false event; just moved from target to target child; ignore.
				return;
			}
			this._onUnHover(e);
		},

		_onHover: function(/*Event*/ e){
			if(this._hover){ return; }
			this._hover=true;
			// If tooltip not showing yet then set a timer to show it shortly
			if(!this.isShowingNow && !this._showTimer){
				this._showTimer = setTimeout(dojo.hitch(this, "open"), this.showDelay);
			}
		},

		_onUnHover: function(/*Event*/ e){
			if(!this._hover){ return; }
			this._hover=false;

			if(this._showTimer){
				clearTimeout(this._showTimer);
				delete this._showTimer;
			}else{
				this.close();
			}
		},

		open: function(){
			// summary: display the tooltip; usually not called directly.
			if(this.isShowingNow){ return; }
			if(this._showTimer){
				clearTimeout(this._showTimer);
				delete this._showTimer;
			}
			dijit.MasterTooltip.show(this.label || this.domNode.innerHTML, this._connectNode);
			this.isShowingNow = true;
		},

		close: function(){
			// summary: hide the tooltip; usually not called directly.
			if(!this.isShowingNow){ return; }
			dijit.MasterTooltip.hide();
			this.isShowingNow = false;
		},

		uninitialize: function(){
			this.close();
		}
	}
);
<|endoftext|>


<commit_before>/* globals Promise */
'use strict';

module.exports = function (app, express, userData) {
  let projectController = false;
  const projectRouter = new express.Router();
  projectRouter
    .get('/', (req, res) => {
      if (!projectController) {
        projectController = lazyLoadProjectController(userData);
      }

      projectController.index(req, res);
    })
    .post('/', (req, res) => {
      if (!projectController) {
        projectController = lazyLoadProjectController(userData);
      }

      let projectModel = require('../models/project-model');
      let parsedProject = projectModel(req.body);

      return new Promise((resolve, reject) => {
          parsedProject.save(err => {
            if (err) {
              return reject(err);
            }

            return resolve(parsedProject);
          });
        }).then((createdProject) => {
          res
            .status(201)
            .json({
              redirectUrl: '/',
              message: `Project ${createdProject.name} has been created!`
            });
        })
        .catch((err) => {
          res
            .status(400)
            .sent(err.message);
        });
    });

  app.use('/createproject', projectRouter);
  app.use('/addproject', projectRouter);
};

function lazyLoadProjectController(userData) {
  const projectController = require('../controllers/project-controller')(userData);
  return projectController;
}<commit_msg>res.send, indent<commit_after>/* globals Promise */
'use strict';

module.exports = function(app, express, userData) {
    let projectController = false;
    const projectRouter = new express.Router();
    projectRouter
        .get('/', (req, res) => {
            if (!projectController) {
                projectController = lazyLoadProjectController(userData);
            }

            projectController.index(req, res);
        })
        .post('/', (req, res) => {
            if (!projectController) {
                projectController = lazyLoadProjectController(userData);
            }

            let projectModel = require('../models/project-model');
            let parsedProject = projectModel(req.body);

            return new Promise((resolve, reject) => {
                    parsedProject.save(err => {
                        if (err) {
                            return reject(err);
                        }

                        return resolve(parsedProject);
                    });
                }).then((createdProject) => {
                    res
                        .status(201)
                        .json({
                            redirectUrl: '/',
                            message: `Project ${createdProject.name} has been created!`
                        });
                })
                .catch((err) => {
                    res
                        .status(400)
                        .send(err.message);
                });
        });

    app.use('/createproject', projectRouter);
    app.use('/addproject', projectRouter);
};

function lazyLoadProjectController(userData) {
    const projectController = require('../controllers/project-controller')(userData);
    return projectController;
}<|endoftext|>