summaryrefslogtreecommitdiff
path: root/js/codeq/core.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/codeq/core.js')
-rw-r--r--js/codeq/core.js254
1 files changed, 2 insertions, 252 deletions
diff --git a/js/codeq/core.js b/js/codeq/core.js
index e86b396..50322c0 100644
--- a/js/codeq/core.js
+++ b/js/codeq/core.js
@@ -1,5 +1,5 @@
/* CodeQ: an online programming tutor.
- Copyright (C) 2015 UL FRI
+ Copyright (C) 2015,2016 UL FRI
This program is free software: you can redistribute it and/or modify it under
the terms of the GNU Affero General Public License as published by the Free
@@ -164,22 +164,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */
// regular expressions for the templating function, etc.
var regexpQuote = new RegExp('"', 'g'),
regexpBackslash = new RegExp('\\\\', 'g'),
- regexpWhiteSpaceStart = new RegExp('^[ \r\n\t]+'),
- regexpWhiteSpaceEnd = new RegExp('[ \r\n\t]+$'),
- regexpWhiteSpaceTrim = new RegExp('^[ \\t\\r\\n]*(.*[^ \\t\\r\\n])[ \\t\\r\\n]*$', 'm'),
regexpAmp = new RegExp('&', 'g'),
regexpLt = new RegExp('<', 'g'),
- regexpGt = new RegExp('>', 'g'),
- regexpCR = new RegExp('\\r', 'g'),
- regexpLF = new RegExp('\\n', 'g'),
- regexpTab = new RegExp('\\t', 'g');
-
- // convert a string into its definition (javascript literal)
- var stringToDef = function (str) {
- return str.replace(regexpBackslash, '\\\\').replace(regexpQuote, '\\"').replace(regexpCR, '\\r').replace(regexpLF, '\\n').replace(regexpTab, '\\t');
- };
-
- var resources = {}; // resource tree, loaded from data/resources.json in the boot sequence
+ regexpGt = new RegExp('>', 'g');
// event dispatch
var eventListeners = {}, // keyed by event name, value is an array of listeners
@@ -211,144 +198,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */
}, 0);
};
- var tokenize = function (line) {
- var result = [],
- N = line.length,
- i = 0, // character index into line
- storedAtom = null, // the previous atom, to decide whether to store a string or an object {key:'', value:''}
- atom = [], // currently parsed content
- isKeyValue = false,
- storeAtom = function () {
- if (atom.length == 0) return;
- if (storedAtom === null) storedAtom = atom.join('');
- else if (isKeyValue) {
- result.push({'key': storedAtom, 'value': atom.join('')});
- storedAtom = null;
- isKeyValue = false;
- }
- else {
- result.push(storedAtom);
- storedAtom = atom.join('');
- }
- atom.length = 0;
- },
- c, q;
-
- while (i < N) {
- c = line[i++];
- switch (c) {
- // end-of-atom characters
- case ' ':
- case '\r':
- case '\n':
- case '\t':
- storeAtom();
- break;
-
- // escape character
- case '\\':
- if (i < N) atom.push(line[i++]);
- break;
-
- // key-value delimiter character
- case '=':
- if (storedAtom) {
- if (isKeyValue) atom.push(c);
- else if (atom.length == 0) isKeyValue = true; // must have been a whitespace before "="
- else {
- storeAtom();
- isKeyValue = true;
- }
- }
- else atom.push(c); // "=" is delimiter only before the value, not before the key
- break;
-
- // quoted string
- case '"':
- case "'":
- stringConsume:
- while (i < N) {
- q = line[i++];
- switch (q) {
- case '\\':
- if (i < N) atom.push(line[i++]);
- break;
- case c:
- break stringConsume;
- default:
- atom.push(q);
- break;
- }
- }
- break;
-
- default:
- atom.push(c);
- break;
- }
- }
- // purge anything in cache
- storeAtom();
- if (storedAtom !== null) result.push(storedAtom);
- return result;
- };
-
- var resolveResource = function (resourceName, resourceBranches) {
- var traversedPath = ['data'], // top-level directory
- branch = resources,
- candidate = null,
- i, fragment;
- if (!resourceName) {
- codeq.log.error('No resource name provided; path: "' + resourceBranches.join('/') + '"');
- return null;
- }
- if (branch[resourceName]) candidate = 'data/' + resourceName; // top-level match
- for (i = 0; i < resourceBranches.length; i++) {
- fragment = resourceBranches[i];
- branch = branch[fragment];
- if (!branch) {
- codeq.log.error('Resource sub-branch ' + fragment + ' does not exist; resource: "' + resourceName + '", path: "' + resourceBranches.join('/') + '"');
- break;
- }
- traversedPath.push(fragment);
- if (branch[resourceName]) candidate = traversedPath.join('/') + '/' + resourceName;
- }
- if (candidate) return codeq.ajaxPrefix + candidate;
- codeq.log.error('Resource ' + resourceName + ' was not found; path: "' + resourceBranches.join('/') + '"');
- return null;
- };
-
- var directiveHandlers = {
- 'resource': function (code, tokens, templatePath) {
- code.push('_result.push("', resolveResource(tokens[1], templatePath) || 'data/broken.png', '");\n');
- },
-
- 'img': function (code, tokens, templatePath) {
- var N = tokens.length,
- attrs = [],
- token, i;
- for (i = 1; i < N; i++) {
- token = tokens[i];
- if (!token || typeof token !== 'object') {
- codeq.log.error('Invalid token at position ' + i + ' in @img');
- continue;
- }
- switch (token.key) {
- case 'src':
- attrs.push('src="' + resolveResource(token.value, templatePath) + '"');
- break;
- case 'alt':
- attrs.push('alt="' + codeq.escapeHtml(token.value) + '"');
- break;
- case 'class':
- attrs.push('class="' + token.value + '"');
- break;
- }
- }
- code.push('_result.push("<img ', attrs.join(' ').replace(regexpQuote, '\\"'), '>");\n');
- }
- };
-
var makeActivityHandler = function (editor, problem_id) {
var lastActivityMillis = Date.now(),
deltaActivityMillis = function deltaActivityMillisFunc () {
@@ -439,10 +288,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */
return codeq.settings['gui_lang'];
},
- 'setResources': function (newResources) {
- resources = newResources;
- },
-
'escapeHtml': function (s) {
return ('' + s).replace(regexpAmp, '&amp;').replace(regexpLt, '&lt;').replace(regexpGt, '&gt;');
},
@@ -484,101 +329,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */
});
},
- 'templator': function (str, templatePath, templateName) {
- var f, parts, i, subparts, subpart,
- src = [ 'var _result = [], echo = function (s) { _result.push(s); };\n' ],
- atoms, j, atom, debugPrefix, s, r, tokens, handler;
-
- if (!templateName) templateName = 'unknown template';
- debugPrefix = '[' + templateName + ']';
- if (!templatePath) templatePath = [];
-
- // remove comments
- parts = str.split('[%--'); // break on start-of-comment
- atoms = [ parts[0] ]; // first part is not a comment
- for (i = 1; i < parts.length; i++) { // iterate over start-of-comments
- atom = parts[i].split('--%]'); // break on end-of-comment
- if (atom.length > 1) { // if end-of-comment was encountered
- atoms.push(atom[1]); // add whatever is trailing it
- for (j = 2; j < atom.length; j++) { // re-add even dangling end-of-comments
- atoms.push('--%]');
- atoms.push(atom[j]);
- }
- }
- }
-
- // start processing
- parts = atoms.join('').split('[%');
-
- if (parts[0].length > 0) src.push('_result.push("', stringToDef(parts[0]), '");\n'); // the first part that doesn't begin with '[%'
- for (i = 1; i < parts.length; i++) { // for every part that begins with '[%'
- if (parts[i].slice(0, 2) === '--') { // a comment start
- subparts = parts[i].split('--%]'); // split at comment end
- }
- else { // a start of a statement or of a value reference
- subparts = parts[i].split('%]'); // there should be only one terminating '%]', find it
- subpart = subparts[0].replace(regexpWhiteSpaceStart, '').replace(regexpWhiteSpaceEnd, ''); // trim the white space
- if (subpart.length > 0) {
- if (subpart[0] === '=') { // a value reference
- s = subpart.slice(1);
- r = regexpWhiteSpaceTrim.exec(s);
- r = r && r[1] || s;
- src.push('_result.push(typeof this.', r, ' === \'undefined\' ? \'', r, ' missing\' : this.', r, ');\n');
- }
- else if (subpart[0] === '@') { // a directive
- tokens = tokenize(subpart.slice(1));
- if (tokens.length === 0) {
- codeq.log.error('An empty directive in ' + templateName);
- }
- else {
- handler = directiveHandlers[tokens[0]];
- if (!handler) {
- codeq.log.error('An unknown directive in ' + templateName + ': ' + tokens[0]);
- }
- else {
- handler(src, tokens, templatePath);
- }
- }
- }
- else { // javascript statement(s)
- src.push(subpart, '\n');
- }
- }
- }
- if ((subparts.length > 1) && (subparts[1].length > 0)) { // there's a trailing text
- src.push('_result.push("', stringToDef(subparts[1]), '");\n');
- }
- }
- src.push('return _result.join("");');
-// if (_internalDoLog_) codeq.log.debug('createTemplate(): ' + debugPrefix + ' creating templating function:\nfunction(_components_) {\n' + src.join('') + '\n}\n=== Created from template: ===\n' + str);
- try {
- f = new Function(src.join('')); // create a function based on the given template
- }
- catch (e) {
- codeq.log.error('createTemplate(): ' + debugPrefix + ' Failed to instantiate template function: ' + e + '\nfunction() {\n' + src.join('') + '\n}\n=== Created from template: ===\n' + str, e);
- throw e;
- }
-
- return function (args) {
- var esc = codeq.escapeHtml,
- escArgs = {},
- key;
- if ((typeof args === 'object') && (args !== null)) {
- for (key in args) {
- if (!args.hasOwnProperty(key)) continue;
- escArgs[key] = esc(args[key]);
- }
- }
- try {
- return f.apply(escArgs);
- }
- catch (e) {
- codeq.log.error('Error evaluating template ' + templateName + ' function: ' + e + '\nfunction() {\n' + src.join('') + '\nCreated from template:\n' + str, e);
- throw e;
- }
- };
- },
-
// codeq event handling
'fire': function (eventName, args) {