Files @ ad49bbd8f984
Branch filter:

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

Bradley M. Kuhn
changelog - should refer to Mercurial repository logs instead
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
bb9ef0638069
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
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
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
bb9ef0638069
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
bb9ef0638069
bb9ef0638069
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
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
bb9ef0638069
bb9ef0638069
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
bb9ef0638069
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
bb9ef0638069
bb9ef0638069
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
a60a0e9092c6
CodeMirror.defineMode("xml", function(config, parserConfig) {
  var indentUnit = config.indentUnit;
  var multilineTagIndentFactor = parserConfig.multilineTagIndentFactor || 1;
  var multilineTagIndentPastTag = parserConfig.multilineTagIndentPastTag || true;

  var Kludges = parserConfig.htmlMode ? {
    autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true,
                      'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true,
                      'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true,
                      'track': true, 'wbr': true},
    implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true,
                       'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true,
                       'th': true, 'tr': true},
    contextGrabbers: {
      'dd': {'dd': true, 'dt': true},
      'dt': {'dd': true, 'dt': true},
      'li': {'li': true},
      'option': {'option': true, 'optgroup': true},
      'optgroup': {'optgroup': true},
      'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true,
            'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true,
            'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true,
            'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true,
            'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true},
      'rp': {'rp': true, 'rt': true},
      'rt': {'rp': true, 'rt': true},
      'tbody': {'tbody': true, 'tfoot': true},
      'td': {'td': true, 'th': true},
      'tfoot': {'tbody': true},
      'th': {'td': true, 'th': true},
      'thead': {'tbody': true, 'tfoot': true},
      'tr': {'tr': true}
    },
    doNotIndent: {"pre": true},
    allowUnquoted: true,
    allowMissing: true
  } : {
    autoSelfClosers: {},
    implicitlyClosed: {},
    contextGrabbers: {},
    doNotIndent: {},
    allowUnquoted: false,
    allowMissing: false
  };
  var alignCDATA = parserConfig.alignCDATA;

  // Return variables for tokenizers
  var tagName, type;

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

    var ch = stream.next();
    if (ch == "<") {
      if (stream.eat("!")) {
        if (stream.eat("[")) {
          if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>"));
          else return null;
        } else if (stream.match("--")) {
          return chain(inBlock("comment", "-->"));
        } else if (stream.match("DOCTYPE", true, true)) {
          stream.eatWhile(/[\w\._\-]/);
          return chain(doctype(1));
        } else {
          return null;
        }
      } else if (stream.eat("?")) {
        stream.eatWhile(/[\w\._\-]/);
        state.tokenize = inBlock("meta", "?>");
        return "meta";
      } else {
        var isClose = stream.eat("/");
        tagName = "";
        var c;
        while ((c = stream.eat(/[^\s\u00a0=<>\"\'\/?]/))) tagName += c;
        if (!tagName) return "error";
        type = isClose ? "closeTag" : "openTag";
        state.tokenize = inTag;
        return "tag";
      }
    } else if (ch == "&") {
      var ok;
      if (stream.eat("#")) {
        if (stream.eat("x")) {
          ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";");
        } else {
          ok = stream.eatWhile(/[\d]/) && stream.eat(";");
        }
      } else {
        ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";");
      }
      return ok ? "atom" : "error";
    } else {
      stream.eatWhile(/[^&<]/);
      return null;
    }
  }

  function inTag(stream, state) {
    var ch = stream.next();
    if (ch == ">" || (ch == "/" && stream.eat(">"))) {
      state.tokenize = inText;
      type = ch == ">" ? "endTag" : "selfcloseTag";
      return "tag";
    } else if (ch == "=") {
      type = "equals";
      return null;
    } else if (ch == "<") {
      return "error";
    } else if (/[\'\"]/.test(ch)) {
      state.tokenize = inAttribute(ch);
      state.stringStartCol = stream.column();
      return state.tokenize(stream, state);
    } else {
      stream.eatWhile(/[^\s\u00a0=<>\"\']/);
      return "word";
    }
  }

  function inAttribute(quote) {
    var closure = function(stream, state) {
      while (!stream.eol()) {
        if (stream.next() == quote) {
          state.tokenize = inTag;
          break;
        }
      }
      return "string";
    };
    closure.isInAttribute = true;
    return closure;
  }

  function inBlock(style, terminator) {
    return function(stream, state) {
      while (!stream.eol()) {
        if (stream.match(terminator)) {
          state.tokenize = inText;
          break;
        }
        stream.next();
      }
      return style;
    };
  }
  function doctype(depth) {
    return function(stream, state) {
      var ch;
      while ((ch = stream.next()) != null) {
        if (ch == "<") {
          state.tokenize = doctype(depth + 1);
          return state.tokenize(stream, state);
        } else if (ch == ">") {
          if (depth == 1) {
            state.tokenize = inText;
            break;
          } else {
            state.tokenize = doctype(depth - 1);
            return state.tokenize(stream, state);
          }
        }
      }
      return "meta";
    };
  }

  var curState, curStream, setStyle;
  function pass() {
    for (var i = arguments.length - 1; i >= 0; i--) curState.cc.push(arguments[i]);
  }
  function cont() {
    pass.apply(null, arguments);
    return true;
  }

  function pushContext(tagName, startOfLine) {
    var noIndent = Kludges.doNotIndent.hasOwnProperty(tagName) || (curState.context && curState.context.noIndent);
    curState.context = {
      prev: curState.context,
      tagName: tagName,
      indent: curState.indented,
      startOfLine: startOfLine,
      noIndent: noIndent
    };
  }
  function popContext() {
    if (curState.context) curState.context = curState.context.prev;
  }

  function element(type) {
    if (type == "openTag") {
      curState.tagName = tagName;
      curState.tagStart = curStream.column();
      return cont(attributes, endtag(curState.startOfLine));
    } else if (type == "closeTag") {
      var err = false;
      if (curState.context) {
        if (curState.context.tagName != tagName) {
          if (Kludges.implicitlyClosed.hasOwnProperty(curState.context.tagName.toLowerCase())) {
            popContext();
          }
          err = !curState.context || curState.context.tagName != tagName;
        }
      } else {
        err = true;
      }
      if (err) setStyle = "error";
      return cont(endclosetag(err));
    }
    return cont();
  }
  function endtag(startOfLine) {
    return function(type) {
      var tagName = curState.tagName;
      curState.tagName = curState.tagStart = null;
      if (type == "selfcloseTag" ||
          (type == "endTag" && Kludges.autoSelfClosers.hasOwnProperty(tagName.toLowerCase()))) {
        maybePopContext(tagName.toLowerCase());
        return cont();
      }
      if (type == "endTag") {
        maybePopContext(tagName.toLowerCase());
        pushContext(tagName, startOfLine);
        return cont();
      }
      return cont();
    };
  }
  function endclosetag(err) {
    return function(type) {
      if (err) setStyle = "error";
      if (type == "endTag") { popContext(); return cont(); }
      setStyle = "error";
      return cont(arguments.callee);
    };
  }
  function maybePopContext(nextTagName) {
    var parentTagName;
    while (true) {
      if (!curState.context) {
        return;
      }
      parentTagName = curState.context.tagName.toLowerCase();
      if (!Kludges.contextGrabbers.hasOwnProperty(parentTagName) ||
          !Kludges.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) {
        return;
      }
      popContext();
    }
  }

  function attributes(type) {
    if (type == "word") {setStyle = "attribute"; return cont(attribute, attributes);}
    if (type == "endTag" || type == "selfcloseTag") return pass();
    setStyle = "error";
    return cont(attributes);
  }
  function attribute(type) {
    if (type == "equals") return cont(attvalue, attributes);
    if (!Kludges.allowMissing) setStyle = "error";
    else if (type == "word") setStyle = "attribute";
    return (type == "endTag" || type == "selfcloseTag") ? pass() : cont();
  }
  function attvalue(type) {
    if (type == "string") return cont(attvaluemaybe);
    if (type == "word" && Kludges.allowUnquoted) {setStyle = "string"; return cont();}
    setStyle = "error";
    return (type == "endTag" || type == "selfCloseTag") ? pass() : cont();
  }
  function attvaluemaybe(type) {
    if (type == "string") return cont(attvaluemaybe);
    else return pass();
  }

  return {
    startState: function() {
      return {tokenize: inText, cc: [], indented: 0, startOfLine: true, tagName: null, tagStart: null, context: null};
    },

    token: function(stream, state) {
      if (!state.tagName && stream.sol()) {
        state.startOfLine = true;
        state.indented = stream.indentation();
      }
      if (stream.eatSpace()) return null;

      setStyle = type = tagName = null;
      var style = state.tokenize(stream, state);
      state.type = type;
      if ((style || type) && style != "comment") {
        curState = state; curStream = stream;
        while (true) {
          var comb = state.cc.pop() || element;
          if (comb(type || style)) break;
        }
      }
      state.startOfLine = false;
      return setStyle || style;
    },

    indent: function(state, textAfter, fullLine) {
      var context = state.context;
      // Indent multi-line strings (e.g. css).
      if (state.tokenize.isInAttribute) {
        return state.stringStartCol + 1;
      }
      if ((state.tokenize != inTag && state.tokenize != inText) ||
          context && context.noIndent)
        return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0;
      // Indent the starts of attribute names.
      if (state.tagName) {
        if (multilineTagIndentPastTag)
          return state.tagStart + state.tagName.length + 2;
        else
          return state.tagStart + indentUnit * multilineTagIndentFactor;
      }
      if (alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0;
      if (context && /^<\//.test(textAfter))
        context = context.prev;
      while (context && !context.startOfLine)
        context = context.prev;
      if (context) return context.indent + indentUnit;
      else return 0;
    },

    electricChars: "/",
    blockCommentStart: "<!--",
    blockCommentEnd: "-->",

    configuration: parserConfig.htmlMode ? "html" : "xml",
    helperType: parserConfig.htmlMode ? "html" : "xml"
  };
});

CodeMirror.defineMIME("text/xml", "xml");
CodeMirror.defineMIME("application/xml", "xml");
if (!CodeMirror.mimeModes.hasOwnProperty("text/html"))
  CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true});