Files @ 211ded263da9
Branch filter:

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

Mads Kiilerich
rhodecode.js: show/hide set_mode_header like filename_container in initCodeMirror file_enable and upload_file_enable
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
/**
* @file smartymixed.js
* @brief Smarty Mixed Codemirror mode (Smarty + Mixed HTML)
* @author Ruslan Osmanov <rrosmanov at gmail dot com>
* @version 3.0
* @date 05.07.2013
*/
CodeMirror.defineMode("smartymixed", function(config) {
  var settings, regs, helpers, parsers,
  htmlMixedMode = CodeMirror.getMode(config, "htmlmixed"),
  smartyMode = CodeMirror.getMode(config, "smarty"),

  settings = {
    rightDelimiter: '}',
    leftDelimiter: '{'
  };

  if (config.hasOwnProperty("leftDelimiter")) {
    settings.leftDelimiter = config.leftDelimiter;
  }
  if (config.hasOwnProperty("rightDelimiter")) {
    settings.rightDelimiter = config.rightDelimiter;
  }

  regs = {
    smartyComment: new RegExp("^" + settings.leftDelimiter + "\\*"),
    literalOpen: new RegExp(settings.leftDelimiter + "literal" + settings.rightDelimiter),
    literalClose: new RegExp(settings.leftDelimiter + "\/literal" + settings.rightDelimiter),
    hasLeftDelimeter: new RegExp(".*" + settings.leftDelimiter),
    htmlHasLeftDelimeter: new RegExp("[^<>]*" + settings.leftDelimiter)
  };

  helpers = {
    chain: function(stream, state, parser) {
      state.tokenize = parser;
      return parser(stream, state);
    },

    cleanChain: function(stream, state, parser) {
      state.tokenize = null;
      state.localState = null;
      state.localMode = null;
      return (typeof parser == "string") ? (parser ? parser : null) : parser(stream, state);
    },

    maybeBackup: function(stream, pat, style) {
      var cur = stream.current();
      var close = cur.search(pat),
      m;
      if (close > - 1) stream.backUp(cur.length - close);
      else if (m = cur.match(/<\/?$/)) {
        stream.backUp(cur.length);
        if (!stream.match(pat, false)) stream.match(cur[0]);
      }
      return style;
    }
  };

  parsers = {
    html: function(stream, state) {
      if (!state.inLiteral && stream.match(regs.htmlHasLeftDelimeter, false)) {
        state.tokenize = parsers.smarty;
        state.localMode = smartyMode;
        state.localState = smartyMode.startState(htmlMixedMode.indent(state.htmlMixedState, ""));
        return helpers.maybeBackup(stream, settings.leftDelimiter, smartyMode.token(stream, state.localState));
      }
      return htmlMixedMode.token(stream, state.htmlMixedState);
    },

    smarty: function(stream, state) {
      if (stream.match(settings.leftDelimiter, false)) {
        if (stream.match(regs.smartyComment, false)) {
          return helpers.chain(stream, state, parsers.inBlock("comment", "*" + settings.rightDelimiter));
        }
      } else if (stream.match(settings.rightDelimiter, false)) {
        stream.eat(settings.rightDelimiter);
        state.tokenize = parsers.html;
        state.localMode = htmlMixedMode;
        state.localState = state.htmlMixedState;
        return "tag";
      }

      return helpers.maybeBackup(stream, settings.rightDelimiter, smartyMode.token(stream, state.localState));
    },

    inBlock: function(style, terminator) {
      return function(stream, state) {
        while (!stream.eol()) {
          if (stream.match(terminator)) {
            helpers.cleanChain(stream, state, "");
            break;
          }
          stream.next();
        }
        return style;
      };
    }
  };

  return {
    startState: function() {
      var state = htmlMixedMode.startState();
      return {
        token: parsers.html,
        localMode: null,
        localState: null,
        htmlMixedState: state,
        tokenize: null,
        inLiteral: false
      };
    },

    copyState: function(state) {
      var local = null, tok = (state.tokenize || state.token);
      if (state.localState) {
        local = CodeMirror.copyState((tok != parsers.html ? smartyMode : htmlMixedMode), state.localState);
      }
      return {
        token: state.token,
        tokenize: state.tokenize,
        localMode: state.localMode,
        localState: local,
        htmlMixedState: CodeMirror.copyState(htmlMixedMode, state.htmlMixedState),
        inLiteral: state.inLiteral
      };
    },

    token: function(stream, state) {
      if (stream.match(settings.leftDelimiter, false)) {
        if (!state.inLiteral && stream.match(regs.literalOpen, true)) {
          state.inLiteral = true;
          return "keyword";
        } else if (state.inLiteral && stream.match(regs.literalClose, true)) {
          state.inLiteral = false;
          return "keyword";
        }
      }
      if (state.inLiteral && state.localState != state.htmlMixedState) {
        state.tokenize = parsers.html;
        state.localMode = htmlMixedMode;
        state.localState = state.htmlMixedState;
      }

      var style = (state.tokenize || state.token)(stream, state);
      return style;
    },

    indent: function(state, textAfter) {
      if (state.localMode == smartyMode
          || (state.inLiteral && !state.localMode)
         || regs.hasLeftDelimeter.test(textAfter)) {
        return CodeMirror.Pass;
      }
      return htmlMixedMode.indent(state.htmlMixedState, textAfter);
    },

    electricChars: "/{}:",

    innerMode: function(state) {
      return {
        state: state.localState || state.htmlMixedState,
        mode: state.localMode || htmlMixedMode
      };
    }
  };
},
"htmlmixed");

CodeMirror.defineMIME("text/x-smarty", "smartymixed");
// vim: et ts=2 sts=2 sw=2