Skip to content

Instantly share code, notes, and snippets.

@MarketingPip
Forked from shenningsgard/coderecorder_app.js
Created December 2, 2023 20:39
Show Gist options
  • Save MarketingPip/c2d4c3706fb068209771b29b899129c2 to your computer and use it in GitHub Desktop.
Save MarketingPip/c2d4c3706fb068209771b29b899129c2 to your computer and use it in GitHub Desktop.
Simple code recorder/playback for the Ace code editor.
$(document).ready(function(){
ace.config.set('basePath', '../js/lib/ace');
var editor = ace.edit("editor");
editor.$blockScrolling = Infinity;
editor.setTheme("ace/theme/monokai");
editor.getSession().setMode("ace/mode/html");
editor.setOptions({
enableBasicAutocompletion: true,
enableSnippets: true,
enableLiveAutocompletion: false
});
var keystrokes = [];
var playbackEvents = [];
function recordKeystroke(e) {
var keyEvent = {
'data': e.data,
'timestamp': Date.now()
};
keystrokes.push(keyEvent);
console.log(e, keyEvent);
}
function captureState() {
var keyEvent = {
'data': {
'action': 'insertText',
'text': editor.getValue()
},
'timestamp': Date.now()
};
keystrokes.push(keyEvent);
}
function record() {
captureState();
editor.on("change", recordKeystroke);
}
window.record = record;
function stop() {
editor.off("change", recordKeystroke);
editor.setReadOnly(false);
if (playbackEvents[0]) {
for (i = 0; i < playbackEvents.length; i++) {
clearTimeout(playbackEvents[i]);
}
}
}
window.stop = stop;
function play() {
var startTime = keystrokes[0].timestamp,
i = 0;
console.log(playbackEvents);
editor.setValue("");
editor.setReadOnly(true);
editor.clearSelection();
for (i = 0; i < keystrokes.length; i++) {
createEvent(startTime, i);
}
}
window.play = play;
function createEvent(starttime, i) {
var k = keystrokes[i],
dT = 1;
var evt = setTimeout(function(){
editor.clearSelection();
switch (k.data.action) {
case 'insertText':
if (k.data.range) {
editor.moveCursorTo(k.data.range.start.row, k.data.range.start.column);
} else {
editor.moveCursorTo(0, 0);
}
editor.insert(k.data.text);
break;
case 'removeText':
editor.getSession().remove(k.data.range);
break;
case 'removeLines':
editor.getSession().remove(k.data.range);
break;
default:
console.log('unknown action: ' + k.data.action);
}
if (i == keystrokes.length - 1) {
editor.setReadOnly(false);
}
}, dT * (keystrokes[i].timestamp - starttime));
playbackEvents.push(evt);
}
function reset(){
stop();
keystrokes = [];
playbackEvents = [];
}
window.reset = reset;
});
<html>
<head>
<title>Recordodecode recorder coderecorder.. you get it; it records code.</title>
<?php include("../include.php") ?>
<script type="text/javascript" src="../js/lib/ace/ace.js"></script>
<script type="text/javascript" src="../js/lib/ace/ext-language_tools.js"></script>
<script type="text/javascript" src="../js/lib/ace/ext-settings_menu.js"></script>
<script type="text/javascript" src="../js/lib/ace/ext-statusbar.js"></script>
<script type="text/javascript" src="../js/lib/ace/ext-keybinding_menu.js"></script>
</head>
<body>
<div class="container-fluid">
<div class="row">
<div id="editor" style="width:100%; height:600px;"></div>
</div>
<div class="row">
<button class="btn btn-warning" onclick="record()">Record</button>
<button class="btn btn-danger" onclick="stop()">Stop</button>
<button class="btn btn-primary" onclick="play()">Play</button>
<button class="btn" onclick="reset()">Reset</button>
</div>
</div>
<script type="text/javascript" src="app.js"></script>
</body>
</html>
@MarketingPip
Copy link
Author

    var editor = ace.edit("editor");

    editor.$blockScrolling = Infinity;
    editor.setTheme("ace/theme/monokai");
    editor.getSession().setMode("ace/mode/html");
    editor.setOptions({
        enableBasicAutocompletion: true,
        enableSnippets: true,
        enableLiveAutocompletion: false
    });


    var keystrokes = [];
    var playbackEvents = [];


    function recordKeystroke(e) {
        var keyEvent = {
            'data':{action:e.action,range:{
        start:e.start,
        end: e.end
    },text:e.lines.join("")},
            'timestamp': Date.now()
        };

        keystrokes.push(keyEvent);
        console.log(e);
    }


    function captureState() {
        var keyEvent = {
            'data': {
                'action': 'insertText',
                'text': editor.getValue()
            },
            'timestamp': Date.now()
        };

        keystrokes.push(keyEvent);
    }

    function record() {
        captureState();
        editor.on("change", recordKeystroke);
    }
    window.record = record;


    function stop() {
        editor.off("change", recordKeystroke);
        editor.setReadOnly(false);

        if (playbackEvents[0]) {
            for (i = 0; i < playbackEvents.length; i++) {
                clearTimeout(playbackEvents[i]);
            }
        }
    }
    window.stop = stop;


    function play() {
        var startTime = keystrokes[0].timestamp,
            i = 0;

        console.log(playbackEvents);

        editor.setValue("");
        editor.setReadOnly(true);
        editor.clearSelection();

        for (i = 0; i < keystrokes.length; i++) {
            createEvent(startTime, i);
        }

    }
    window.play = play;


     function createEvent(starttime, i) {
        var k = keystrokes[i],
            dT = 1;

        var evt = setTimeout(function(){

            editor.clearSelection();

            switch (k.data.action) {
                case 'insert':
                    if (k.data.range) {
                        editor.moveCursorTo(k.data.range.start.row, k.data.range.start.column);
                    } else {
                        editor.moveCursorTo(0, 0);
                    }
                    editor.insert(k.data.text);
                    break;

                case 'removeText':

                    editor.getSession().remove(k.data.range);
                    break;

                case 'remove':

                    editor.getSession().remove(k.data.range);
                    break;

                default:
                    console.log('unknown action: ' + k.data.action);
            }

            if (i == keystrokes.length - 1) {
                editor.setReadOnly(false);
            }

        }, dT * (keystrokes[i].timestamp - starttime));

        playbackEvents.push(evt);

    }

    function reset(){
        stop();
        keystrokes = [];
        playbackEvents = [];
    }
    window.reset = reset;

