// 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); }; })();