summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--js/codeq/mainScreen.js126
-rw-r--r--js/codeq/prolog.js5
-rw-r--r--js/codeq/prologPythonLib.js341
-rw-r--r--js/prolog.js5
-rw-r--r--js/python.js3
5 files changed, 9 insertions, 471 deletions
diff --git a/js/codeq/mainScreen.js b/js/codeq/mainScreen.js
deleted file mode 100644
index e842ee3..0000000
--- a/js/codeq/mainScreen.js
+++ /dev/null
@@ -1,126 +0,0 @@
-/**
- * Created by robert on 9/17/15.
- */
-
-(function() {
- var problems,//this will the actual (sub)state machine
- stateNameTag = 'stateName';
-
- var divs = {};
- divs['description'] = $('div.col-lg-3.col-md-6.col-sm-12:has(#description)');//lets actually find the needed divs for later use
- divs['code'] = $('div.col-lg-3.col-md-6.col-sm-12:has(#code_editor)');
- divs['console'] = $('div.col-lg-3.col-md-6.col-sm-12:has(#console)');//named 'consoleDiv', because 'console' is already in use
- divs['info'] = $('div.col-lg-3.col-md-6.col-sm-12:has(#info)');
-
- divs['description'].data(stateNameTag, 'description');
- divs['code'].data(stateNameTag, 'code');
- divs['console'].data(stateNameTag, 'console');
- divs['info'].data(stateNameTag, 'info');
-
- var eventName = 'mousedown',//event name of the event which will trigger the transition between these substates
- mouseDownEventFunction = function () {
- problems.transition($(this).data(stateNameTag));
- },
- removeListenersFromDivs = function () {
- $.each(divs, function (i, value) {
- value.off(eventName, mouseDownEventFunction);
- });
- },
- removeBlockClassesFromDivs = function () {
- $.each(divs, function (i, value) {
- value.removeClass('block');
- });
- },
- removeChangedClassesFromDivs = function () {
- $.each(divs, function (i, value) {
- value.removeClass('block-focus block-less-width block-less-height block-less-everything').addClass('block');//these class names were chosen for the view where the screen is partitioned in 4 quarters (2 by 2)
- });
- },
- setTransitionsBetweenDivs = function (current) {
- $.each(divs, function (key, value) {
- if (current !== key) value.on(eventName, mouseDownEventFunction);
- });
- },
- addClassesToDivs = function (divsWithClasses) {
- $.each(divsWithClasses, function (divName, className) {
- divs[divName].addClass(className);
- });
- },
- substates = {
- 'description': {
- 'enter': function () {
- removeBlockClassesFromDivs();
- addClassesToDivs({
- 'description': 'block-focus',
- 'code': 'block-less-width',
- 'console': 'block-less-height',
- 'info': 'block-less-everything'
- });
- setTransitionsBetweenDivs('description');
- },
- 'exit': function () {
- removeChangedClassesFromDivs();
- removeListenersFromDivs();
- }
- },
- 'code': {
- 'enter': function () {
- removeBlockClassesFromDivs();
- addClassesToDivs({
- 'description': 'block-less-width',
- 'code': 'block-focus',
- 'console': 'block-less-everything',
- 'info': 'block-less-height'
- });
- setTransitionsBetweenDivs('code');
- },
- 'exit': function () {
- removeChangedClassesFromDivs();
- removeListenersFromDivs();
- }
- },
- 'info': {
- 'enter': function () {
- removeBlockClassesFromDivs();
- addClassesToDivs({
- 'description': 'block-less-everything',
- 'code': 'block-less-height',
- 'console': 'block-less-width',
- 'info': 'block-focus'
- });
- setTransitionsBetweenDivs('info');
- },
- 'exit': function () {
- removeChangedClassesFromDivs();
- removeListenersFromDivs();
- }
- },
- 'console': {
- 'enter': function () {
- removeBlockClassesFromDivs();
- addClassesToDivs({
- 'description': 'block-less-height',
- 'code': 'block-less-everything',
- 'console': 'block-focus',
- 'info': 'block-less-width'
- });
- setTransitionsBetweenDivs('console');
- },
- 'exit': function () {
- removeChangedClassesFromDivs();
- removeListenersFromDivs();
- }
- }
- };
- codeq.globalStateMachine.register('main', {
- 'enter': function () {
- $('#screen_prolog').css('display', '');
- problems = codeq.makeStateMachine(substates);
- problems.transition(divs['description'].data(stateNameTag));
- },
- 'exit': function () {
- $('#screen_prolog').css('display', 'none');
- problems.destroy();
- }
- });
-})(); \ No newline at end of file
diff --git a/js/codeq/prolog.js b/js/codeq/prolog.js
index 1978ba4..e411895 100644
--- a/js/codeq/prolog.js
+++ b/js/codeq/prolog.js
@@ -220,6 +220,7 @@
var makePrologTerminalHandler = function (jqConsole, editor, problem_id, activityHandler) {
var promptMode = true, // default: query composition; alternative: query result browsing
+ manualStop = false,// if the user stopped showing next answers (false) or if there are no more answers (true)
terminal = codeq.makeConsole(jqConsole, {
'greeting': 'CodeQ Prolog terminal proxy'
}),
@@ -236,7 +237,7 @@
}
if (promptMode) {
terminal.setLineBuffered();
- terminal.append('.\n?- ', 'output');
+ terminal.append(manualStop ? '?- ' : '.\n?- ', 'output');
}
},
tcf = function terminalCommandFailed (error) {
@@ -261,6 +262,7 @@
terminal.onInput = function (command) {
if (promptMode) {
promptMode = false;
+ manualStop = false;
terminal.setNotBuffered();
return codeq.comms.sendQuery({
'problem_id': problem_id,
@@ -282,6 +284,7 @@
}
else {
// stop searching for answers
+ manualStop = true;
return codeq.comms.sendQuery({
'problem_id': problem_id,
'step': 'end',
diff --git a/js/codeq/prologPythonLib.js b/js/codeq/prologPythonLib.js
deleted file mode 100644
index 400a56e..0000000
--- a/js/codeq/prologPythonLib.js
+++ /dev/null
@@ -1,341 +0,0 @@
-/**
- * Created by robert on 9/15/15.
- */
-
-/**
- * this is currently not used - I made this common python/prolog library a bit to early, but I don't want to delete everything, so I'll leave it for now in case it can be used later without to many changes
- *
- *
- *
- * @param editor
- * @param problem_id
- * @returns {{queueTrace: Function, flush: Function, addAndPurge: Function}}
- */
-
-codeq.makeActivityHandler = function (editor, problem_id) {
- var lastActivityMillis = Date.now(),
- deltaActivityMillis = function deltaActivityMillisFunc () {
- var now = Date.now(),
- dt = now - lastActivityMillis;
- lastActivityMillis = now;
- return dt;
- },
- queue = [],
- ts = null,
- timer = function () {
- var promise;
- ts = null;
- if (queue.length === 0) return Q(true);
- promise = codeq.comms.sendActivity(queue, editor.getDoc().getValue(), problem_id);
- queue.length = 0;
- return promise;
- },
- flush = function () {
- clearTimeout(ts);
- return timer();
- };
-
- return {
- 'queueTrace': function (trace) {
- trace['dt'] = deltaActivityMillis();
- queue.push(trace);
- if (ts === null) setTimeout(timer, 10000); // flush every 10 seconds
- },
- 'flush': flush,
- 'addAndPurge': function (trace) {
- var accumulatedTrace = queue;
- queue = [];
- trace['dt'] = deltaActivityMillis();
- accumulatedTrace.push(trace);
- if (ts !== null) {
- clearTimeout(ts);
- ts = null;
- }
- return accumulatedTrace;
- }
- };
-};
-
-/**
- * Creates a new handler for the given Programming language assignment definition.
- *
- * @param {string} language - either 'prolog' or 'python'
- * @param {PrologTaskDef} info
- * @param {function} makeTerminalHandlerFun - either the makePythonTerminalHandler or makePrologTerminalHandler function
- * @returns {{destroy: Function, processServerHints: Function}}
- */
-codeq.createProgrammingLanguageHandler = function (language,info,makeTerminalHandlerFun) {
- var firstCharacterPos = {'line': 0, 'ch': 0};
-
- var problem = info.problem,
- jqDescription = $('#description'),
- jqEditor = $('#code_editor'),
- jqConsole = $('#console'),
- jqHints = $('#info'),
- editor = CodeMirror(jqEditor[0], { cursorHeight: 0.85, lineNumbers: true, matchBrackets: true }),
- activityHandler = codeq.makeActivityHandler(editor, problem.id),
- terminal = makeTerminalHandlerFun(jqConsole, editor, problem.id, activityHandler),
- hintDefs = problem.hint,
- hintCounter = 0, // for generating unique class-names
- hintCleaners = [],
- clearHints = function () {
- var i;
- for (i = hintCleaners.length - 1; i >= 0; i--) {
- hintCleaners[i]();
- }
- hintCleaners.length = 0;
- hintCounter = 0;
- },
- addMark = function (start, end) {
- var posStart = editor.posFromIndex(start),
- posEnd = editor.posFromIndex(end),
- doc = editor.getDoc(),
- mark = doc.markText(posStart, posEnd, {className: 'editor-mark _emark_' + hintCounter}),
- result = {start: posStart, end: posEnd, mark: mark, className: '_emark_' + hintCounter};
- hintCleaners.push(function () { mark.clear(); mark = null; doc = null; result.mark = null; });
- hintCounter++;
- return result;
- },
- processTemplate = function (template, args) {
- if (!args)
- return template;
- return template.replace(/\[%=(\w+)%\]/g, function(match, name) {
- return args[name];
- });
- },
- hintHandlers = {
- 'static': function (type, template, serverHint) {
- codeq.log.debug('Processing static hint');
- var message = processTemplate(template, serverHint.args);
- jqHints.append('<div class="hint-static">' + message + '</div>');
- // no hint cleaner here, a static hint remains on the screen
- },
- 'popup': function (type, template, serverHint) {
- codeq.log.debug('Processing popup hint');
- var message = processTemplate(template, serverHint.args),
- mark = addMark(serverHint.start, serverHint.end), // add the mark
- jqMark = jqEditor.find('.' + mark.className);
- /* jqPopup = null,
- onBlur = function () {
- codeq.log.debug('Removing popup');
- if (jqPopup) {
- jqPopup.off('blur', onBlur);
- jqPopup.remove();
- jqPopup = null;
- }
- };
-
- window.jqMark = jqMark; // TODO: DEBUG
-
- jqMark.on('click', function () {
- if (jqPopup) return;
- codeq.log.debug('Showing popup');
- var pos = mark.mark.find(), // results in {from: {line: number, ch: number}, to: {line: number, ch: number}}
- left = pos.from.ch < pos.to.ch ? pos.from.ch : pos.to.ch,
- down = pos.from.line < pos.to.line ? pos.to.line : pos.from.line;
- jqPopup = $('<div style="position: absolute;" class="editor-popup ' + mark.className + '"></div>').html(template);
- editor.addWidget({line: down, ch: left}, jqPopup[0], true);
- jqPopup = jqEditor.find('.editor-popup.' + mark.className);
- setTimeout(function () {jqPopup.trigger('focus'); jqPopup.on('click', onBlur);}, 50); // event handlers can be registered only when the DOM elements is part of the document
- window.jqPopup = jqPopup; // TODO: DEBUG
- });
-
- hintCleaners.push(function () {
- if (jqPopup) {
- jqPopup.off('blur', onBlur);
- jqPopup.remove();
- jqPopup = null;
- }
- if (jqMark) {
- jqMark = null;
- }
- mark = null;
- });*/
-
- jqMark.popover({content: message, html: true, placement: 'auto bottom', trigger: 'hover focus click', container: 'body'});
- hintCleaners.push(function () { if (jqMark) { jqMark.popover('destroy'); jqMark = null; } });
-
- mark.mark.on('', function () {});
- },
- 'dropdown': function (type, template, serverHint) {
- codeq.log.debug('Processing dropdown hint');
- var completion = null, // the completion object, created in showHint()
- close = function () {
- if (completion) {
- completion.close();
- completion = null;
- }
- };
-
- if ((editor.listSelections().length > 1) || editor.somethingSelected()) {
- // showHint() doesn't work if a selection is activeparts
- }
-
- editor.showHint({
- hint: function () {
- var hints = {
- list: serverHint.choices,
- from: editor.posFromIndex(serverHint.start),
- to: editor.posFromIndex(serverHint.end)
- };
- completion = editor.state.completionActive;
- return hints;
- },
- completeOnSingleClick: true,
- completeSingle: false
- });
-
- hintCleaners.push(close);
- }
- };
-
- editor.setValue(info.solution);
- $('#title').text(problem.slug);
- jqDescription.html(problem.description);
-
- editor.on('change', function (instance, changeObj) {
- var doc = editor.getDoc(),
- pos = codeq.codePointCount(doc.getRange(firstCharacterPos, changeObj.from));
-
- if (changeObj.removed) {
- activityHandler.queueTrace({'typ': 'rm', 'off': pos, 'len': codeq.codePointCount(changeObj.removed)});
- }
-
- if (changeObj.text) {
- activityHandler.queueTrace({'typ': 'ins', 'off': pos, 'txt': changeObj.text});
- }
- });
-
- var handler = {
- destroy: function () {
- terminal.destroy();
- jqDescription.empty();
- jqEditor.empty(); // TODO: perhaps you do not want to "free" the editor, just empty it
- jqConsole.empty(); // TODO: the same with the console
- jqHints.empty(); // TODO: just make static references to these
- jqDescription = null;
- jqEditor = null;
- jqConsole = null;
- jqHints = null;
- },
-
- /**
- * Processes and display appropriately the server hints.
- * TODO: sort hints so static and popup hints come first, and a (single) drop-down hint last
- *
- * @param {ServerHint[]} serverHints an array of hints from the server
- */
- processServerHints: function (serverHints) {
- var n = serverHints.length,
- /** number */ i,
- /** ServerHint */ serverHint,
- /** HintDefinition */ hintDef,
- hintType, hintTemplate, t, fn;
- clearHints();
- for (i = 0; i < n; i++) {
- serverHint = serverHints[i];
- hintDef = hintDefs[serverHint.id];
- if (serverHint.indices) {
- indices = serverHint.indices
- for (i = 0; i < indices.length; i++) {
- hintDef = hintDef[indices[i]];
- if (!hintDef)
- break;
- }
- }
- if (!hintDef) {
- codeq.log.error('Undefined hint ' + serverHint.id + ' with indices ' + serverHint.indices);
- continue;
- }
- t = typeof hintDef;
- if (t === 'object') {
- hintType = hintDef.type;
- hintTemplate = hintDef.message;
- }
- else if (t === 'string') {
- hintType = 'static';
- hintTemplate = hintDef;
- }
- else {
- codeq.log.error('Unsupported hint definition: ' + t);
- continue;
- }
-
- fn = hintHandlers[hintType];
- if (!fn) codeq.log.error('Unsupported hint type: ' + hintType);
- else fn(hintType, hintTemplate, serverHint);
- }
- }
- };
-
- var jqButtons = $('#block-toolbar button');
-// $(jqButtons.get(0)).on('click', function () { handler.processServerHints([{id:'x_must_be_female'}]); });
-// $(jqButtons.get(1)).on('click', function () { handler.processServerHints([{id:'popup_unknown', start: 20, end: 26}]); });
-// $(jqButtons.get(2)).on('click', function () { handler.processServerHints([{id:'drop_down', start: 20, end: 26, choices:['ena', 'dva', 'tri']}]); });
-
- $('#btn_code_hint').on('click', function () {
- if (language === 'prolog') {
- terminal.append('hint.\n', 'input');
- terminal.inputDisable();
- }
- var doc = editor.getDoc();
- codeq.comms.sendHint({
- 'language': 'prolog',
- 'program': editor.getDoc().getValue(),
- 'problem_id': problem.id
- }).then(
- function hintSuccess(data) {
- if (data.code === 0)
- handler.processServerHints(data.hints);
- else
- terminal.append(data.message + '\n', 'error');
- },
- function hintFailed (error) {
- terminal.append(error + '\n', 'error');
- }
- ).fin(function () {
- if(language === 'prolog'){
- terminal.inputEnable();
- terminal.append('?- ', 'output');
- }
- }
- ).done();
- });
- $('#btn_code_test').on('click', function () {
- if(language === 'prolog'){
- terminal.append('test.\n', 'input');
- terminal.inputDisable();
- }
- var doc = editor.getDoc();
- codeq.comms.sendTest({
- 'language': language,
- 'program': editor.getDoc().getValue(),
- 'problem_id': problem.id
- }).then(
- function testSuccess(data) {
- if (data.code === 0)
- handler.processServerHints(data.hints);
- else
- terminal.append(data.message + '\n', 'error');
- },
- function testFailed (error) {
- terminal.append(error + '\n', 'error');
- }
- ).fin(function () {
- if(language === 'prolog'){
- terminal.inputEnable();
- terminal.append('?- ', 'output');
- }
- }
- ).done();
- });
-
- if(language === 'python'){
- // TODO first line of interpreter output is buffered without this, why?
- codeq.comms.sendPush({
- 'text': ''
- });
- }
-
- return handler;
-};
diff --git a/js/prolog.js b/js/prolog.js
index 29ceb3d..fad1dd4 100644
--- a/js/prolog.js
+++ b/js/prolog.js
@@ -8,6 +8,7 @@
var makePrologTerminalHandler = function (jqConsole, editor, problem_id, activityHandler) {
var promptMode = true, // default: query composition; alternative: query result browsing
+ manualStop = false, // if the user stopped showing next answers (false) or if there are no more answers (true)
terminal = codeq.makeConsole(jqConsole, {
'greeting': 'CodeQ Prolog terminal proxy'
}),
@@ -24,7 +25,7 @@
}
if (promptMode) {
terminal.setLineBuffered();
- terminal.append('.\n?- ', 'output');
+ terminal.append(manualStop ? '?- ' : '.\n?- ', 'output');
}
},
tcf = function terminalCommandFailed (error) {
@@ -49,6 +50,7 @@
terminal.onInput = function (command) {
if (promptMode) {
promptMode = false;
+ manualStop = false;
terminal.setNotBuffered();
return codeq.comms.sendQuery({
'problem_id': problem_id,
@@ -70,6 +72,7 @@
}
else {
// stop searching for answers
+ manualStop = true;
return codeq.comms.sendQuery({
'problem_id': problem_id,
'step': 'end',
diff --git a/js/python.js b/js/python.js
index fa4943b..1f2b5cb 100644
--- a/js/python.js
+++ b/js/python.js
@@ -6,7 +6,6 @@
// a constant
var firstCharacterPos = {'line': 0, 'ch': 0};
- //codeq.makePythonTerminalHandler = function (jqConsole, editor, problem_id, activityHandler) {
var makePythonTerminalHandler = function (jqConsole, editor, problem_id, activityHandler) {
var terminal = codeq.makeConsole(jqConsole, {
'greeting': 'CodeQ Python terminal proxy'
@@ -38,7 +37,7 @@
return terminal;
};
- var makeActivityHandler = function (editor, problem_id) {
+ var makeActivityHandler = function (editor, problem_id) {
var lastActivityMillis = Date.now(),
deltaActivityMillis = function deltaActivityMillisFunc () {
var now = Date.now(),