Files @ 9dd726706178
Branch filter:

Location: kallithea/rhodecode/public/js/mode/coffeescript/coffeescript.js - annotation

Bradley M. Kuhn
Complete copyright notices for web interface; change footer to link to them.

The original copyright notice found in the footer was not accurate as it
included only one of the many copyright holders in this project. This change
creates an "about" page, which currently contains just the copyright and
license information. It links to repository for additional potential copyright
holders not listed on the about page.

Unlisted contributors are mentioned in template comments.

Html links for Kallithea is fixed and we link to Conservancy.

Display of version information in the footer is improved.
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
bb9ef0638069
bb9ef0638069
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
/**
 * Link to the project's GitHub page:
 * https://github.com/pickhardt/coffeescript-codemirror-mode
 */
CodeMirror.defineMode('coffeescript', function(conf) {
    var ERRORCLASS = 'error';

    function wordRegexp(words) {
        return new RegExp("^((" + words.join(")|(") + "))\\b");
    }

    var singleOperators = new RegExp("^[\\+\\-\\*/%&|\\^~<>!\?]");
    var singleDelimiters = new RegExp('^[\\(\\)\\[\\]\\{\\},:`=;\\.]');
    var doubleOperators = new RegExp("^((\->)|(\=>)|(\\+\\+)|(\\+\\=)|(\\-\\-)|(\\-\\=)|(\\*\\*)|(\\*\\=)|(\\/\\/)|(\\/\\=)|(==)|(!=)|(<=)|(>=)|(<>)|(<<)|(>>)|(//))");
    var doubleDelimiters = new RegExp("^((\\.\\.)|(\\+=)|(\\-=)|(\\*=)|(%=)|(/=)|(&=)|(\\|=)|(\\^=))");
    var tripleDelimiters = new RegExp("^((\\.\\.\\.)|(//=)|(>>=)|(<<=)|(\\*\\*=))");
    var identifiers = new RegExp("^[_A-Za-z$][_A-Za-z$0-9]*");
    var properties = new RegExp("^(@|this\.)[_A-Za-z$][_A-Za-z$0-9]*");

    var wordOperators = wordRegexp(['and', 'or', 'not',
                                    'is', 'isnt', 'in',
                                    'instanceof', 'typeof']);
    var indentKeywords = ['for', 'while', 'loop', 'if', 'unless', 'else',
                          'switch', 'try', 'catch', 'finally', 'class'];
    var commonKeywords = ['break', 'by', 'continue', 'debugger', 'delete',
                          'do', 'in', 'of', 'new', 'return', 'then',
                          'this', 'throw', 'when', 'until'];

    var keywords = wordRegexp(indentKeywords.concat(commonKeywords));

    indentKeywords = wordRegexp(indentKeywords);


    var stringPrefixes = new RegExp("^('{3}|\"{3}|['\"])");
    var regexPrefixes = new RegExp("^(/{3}|/)");
    var commonConstants = ['Infinity', 'NaN', 'undefined', 'null', 'true', 'false', 'on', 'off', 'yes', 'no'];
    var constants = wordRegexp(commonConstants);

    // Tokenizers
    function tokenBase(stream, state) {
        // Handle scope changes
        if (stream.sol()) {
            var scopeOffset = state.scopes[0].offset;
            if (stream.eatSpace()) {
                var lineOffset = stream.indentation();
                if (lineOffset > scopeOffset) {
                    return 'indent';
                } else if (lineOffset < scopeOffset) {
                    return 'dedent';
                }
                return null;
            } else {
                if (scopeOffset > 0) {
                    dedent(stream, state);
                }
            }
        }
        if (stream.eatSpace()) {
            return null;
        }

        var ch = stream.peek();

        // Handle docco title comment (single line)
        if (stream.match("####")) {
            stream.skipToEnd();
            return 'comment';
        }

        // Handle multi line comments
        if (stream.match("###")) {
            state.tokenize = longComment;
            return state.tokenize(stream, state);
        }

        // Single line comment
        if (ch === '#') {
            stream.skipToEnd();
            return 'comment';
        }

        // Handle number literals
        if (stream.match(/^-?[0-9\.]/, false)) {
            var floatLiteral = false;
            // Floats
            if (stream.match(/^-?\d*\.\d+(e[\+\-]?\d+)?/i)) {
              floatLiteral = true;
            }
            if (stream.match(/^-?\d+\.\d*/)) {
              floatLiteral = true;
            }
            if (stream.match(/^-?\.\d+/)) {
              floatLiteral = true;
            }

            if (floatLiteral) {
                // prevent from getting extra . on 1..
                if (stream.peek() == "."){
                    stream.backUp(1);
                }
                return 'number';
            }
            // Integers
            var intLiteral = false;
            // Hex
            if (stream.match(/^-?0x[0-9a-f]+/i)) {
              intLiteral = true;
            }
            // Decimal
            if (stream.match(/^-?[1-9]\d*(e[\+\-]?\d+)?/)) {
                intLiteral = true;
            }
            // Zero by itself with no other piece of number.
            if (stream.match(/^-?0(?![\dx])/i)) {
              intLiteral = true;
            }
            if (intLiteral) {
                return 'number';
            }
        }

        // Handle strings
        if (stream.match(stringPrefixes)) {
            state.tokenize = tokenFactory(stream.current(), 'string');
            return state.tokenize(stream, state);
        }
        // Handle regex literals
        if (stream.match(regexPrefixes)) {
            if (stream.current() != '/' || stream.match(/^.*\//, false)) { // prevent highlight of division
                state.tokenize = tokenFactory(stream.current(), 'string-2');
                return state.tokenize(stream, state);
            } else {
                stream.backUp(1);
            }
        }

        // Handle operators and delimiters
        if (stream.match(tripleDelimiters) || stream.match(doubleDelimiters)) {
            return 'punctuation';
        }
        if (stream.match(doubleOperators)
            || stream.match(singleOperators)
            || stream.match(wordOperators)) {
            return 'operator';
        }
        if (stream.match(singleDelimiters)) {
            return 'punctuation';
        }

        if (stream.match(constants)) {
            return 'atom';
        }

        if (stream.match(keywords)) {
            return 'keyword';
        }

        if (stream.match(identifiers)) {
            return 'variable';
        }

        if (stream.match(properties)) {
            return 'property';
        }

        // Handle non-detected items
        stream.next();
        return ERRORCLASS;
    }

    function tokenFactory(delimiter, outclass) {
        var singleline = delimiter.length == 1;
        return function(stream, state) {
            while (!stream.eol()) {
                stream.eatWhile(/[^'"\/\\]/);
                if (stream.eat('\\')) {
                    stream.next();
                    if (singleline && stream.eol()) {
                        return outclass;
                    }
                } else if (stream.match(delimiter)) {
                    state.tokenize = tokenBase;
                    return outclass;
                } else {
                    stream.eat(/['"\/]/);
                }
            }
            if (singleline) {
                if (conf.mode.singleLineStringErrors) {
                    outclass = ERRORCLASS;
                } else {
                    state.tokenize = tokenBase;
                }
            }
            return outclass;
        };
    }

    function longComment(stream, state) {
        while (!stream.eol()) {
            stream.eatWhile(/[^#]/);
            if (stream.match("###")) {
                state.tokenize = tokenBase;
                break;
            }
            stream.eatWhile("#");
        }
        return "comment";
    }

    function indent(stream, state, type) {
        type = type || 'coffee';
        var indentUnit = 0;
        if (type === 'coffee') {
            for (var i = 0; i < state.scopes.length; i++) {
                if (state.scopes[i].type === 'coffee') {
                    indentUnit = state.scopes[i].offset + conf.indentUnit;
                    break;
                }
            }
        } else {
            indentUnit = stream.column() + stream.current().length;
        }
        state.scopes.unshift({
            offset: indentUnit,
            type: type
        });
    }

    function dedent(stream, state) {
        if (state.scopes.length == 1) return;
        if (state.scopes[0].type === 'coffee') {
            var _indent = stream.indentation();
            var _indent_index = -1;
            for (var i = 0; i < state.scopes.length; ++i) {
                if (_indent === state.scopes[i].offset) {
                    _indent_index = i;
                    break;
                }
            }
            if (_indent_index === -1) {
                return true;
            }
            while (state.scopes[0].offset !== _indent) {
                state.scopes.shift();
            }
            return false;
        } else {
            state.scopes.shift();
            return false;
        }
    }

    function tokenLexer(stream, state) {
        var style = state.tokenize(stream, state);
        var current = stream.current();

        // Handle '.' connected identifiers
        if (current === '.') {
            style = state.tokenize(stream, state);
            current = stream.current();
            if (style === 'variable') {
                return 'variable';
            } else {
                return ERRORCLASS;
            }
        }

        // Handle scope changes.
        if (current === 'return') {
            state.dedent += 1;
        }
        if (((current === '->' || current === '=>') &&
                  !state.lambda &&
                  state.scopes[0].type == 'coffee' &&
                  stream.peek() === '')
               || style === 'indent') {
            indent(stream, state);
        }
        var delimiter_index = '[({'.indexOf(current);
        if (delimiter_index !== -1) {
            indent(stream, state, '])}'.slice(delimiter_index, delimiter_index+1));
        }
        if (indentKeywords.exec(current)){
            indent(stream, state);
        }
        if (current == 'then'){
            dedent(stream, state);
        }


        if (style === 'dedent') {
            if (dedent(stream, state)) {
                return ERRORCLASS;
            }
        }
        delimiter_index = '])}'.indexOf(current);
        if (delimiter_index !== -1) {
            if (dedent(stream, state)) {
                return ERRORCLASS;
            }
        }
        if (state.dedent > 0 && stream.eol() && state.scopes[0].type == 'coffee') {
            if (state.scopes.length > 1) state.scopes.shift();
            state.dedent -= 1;
        }

        return style;
    }

    var external = {
        startState: function(basecolumn) {
            return {
              tokenize: tokenBase,
              scopes: [{offset:basecolumn || 0, type:'coffee'}],
              lastToken: null,
              lambda: false,
              dedent: 0
          };
        },

        token: function(stream, state) {
            var style = tokenLexer(stream, state);

            state.lastToken = {style:style, content: stream.current()};

            if (stream.eol() && stream.lambda) {
                state.lambda = false;
            }

            return style;
        },

        indent: function(state) {
            if (state.tokenize != tokenBase) {
                return 0;
            }

            return state.scopes[0].offset;
        },

        lineComment: "#",
        fold: "indent"
    };
    return external;
});

CodeMirror.defineMIME('text/x-coffeescript', 'coffeescript');