From 0c168d0027f3350344d0fcdf16c554dcc8f3c92b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Smodi=C5=A1?= Date: Fri, 2 Oct 2015 11:22:06 +0200 Subject: Remove deprecated files. --- js/codeq.js | 749 ------- js/def_parser.js | 436 ---- js/jquery/jquery.console.js | 773 ------- js/jquery/jquery.terminal-0.8.8.js | 4335 ------------------------------------ 4 files changed, 6293 deletions(-) delete mode 100644 js/codeq.js delete mode 100644 js/def_parser.js delete mode 100644 js/jquery/jquery.console.js delete mode 100644 js/jquery/jquery.terminal-0.8.8.js (limited to 'js') diff --git a/js/codeq.js b/js/codeq.js deleted file mode 100644 index 702ccfa..0000000 --- a/js/codeq.js +++ /dev/null @@ -1,749 +0,0 @@ -// introduce the namespace object for codeq -window.codeq = {}; -window.siteDefinition = { logLevel: 'debug' }; // for debug purposes -window.phandler = null; // TODO: this is for debug only - -// type definitions, so the IDE and coders have easier work -/** - * @typedef {Object} ServerHint a hint sent by the server - * @property {string} id the hint ID - * @property {Object} args optional arguments for the hint in case of a pop-up or static hint - * @property {string[]} choices array of choices in case of a drop-down hint - * @property {number} start the starting position of the highlighted code, in case of a pop-up or drop-down hint - * @property {number} end the ending position of the highlighted code, in case of a pop-up or drop-down hint - */ - -(function () { - - // regular expressions for the templating function, the logging system, etc. - var regexpQuote = new RegExp('"', 'g'), - regexpBackslash = new RegExp('\\\\', 'g'), - regexpWhiteSpaceStart = new RegExp('^[ \r\n\t]+'), - regexpWhiteSpaceEnd = new RegExp('[ \r\n\t]+$'), - regexpWhiteSpaceNonPrintable = new RegExp('[\r\n\t]', 'g'), - regexpWhiteSpaceBeforeTag = new RegExp('[ \r\n\t]+(?=<)', 'g'), - regexpWhiteSpaceAfterTag = new RegExp('>[ \r\n\t]+', 'g'), - regexpIKeyMarker = new RegExp('(?:^|\\s)(ikey-marker.*)(?:$|\\s)'), - regexpWhiteSpace = new RegExp('[ \\r\\n\\t]+'); - - // ================================================================================ - // The log module: contains methods for logging, sending logs to the server - // ================================================================================ - - var jsonize; // JSONization function - - if (JSON && JSON.stringify) { - jsonize = JSON.stringify; - } - else { - jsonize = function (obj) { - var t, buffer, i, isFirst; - if (null === obj) return 'null'; - t = typeof obj; - if (t === 'string') { - return '"' + obj.replace(regexpBackslash, '\\\\').replace(regexpQuote, '\\"') + '"'; - } - if (t === 'number') { - if (isFinite(obj)) return obj.toString(); - throw new Error('Cannot jsonize a non-finite number: ' + obj.toString()); - } - if (t === 'boolean') { - if (obj) return 'true'; - return 'false'; - } - if (t === 'object') { - if (obj instanceof String) return jsonize(obj.valueOf()); - if (obj instanceof Number) return jsonize(obj.valueOf()); - if (obj instanceof Boolean) return jsonize(obj.valueOf()); - if (obj instanceof Array) { - buffer = [ '[' ]; - isFirst = true; - for (i = 0; i < obj.length; i++) { - if (isFirst) isFirst = false; - else buffer.push(','); - buffer.push(jsonize(obj[i])); - } - buffer.push(']'); - return buffer.join(''); - } - buffer = [ '{' ]; - isFirst = true; - for (i in obj) { - if (isFirst) isFirst = false; - else buffer.push(','); - buffer.push(jsonize(i), ':', jsonize(obj[i])); - } - buffer.push('}'); - return buffer.join(''); - } - throw new Error('Cannot jsonize ' + t); - }; - } - - codeq.jsonize = jsonize; - - codeq.log = {}; - (function () { - var assembleOutput = function (stuff, e) { - var lines = [ stuff ]; - if (e && e.stack) lines.push(e.stack); - return lines.join('\n'); - }; - - if (window.siteDefinition && window.siteDefinition.logService) { - var url = window.siteDefinition.logService, - logs = [], - storeLog = function (level, stuff, e) { - logs.push({ - 't': Date.now(), - 'l': level, - 'm': assembleOutput(stuff, e) - }); - }; - if (window.siteDefinition && (window.siteDefinition.logLevel == 'debug')) { - codeq.log.debug = function (stuff, e) { storeLog('debug', stuff, e); }; - } - else codeq.log.debug = function () {}; - - if (window.siteDefinition && ((window.siteDefinition.logLevel == 'info') || (window.siteDefinition.logLevel == 'debug'))) { - codeq.log.info = function (stuff, e) { storeLog('info', stuff, e); }; - } - else codeq.log.info = function () {}; - - codeq.log.error = function (stuff, e) { storeLog('error', stuff, e); }; - - setInterval(function () { - var copyOfLogs; - if (logs.length < 1) return; - copyOfLogs = jsonize({'logs': logs}); - logs = []; - $.ajax({ - contentType: 'application/json', - dataType: 'application/json', - type: 'POST', - url: url, - data: copyOfLogs, - error: function (jqXHR, textStatus, errorThrown) { - if (window.console && console.log) console.log(assembleOutput('Posting of logs to ' + url + ' failed: ' + textStatus, errorThrown)); - else dump(assembleOutput('Posting of logs to ' + url + ' failed: ' + textStatus, errorThrown)); - }, - success: function (data, textStatus, jqXHR) { - } - }); - }, 1000); - } - else if (window.console && console.log) { - if (window.siteDefinition && (window.siteDefinition.logLevel == 'debug')) { - codeq.log.debug = function (stuff, e) { console.log(assembleOutput('DEBUG: ' + stuff, e)); }; - } - else codeq.log.debug = function () {}; - - if (window.siteDefinition && ((window.siteDefinition.logLevel == 'info') || (window.siteDefinition.logLevel == 'debug'))) { - codeq.log.info = function (stuff, e) { console.log(assembleOutput('INFO: ' + stuff, e)); }; - } - else codeq.log.info = function () {}; - - codeq.log.error = function (stuff, e) { console.log(assembleOutput('ERROR: ' + stuff, e)); }; - } - else { - if (window.siteDefinition && (window.siteDefinition.logLevel == 'debug')) { - codeq.log.debug = function (stuff, e) { dump(assembleOutput('DEBUG: ' + stuff, e)); }; - } - else codeq.log.debug = function () {}; - - if (window.siteDefinition && ((window.siteDefinition.logLevel == 'info') || (window.siteDefinition.logLevel == 'debug'))) { - codeq.log.info = function (stuff, e) { dump(assembleOutput('INFO: ' + stuff, e)); }; - } - else codeq.log.info = function () {}; - - codeq.log.error = function (stuff, e) { dump(assembleOutput('ERROR: ' + stuff, e)); }; - } - })(); - - // ================================================================================ - // The system module: contains essential methods for the operation of the app - // ================================================================================ - - // -------------------------------------------------------------------------------- - // The templating part: the createTemplate() and its utility functions - // -------------------------------------------------------------------------------- - - // jQuery extension - jQuery.fn.makeUnselectable = function () { - this.attr("unselectable", "on").attr("draggable", "false"); - this.find("*").attr("unselectable", "on").attr("draggable", "false"); - return this; - }; - - var - emptyConstObject = {}; // for use as a default read-only parameter in various methods, so we don't instantiate empty objects for no reason - - // convert a string into its definition - var stringToDef = function (str) { - return str.replace(regexpBackslash, '\\\\').replace(regexpQuote, '\\"').replace(regexpWhiteSpaceNonPrintable, ' '); - }; - - // given a HTML source, remove whitespace among tags - var cleanHtml = function (html) { - // JavaScript doesn't support lookbehind, so we use the split-join trick - return html.replace(regexpWhiteSpaceBeforeTag, '').split(regexpWhiteSpaceAfterTag).join('>'); - }; - - var trailingBackslashCount = function (s) { - var n = 0, i = s.length - 1; - while ((i >= 0) && (s.charAt(i) === '\\')) { - n++; - i--; - } - return n; - }; - - /** - * Takes a string of "argName=argValue" arguments separated with a comma. - * Creates and returns an array of arguments, where each argument is - * represented as an object in the form { name: "argName", value: "argValue" }. - * Heading and trailing whitespace is auto-removed. - */ - var splitComponentArguments = function (s) { - var commaParts = s.split(','), - args = [], // array of arguments, an argument is an object with the properties name and value (atomL and atomR) - doubleParts, singleParts, i, atom, j, k, l, - doublePart, singlePart, doubleLastIndex, singleLastIndex, - equalsParts, atomL, atomR, - singleOpen = false, doubleOpen = false; - - atom = []; // substrings of the currently assembling atom - atomL = false; // the left-side atom - atomR = false; // the right-side atom, between them is an equals sign - for (i = 0; i < commaParts.length; i++) { - doubleParts = commaParts[i].split('"'); // first split after double quotes - doubleLastIndex = doubleParts.length - 1; - for (j = 0; j < doubleParts.length; j++) { // and process the parts - doublePart = doubleParts[j]; - singleParts = doublePart.split("'"); // split after single quotes - singleLastIndex = singleParts.length - 1; - for (k = 0; k < singleParts.length; k++) { // process the parts delimited by single quotes - if (atomL || singleOpen || doubleOpen) { // left side of the assignment was already found, or quotes are active - atom.push(singleParts[k]); // don't search for the equals sign - } - else { // we don't have the left side of the assignment yet and no quotes are open - equalsParts = singleParts[k].split('='); // search for the equals sign - atom.push(equalsParts[0]); - if (equalsParts.length > 1) { // equals sign was found: we have the left side of the assignment - atomL = jQuery.trim(atom.join('')); // store the left side of the assignment - if (atomL === '') throw new Error('splitComponentArguments(): left side of the argument at index ' + args.length + ' is empty: ' + s); - atom = []; // and reset the atom buffer - atom.push(equalsParts[1]); // save the rest into the atom buffer - for (l = 2; l < equalsParts.length; l++) { // there may be more than 1 equals sign, store them, too - atom.push('='); - atom.push(equalsParts[l]); - } - } - } - if (k < singleLastIndex) { // the last item does not have a quote attached - atom.push("'"); - if (!doubleOpen) { - if ((trailingBackslashCount(singleParts[k]) % 2) == 0) singleOpen = !singleOpen; - } - } - } - if (j < doubleLastIndex) { // the last item does not have a quote attached - atom.push('"'); - if (!singleOpen) { - if ((trailingBackslashCount(doublePart) % 2) == 0) doubleOpen = !doubleOpen; - } - } - } - if (singleOpen || doubleOpen) { // a quote is still open: include the comma - atom.push(','); - } - else { // no open quotes, and a comma or end-of-line encoutered: means end of an atom - if (!atomL) throw new Error('splitComponentArguments(): the argument at index ' + args.length + ' does not contain a parameter assignment: ' + s); - atomR = jQuery.trim(atom.join('')); - args.push({ 'name': atomL, 'value': atomR }); - atomL = false; - atomR = false; - atom = []; - } - } - - if (atomL || (atom.length > 0)) throw new Error('splitComponentArguments(): premature end of the last argument: ' + s); - - return args; - }; - - - var QuotesWalker = function (s, isLongQuotes) { - var doubleQuotes, singleQuotes, quoteLen, iteration = 0, - n = s.length, - startCharPos = 0, - unescapedIndexOf = function (s, quotes, startPos) { - var n = s.length, pos; - while (startPos < n) { - pos = s.indexOf(quotes, startPos); - if (pos <= 0) return pos; - if (s.charAt(pos-1) != '\\') return pos; - startPos = pos + 1; - } - return -1; - }; - - if (isLongQuotes) { - doubleQuotes= '"""'; - singleQuotes = "'''"; - quoteLen = 3; - } - else { - doubleQuotes= '"'; - singleQuotes = "'"; - quoteLen = 1; - } - - this.prefixString = ''; - this.quotedString = ''; - this.quoteType = ''; - - this.next = function () { - var doubleQuotePos, singleQuotePos, quotePos, quoteType; - iteration++; - if (startCharPos >= n) { - this.prefixString = ''; - this.quotedString = ''; - this.quoteType = ''; - codeq.log.debug("QuotesWalker #" + iteration + ': no more data, returning false'); - return false; - } - // with which quotes to start, single or double? - doubleQuotePos = unescapedIndexOf(s, doubleQuotes, startCharPos); - singleQuotePos = unescapedIndexOf(s, singleQuotes, startCharPos); - if (doubleQuotePos < 0) { - if (singleQuotePos < 0) { - // the end - this.prefixString = s.slice(startCharPos, n); - this.quotedString = ''; - this.quoteType = ''; - startCharPos = n; - codeq.log.debug("QuotesWalker #" + iteration + ': last data, remaining string: ' + this.prefixString); - return true; - } - quotePos = singleQuotePos; - quoteType = singleQuotes; - } - else if (singleQuotePos < 0) { - quotePos = doubleQuotePos; - quoteType = doubleQuotes; - } - else if (doubleQuotePos < singleQuotePos) { - quotePos = doubleQuotePos; - quoteType = doubleQuotes; - } - else { - quotePos = singleQuotePos; - quoteType = singleQuotes; - } - this.quoteType = quoteType; - - this.prefixString = s.slice(startCharPos, quotePos); - startCharPos = quotePos + quoteLen; - quotePos = unescapedIndexOf(s, quoteType, startCharPos); - this.quotedString = s.slice(startCharPos, quotePos); - startCharPos = quotePos + quoteLen; - codeq.log.debug('QuotesWalker #' + iteration + ': quoteType=' + this.quoteType + ', data:\nprefix=' + this.prefixString + '\nquoted=' + this.quotedString); - return true; - }; - }; - - var escapePythonicLongString = function (s, output) { - var pos = 0, - parts = s.split("'"), - n = parts.length, - i, part, previousPart; - output.push("'"); // starting quote - - previousPart = parts[0]; - output.push(previousPart.split('\r').join('\\r').split('\t').join('\\t').split('\n').join('\\n')); - for (i = 1; i < n; i++) { - part = parts[i]; - // first escape the single quote, if required - if (previousPart.charAt(previousPart.length - 1) != '\\') output.push('\\'); - // escape \r, \n, \t - output.push(part.split('\r').join('\\r').split('\t').join('\\t').split('\n').join('\\n')); - previousPart = part; - } - - output.push("'"); // ending quote - }; - - // the "engine" of codeq - codeq.system = { - // define XML namespaces, for use in generating HTML content - ns: { - svg: 'http://www.w3.org/2000/svg' - }, - - // the method for creating a templating function from the given string template - createTemplate: function (str, templateName, _internalDoLog_) { - var f, parts, i, subparts, subpart, - isSvg = str.substring(0, 4) === ' 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(cleanHtml(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 - src.push('_result.push(', subpart.slice(1), ');\n'); - } - else if (subpart[0] === '@') { // a component directive, this gets processed in two phases - atoms = subpart.slice(1).replace(regexpWhiteSpaceStart, ''); // get the whole directive, remove any heading whitespace - componentName = atoms.split(regexpWhiteSpace, 1)[0]; // extract the component name - atoms = splitComponentArguments(atoms.slice(componentName.length)); // extract the atoms - src.push('_tmp={"name":"', stringToDef(componentName), '","params":{},"key":"image"+_counter};\n'); - src.push('_components_.push(_tmp);\n'); - src.push('_tmp=_tmp.params;\n'); - for (j = 0; j < atoms.length; j++) { - atom = atoms[j]; - src.push('_tmp["', stringToDef(atom.name), '"]=', atom.value, ';\n'); - } -// src.push('_result.push(\'<', nodeName, ' class="image\', _counter, \'">\');\n'); - src.push('_result.push(\'\');\n'); - src.push('_counter++;\n'); - } - else { // a statement - src.push(subpart, '\n'); - } - } - } - if ((subparts.length > 1) && (subparts[1].length > 0)) { // there's a trailing text - src.push('_result.push("', stringToDef(cleanHtml(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('_components_', src.join('')); // create a function that takes the single argument named _components_ (an array) - } - catch (e) { - codeq.log.error('createTemplate(): ' + debugPrefix + ' Failed to instantiate template function: ' + e + '\nfunction(_components_) {\n' + src.join('') + '\n}\n=== Created from template: ===\n' + str, e); - throw e; - } - - return function () { // takes params, callback - var param, templateParams, callback, html, components = [], i, jq, jqContainer, processDom; - - // parse arguments - // first set defaults - templateParams = false; - callback = false; - jqContainer = false; - for (i = arguments.length - 1; i >= 0; i--) { - param = arguments[i]; - if (param instanceof Function) { - // set the optional callback that will be invoked with a jQuery argument representing the "compiled" template, after the template is all set up - if (callback) throw new Error(debugPrefix + ' More than one callback provided to a template function'); - callback = param; - } - else if (param instanceof jQuery) { - // set the container that will receive the template content, the container is mandatory for SVG - if (jqContainer) throw new Error(debugPrefix + ' More than one jQuery container provided to a template function'); - jqContainer = param; - } - else if (param instanceof Object) { // BEWARE: this one catches all Objects, so do testing for descendants (e.g.: Function, jQuery) before testing for Object! - // set the parameters to the template function, they are optional - if (templateParams) throw new Error(debugPrefix + ' More than one object with template parameters provided to a template function'); - templateParams = param; - } - else throw new Error(debugPrefix + ' Unknown parameter provided to a template function: ' + typeof param); - } - // we need at least an empty object for the template function - if (!templateParams) templateParams = emptyConstObject; - // the container is mandatory for SVG - //if (isSvg && !jqContainer) throw new Error(debugPrefix + ' jQuery object is a mandatory parameter to the template function when the template is a SVG object'); - - // process DOM, after the template is instantiated - processDom = function () { - var componentDef, i, finishedIteration, finishComponent, cjq, params, key, variant, variantsCache, - iterationCount, currentIteration, newJq; - - jq.data('templateName', templateName); // for debugging - - iterationCount = 1 + components.length; // first one is the sentinel - currentIteration = 0; // how many iterations were processed - finishedIteration = function () { - currentIteration++; - if (iterationCount === currentIteration) { - jq.makeUnselectable(); - if (callback) callback(jq, templateParams); - } - }; - - finishComponent = function (cjq, classes, params, reservedParams) { - var attrName; - if (params['class']) classes.push(params['class']); - cjq.attr('class', classes.join(' ')); - for (attrName in params) { - if (attrName === 'class') continue; // a fixed reserved parameter - if (attrName in reservedParams) continue; // reserved parameters as specified by the corresponding handler - cjq.attr(attrName, params[attrName]); // set the attribute - } - finishedIteration(); - }; - - for (i = 0; i < components.length; i++) { - componentDef = components[i]; - params = componentDef.params; - cjq = jq.find('.' + componentDef.key); - if (cjq.length == 0) { - if (jq.hasClass(componentDef.key)) cjq = jq; - } - if (cjq.length == 0) { - codeq.log.error('codeq.system.createTemplate::fn(): internal error: could not obtain reference to a template component of type ' + componentDef.name + ', key=' + componentDef.key); - continue; - } - if (_internalDoLog_) codeq.log.debug('codeq.system.createTemplate::fn(): ' + debugPrefix + ' searching for a component with class ' + componentDef.key + ', found ' + cjq.length); - isSvg = 'ownerSVGElement' in cjq[0]; - switch (componentDef.name) { - case 'text': - key = params.key; - if (!key) { - codeq.log.error('codeq.system.createTemplate::fn(): ' + debugPrefix + ' A text component is missing the key'); - finishedIteration(); - } - else { - if (isSvg) newJq = $(document.createElementNS(codeq.ns.svg, 'tspan')); - else newJq = $(''); - cjq.replaceWith(newJq); - if (jq === cjq) jq = newJq; - cjq = newJq; - cjq.attr('data-tkey', key); - translate(cjq); - if (_internalDoLog_) codeq.log.debug('codeq.system.createTemplate::fn(): ' + debugPrefix + ' Instantiated intellitext: key=' + key); - finishComponent(cjq, ['intellitext'], params, {'key':true}); - } - break; - case 'image': - key = params.key; - if (isSvg) { - codeq.log.error('codeq.system.createTemplate::fn(): ' + debugPrefix + ' Currently there is no support for inlining images into SVG'); - finishedIteration(); - } - else if (!key) { - codeq.log.error('codeq.system.createTemplate::fn(): ' + debugPrefix + ' An image component is missing the key'); - finishedIteration(); - } - else { - newJq = $(''); - cjq.replaceWith(newJq); - if (jq === cjq) jq = newJq; - cjq = newJq; - variant = params.variant || 'normal'; - cjq.attr('data-ikey', key); // HTML5 data - cjq.attr('data-ivariant', variant); - cjq.data['ikey'] = key; // jQuery data - cjq.data['ivariant'] = variant; - cjq.data['ivariants'] = variantsCache = {}; - setButtonVariant(cjq, variantsCache, key, variant, (function (cjq, params, variant) { - return function () { - if (_internalDoLog_) codeq.log.debug('codeq.system.createTemplate::fn(): ' + debugPrefix + ' Instantiated image: key=' + params.key + ', variant=' + variant); - finishComponent(cjq, ['intellimage'], params, {'key':true, 'variant':true}); - }; - })(cjq, params, variant)); - } - break; - default: - codeq.log.error('codeq.system.createTemplate::fn(): ' + debugPrefix + ' Invalid component name: ' + componentDef.name); - finishedIteration(); - break; - } - } - finishedIteration(); // the sentinel - }; - - // create DOM - - try { - html = f.apply(templateParams, [components]); - if (_internalDoLog_) { - codeq.log.debug('createTemplate(): ' + debugPrefix + ' instantiating template:\n' + html); - } - } - catch (e) { - codeq.log.error('createTemplate(): ' + debugPrefix + ' Failed to invoke template function: ' + e + '\nfunction(_components_) {\n' + src.join('') + '\n}\n=== Created from template: ===\n' + str, e); - throw e; - } - - jq = $(html); - if (jqContainer) jqContainer.append(jq); - processDom(); - - // TODO: what follows is the code that uses SVG jQuery plugin to instantiate SVG DOM, but the created images are not always correctly sized; needs analysis of what is happening - /* if (isSvg) { - jqContainer.empty().svg({ - 'loadURL': html, - 'initPath': '/js/svg/', // where to load blank.svg from if needed - 'changeSize': true, // get the size from the SVG markup, don't retain the existing size of the container - 'onLoad': function (jqSvg) { - // it should hold that jqContainer == jqSvg, but we ignore the parameter anyway - jq = $(jqContainer.children()[0]); - processDom(); - } - }); - } - else { - jq = $(html); - if (jqContainer) jqContainer.append(jq); - processDom(); - }*/ - }; - }, // createTemplate - - // -------------------------------------------------------------------------------- - // Task info parser: converts simplified pythonic syntax to a JavaScript function - // -------------------------------------------------------------------------------- - // deprecated: use codeq.parseDefinition() instead - parseInfo: function (infoText) { - var parts = [], - n, lines, line, i, j, len, walker, fn, obj; - // convert pythonic long-strings to ordinary strings, escaping things as we go - walker = new QuotesWalker(infoText, true); - while (walker.next()) { - if (walker.prefixString.length > 0) parts.push(walker.prefixString); - if (walker.quotedString.length > 0) escapePythonicLongString(walker.quotedString, parts); - } - - // split into separate lines, remove comments, add semicolons - lines = parts.join('').split('\n'); // split at line feed characters - n = lines.length; - for (i = 0; i < n; i++) { - line = lines[i]; - len = line.length; - if (len > 0) { - // if exists: find the first python's comment character (#) that is not in a string (between two quotes) - parts = []; - walker = new QuotesWalker(line, false); - while (walker.next()) { - if (walker.prefixString.length > 0) { - j = walker.prefixString.indexOf('#'); - if (j >= 0) { - parts.push(walker.prefixString.slice(0, j)); - break; // commented out till the EOL - } - parts.push(walker.prefixString); - } - parts.push(walker.quoteType); - parts.push(walker.quotedString); - parts.push(walker.quoteType); - } - - line = parts.join('').replace(regexpWhiteSpaceEnd, ''); // trim the white space at the end - if ((line.length > 0) && (line[line.length - 1] != ';')) line = line + ';'; // and add a semicolon - lines[i] = line; - } - } - - // compose the function - lines.unshift("var description, hint;"); - lines.push("__params__.description = description;", "__params__.hint = hint;"); - codeq.log.debug("Creating a new parseInfo function having the body: "); - codeq.log.debug(lines); - fn = new Function("__params__", lines.join('\n')); - obj = {}; - fn(obj); - return obj; // obj now contains "description" and "hint" - }, - - load: function (request) { - $.ajax({ - contentType: request.contentType, - dataType: request.type, - type: request.data ? 'POST' : 'GET', - url: request.url + '?_=' + Date.now(), - data: request.data, - error: function (jqXHR, textStatus, errorThrown) { - codeq.log.error('Loading of ' + request.url + ' failed: ' + textStatus, errorThrown); - try { - if (request.callback) request.callback(null, 'Error: ' + (errorThrown ? '' + errorThrown : textStatus), request.url); - } - catch (e) { - codeq.log.error('Callback with error failed on request ' + request.url + ': ' + e, e); - } - }, - success: function (data, textStatus, jqXHR) { - try { - if (request.callback) request.callback(data, 'OK', request.url); - } - catch (e) { - codeq.log.error('Callback failed on successful request ' + request.url + ': ' + e, e); - } - } - }); - } - - }; // codeq.system = { - - /** - * Returns the number of Unicode code points in the given string. - * - * @param s {string} - * @returns {number} - */ - codeq.codePointCount = function (s) { - var n = 0, i, code; - if (typeof s !== 'string') { - code = 'codePointCount(): argument not a string: type = ' + typeof s + ', is null = ' + (s === null); - if ((typeof s === 'object') && (s !== null) && s.constructor) code += ', constructor = ' + s.constructor.name; - codeq.log.error(code); - return 0; - } - for (i = s.length - 1; i >= 0; i--) { - try { - code = s.charCodeAt(i); - } - catch (e) { - codeq.log.error('Invocation of charCodeAt() failed at iteration #' + i + ': ' + e, e); - return 0; - } - if ((code >= 0xd800) && (code < 0xe000)) i++; - n++; - } - return n; - }; - - var jqDisabled = $('#disabled'), - waitCssEnter = {'cursor': 'wait', 'display': ''}; - - codeq.wait = function (promise) { - jqDisabled.css(waitCssEnter); - return promise.fin(function () { - jqDisabled.css('display', 'none'); - }); - }; - -})(); diff --git a/js/def_parser.js b/js/def_parser.js deleted file mode 100644 index 87c9e49..0000000 --- a/js/def_parser.js +++ /dev/null @@ -1,436 +0,0 @@ -/** - * A parser/compiler for the pythonic definitions of assignments. - * Supports basic assignment statements, no expressions using operators (yet). - */ - -(function () { - var regexpWhitespace = new RegExp('[ \t]'), - regexpNameStart = new RegExp('[a-zA-Z_]'), - regexpName = new RegExp('[a-zA-Z0-9_]'), - regexpNumber = new RegExp('[0-9]'), - regexpNumberAndDot = new RegExp('[0-9.]'); - - var isEscape = function (s, pos) { - var i, result = false; - for (i = pos; i >= pos; i--) { - if (s.charAt(pos) === '\\') result = !result; - else break; - } - return result; - }; - - var escapePyString = function (s, output) { - var parts = s.split("'"), - n = parts.length, - i, part, previousPart; - output.push("'"); // starting quote - - previousPart = parts[0]; - output.push(previousPart.split('\r').join('\\r').split('\t').join('\\t').split('\n').join('\\n')); - for (i = 1; i < n; i++) { - part = parts[i]; - // first escape the single quote, if required - if (!isEscape(previousPart, previousPart.length - 1)) output.push('\\'); - // escape \r, \n, \t - output.push(part.split('\r').join('\\r').split('\t').join('\\t').split('\n').join('\\n')); - previousPart = part; - } - - output.push("'"); // ending quote - }; - - var tokenize = function (input) { - var pos = 0, row = 1, col = 1, - n = input.length, - is_line_start = true, - getMultilineString = function (type) { - var p = pos, i, j, l, parts, part, is_escaped, result; - while (p < n) { - i = input.indexOf(type, p); - if (i < 0) throw new Error('Unterminated long string at position #' + pos + ', line ' + row + ', character ' + col); - is_escaped = false; - for (j = i-1; j >= pos; j--) { - if (input.charAt(j) === '\\') is_escaped = !is_escaped; - else break; - } - if (is_escaped) p = i + 1; // an escaped quote - else { - // process line continuations - parts = input.slice(pos, i).split('\n'); - col += i + 3 - pos; // position the next column pointer - pos = i + 3; // position the next character pointer - l = parts.length - 1; - if (l === 0) return parts[0]; // no newline character in the string - row += l; // add the lines of the string - col = 1 + parts[l].length; - result = []; // the resulting string - for (i = 0; i < l; i++) { - part = parts[i]; // check the part for a trailing escape character - is_escaped = false; - for (j = part.length - 1; j >= 0; j--) { - if (part.charAt(j) === '\\') is_escaped = !is_escaped; - else break; - } - if (is_escaped) { - // only add the line with the tail escape character trimmed - result.push(part.slice(0, part.length - 1)); - } - else { - // add the line and the trailing newline - result.push(part, '\n'); - } - } - result.push(parts[l]); // the last line, which is not checked for an escape character - return result.join(''); - } - } - throw new Error('Unterminated long string at position #' + pos + ', line ' + row + ', character ' + col); - }, - getString = function (type) { - var p = pos, i, j, is_escaped, s; - while (p < n) { - i = input.indexOf(type, p); - j = input.indexOf('\n', p); - if (i < 0) throw new Error('Unterminated string at position #' + pos + ', line ' + row + ', character ' + col); - if ((j >= 0) && (j < i)) throw new Error('Unterminated string at position #' + pos + ', line ' + row + ', character ' + col); - is_escaped = false; - for (j = i-1; j >= pos; j--) { - if (input.charAt(j) === '\\') is_escaped = !is_escaped; - else break; - } - if (is_escaped) p = i + 1; // an escaped quote - else { - s = input.slice(pos, i); - col += i + 1 - pos; // position the next column pointer - pos = i + 1; // position the next character pointer - return s; - } - } - throw new Error('Unterminated string at position #' + pos + ', line ' + row + ', character ' + col); - }; - - // the next() function - return function () { - var s, count = 0, token = null, parts, i; - if (pos >= n) return null; - var c = input.charAt(pos++), token_row = row, token_col = col; - - // skip white-space - for (;;) { - if (c === ' ') { - count++; - col++; - } - else if (c === '\t') { - // tab is worth 4 spaces - count += 4; - col++; - } - else if (c === '\n') { - count = 0; - is_line_start = true; - row++; - col = 1; - } - else if (c === '\r') { - if (pos >= n) return null; // EOF - if (input.charAt(pos) !== '\n') throw new Error("CR character without a trailing LF at character #" + (pos-1)); - pos++; - count = 0; - is_line_start = true; - row++; - col = 1; - } - else break; - if (pos >= n) return null; // EOF - c = input.charAt(pos++); - } - - if ((c === '"') || (c === "'")) { - // a quote starts a string, now see whether it's a multi-line string - if ((pos+1 < n) && (input.charAt(pos) == c) && (input.charAt(pos+1) == c)) { - // it's a long string - pos += 2; - s = getMultilineString(c === '"' ? '"""' : "'''"); - } - else { - s = getString(c); - } - token = {'type': 'string', 'value': s}; - } - - else if (c.match(regexpNameStart)) { - parts = [ c ]; // the name builder - col++; - while (pos < n) { - c = input.charAt(pos); - if (c.match(regexpName)) { - parts.push(c); - pos++; - col++; - } - else break; - } - token = {'type': 'name', 'value': parts.join('')}; - } - - else if (c.match(regexpNumberAndDot)) { - parts = [ c ]; // the number builder - col++; - while ((pos < n) && (c != '.')) { - c = input.charAt(pos); - if (c.match(regexpNumberAndDot)) { - parts.push(c); - pos++; - col++; - } - else break; - } - while (pos < n) { - if (c.match(regexpNumber)) { - parts.push(c); - pos++; - col++; - } - else break; - } - token = {'type': 'number', 'value': +parts.join('')}; - } - - else if (c === '=') { - col++; - if ((pos < n) && (input.charAt(pos) === '=')) { - pos++; - col++; - token = {'type': 'eq'}; - } - else { - token = {'type': 'assign'}; - } - } - - else if (c === '{') { - token = {'type': 'lbrace'}; - col++; - } - - else if (c === '}') { - token = {'type': 'rbrace'}; - col++; - } - - else if (c === '[') { - token = {'type': 'lbracket'}; - col++; - } - - else if (c === ']') { - token = {'type': 'rbracket'}; - col++; - } - - else if (c === '(') { - token = {'type': 'lparen'}; - col++; - } - - else if (c === ')') { - token = {'type': 'rparen'}; - col++; - } - - else if (c === ':') { - token = {'type': 'colon'}; - col++; - } - - else if (c === ';') { - token = {'type': 'semicolon'}; - col++; - } - - else if (c === ',') { - token = {'type': 'comma'}; - col++; - } - - else if (c === '#') { - // a comment till the end of line - i = input.indexOf('\n', pos); - if (i < 0) { - // this is the last line - s = input.slice(pos); - } - else { - s = input.slice(pos, i); - } - token = {'type': 'comment', 'value': s}; - col += i - pos; - pos = i; // we want the next invocation to parse the trailing newline, so it correctly sets line_start, etc. - } - - else { - token = {'type': 'unknown', 'value': c}; - col++; - } - - token['line_start'] = is_line_start; - token['whitespace_offset'] = count; - token['line'] = token_row; - token['column'] = token_col; - return token; - }; - }; - - var parseExpression = function (token, next, output) { - var nextToken; - if (token.type === 'string') { - // string literal - escapePyString(token.value, output); - } - else if (token.type === 'number') { - // number literal - output.push('' + token.value); - } - else if (token.type === 'lbrace') { - // object literal - output.push('{'); - if (!(nextToken = next())) throw new Error("Unfinished line, at line " + token.line + ", column " + token.line); - if (nextToken.type === 'rbrace') { - output.push('}'); - return; // end of object literal - } - for (;;) { - if (nextToken.type === 'string') { - escapePyString(nextToken.value, output); - } - else if (nextToken.type === 'number') { - output.push('' + token.value); - } - else throw new Error("Object key not a string or a number, at line " + nextToken.line + ", column " + nextToken.column); - - if (!(nextToken = next())) throw new Error("Unfinished line, at line " + token.line + ", column " + token.column); - if (nextToken.type !== 'colon') throw new Error("Expected :, at line " + nextToken.line + ", column " + nextToken.column); - output.push(':'); - - if (!(nextToken = next())) throw new Error("Unfinished line, at line " + token.line + ", column " + token.column); - parseExpression(nextToken, next, output); - - if (!(nextToken = next())) throw new Error("Unfinished line, at line " + token.line + ", column " + token.column); - if (nextToken.type === 'comma') { - output.push(','); - } - else if (nextToken.type === 'rbrace') { - output.push('}'); - break; // end of object literal - } - else throw new Error("Expected , or }, at line " + nextToken.line + ", column " + nextToken.column); - - if (!(nextToken = next())) throw new Error("Unfinished line, at line " + token.line + ", column " + token.column); - } - } - else if (token.type === 'lbracket') { - // array literal - output.push('['); - if (!(nextToken = next())) throw new Error("Unfinished line, at line " + token.line + ", column " + token.line); - if (nextToken.type === 'rbracket') { - output.push(']'); - return; // end of array literal - } - for (;;) { - parseExpression(nextToken, next, output); - - if (!(nextToken = next())) throw new Error("Unfinished line, at line " + token.line + ", column " + token.column); - if (nextToken.type === 'comma') { - output.push(','); - } - else if (nextToken.type === 'rbracket') { - output.push(']'); - break; // end of array literal - } - else throw new Error("Expected , or ], at line " + nextToken.line + ", column " + nextToken.column); - - if (!(nextToken = next())) throw new Error("Unfinished line, at line " + token.line + ", column " + token.column); - } - } - else throw new Error("Unexpected token: expected a string, number, object, or array, at line " + token.line + ", column " + token.column); - }; - - - /** - * @typedef {string|{type: string, message: string}} HintDefinition - */ - /** - * @typedef {Object} PrologTaskDef a Prolog assignment definition - * @property {string} description the assignment description - * @property {Object.} hint the assignment hint definitions, keyed by hint ID - */ - - /** - * Converts the given pythonic assignment definition into a JavaScriptish definition, - * executes it, and takes the variables "description" and "hint" from the definition. - * - * @param {string} definition The assignment definition. - * @returns {PrologTaskDef} - */ - codeq.parseDefinition = function (definition) { - var next = tokenize(definition), - vars = { 'description': true, 'hint': true }, - parts = [ ], // first element is just a placeholder, to be replaced with the full "var" declaration at the end - token, first_token, varname, v, fn, obj; - - while (token = next()) { - // parse line by line - if (!token.line_start) throw new Error("The token does not start in a new line, at line " + token.line + ", column " + token.column); - if (token.type === 'comment') continue; - if (token.whitespace_offset > 0) throw new Error("Cannot parse indented lines, at line " + token.line); - - // parse lvalue - if (token.type !== 'name') throw new Error("Expected a lvalue, at line " + token.line + ", column " + token.column); - varname = token.value; - vars[varname] = true; // remember the variable name, so we will declare it at the end - parts.push(';\n'); // close the previous line -- the first time this is wrong because there is no previous line yet, but we will replace it with a variable declaration - parts.push(varname); // start the new line with the assignment statement -- the only statement we support - first_token = token; - if (!(token = next())) throw new Error("Unfinished line, at line " + first_token.line); - - // optional index - if (token.type === 'lbracket') { - // index operator - parts.push('['); - if (!(token = next())) throw new Error("Unfinished line, at line " + first_token.line); - if (token.type === 'string') escapePyString(token.value, parts); - else if (token.type === 'number') parts.push('' + token.value); - else throw new Error("Unsupported index expression, at line " + token.line + ", column " + token.column); - if (!(token = next())) throw new Error("Unfinished line, at line " + first_token.line); - if (token.type !== 'rbracket') throw new Error("Expected ], at line " + token.line + ", column " + token.column + ", token " + token.type); - parts.push(']'); - if (!(token = next())) throw new Error("Unfinished line, at line " + first_token.line); - } - - // the assignment operator - if (token.type !== 'assign') throw new Error("Expected =, at line " + token.line + ", column " + token.column); - parts.push('='); - if (!(token = next())) throw new Error("Unfinished line, at line " + first_token.line); - - // parse rvalue - parseExpression(token, next, parts); - } - - if (parts.length === 0) return {}; // empty definition - - v = []; - for (varname in vars) { - if (vars.hasOwnProperty(varname)) v.push(varname); - } - - parts[0] = 'var ' + v.join(', ') + ';\n'; - parts.push(';\nreturn {"description":description,"hint":hint};'); - v = parts.join(''); - codeq.log.debug("Creating a new parseInfo function having the body:\n" + v); - fn = new Function("__params__", v); - obj = fn(); - return obj; // obj now contains "description" and "hint" - }; // parseDefinition - -})(); \ No newline at end of file diff --git a/js/jquery/jquery.console.js b/js/jquery/jquery.console.js deleted file mode 100644 index 4a75a99..0000000 --- a/js/jquery/jquery.console.js +++ /dev/null @@ -1,773 +0,0 @@ -// JQuery Console 1.0 -// Sun Feb 21 20:28:47 GMT 2010 -// -// Copyright 2010 Chris Done, Simon David Pratt. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// -// 1. Redistributions of source code must retain the above -// copyright notice, this list of conditions and the following -// disclaimer. -// -// 2. Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials -// provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -// TESTED ON -// Internet Explorer 6 -// Opera 10.01 -// Chromium 4.0.237.0 (Ubuntu build 31094) -// Firefox 3.5.8, 3.6.2 (Mac) -// Safari 4.0.5 (6531.22.7) (Mac) -// Google Chrome 5.0.375.55 (Mac) - -(function($){ - var isWebkit = !!~navigator.userAgent.indexOf(' AppleWebKit/'); - - $.fn.console = function(config){ - //////////////////////////////////////////////////////////////////////// - // Constants - // Some are enums, data types, others just for optimisation - var keyCodes = { - // left - 37: moveBackward, - // right - 39: moveForward, - // up - 38: previousHistory, - // down - 40: nextHistory, - // backspace - 8: backDelete, - // delete - 46: forwardDelete, - // end - 35: moveToEnd, - // start - 36: moveToStart, - // return - 13: commandTrigger, - // tab - 18: doNothing, - // tab - 9: doComplete - }; - var ctrlCodes = { - // C-a - 65: moveToStart, - // C-e - 69: moveToEnd, - // C-d - 68: forwardDelete, - // C-n - 78: nextHistory, - // C-p - 80: previousHistory, - // C-b - 66: moveBackward, - // C-f - 70: moveForward, - // C-k - 75: deleteUntilEnd - }; - if(config.ctrlCodes) { - $.extend(ctrlCodes, config.ctrlCodes); - } - var altCodes = { - // M-f - 70: moveToNextWord, - // M-b - 66: moveToPreviousWord, - // M-d - 68: deleteNextWord - }; - var shiftCodes = { - // return - 13: newLine, - }; - var cursor = ' '; - - //////////////////////////////////////////////////////////////////////// - // Globals - var container = $(this); - var inner = $('
'); - // erjiang: changed this from a text input to a textarea so we - // can get pasted newlines - var typer = $(''); - // Prompt - var promptBox; - var prompt; - var continuedPromptLabel = config && config.continuedPromptLabel? - config.continuedPromptLabel : "> "; - var column = 0; - var promptText = ''; - var restoreText = ''; - var continuedText = ''; - var fadeOnReset = config.fadeOnReset !== undefined ? config.fadeOnReset : true; - // Prompt history stack - var history = []; - var ringn = 0; - // For reasons unknown to The Sword of Michael himself, Opera - // triggers and sends a key character when you hit various - // keys like PgUp, End, etc. So there is no way of knowing - // when a user has typed '#' or End. My solution is in the - // typer.keydown and typer.keypress functions; I use the - // variable below to ignore the keypress event if the keydown - // event succeeds. - var cancelKeyPress = 0; - // When this value is false, the prompt will not respond to input - var acceptInput = true; - // When this value is true, the command has been canceled - var cancelCommand = false; - - // External exports object - var extern = {}; - - //////////////////////////////////////////////////////////////////////// - // Main entry point - (function(){ - extern.promptLabel = config && config.promptLabel? config.promptLabel : "> "; - container.append(inner); - inner.append(typer); - typer.css({position:'absolute',top:0,left:'-9999px'}); - if (config.welcomeMessage) - message(config.welcomeMessage,'jquery-console-welcome'); - newPromptBox(); - if (config.autofocus) { - inner.addClass('jquery-console-focus'); - typer.focus(); - setTimeout(function(){ - inner.addClass('jquery-console-focus'); - typer.focus(); - },100); - } - extern.inner = inner; - extern.typer = typer; - extern.scrollToBottom = scrollToBottom; - extern.report = report; - })(); - - //////////////////////////////////////////////////////////////////////// - // Reset terminal - extern.reset = function(){ - var welcome = (typeof config.welcomeMessage != 'undefined'); - - var removeElements = function() { - inner.find('div').each(function(){ - if (!welcome) { - $(this).remove(); - } else { - welcome = false; - } - }); - }; - - if (fadeOnReset) { - inner.parent().fadeOut(function() { - removeElements(); - newPromptBox(); - inner.parent().fadeIn(focusConsole); - }); - } - else { - removeElements(); - newPromptBox(); - focusConsole(); - } - }; - - var focusConsole = function() { - inner.addClass('jquery-console-focus'); - typer.focus(); - }; - - extern.focus = function(){ - focusConsole(); - } - - //////////////////////////////////////////////////////////////////////// - // Reset terminal - extern.notice = function(msg,style){ - var n = $('
').append($('
').text(msg)) - .css({visibility:'hidden'}); - container.append(n); - var focused = true; - if (style=='fadeout') - setTimeout(function(){ - n.fadeOut(function(){ - n.remove(); - }); - },4000); - else if (style=='prompt') { - var a = $('
'); - n.append(a); - focused = false; - a.click(function(){ n.fadeOut(function(){ n.remove();inner.css({opacity:1}) }); }); - } - var h = n.height(); - n.css({height:'0px',visibility:'visible'}) - .animate({height:h+'px'},function(){ - if (!focused) inner.css({opacity:0.5}); - }); - n.css('cursor','default'); - return n; - }; - - //////////////////////////////////////////////////////////////////////// - // Make a new prompt box - function newPromptBox() { - column = 0; - promptText = ''; - ringn = 0; // Reset the position of the history ring - enableInput(); - promptBox = $('
'); - var label = $(''); - var labelText = extern.continuedPrompt? continuedPromptLabel : extern.promptLabel; - promptBox.append(label.text(labelText).show()); - label.html(label.html().replace(' ',' ')); - prompt = $(''); - promptBox.append(prompt); - inner.append(promptBox); - updatePromptDisplay(); - }; - - //////////////////////////////////////////////////////////////////////// - // Handle setting focus - container.click(function(){ - // Don't mess with the focus if there is an active selection - if (window.getSelection().toString()) { - return false; - } - - inner.addClass('jquery-console-focus'); - inner.removeClass('jquery-console-nofocus'); - if (isWebkit) { - typer.focusWithoutScrolling(); - } else { - typer.css('position', 'fixed').focus(); - } - scrollToBottom(); - return false; - }); - - //////////////////////////////////////////////////////////////////////// - // Handle losing focus - typer.blur(function(){ - inner.removeClass('jquery-console-focus'); - inner.addClass('jquery-console-nofocus'); - }); - - //////////////////////////////////////////////////////////////////////// - // Bind to the paste event of the input box so we know when we - // get pasted data - typer.bind('paste', function(e) { - // wipe typer input clean just in case - typer.val(""); - // this timeout is required because the onpaste event is - // fired *before* the text is actually pasted - setTimeout(function() { - typer.consoleInsert(typer.val()); - typer.val(""); - }, 0); - }); - - //////////////////////////////////////////////////////////////////////// - // Handle key hit before translation - // For picking up control characters like up/left/down/right - - typer.keydown(function(e){ - cancelKeyPress = 0; - var keyCode = e.keyCode; - // C-c: cancel the execution - if(e.ctrlKey && keyCode == 67) { - cancelKeyPress = keyCode; - cancelExecution(); - return false; - } - if (acceptInput) { - if (e.shiftKey && keyCode in shiftCodes) { - cancelKeyPress = keyCode; - (shiftCodes[keyCode])(); - return false; - } else if (e.altKey && keyCode in altCodes) { - cancelKeyPress = keyCode; - (altCodes[keyCode])(); - return false; - } else if (e.ctrlKey && keyCode in ctrlCodes) { - cancelKeyPress = keyCode; - (ctrlCodes[keyCode])(); - return false; - } else if (keyCode in keyCodes) { - cancelKeyPress = keyCode; - (keyCodes[keyCode])(); - return false; - } - } - }); - - //////////////////////////////////////////////////////////////////////// - // Handle key press - typer.keypress(function(e){ - var keyCode = e.keyCode || e.which; - if (isIgnorableKey(e)) { - return false; - } - // C-v: don't insert on paste event - if ((e.ctrlKey || e.metaKey) && String.fromCharCode(keyCode).toLowerCase() == 'v') { - return true; - } - if (acceptInput && cancelKeyPress != keyCode && keyCode >= 32){ - if (cancelKeyPress) return false; - if ( - typeof config.charInsertTrigger == 'undefined' || ( - typeof config.charInsertTrigger == 'function' && - config.charInsertTrigger(keyCode,promptText) - ) - ){ - typer.consoleInsert(keyCode); - } - } - if (isWebkit) return false; - }); - - function isIgnorableKey(e) { - // for now just filter alt+tab that we receive on some platforms when - // user switches windows (goes away from the browser) - return ((e.keyCode == keyCodes.tab || e.keyCode == 192) && e.altKey); - }; - - //////////////////////////////////////////////////////////////////////// - // Rotate through the command history - function rotateHistory(n){ - if (history.length == 0) return; - ringn += n; - if (ringn < 0) ringn = history.length; - else if (ringn > history.length) ringn = 0; - var prevText = promptText; - if (ringn == 0) { - promptText = restoreText; - } else { - promptText = history[ringn - 1]; - } - if (config.historyPreserveColumn) { - if (promptText.length < column + 1) { - column = promptText.length; - } else if (column == 0) { - column = promptText.length; - } - } else { - column = promptText.length; - } - updatePromptDisplay(); - }; - - function previousHistory() { - rotateHistory(-1); - }; - - function nextHistory() { - rotateHistory(1); - }; - - // Add something to the history ring - function addToHistory(line){ - history.push(line); - restoreText = ''; - }; - - // Delete the character at the current position - function deleteCharAtPos(){ - if (column < promptText.length){ - promptText = - promptText.substring(0,column) + - promptText.substring(column+1); - restoreText = promptText; - return true; - } else return false; - }; - - function backDelete() { - if (moveColumn(-1)){ - deleteCharAtPos(); - updatePromptDisplay(); - } - }; - - function forwardDelete() { - if (deleteCharAtPos()){ - updatePromptDisplay(); - } - }; - - function deleteUntilEnd() { - while(deleteCharAtPos()) { - updatePromptDisplay(); - } - }; - - function deleteNextWord() { - // A word is defined within this context as a series of alphanumeric - // characters. - // Delete up to the next alphanumeric character - while( - column < promptText.length && - !isCharAlphanumeric(promptText[column]) - ) { - deleteCharAtPos(); - updatePromptDisplay(); - } - // Then, delete until the next non-alphanumeric character - while( - column < promptText.length && - isCharAlphanumeric(promptText[column]) - ) { - deleteCharAtPos(); - updatePromptDisplay(); - } - }; - - function newLine() { - var lines = promptText.split("\n"); - var last_line = lines.slice(-1)[0]; - var spaces = last_line.match(/^(\s*)/g)[0]; - var new_line = "\n" + spaces; - promptText += new_line; - moveColumn(new_line.length); - updatePromptDisplay(); - }; - - //////////////////////////////////////////////////////////////////////// - // Validate command and trigger it if valid, or show a validation error - function commandTrigger() { - var line = promptText; - if (typeof config.commandValidate == 'function') { - var ret = config.commandValidate(line); - if (ret == true || ret == false) { - if (ret) { - handleCommand(); - } - } else { - commandResult(ret,"jquery-console-message-error"); - } - } else { - handleCommand(); - } - }; - - // Scroll to the bottom of the view - function scrollToBottom() { - var version = jQuery.fn.jquery.split('.'); - var major = parseInt(version[0]); - var minor = parseInt(version[1]); - - // check if we're using jquery > 1.6 - if ((major == 1 && minor > 6) || major > 1) { - inner.prop({ scrollTop: inner.prop("scrollHeight") }); - } - else { - inner.attr({ scrollTop: inner.attr("scrollHeight") }); - } - }; - - function cancelExecution() { - if(typeof config.cancelHandle == 'function') { - config.cancelHandle(); - } - } - - //////////////////////////////////////////////////////////////////////// - // Handle a command - function handleCommand() { - if (typeof config.commandHandle == 'function') { - disableInput(); - addToHistory(promptText); - var text = promptText; - if (extern.continuedPrompt) { - if (continuedText) - continuedText += '\n' + promptText; - else continuedText = promptText; - } else continuedText = undefined; - if (continuedText) text = continuedText; - var ret = config.commandHandle(text,function(msgs){ - commandResult(msgs); - }); - if (extern.continuedPrompt && !continuedText) - continuedText = promptText; - if (typeof ret == 'boolean') { - if (ret) { - // Command succeeded without a result. - commandResult(); - } else { - commandResult( - 'Command failed.', - "jquery-console-message-error" - ); - } - } else if (typeof ret == "string") { - commandResult(ret,"jquery-console-message-success"); - } else if (typeof ret == 'object' && ret.length) { - commandResult(ret); - } else if (extern.continuedPrompt) { - commandResult(); - } - } - }; - - //////////////////////////////////////////////////////////////////////// - // Disable input - function disableInput() { - acceptInput = false; - }; - - // Enable input - function enableInput() { - acceptInput = true; - } - - //////////////////////////////////////////////////////////////////////// - // Reset the prompt in invalid command - function commandResult(msg,className) { - column = -1; - updatePromptDisplay(); - if (typeof msg == 'string') { - message(msg,className); - } else if ($.isArray(msg)) { - for (var x in msg) { - var ret = msg[x]; - message(ret.msg,ret.className); - } - } else { // Assume it's a DOM node or jQuery object. - inner.append(msg); - } - newPromptBox(); - }; - - //////////////////////////////////////////////////////////////////////// - // Report some message into the console - function report(msg,className) { - var text = promptText; - promptBox.remove(); - commandResult(msg,className); - extern.promptText(text); - }; - - //////////////////////////////////////////////////////////////////////// - // Display a message - function message(msg,className) { - var mesg = $('
'); - if (className) mesg.addClass(className); - mesg.filledText(msg).hide(); - inner.append(mesg); - mesg.show(); - }; - - //////////////////////////////////////////////////////////////////////// - // Handle normal character insertion - // data can either be a number, which will be interpreted as the - // numeric value of a single character, or a string - typer.consoleInsert = function(data){ - // TODO: remove redundant indirection - var text = (typeof data == 'number') ? String.fromCharCode(data) : data; - var before = promptText.substring(0,column); - var after = promptText.substring(column); - promptText = before + text + after; - moveColumn(text.length); - restoreText = promptText; - updatePromptDisplay(); - }; - - //////////////////////////////////////////////////////////////////////// - // Move to another column relative to this one - // Negative means go back, positive means go forward. - function moveColumn(n){ - if (column + n >= 0 && column + n <= promptText.length){ - column += n; - return true; - } else return false; - }; - - function moveForward() { - if(moveColumn(1)) { - updatePromptDisplay(); - return true; - } - return false; - }; - - function moveBackward() { - if(moveColumn(-1)) { - updatePromptDisplay(); - return true; - } - return false; - }; - - function moveToStart() { - if (moveColumn(-column)) - updatePromptDisplay(); - }; - - function moveToEnd() { - if (moveColumn(promptText.length-column)) - updatePromptDisplay(); - }; - - function moveToNextWord() { - while( - column < promptText.length && - !isCharAlphanumeric(promptText[column]) && - moveForward() - ) {} - while( - column < promptText.length && - isCharAlphanumeric(promptText[column]) && - moveForward() - ) {} - }; - - function moveToPreviousWord() { - // Move backward until we find the first alphanumeric - while( - column -1 >= 0 && - !isCharAlphanumeric(promptText[column-1]) && - moveBackward() - ) {} - // Move until we find the first non-alphanumeric - while( - column -1 >= 0 && - isCharAlphanumeric(promptText[column-1]) && - moveBackward() - ) {} - }; - - function isCharAlphanumeric(charToTest) { - if(typeof charToTest == 'string') { - var code = charToTest.charCodeAt(); - return (code >= 'A'.charCodeAt() && code <= 'Z'.charCodeAt()) || - (code >= 'a'.charCodeAt() && code <= 'z'.charCodeAt()) || - (code >= '0'.charCodeAt() && code <= '9'.charCodeAt()); - } - return false; - }; - - function doComplete() { - if(typeof config.completeHandle == 'function') { - var completions = config.completeHandle(promptText); - var len = completions.length; - if (len === 1) { - extern.promptText(promptText + completions[0]); - } else if (len > 1 && config.cols) { - var prompt = promptText; - // Compute the number of rows that will fit in the width - var max = 0; - for (var i = 0;i < len;i++) { - max = Math.max(max, completions[i].length); - } - max += 2; - var n = Math.floor(config.cols / max); - var buffer = ""; - var col = 0; - for (i = 0;i < len;i++) { - var completion = completions[i]; - buffer += completions[i]; - for (var j = completion.length;j < max;j++) { - buffer += " "; - } - if (++col >= n) { - buffer += "\n"; - col = 0; - } - } - commandResult(buffer,"jquery-console-message-value"); - extern.promptText(prompt); - } - } - }; - - function doNothing() {}; - - extern.promptText = function(text){ - if (typeof text === 'string') { - promptText = text; - column = promptText.length; - updatePromptDisplay(); - } - return promptText; - }; - - //////////////////////////////////////////////////////////////////////// - // Update the prompt display - function updatePromptDisplay(){ - var line = promptText; - var html = ''; - if (column > 0 && line == ''){ - // When we have an empty line just display a cursor. - html = cursor; - } else if (column == promptText.length){ - // We're at the end of the line, so we need to display - // the text *and* cursor. - html = htmlEncode(line) + cursor; - } else { - // Grab the current character, if there is one, and - // make it the current cursor. - var before = line.substring(0, column); - var current = line.substring(column,column+1); - if (current){ - current = - '' + - htmlEncode(current) + - ''; - } - var after = line.substring(column+1); - html = htmlEncode(before) + current + htmlEncode(after); - } - prompt.html(html); - scrollToBottom(); - }; - - // Simple HTML encoding - // Simply replace '<', '>' and '&' - // TODO: Use jQuery's .html() trick, or grab a proper, fast - // HTML encoder. - function htmlEncode(text){ - return ( - text.replace(/&/g,'&') - .replace(/') - ); - }; - - return extern; - }; - // Simple utility for printing messages - $.fn.filledText = function(txt){ - $(this).text(txt); - $(this).html($(this).html().replace(/\n/g,'
')); - return this; - }; - - // Alternative method for focus without scrolling - $.fn.focusWithoutScrolling = function(){ - var x = window.scrollX, y = window.scrollY; - $(this).focus(); - window.scrollTo(x, y); - }; -})(jQuery); diff --git a/js/jquery/jquery.terminal-0.8.8.js b/js/jquery/jquery.terminal-0.8.8.js deleted file mode 100644 index 085317b..0000000 --- a/js/jquery/jquery.terminal-0.8.8.js +++ /dev/null @@ -1,4335 +0,0 @@ -/**@license - * __ _____ ________ __ - * / // _ /__ __ _____ ___ __ _/__ ___/__ ___ ______ __ __ __ ___ / / - * __ / // // // // // _ // _// // / / // _ // _// // // \/ // _ \/ / - * / / // // // // // ___// / / // / / // ___// / / / / // // /\ // // / /__ - * \___//____ \\___//____//_/ _\_ / /_//____//_/ /_/ /_//_//_/ /_/ \__\_\___/ - * \/ /____/ version 0.8.8 - * http://terminal.jcubic.pl - * - * Licensed under GNU LGPL Version 3 license - * Copyright (c) 2011-2013 Jakub Jankiewicz - * - * Includes: - * - * Storage plugin Distributed under the MIT License - * Copyright (c) 2010 Dave Schindler - * - * jQuery Timers licenced with the WTFPL - * - * - * Cross-Browser Split 1.1.1 - * Copyright 2007-2012 Steven Levithan - * Available under the MIT License - * - * sprintf.js - * Copyright (c) 2007-2013 Alexandru Marasteanu - * licensed under 3 clause BSD license - * - * Date: Thu, 10 Jul 2014 17:20:49 +0000 - * - */ - -(function(ctx) { - var sprintf = function() { - if (!sprintf.cache.hasOwnProperty(arguments[0])) { - sprintf.cache[arguments[0]] = sprintf.parse(arguments[0]); - } - return sprintf.format.call(null, sprintf.cache[arguments[0]], arguments); - }; - - sprintf.format = function(parse_tree, argv) { - var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length; - for (i = 0; i < tree_length; i++) { - node_type = get_type(parse_tree[i]); - if (node_type === 'string') { - output.push(parse_tree[i]); - } - else if (node_type === 'array') { - match = parse_tree[i]; // convenience purposes only - if (match[2]) { // keyword argument - arg = argv[cursor]; - for (k = 0; k < match[2].length; k++) { - if (!arg.hasOwnProperty(match[2][k])) { - throw(sprintf('[sprintf] property "%s" does not exist', match[2][k])); - } - arg = arg[match[2][k]]; - } - } - else if (match[1]) { // positional argument (explicit) - arg = argv[match[1]]; - } - else { // positional argument (implicit) - arg = argv[cursor++]; - } - - if (/[^s]/.test(match[8]) && (get_type(arg) != 'number')) { - throw(sprintf('[sprintf] expecting number but found %s', get_type(arg))); - } - switch (match[8]) { - case 'b': arg = arg.toString(2); break; - case 'c': arg = String.fromCharCode(arg); break; - case 'd': arg = parseInt(arg, 10); break; - case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break; - case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break; - case 'o': arg = arg.toString(8); break; - case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg); break; - case 'u': arg = arg >>> 0; break; - case 'x': arg = arg.toString(16); break; - case 'X': arg = arg.toString(16).toUpperCase(); break; - } - arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg); - pad_character = match[4] ? match[4] == '0' ? '0' : match[4].charAt(1) : ' '; - pad_length = match[6] - String(arg).length; - pad = match[6] ? str_repeat(pad_character, pad_length) : ''; - output.push(match[5] ? arg + pad : pad + arg); - } - } - return output.join(''); - }; - - sprintf.cache = {}; - - sprintf.parse = function(fmt) { - var _fmt = fmt, match = [], parse_tree = [], arg_names = 0; - while (_fmt) { - if ((match = /^[^\x25]+/.exec(_fmt)) !== null) { - parse_tree.push(match[0]); - } - else if ((match = /^\x25{2}/.exec(_fmt)) !== null) { - parse_tree.push('%'); - } - else if ((match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) { - if (match[2]) { - arg_names |= 1; - var field_list = [], replacement_field = match[2], field_match = []; - if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) { - field_list.push(field_match[1]); - while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') { - if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) { - field_list.push(field_match[1]); - } - else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) { - field_list.push(field_match[1]); - } - else { - throw('[sprintf] huh?'); - } - } - } - else { - throw('[sprintf] huh?'); - } - match[2] = field_list; - } - else { - arg_names |= 2; - } - if (arg_names === 3) { - throw('[sprintf] mixing positional and named placeholders is not (yet) supported'); - } - parse_tree.push(match); - } - else { - throw('[sprintf] huh?'); - } - _fmt = _fmt.substring(match[0].length); - } - return parse_tree; - }; - - var vsprintf = function(fmt, argv, _argv) { - _argv = argv.slice(0); - _argv.splice(0, 0, fmt); - return sprintf.apply(null, _argv); - }; - - /** - * helpers - */ - function get_type(variable) { - return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase(); - } - - function str_repeat(input, multiplier) { - for (var output = []; multiplier > 0; output[--multiplier] = input) {/* do nothing */} - return output.join(''); - } - - /** - * export to either browser or node.js - */ - ctx.sprintf = sprintf; - ctx.vsprintf = vsprintf; -})(typeof exports != "undefined" ? exports : window); - -(function($, undefined) { - "use strict"; - // ----------------------------------------------------------------------- - // :: map object to object - // ----------------------------------------------------------------------- - $.omap = function(o, fn) { - var result = {}; - $.each(o, function(k, v) { - result[k] = fn.call(o, k, v); - }); - return result; - }; - // ----------------------------------------------------------------------- - // :: Storage plugin - // ----------------------------------------------------------------------- - // Private data - var isLS = typeof window.localStorage !== 'undefined'; - // Private functions - function wls(n, v) { - var c; - if (typeof n === 'string' && typeof v === 'string') { - localStorage[n] = v; - return true; - } else if (typeof n === 'object' && typeof v === 'undefined') { - for (c in n) { - if (n.hasOwnProperty(c)) { - localStorage[c] = n[c]; - } - } - return true; - } - return false; - } - function wc(n, v) { - var dt, e, c; - dt = new Date(); - dt.setTime(dt.getTime() + 31536000000); - e = '; expires=' + dt.toGMTString(); - if (typeof n === 'string' && typeof v === 'string') { - document.cookie = n + '=' + v + e + '; path=/'; - return true; - } else if (typeof n === 'object' && typeof v === 'undefined') { - for (c in n) { - if (n.hasOwnProperty(c)) { - document.cookie = c + '=' + n[c] + e + '; path=/'; - } - } - return true; - } - return false; - } - function rls(n) { - return localStorage[n]; - } - function rc(n) { - var nn, ca, i, c; - nn = n + '='; - ca = document.cookie.split(';'); - for (i = 0; i < ca.length; i++) { - c = ca[i]; - while (c.charAt(0) === ' ') { - c = c.substring(1, c.length); - } - if (c.indexOf(nn) === 0) { - return c.substring(nn.length, c.length); - } - } - return null; - } - function dls(n) { - return delete localStorage[n]; - } - function dc(n) { - return wc(n, '', -1); - } - /** - * Public API - * $.Storage.set("name", "value") - * $.Storage.set({"name1":"value1", "name2":"value2", etc}) - * $.Storage.get("name") - * $.Storage.remove("name") - */ - $.extend({ - Storage: { - set: isLS ? wls : wc, - get: isLS ? rls : rc, - remove: isLS ? dls : dc - } - }); - // ----------------------------------------------------------------------- - // :: jQuery Timers - // ----------------------------------------------------------------------- - jQuery.fn.extend({ - everyTime: function(interval, label, fn, times, belay) { - return this.each(function() { - jQuery.timer.add(this, interval, label, fn, times, belay); - }); - }, - oneTime: function(interval, label, fn) { - return this.each(function() { - jQuery.timer.add(this, interval, label, fn, 1); - }); - }, - stopTime: function(label, fn) { - return this.each(function() { - jQuery.timer.remove(this, label, fn); - }); - } - }); - - jQuery.extend({ - timer: { - guid: 1, - global: {}, - regex: /^([0-9]+)\s*(.*s)?$/, - powers: { - // Yeah this is major overkill... - 'ms': 1, - 'cs': 10, - 'ds': 100, - 's': 1000, - 'das': 10000, - 'hs': 100000, - 'ks': 1000000 - }, - timeParse: function(value) { - if (value === undefined || value === null) { - return null; - } - var result = this.regex.exec(jQuery.trim(value.toString())); - if (result[2]) { - var num = parseInt(result[1], 10); - var mult = this.powers[result[2]] || 1; - return num * mult; - } else { - return value; - } - }, - add: function(element, interval, label, fn, times, belay) { - var counter = 0; - - if (jQuery.isFunction(label)) { - if (!times) { - times = fn; - } - fn = label; - label = interval; - } - - interval = jQuery.timer.timeParse(interval); - - if (typeof interval !== 'number' || - isNaN(interval) || - interval <= 0) { - return; - } - if (times && times.constructor !== Number) { - belay = !!times; - times = 0; - } - - times = times || 0; - belay = belay || false; - - if (!element.$timers) { - element.$timers = {}; - } - if (!element.$timers[label]) { - element.$timers[label] = {}; - } - fn.$timerID = fn.$timerID || this.guid++; - - var handler = function() { - if (belay && handler.inProgress) { - return; - } - handler.inProgress = true; - if ((++counter > times && times !== 0) || - fn.call(element, counter) === false) { - jQuery.timer.remove(element, label, fn); - } - handler.inProgress = false; - }; - - handler.$timerID = fn.$timerID; - - if (!element.$timers[label][fn.$timerID]) { - element.$timers[label][fn.$timerID] = window.setInterval(handler, interval); - } - - if (!this.global[label]) { - this.global[label] = []; - } - this.global[label].push(element); - - }, - remove: function(element, label, fn) { - var timers = element.$timers, ret; - - if (timers) { - - if (!label) { - for (var lab in timers) { - if (timers.hasOwnProperty(lab)) { - this.remove(element, lab, fn); - } - } - } else if (timers[label]) { - if (fn) { - if (fn.$timerID) { - window.clearInterval(timers[label][fn.$timerID]); - delete timers[label][fn.$timerID]; - } - } else { - for (var _fn in timers[label]) { - if (timers[label].hasOwnProperty(_fn)) { - window.clearInterval(timers[label][_fn]); - delete timers[label][_fn]; - } - } - } - - for (ret in timers[label]) { - if (timers[label].hasOwnProperty(ret)) { - break; - } - } - if (!ret) { - ret = null; - delete timers[label]; - } - } - - for (ret in timers) { - if (timers.hasOwnProperty(ret)) { - break; - } - } - if (!ret) { - element.$timers = null; - } - } - } - } - }); - - if (/(msie) ([\w.]+)/.exec(navigator.userAgent.toLowerCase())) { - jQuery(window).one('unload', function() { - var global = jQuery.timer.global; - for (var label in global) { - if (global.hasOwnProperty(label)) { - var els = global[label], i = els.length; - while (--i) { - jQuery.timer.remove(els[i], label); - } - } - } - }); - } - // ----------------------------------------------------------------------- - // :: CROSS BROWSER SPLIT - // ----------------------------------------------------------------------- - - (function(undef) { - - // prevent double include - - if (!String.prototype.split.toString().match(/\[native/)) { - return; - } - - var nativeSplit = String.prototype.split, - compliantExecNpcg = /()??/.exec("")[1] === undef, // NPCG: nonparticipating capturing group - self; - - self = function (str, separator, limit) { - // If `separator` is not a regex, use `nativeSplit` - if (Object.prototype.toString.call(separator) !== "[object RegExp]") { - return nativeSplit.call(str, separator, limit); - } - var output = [], - flags = (separator.ignoreCase ? "i" : "") + - (separator.multiline ? "m" : "") + - (separator.extended ? "x" : "") + // Proposed for ES6 - (separator.sticky ? "y" : ""), // Firefox 3+ - lastLastIndex = 0, - // Make `global` and avoid `lastIndex` issues by working with a copy - separator2, match, lastIndex, lastLength; - separator = new RegExp(separator.source, flags + "g"); - str += ""; // Type-convert - if (!compliantExecNpcg) { - // Doesn't need flags gy, but they don't hurt - separator2 = new RegExp("^" + separator.source + "$(?!\\s)", flags); - } - /* Values for `limit`, per the spec: - * If undefined: 4294967295 // Math.pow(2, 32) - 1 - * If 0, Infinity, or NaN: 0 - * If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296; - * If negative number: 4294967296 - Math.floor(Math.abs(limit)) - * If other: Type-convert, then use the above rules - */ - // ? Math.pow(2, 32) - 1 : ToUint32(limit) - limit = limit === undef ? -1 >>> 0 : limit >>> 0; - while (match = separator.exec(str)) { - // `separator.lastIndex` is not reliable cross-browser - lastIndex = match.index + match[0].length; - if (lastIndex > lastLastIndex) { - output.push(str.slice(lastLastIndex, match.index)); - // Fix browsers whose `exec` methods don't consistently return `undefined` for - // nonparticipating capturing groups - if (!compliantExecNpcg && match.length > 1) { - match[0].replace(separator2, function () { - for (var i = 1; i < arguments.length - 2; i++) { - if (arguments[i] === undef) { - match[i] = undef; - } - } - }); - } - if (match.length > 1 && match.index < str.length) { - Array.prototype.push.apply(output, match.slice(1)); - } - lastLength = match[0].length; - lastLastIndex = lastIndex; - if (output.length >= limit) { - break; - } - } - if (separator.lastIndex === match.index) { - separator.lastIndex++; // Avoid an infinite loop - } - } - if (lastLastIndex === str.length) { - if (lastLength || !separator.test("")) { - output.push(""); - } - } else { - output.push(str.slice(lastLastIndex)); - } - return output.length > limit ? output.slice(0, limit) : output; - }; - - // For convenience - String.prototype.split = function (separator, limit) { - return self(this, separator, limit); - }; - - return self; - - })(); - // ----------------------------------------------------------------------- - // :: Split string to array of strings with the same length - // ----------------------------------------------------------------------- - function str_parts(str, length) { - var result = []; - var len = str.length; - if (len < length) { - return [str]; - } - for (var i = 0; i < len; i += length) { - result.push(str.substring(i, i + length)); - } - return result; - } - // ----------------------------------------------------------------------- - // :: CYCLE DATA STRUCTURE - // ----------------------------------------------------------------------- - function Cycle(init) { - var data = init ? [init] : []; - var pos = 0; - $.extend(this, { - get: function() { - return data; - }, - rotate: function() { - if (data.length === 1) { - return data[0]; - } else { - if (pos === data.length - 1) { - pos = 0; - } else { - ++pos; - } - return data[pos]; - } - }, - length: function() { - return data.length; - }, - set: function(item) { - for (var i = data.length; i--;) { - if (data[i] === item) { - pos = i; - return; - } - } - this.append(item); - }, - front: function() { - return data[pos]; - }, - append: function(item) { - data.push(item); - } - }); - } - // ----------------------------------------------------------------------- - // :: STACK DATA STRUCTURE - // ----------------------------------------------------------------------- - function Stack(init) { - var data = init ? [init] : []; - $.extend(this, { - map: function(fn) { - return $.map(data, fn); - }, - size: function() { - return data.length; - }, - pop: function() { - if (data.length === 0) { - return null; - } else { - var value = data[data.length - 1]; - data = data.slice(0, data.length - 1); - return value; - } - }, - push: function(value) { - data = data.concat([value]); - return value; - }, - top: function() { - return data.length > 0 ? data[data.length - 1] : null; - } - }); - } - // ----------------------------------------------------------------------- - // :: Serialize object myself (biwascheme or prototype library do something - // :: wicked with JSON serialization for Arrays) - // ----------------------------------------------------------------------- - $.json_stringify = function(object, level) { - var result = '', i; - level = level === undefined ? 1 : level; - var type = typeof object; - switch (type) { - case 'function': - result += object; - break; - case 'boolean': - result += object ? 'true' : 'false'; - break; - case 'object': - if (object === null) { - result += 'null'; - } else if (object instanceof Array) { - result += '['; - var len = object.length; - for (i = 0; i < len - 1; ++i) { - result += $.json_stringify(object[i], level + 1); - } - result += $.json_stringify(object[len - 1], level + 1) + ']'; - } else { - result += '{'; - for (var property in object) { - if (object.hasOwnProperty(property)) { - result += '"' + property + '":' + - $.json_stringify(object[property], level + 1); - } - } - result += '}'; - } - break; - case 'string': - var str = object; - var repl = { - '\\\\': '\\\\', - '"': '\\"', - '/': '\\/', - '\\n': '\\n', - '\\r': '\\r', - '\\t': '\\t'}; - for (i in repl) { - if (repl.hasOwnProperty(i)) { - str = str.replace(new RegExp(i, 'g'), repl[i]); - } - } - result += '"' + str + '"'; - break; - case 'number': - result += String(object); - break; - } - result += (level > 1 ? ',' : ''); - // quick hacks below - if (level === 1) { - // fix last comma - result = result.replace(/,([\]}])/g, '$1'); - } - // fix comma before array or object - return result.replace(/([\[{]),/g, '$1'); - }; - // ----------------------------------------------------------------------- - // :: HISTORY CLASS - // ----------------------------------------------------------------------- - function History(name, size) { - var enabled = true; - var storage_key = ''; - if (typeof name === 'string' && name !== '') { - storage_key = name + '_'; - } - storage_key += 'commands'; - var data = $.Storage.get(storage_key); - data = data ? $.parseJSON(data) : []; - var pos = data.length-1; - $.extend(this, { - append: function(item) { - if (enabled) { - if (data[data.length-1] !== item) { - data.push(item); - if (size && data.length > size) { - data = data.slice(-size); - } - pos = data.length-1; - $.Storage.set(storage_key, $.json_stringify(data)); - } - } - }, - data: function() { - return data; - }, - reset: function() { - pos = data.length-1; - }, - last: function() { - return data[length-1]; - }, - end: function() { - return pos === data.length-1; - }, - position: function() { - return pos; - }, - current: function() { - return data[pos]; - }, - next: function() { - if (pos < data.length-1) { - ++pos; - } - if (pos !== -1) { - return data[pos]; - } - }, - previous: function() { - var old = pos; - if (pos > 0) { - --pos; - } - if (old !== -1) { - return data[pos]; - } - }, - clear: function() { - data = []; - this.purge(); - }, - enabled: function() { - return enabled; - }, - enable: function() { - enabled = true; - }, - purge: function() { - $.Storage.remove(storage_key); - }, - disable: function() { - enabled = false; - } - }); - } - // ----------------------------------------------------------------------- - // :: COMMAND LINE PLUGIN - // ----------------------------------------------------------------------- - $.fn.cmd = function(options) { - var self = this; - var maybe_data = self.data('cmd'); - if (maybe_data) { - return maybe_data; - } - self.addClass('cmd'); - self.append('' + - ' '); - var clip = $('