[ Index ]

PHP Cross Reference of MyBB 1.8.38

title

Body

[close]

/admin/jscripts/codemirror/mode/xml/ -> xml.js (source)

   1  // CodeMirror, copyright (c) by Marijn Haverbeke and others
   2  // Distributed under an MIT license: http://codemirror.net/LICENSE
   3  
   4  (function(mod) {
   5    if (typeof exports == "object" && typeof module == "object") // CommonJS
   6      mod(require("../../lib/codemirror"));
   7    else if (typeof define == "function" && define.amd) // AMD
   8      define(["../../lib/codemirror"], mod);
   9    else // Plain browser env
  10      mod(CodeMirror);
  11  })(function(CodeMirror) {
  12  "use strict";
  13  
  14  var htmlConfig = {
  15    autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true,
  16                      'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true,
  17                      'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true,
  18                      'track': true, 'wbr': true, 'menuitem': true},
  19    implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true,
  20                       'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true,
  21                       'th': true, 'tr': true},
  22    contextGrabbers: {
  23      'dd': {'dd': true, 'dt': true},
  24      'dt': {'dd': true, 'dt': true},
  25      'li': {'li': true},
  26      'option': {'option': true, 'optgroup': true},
  27      'optgroup': {'optgroup': true},
  28      'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true,
  29            'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true,
  30            'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true,
  31            'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true,
  32            'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true},
  33      'rp': {'rp': true, 'rt': true},
  34      'rt': {'rp': true, 'rt': true},
  35      'tbody': {'tbody': true, 'tfoot': true},
  36      'td': {'td': true, 'th': true},
  37      'tfoot': {'tbody': true},
  38      'th': {'td': true, 'th': true},
  39      'thead': {'tbody': true, 'tfoot': true},
  40      'tr': {'tr': true}
  41    },
  42    doNotIndent: {"pre": true},
  43    allowUnquoted: true,
  44    allowMissing: true,
  45    caseFold: true
  46  }
  47  
  48  var xmlConfig = {
  49    autoSelfClosers: {},
  50    implicitlyClosed: {},
  51    contextGrabbers: {},
  52    doNotIndent: {},
  53    allowUnquoted: false,
  54    allowMissing: false,
  55    caseFold: false
  56  }
  57  
  58  CodeMirror.defineMode("xml", function(editorConf, config_) {
  59    var indentUnit = editorConf.indentUnit
  60    var config = {}
  61    var defaults = config_.htmlMode ? htmlConfig : xmlConfig
  62    for (var prop in defaults) config[prop] = defaults[prop]
  63    for (var prop in config_) config[prop] = config_[prop]
  64  
  65    // Return variables for tokenizers
  66    var type, setStyle;
  67  
  68    function inText(stream, state) {
  69      function chain(parser) {
  70        state.tokenize = parser;
  71        return parser(stream, state);
  72      }
  73  
  74      var ch = stream.next();
  75      if (ch == "<") {
  76        if (stream.eat("!")) {
  77          if (stream.eat("[")) {
  78            if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>"));
  79            else return null;
  80          } else if (stream.match("--")) {
  81            return chain(inBlock("comment", "-->"));
  82          } else if (stream.match("DOCTYPE", true, true)) {
  83            stream.eatWhile(/[\w\._\-]/);
  84            return chain(doctype(1));
  85          } else {
  86            return null;
  87          }
  88        } else if (stream.eat("?")) {
  89          stream.eatWhile(/[\w\._\-]/);
  90          state.tokenize = inBlock("meta", "?>");
  91          return "meta";
  92        } else {
  93          type = stream.eat("/") ? "closeTag" : "openTag";
  94          state.tokenize = inTag;
  95          return "tag bracket";
  96        }
  97      } else if (ch == "&") {
  98        var ok;
  99        if (stream.eat("#")) {
 100          if (stream.eat("x")) {
 101            ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";");
 102          } else {
 103            ok = stream.eatWhile(/[\d]/) && stream.eat(";");
 104          }
 105        } else {
 106          ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";");
 107        }
 108        return ok ? "atom" : "error";
 109      } else {
 110        stream.eatWhile(/[^&<]/);
 111        return null;
 112      }
 113    }
 114    inText.isInText = true;
 115  
 116    function inTag(stream, state) {
 117      var ch = stream.next();
 118      if (ch == ">" || (ch == "/" && stream.eat(">"))) {
 119        state.tokenize = inText;
 120        type = ch == ">" ? "endTag" : "selfcloseTag";
 121        return "tag bracket";
 122      } else if (ch == "=") {
 123        type = "equals";
 124        return null;
 125      } else if (ch == "<") {
 126        state.tokenize = inText;
 127        state.state = baseState;
 128        state.tagName = state.tagStart = null;
 129        var next = state.tokenize(stream, state);
 130        return next ? next + " tag error" : "tag error";
 131      } else if (/[\'\"]/.test(ch)) {
 132        state.tokenize = inAttribute(ch);
 133        state.stringStartCol = stream.column();
 134        return state.tokenize(stream, state);
 135      } else {
 136        stream.match(/^[^\s\u00a0=<>\"\']*[^\s\u00a0=<>\"\'\/]/);
 137        return "word";
 138      }
 139    }
 140  
 141    function inAttribute(quote) {
 142      var closure = function(stream, state) {
 143        while (!stream.eol()) {
 144          if (stream.next() == quote) {
 145            state.tokenize = inTag;
 146            break;
 147          }
 148        }
 149        return "string";
 150      };
 151      closure.isInAttribute = true;
 152      return closure;
 153    }
 154  
 155    function inBlock(style, terminator) {
 156      return function(stream, state) {
 157        while (!stream.eol()) {
 158          if (stream.match(terminator)) {
 159            state.tokenize = inText;
 160            break;
 161          }
 162          stream.next();
 163        }
 164        return style;
 165      };
 166    }
 167    function doctype(depth) {
 168      return function(stream, state) {
 169        var ch;
 170        while ((ch = stream.next()) != null) {
 171          if (ch == "<") {
 172            state.tokenize = doctype(depth + 1);
 173            return state.tokenize(stream, state);
 174          } else if (ch == ">") {
 175            if (depth == 1) {
 176              state.tokenize = inText;
 177              break;
 178            } else {
 179              state.tokenize = doctype(depth - 1);
 180              return state.tokenize(stream, state);
 181            }
 182          }
 183        }
 184        return "meta";
 185      };
 186    }
 187  
 188    function Context(state, tagName, startOfLine) {
 189      this.prev = state.context;
 190      this.tagName = tagName;
 191      this.indent = state.indented;
 192      this.startOfLine = startOfLine;
 193      if (config.doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.noIndent))
 194        this.noIndent = true;
 195    }
 196    function popContext(state) {
 197      if (state.context) state.context = state.context.prev;
 198    }
 199    function maybePopContext(state, nextTagName) {
 200      var parentTagName;
 201      while (true) {
 202        if (!state.context) {
 203          return;
 204        }
 205        parentTagName = state.context.tagName;
 206        if (!config.contextGrabbers.hasOwnProperty(parentTagName) ||
 207            !config.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) {
 208          return;
 209        }
 210        popContext(state);
 211      }
 212    }
 213  
 214    function baseState(type, stream, state) {
 215      if (type == "openTag") {
 216        state.tagStart = stream.column();
 217        return tagNameState;
 218      } else if (type == "closeTag") {
 219        return closeTagNameState;
 220      } else {
 221        return baseState;
 222      }
 223    }
 224    function tagNameState(type, stream, state) {
 225      if (type == "word") {
 226        state.tagName = stream.current();
 227        setStyle = "tag";
 228        return attrState;
 229      } else {
 230        setStyle = "error";
 231        return tagNameState;
 232      }
 233    }
 234    function closeTagNameState(type, stream, state) {
 235      if (type == "word") {
 236        var tagName = stream.current();
 237        if (state.context && state.context.tagName != tagName &&
 238            config.implicitlyClosed.hasOwnProperty(state.context.tagName))
 239          popContext(state);
 240        if ((state.context && state.context.tagName == tagName) || config.matchClosing === false) {
 241          setStyle = "tag";
 242          return closeState;
 243        } else {
 244          setStyle = "tag error";
 245          return closeStateErr;
 246        }
 247      } else {
 248        setStyle = "error";
 249        return closeStateErr;
 250      }
 251    }
 252  
 253    function closeState(type, _stream, state) {
 254      if (type != "endTag") {
 255        setStyle = "error";
 256        return closeState;
 257      }
 258      popContext(state);
 259      return baseState;
 260    }
 261    function closeStateErr(type, stream, state) {
 262      setStyle = "error";
 263      return closeState(type, stream, state);
 264    }
 265  
 266    function attrState(type, _stream, state) {
 267      if (type == "word") {
 268        setStyle = "attribute";
 269        return attrEqState;
 270      } else if (type == "endTag" || type == "selfcloseTag") {
 271        var tagName = state.tagName, tagStart = state.tagStart;
 272        state.tagName = state.tagStart = null;
 273        if (type == "selfcloseTag" ||
 274            config.autoSelfClosers.hasOwnProperty(tagName)) {
 275          maybePopContext(state, tagName);
 276        } else {
 277          maybePopContext(state, tagName);
 278          state.context = new Context(state, tagName, tagStart == state.indented);
 279        }
 280        return baseState;
 281      }
 282      setStyle = "error";
 283      return attrState;
 284    }
 285    function attrEqState(type, stream, state) {
 286      if (type == "equals") return attrValueState;
 287      if (!config.allowMissing) setStyle = "error";
 288      return attrState(type, stream, state);
 289    }
 290    function attrValueState(type, stream, state) {
 291      if (type == "string") return attrContinuedState;
 292      if (type == "word" && config.allowUnquoted) {setStyle = "string"; return attrState;}
 293      setStyle = "error";
 294      return attrState(type, stream, state);
 295    }
 296    function attrContinuedState(type, stream, state) {
 297      if (type == "string") return attrContinuedState;
 298      return attrState(type, stream, state);
 299    }
 300  
 301    return {
 302      startState: function(baseIndent) {
 303        var state = {tokenize: inText,
 304                     state: baseState,
 305                     indented: baseIndent || 0,
 306                     tagName: null, tagStart: null,
 307                     context: null}
 308        if (baseIndent != null) state.baseIndent = baseIndent
 309        return state
 310      },
 311  
 312      token: function(stream, state) {
 313        if (!state.tagName && stream.sol())
 314          state.indented = stream.indentation();
 315  
 316        if (stream.eatSpace()) return null;
 317        type = null;
 318        var style = state.tokenize(stream, state);
 319        if ((style || type) && style != "comment") {
 320          setStyle = null;
 321          state.state = state.state(type || style, stream, state);
 322          if (setStyle)
 323            style = setStyle == "error" ? style + " error" : setStyle;
 324        }
 325        return style;
 326      },
 327  
 328      indent: function(state, textAfter, fullLine) {
 329        var context = state.context;
 330        // Indent multi-line strings (e.g. css).
 331        if (state.tokenize.isInAttribute) {
 332          if (state.tagStart == state.indented)
 333            return state.stringStartCol + 1;
 334          else
 335            return state.indented + indentUnit;
 336        }
 337        if (context && context.noIndent) return CodeMirror.Pass;
 338        if (state.tokenize != inTag && state.tokenize != inText)
 339          return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0;
 340        // Indent the starts of attribute names.
 341        if (state.tagName) {
 342          if (config.multilineTagIndentPastTag !== false)
 343            return state.tagStart + state.tagName.length + 2;
 344          else
 345            return state.tagStart + indentUnit * (config.multilineTagIndentFactor || 1);
 346        }
 347        if (config.alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0;
 348        var tagAfter = textAfter && /^<(\/)?([\w_:\.-]*)/.exec(textAfter);
 349        if (tagAfter && tagAfter[1]) { // Closing tag spotted
 350          while (context) {
 351            if (context.tagName == tagAfter[2]) {
 352              context = context.prev;
 353              break;
 354            } else if (config.implicitlyClosed.hasOwnProperty(context.tagName)) {
 355              context = context.prev;
 356            } else {
 357              break;
 358            }
 359          }
 360        } else if (tagAfter) { // Opening tag spotted
 361          while (context) {
 362            var grabbers = config.contextGrabbers[context.tagName];
 363            if (grabbers && grabbers.hasOwnProperty(tagAfter[2]))
 364              context = context.prev;
 365            else
 366              break;
 367          }
 368        }
 369        while (context && context.prev && !context.startOfLine)
 370          context = context.prev;
 371        if (context) return context.indent + indentUnit;
 372        else return state.baseIndent || 0;
 373      },
 374  
 375      electricInput: /<\/[\s\w:]+>$/,
 376      blockCommentStart: "<!--",
 377      blockCommentEnd: "-->",
 378  
 379      configuration: config.htmlMode ? "html" : "xml",
 380      helperType: config.htmlMode ? "html" : "xml",
 381  
 382      skipAttribute: function(state) {
 383        if (state.state == attrValueState)
 384          state.state = attrState
 385      }
 386    };
 387  });
 388  
 389  CodeMirror.defineMIME("text/xml", "xml");
 390  CodeMirror.defineMIME("application/xml", "xml");
 391  if (!CodeMirror.mimeModes.hasOwnProperty("text/html"))
 392    CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true});
 393  
 394  });


2005 - 2021 © MyBB.de | Alle Rechte vorbehalten! | Sponsor: netcup Cross-referenced by PHPXref