Files @ a991e5c57a8d
Branch filter:

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

Andrew Shadura
rhodecode.js: Get rid of some more YUI
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