Newer
Older
KaiFengAxure / 开封原型PC / plugins / recordplay / recordplay.js
@zhangdeliang zhangdeliang on 1 Jul 18 KB 1
// use this to isolate the scope
(function() {

        if(!$axure.document.configuration.showRecordPlay) { return; }

    $(window.document).ready(function() {
        $axure.player.createPluginHost({
            id: 'recordPlayHost',
            context: 'interface',
            title: 'Recording'
        });
        _generateRecordPlay();

        $('#recordButton').click(_recordClick);
        $('#playButton').click(_playClick);
        $('#stopButton').click(_stopClick);
        $('#deleteButton').click(_deleteClick);

        // bind to the page load

        $axure.page.bind('load.page_notes', function() {
            
            $.ajax({
                type: "POST",
                url: '/RecordController/ListRecordings',
                success: function(response) {

                    $('#recordNameHeader').html("");
                    $('#recordPlayContent').html("");
                    //populate the notes 
                    
                    axRecordingList = [];

                    if(!eventList) {
                        recordingIndex = 0;
                        eventList = [];
                        recordingStartTime = 0;
                        bulkEventElement = "";
                        lastBulkEvent = {};
                    }

                    for(var idx in response.recordingList) {
                        getOneRecording(response.recordingList[idx]);
                    }

                    return false;
                },
                //                dataType: 'json'
            });
        });
    });
    
    var nameMatcher = new RegExp("^axRecording[0-9]{4}$", "i");
    var indexMatcher = new RegExp("[0-9]{4}$", "i");

    var convertFromJson = function(oneRecording) {
        
        if(nameMatcher.exec(oneRecording.recordingName)) {
            var myArray = indexMatcher.exec(oneRecording.recordingName);
            var currIdx = parseInt(myArray);
            if(recordingIndex < currIdx) {
                recordingIndex = currIdx;
            }
        }
        

        for(var idx in oneRecording.eventList) {
            var thisEvent = oneRecording.eventList[idx];
                thisEvent.eventInfo = {};
                            thisEvent.eventInfo.srcElement = thisEvent.elementID;
                // TODO: check that this is correct.

            if(isBulkMouse(thisEvent.eventType)) {
                thisEvent.eventInfo.mousePositions = [];
                thisEvent.eventInfo.mousePositions = thisEvent.mousePositions;
                thisEvent.timeStamp = thisEvent.mousePositions[0].timeStamp;
            }
            if(isSingleMouse(thisEvent.eventType)) {
                thisEvent.eventInfo.cursor = {};
                thisEvent.eventInfo.cursor = thisEvent.cursor;
                
            }
            if(thisEvent.eventType === 'OnDrag') {
                thisEvent.eventInfo.dragInfo = {};
                thisEvent.eventInfo.dragInfo = thisEvent.dragInfo;
                thisEvent.timeStamp = thisEvent.dragInfo.startTime;
            }

        }
        return oneRecording;
    };

    var getOneRecording = function(recordingItem) {
        $.ajax({
                type: "POST",
                url: '/RecordController/GetRecording',
                data: { 'recordingId': recordingItem.recordingId },
            success: function(response) {
                        axRecordingList[axRecordingList.length] = convertFromJson(response);
                        var axRecordingContainer = $('#recordingContainer').find('li').filter('.recordingRootNode');
                        axRecordingContainer.append(_formAxRecordingBranch(response));
                        _attachEventTriggers(response);     
            },                //                dataType: 'json'
        });

    };
    
    var axRecordingList;
    var eventList;
    var recordingIndex;
    var recordingStartTime;
    var recordingId;
    var recordingName;


    var leadingZeros = function(number, digits) { // because this thing doesn't have string.format (or does it?)
        var recurseLeadingZeros = function(number, digitsLeft) {
            if(digitsLeft > 0) {
                return recurseLeadingZeros("0" + number, digitsLeft - 1);
            } else {
                return number;
            }
        };
        return recurseLeadingZeros(number, digits - String(number).length);
    };
    

    var generateRecordingName = function() {
        return "axRecording" + leadingZeros(recordingIndex, 4);
    };

    var isSingleMouse = function(eventType) {
        return (eventType === 'OnClick' ||
            eventType === 'OnMouseUp' ||
            eventType === 'OnMouseDown' ||
            eventType === 'OnMouseOver' ||
            eventType === 'OnKeyUp' ||
            eventType === 'OnSelectedChange' ||
            eventType === 'OnSelect' ||
            eventType === 'OnUnselect' ||
            eventType === 'OnTextChange' ||
            eventType === 'OnMouseOut');
    };

    var isBulkMouse = function(eventType) {
        return (eventType === 'OnMouseHover' ||
            eventType === 'OnMouseMove');
    };

    var bulkEventElement;
    var lastBulkEvent;


    $axure.messageCenter.addMessageListener(function(message, eventData) {
        var lastEvent, lastBulkData;
        
        if(message === 'logEvent') {
            
            if(bulkEventElement !== eventData.elementID) {
                lastBulkEvent = {};
                bulkEventElement = eventData.elementID;
            }
            
            if(isBulkMouse(eventData.eventType)) {
                lastEvent = lastBulkEvent[eventData.eventType];

                if(lastEvent) {
                    // this is the second or third or whatever onmousemove in a row
                    lastBulkData = lastEvent.eventInfo.mousePositions;
                    lastBulkData[lastBulkData.length] = {
                        cursor: eventData.eventInfo.cursor,
                        timeStamp: eventData.timeStamp
                    };
                } else {

                    eventData.eventInfo.mousePositions = [];
                    eventData.eventInfo.mousePositions[0] = {
                        cursor: eventData.eventInfo.cursor,
                        timeStamp: eventData.timeStamp
                    };
                    eventList[eventList.length] = eventData;
                    lastBulkEvent[eventData.eventType] = eventData;
                }
            } else {
                var z = true;
            }
            
            if(isSingleMouse(eventData.eventType) ) {
                eventList[eventList.length] = eventData;
                lastBulkEvent = {};
                bulkEventElement = eventData.elementID;
            }

            if(eventData.eventType === 'OnDrag') {

                lastEvent = lastBulkEvent[eventData.eventType];
                
                if (lastEvent) {
                    // this is the second or third or whatever onmousemove in a row
                    lastBulkData = lastEvent.eventInfo.mousePositions;
                    lastBulkData[lastBulkData.length] = {
                        dragInfo: eventData.eventInfo.dragInfo,
                        timeStamp: eventData.timeStamp
                    };
                } else {
                    eventData.eventInfo.mousePositions = [];
                    eventData.eventInfo.mousePositions[0] = {
                        dragInfo: eventData.eventInfo.dragInfo,
                        timeStamp: eventData.timeStamp
                    };
                    eventList[eventList.length] = eventData;
                    lastBulkEvent[eventData.eventType] = eventData;
                }
            }
//            if(eventData.eventType === 'OnKeyUp') {
//                transmissionFields.eventInfo = eventData.eventInfo;
//                $.ajax({
//                    type: "POST",
//                    url: '/RecordController/LogMouseClick',
//                    data: transmissionFields,
//                });
//            }            
        }

    });
    
    
    var _recordClick = function(event) {
        $('#recordButton').addClass('recordPlayButtonSelected');
        recordingIndex++;
        //        $axure.recording.startRecord();

        recordingStartTime = new Date().getTime();

        $.ajax({
            type: "POST",
            url: '/RecordController/CreateRecording',
            data: {
                'recordingName': generateRecordingName(),
                timeStamp: recordingStartTime
            },
            success: function(response) {
                recordingId = response.recordingId;
                recordingName = response.recordingName;
        $axure.messageCenter.postMessage('startRecording', {'recordingId' : recordingId, 'recordingName': recordingName});
            },
            //                dataType: 'json'
        });
        
    };

    var _playClick = function(event) {
        $('#playButton').addClass('recordPlayButtonSelected');
    };

    var _stopClick = function(event) {
        var axRecording, axObjectDictionary, axRecordingContainer, transmissionFields;
        $('#sitemapLinksContainer').toggle();
        if($('#recordButton').is('.recordPlayButtonSelected')) {
            $('#recordButton').removeClass('recordPlayButtonSelected');
            //            $axure.recording.stopRecord();

            axRecording = {
                'recordingId' : recordingId,
                'recordingName': recordingName,
                'eventList': eventList
            };
            
            axRecordingList[axRecordingList.length] = axRecording;
            axRecordingContainer = $('#recordingContainer').find('li').filter('.recordingRootNode');
            axRecordingContainer.append(_formAxRecordingBranch(axRecording));
            _attachEventTriggers(axRecording);

            lastBulkEvent = {};

            var recordingStepList = [];

            for(var eventListIdx in eventList) {
                var eventListItem = eventList[eventListIdx];

                if(eventListItem.eventType === 'OnDrag') {
                    var lastDrag = eventListItem.eventInfo.mousePositions[eventListItem.eventInfo.mousePositions.length - 1].dragInfo;
                    eventListItem.eventInfo.dragInfo.currentX = lastDrag.currentX;
                    eventListItem.eventInfo.dragInfo.currentY = lastDrag.currentY;
                    eventListItem.eventInfo.dragInfo.currentTime = lastDrag.currentTime;
                    eventListItem.eventInfo.dragInfo.xDelta = eventListItem.eventInfo.dragInfo.currentX - eventListItem.eventInfo.dragInfo.lastX;
                    eventListItem.eventInfo.dragInfo.yDelta = eventListItem.eventInfo.dragInfo.currentY - eventListItem.eventInfo.dragInfo.lastY;
                    transmissionFields = {};
                    transmissionFields = tackItOn(transmissionFields, eventListItem, ['eventType', 'elementID', 'path']);
                    transmissionFields = tackItOn(transmissionFields, eventListItem.eventInfo, ['dragInfo']);
                    transmissionFields.recordingId = recordingId;
                }

                if(isSingleMouse(eventListItem.eventType)) {
                    transmissionFields = {};
                    transmissionFields = tackItOn(transmissionFields, eventListItem, ['timeStamp', 'eventType', 'elementID', 'path']);
                    transmissionFields = tackItOn(transmissionFields, eventListItem.eventInfo, ['cursor']);
                    transmissionFields.recordingId = recordingId;
                }

                if(isBulkMouse(eventListItem.eventType)) {
                    transmissionFields = {};
                    transmissionFields = tackItOn(transmissionFields, eventListItem, ['eventType', 'elementID', 'path']);
                    transmissionFields = tackItOn(transmissionFields, eventListItem.eventInfo, ['mousePositions']);
                    transmissionFields.recordingId = recordingId;
                }
                recordingStepList[recordingStepList.length] = transmissionFields;
            }

            eventList = [];
            $axure.messageCenter.postMessage('stopRecording', axObjectDictionary);

            var jsonText = {
                'recordingName': recordingName,
                'recordingId': recordingId,
                recordingStart: new Date().getTime(),
                recordingEnd: recordingStartTime,
                'eventList': recordingStepList
            };

            $.ajax({
                type: "POST",
                url: '/RecordController/StopRecording',
                data: { 'jsonText': JSON.stringify(jsonText) }
                
            });

        }

        if($('#playButton').is('.recordPlayButtonSelected')) {
            $('#playButton').removeClass('recordPlayButtonSelected');
        }
    };
    
    var _deleteClick = function(event) {
        $.ajax({
                type: "POST",
                url: '/RecordController/DeleteRecordings',
            success: function(response) {
                var x = true;
            },                //                dataType: 'json'
        });
    };

    var tackItOn = function(destination, source, fields) {

        for(var idx in fields) {
            destination[fields[idx]] = source[fields[idx]];
        }
        return destination;
    };

    var makeFirstLetterLower = function(eventName) {
        return eventName.substr(0, 1).toLowerCase() + eventName.substr(1);
    };

    var _attachEventTriggers = function(axRecording) {
        for(var eventIdx in axRecording.eventList) {
            var eventObject = axRecording.eventList[eventIdx];
            var eventID = axRecording['recordingId'] + '_' + eventObject.timeStamp;
            currentEvent = eventID;
            $('#' + eventID).click(_triggerEvent(axRecording['recordingId'], eventObject.timeStamp));
            //            $('#' + eventID).click(event.trigger);
        }
    };

    var _formAxRecordingBranch = function(axRecording) {
        var eventObject, eventID, RDOID;
        var recordPlayUi = '<ul class="recordingTree">';
        recordPlayUi += "<li class='recordingNode recordingExpandableNode'>";
        recordPlayUi += '<div class="recordingContainer" style="margin-left:15px">';
        recordPlayUi += '<a class="recordingPlusMinusLink"><span class="recordingMinus"></span></a>';
        recordPlayUi += '<a class="recordingPageLink" nodeurl="home.html">';
        recordPlayUi += '<span class="recordingPageIcon"></span>';
        recordPlayUi += '<span class="recordingPageName">' + axRecording['recordingName'] + '</span>';
        recordPlayUi += '</a>';

        recordPlayUi += '<ul>';

        for(eventID in axRecording.eventList) {

            eventObject = axRecording.eventList[eventID];

            recordPlayUi += '<li class="recordingNode recordingLeafNode">';
            recordPlayUi += '<div class="recordingEventContainer" style="margin-left:44px">';
            var eventID = axRecording['recordingId'] + '_' + eventObject.timeStamp;
            recordPlayUi += '<a id="' + eventID + '" class="sitemapPageLink">';
            recordPlayUi += 'Event ID: ' + eventID + '<br/>';

            recordPlayUi += '<span class="sitemapPageIcon"></span>';
            recordPlayUi += '<span class="sitemapPageName">';

            recordPlayUi += 'elementID: ' + eventObject.elementID + '<br/>';
            recordPlayUi += 'eventType: ' + eventObject.eventType + '<br/>';
//            recordPlayUi += 'cursor: ' + eventObject.eventInfo.cursor.x + ',' + eventObject.eventInfo.cursor.y + '<br/>';

            for(RDOID in eventObject.path) {
                recordPlayUi += '/' + eventObject.path[RDOID];
            }
            recordPlayUi += '<br/>';
            recordPlayUi += '</span>';
            recordPlayUi += '</a>';
            recordPlayUi += '</div>';
            recordPlayUi += '</li>';
        }

        recordPlayUi += '</ul>';

        recordPlayUi += '</div>';

        recordPlayUi += "</li>";
        recordPlayUi += "</ul>";

        return recordPlayUi;
    };

    var currentEvent = '';

    var _triggerEvent = function(axRecording, timeStamp) {
        //            $axure.messageCenter.postMessage('triggerEvent', false);


        for(var axRecordingIdx in axRecordingList) {
            if(axRecordingList[axRecordingIdx].recordingId === axRecording) {
                for(var eventIdx in axRecordingList[axRecordingIdx].eventList) {
                    if(axRecordingList[axRecordingIdx].eventList[eventIdx].timeStamp === timeStamp) {

                        var thisEvent = axRecordingList[axRecordingIdx].eventList[eventIdx];
                        //                            thisEvent.trigger();

                        var thisEventInfo, lowerEventType;
                        lowerEventType = thisEvent.eventType.toLowerCase();
                        if(lowerEventType === 'onclick' || lowerEventType === 'onmousein') {
                            thisEventInfo = {};
                            thisEventInfo = tackItOn(thisEventInfo, thisEvent.eventInfo, ['cursor', 'timeStamp', 'srcElement']);
                            if(thisEvent.eventInfo.inputType) {
                                thisEventInfo = tackItOn(thisEventInfo, thisEvent.eventInfo, ['inputType', 'inputValue']);
                            }
                        } else {
                            thisEventInfo = thisEvent.eventInfo;
                        }

                        var thisParameters = {
                            'element': thisEvent.elementID,
                            'eventInfo': thisEventInfo,
                            //                            'axEventObject': thisEvent.eventObject,
                            'eventType': thisEvent.eventType
                        };

                        return function() {
                            $axure.messageCenter.postMessage('playEvent', thisParameters);
                        };

                    }
                }
            }
        }
    };

    var _generateRecordPlay = function() {
        var recordPlayUi = "<div id='recordPlayContainer'>";

        recordPlayUi += "<div id='recordPlayToolbar'>";

        recordPlayUi += "<div style='height:30px;'>";

        recordPlayUi += "<a id='recordButton' title='Start a Recording' class='recordPlayButton'></a>";
        recordPlayUi += "<a id='playButton' title='Play Back a Recording' class='recordPlayButton'></a>";
        recordPlayUi += "<a id='stopButton' title='Stop' class='recordPlayButton'></a>";
        recordPlayUi += "<a id='deleteButton' title='Delete All Recordings' class='recordPlayButton'></a>";
        recordPlayUi += "</div>";

        recordPlayUi += "<div id='recordingContainer'><li class='recordingNode recordingRootNode'></li></div>";
        recordPlayUi += "</div>";

        $('#recordPlayHost').html(recordPlayUi);
    };

})();