Вход Регистрация
Файл: usr/plugins/highlight_code/parsexml.js
Строк: 447
<?php
/* This file defines an XML parser, with a few kludges to make it
 * useable for HTML. autoSelfClosers defines a set of tag names that
 * are expected to not have a closing tag, and doNotIndent specifies
 * the tags inside of which no indentation should happen (see Config
 * object). These can be disabled by passing the editor an object like
 * {useHTMLKludges: false} as parserConfig option.
 */

var XMLParser Editor.Parser = (function() {
  var 
Kludges = {
    
autoSelfClosers: {"br"true"img"true"hr"true"link"true"input"true,
                      
"meta"true"col"true"frame"true"base"true"area"true},
    
doNotIndent: {"pre"true"!cdata"true}
  };
  var 
NoKludges = {autoSelfClosers: {}, doNotIndent: {"!cdata"true}};
  var 
UseKludges Kludges;
  var 
alignCDATA false;

  
// Simple stateful tokenizer for XML documents. Returns a
  // MochiKit-style iterator, with a state property that contains a
  // function encapsulating the current state. See tokenize.js.
  
var tokenizeXML = (function() {
    function 
inText(sourcesetState) {
      var 
ch source.next();
      if (
ch == "<") {
        if (
source.equals("!")) {
          
source.next();
          if (
source.equals("[")) {
            if (
source.lookAhead("[CDATA["true)) {
              
setState(inBlock("xml-cdata""]]>"));
              return 
null;
            }
            else {
              return 
"xml-text";
            }
          }
          else if (
source.lookAhead("--"true)) {
            
setState(inBlock("xml-comment""-->"));
            return 
null;
          }
          else {
            return 
"xml-text";
          }
        }
        else if (
source.equals("?")) {
          
source.next();
          
source.nextWhileMatches(/[w._-]/);
          
setState(inBlock("xml-processing""?>"));
          return 
"xml-processing";
        }
        else {
          if (
source.equals("/")) source.next();
          
setState(inTag);
          return 
"xml-punctuation";
        }
      }
      else if (
ch == "&") {
        while (!
source.endOfLine()) {
          if (
source.next() == ";")
            break;
        }
        return 
"xml-entity";
      }
      else {
        
source.nextWhileMatches(/[^&<n]/);
        return 
"xml-text";
      }
    }

    function 
inTag(sourcesetState) {
      var 
ch source.next();
      if (
ch == ">") {
        
setState(inText);
        return 
"xml-punctuation";
      }
      else if (/[?/]/.
test(ch) && source.equals(">")) {
        
source.next();
        
setState(inText);
        return 
"xml-punctuation";
      }
      else if (
ch == "=") {
        return 
"xml-punctuation";
      }
      else if (/[
'"]/.test(ch)) {
        setState(inAttribute(ch));
        return null;
      }
      else {
        source.nextWhileMatches(/[^su00a0=<>"'
/?]/);
        return 
"xml-name";
      }
    }

    function 
inAttribute(quote) {
      return function(
sourcesetState) {
        while (!
source.endOfLine()) {
          if (
source.next() == quote) {
            
setState(inTag);
            break;
          }
        }
        return 
"xml-attribute";
      };
    }

    function 
inBlock(styleterminator) {
      return function(
sourcesetState) {
        while (!
source.endOfLine()) {
          if (
source.lookAhead(terminatortrue)) {
            
setState(inText);
            break;
          }
          
source.next();
        }
        return 
style;
      };
    }

    return function(
sourcestartState) {
      return 
tokenizer(sourcestartState || inText);
    };
  })();

  
// The parser. The structure of this function largely follows that of
  // parseJavaScript in parsejavascript.js (there is actually a bit more
  // shared code than I'd like), but it is quite a bit simpler.
  
function parseXML(source) {
    var 
tokens tokenizeXML(source), token;
    var 
cc = [base];
    var 
tokenNr 0indented 0;
    var 
currentTag nullcontext null;
    var 
consume;
    
    function 
push(fs) {
      for (var 
fs.length 1>= 0i--)
        
cc.push(fs[i]);
    }
    function 
cont() {
      
push(arguments);
      
consume true;
    }
    function 
pass() {
      
push(arguments);
      
consume false;
    }

    function 
markErr() {
      
token.style += " xml-error";
    }
    function 
expect(text) {
      return function(
stylecontent) {
        if (
content == textcont();
        else {
markErr(); cont(arguments.callee);}
      };
    }

    function 
pushContext(tagnamestartOfLine) {
      var 
noIndent UseKludges.doNotIndent.hasOwnProperty(tagname) || (context && context.noIndent);
      
context = {prevcontextnametagnameindentindentedstartOfLinestartOfLinenoIndentnoIndent};
    }
    function 
popContext() {
      
context context.prev;
    }
    function 
computeIndentation(baseContext) {
      return function(
nextCharscurrent) {
        var 
context baseContext;
        if (
context && context.noIndent)
          return 
current;
        if (
alignCDATA && /<![CDATA[/.test(nextChars))
          return 
0;
        if (
context && /^<//.test(nextChars))
          
context context.prev;
        while (
context && !context.startOfLine)
          
context context.prev;
        if (
context)
          return 
context.indent indentUnit;
        else
          return 
0;
      };
    }

    function 
base() {
      return 
pass(elementbase);
    }
    var 
harmlessTokens = {"xml-text"true"xml-entity"true"xml-comment"true"xml-processing"true};
    function 
element(stylecontent) {
      if (
content == "<"cont(tagnameattributesendtag(tokenNr == 1));
      else if (
content == "</"cont(closetagnameexpect(">"));
      else if (
style == "xml-cdata") {
        if (!
context || context.name != "!cdata"pushContext("!cdata");
        if (/]]>$/.
test(content)) popContext();
        
cont();
      }
      else if (
harmlessTokens.hasOwnProperty(style)) cont();
      else {
markErr(); cont();}
    }
    function 
tagname(stylecontent) {
      if (
style == "xml-name") {
        
currentTag content.toLowerCase();
        
token.style "xml-tagname";
        
cont();
      }
      else {
        
currentTag null;
        
pass();
      }
    }
    function 
closetagname(stylecontent) {
      if (
style == "xml-name") {
        
token.style "xml-tagname";
        if (
context && content.toLowerCase() == context.namepopContext();
        else 
markErr();
      }
      
cont();
    }
    function 
endtag(startOfLine) {
      return function(
stylecontent) {
        if (
content == "/>" || (content == ">" && UseKludges.autoSelfClosers.hasOwnProperty(currentTag))) cont();
        else if (
content == ">") {pushContext(currentTagstartOfLine); cont();}
        else {
markErr(); cont(arguments.callee);}
      };
    }
    function 
attributes(style) {
      if (
style == "xml-name") {token.style "xml-attname"cont(attributeattributes);}
      else 
pass();
    }
    function 
attribute(stylecontent) {
      if (
content == "="cont(value);
      else if (
content == ">" || content == "/>"pass(endtag);
      else 
pass();
    }
    function 
value(style) {
      if (
style == "xml-attribute"cont(value);
      else 
pass();
    }

    return {
      
indentation: function() {return indented;},

      
next: function(){
        
token tokens.next();
        if (
token.style == "whitespace" && tokenNr == 0)
          
indented token.value.length;
        else
          
tokenNr++;
        if (
token.content == "n") {
          
indented tokenNr 0;
          
token.indentation computeIndentation(context);
        }

        if (
token.style == "whitespace" || token.type == "xml-comment")
          return 
token;

        while(
true){
          
consume false;
          
cc.pop()(token.styletoken.content);
          if (
consume) return token;
        }
      },

      
copy: function(){
        var 
_cc cc.concat([]), _tokenState tokens.state_context context;
        var 
parser this;
        
        return function(
input){
          
cc _cc.concat([]);
          
tokenNr indented 0;
          
context _context;
          
tokens tokenizeXML(input_tokenState);
          return 
parser;
        };
      }
    };
  }

  return {
    
makeparseXML,
    
electricChars"/",
    
configure: function(config) {
      if (
config.useHTMLKludges != null)
        
UseKludges config.useHTMLKludges Kludges NoKludges;
      if (
config.alignCDATA)
        
alignCDATA config.alignCDATA;
    }
  };
})();
?>
Онлайн: 1
Реклама