@MarketingPip
Copy link
Author

 var editor = ace.edit("editor");

    editor.$blockScrolling = Infinity;
    editor.setTheme("ace/theme/monokai");
    editor.getSession().setMode("ace/mode/html");
    editor.setOptions({
        enableBasicAutocompletion: true,
        enableSnippets: true,
        enableLiveAutocompletion: false
    });


    var keystrokes = [];
    var playbackEvents = [];


    function recordKeystroke(e) {
        var keyEvent = {
            'data':{action:e.action,range:{
        start:e.start,
        end: e.end
    },text:e.lines.join("")},
            'timestamp': Date.now()
        };

        keystrokes.push(keyEvent);
    }


    function captureState() {
        var keyEvent = {
            'data': {
                'action': 'insertText',
                'text': editor.getValue()
            },
            'timestamp': Date.now()
        };

        keystrokes.push(keyEvent);
    }

    function record() {
        captureState();
        editor.on("change", recordKeystroke);
    }
    window.record = record;


    function stop() {
        editor.off("change", recordKeystroke);
        editor.setReadOnly(false);

        if (playbackEvents[0]) {
            for (i = 0; i < playbackEvents.length; i++) {
                clearTimeout(playbackEvents[i]);
            }
        }
    }
    window.stop = stop;


    function play() {
        var startTime = keystrokes[0].timestamp,
            i = 0;

        console.log(playbackEvents);

        editor.setValue("");
        editor.setReadOnly(true);
        editor.clearSelection();

        for (i = 0; i < keystrokes.length; i++) {
            createEvent(startTime, i);
        }

    }
    window.play = play;


     function createEvent(starttime, i) {
        var k = keystrokes[i],
            dT = 1;

        var evt = setTimeout(function(){

            editor.clearSelection();
console.log(k.data.action)
            switch (k.data.action) {
                
                case 'insert':
                    if (k.data.range) {
                        editor.moveCursorTo(k.data.range.start.row, k.data.range.start.column);
                    } else {
                        editor.moveCursorTo(0, 0);
                    }

                    if(k.data.text === ""){
                      k.data.text = "\n"
                    }
                
                       console.log("yup")
                    editor.insert(k.data.text);
                    break;

                case 'removeText':

                    editor.getSession().remove(k.data.range);
                    break;

                case 'remove':

                    editor.getSession().remove(k.data.range);
                    break;

                default:
                    console.log('unknown action: ' + k.data.action);
            }

            if (i == keystrokes.length - 1) {
                editor.setReadOnly(false);
            }

        }, dT * (keystrokes[i].timestamp - starttime));

        playbackEvents.push(evt);

    }

    function reset(){
        stop();
        keystrokes = [];
        playbackEvents = [];
    }
    window.reset = reset;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment