Вход Регистрация
Файл: usr/plugins/highlight_code/codemirror.js
Строк: 1040
<?php
/* CodeMirror main module (http://codemirror.net/)
 *
 * Implements the CodeMirror constructor and prototype, which take care
 * of initializing the editor frame, and providing the outside interface.
 */

// The CodeMirrorConfig object is used to specify a default
// configuration. If you specify such an object before loading this
// file, the values you put into it will override the defaults given
// below. You can also assign to it after loading.
var CodeMirrorConfig window.CodeMirrorConfig || {};

var 
CodeMirror = (function(){
  function 
setDefaults(objectdefaults) {
    for (var 
option in defaults) {
      if (!
object.hasOwnProperty(option))
        
object[option] = defaults[option];
    }
  }
  function forEach(array, 
action) {
    for (var 
0< array.lengthi++)
      
action(array[i]);
  }

  
// These default options can be overridden by passing a set of
  // options to a specific CodeMirror constructor. See manual.html for
  // their meaning.
  
setDefaults(CodeMirrorConfig, {
    
stylesheet: [],
    
path"",
    
parserfile: [],
    
basefiles: ["util.js""stringstream.js""select.js""undo.js""editor.js""tokenize.js"],
    
iframeClassnull,
    
passDelay200,
    
passTime50,
    
lineNumberDelay200,
    
lineNumberTime50,
    
continuousScanningfalse,
    
saveFunctionnull,
    
onChangenull,
    
undoDepth50,
    
undoDelay800,
    
disableSpellchecktrue,
    
textWrappingtrue,
    
readOnlyfalse,
    
width"",
    
height"300px",
    
minHeight100,
    
autoMatchParensfalse,
    
parserConfignull,
    
tabMode"indent"// or "spaces", "default", "shift"
    
enterMode"indent"// or "keep", "flat"
    
electricCharstrue,
    
reindentOnLoadfalse,
    
activeTokensnull,
    
cursorActivitynull,
    
lineNumbersfalse,
    
firstLineNumber1,
    
indentUnit2,
    
domainnull
  
});

  function 
addLineNumberDiv(containerfirstNum) {
    var 
nums document.createElement("DIV"),
        
scroller document.createElement("DIV");
    
nums.style.position "absolute";
    
nums.style.height "100%";
    if (
nums.style.setExpression) {
      try {
nums.style.setExpression("height""this.previousSibling.offsetHeight + 'px'");}
      catch(
e) {} // Seems to throw 'Not Implemented' on some IE8 versions
    
}
    
nums.style.top "0px";
    
nums.style.left "0px";
    
nums.style.overflow "hidden";
    
container.appendChild(nums);
    
scroller.className "CodeMirror-line-numbers";
    
nums.appendChild(scroller);
    
scroller.innerHTML "<div>" firstNum "</div>";
    return 
nums;
  }

  function 
frameHTML(options) {
    if (
typeof options.parserfile == "string")
      
options.parserfile = [options.parserfile];
    if (
typeof options.basefiles == "string")
      
options.basefiles = [options.basefiles];
    if (
typeof options.stylesheet == "string")
      
options.stylesheet = [options.stylesheet];

    var 
html = ["<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head>"];
    // Hack to work around a bunch of IE8-specific problems.
    
html.push("<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>");
    forEach(
options.stylesheet, function(file) {
      
html.push("<link rel="stylesheet" type="text/css" href="" + file + ""/>");
    });
    forEach(
options.basefiles.concat(options.parserfile), function(file) {
      if (!/^
https?:/.test(file)) file options.path file;
      
html.push("<script type="text/javascript" src="" + file + ""><" "/script>");
    });
    
html.push("</head><body style="border-width0;" class="editbox" spellcheck="" +
              (options.disableSpellcheck ? "
false" : "true") + ""></body></html>");
    return 
html.join("");
  }

  var 
internetExplorer document.selection && window.ActiveXObject && /MSIE/.test(navigator.userAgent);

  function 
CodeMirror(placeoptions) {
    
// Use passed options, if any, to override defaults.
    
this.options options options || {};
    
setDefaults(optionsCodeMirrorConfig);

    
// Backward compatibility for deprecated options.
    
if (options.dumbTabsoptions.tabMode "spaces";
    else if (
options.normalTaboptions.tabMode "default";

    var 
frame this.frame document.createElement("IFRAME");
    if (
options.iframeClassframe.className options.iframeClass;
    
frame.frameBorder 0;
    
frame.style.border "0";
    
frame.style.width '100%';
    
frame.style.height '100%';
    
// display: block occasionally suppresses some Firefox bugs, so we
    // always add it, redundant as it sounds.
    
frame.style.display "block";

    var 
div this.wrapping document.createElement("DIV");
    
div.style.position "relative";
    
div.className "CodeMirror-wrapping";
    
div.style.width options.width;
    
div.style.height = (options.height == "dynamic") ? options.minHeight "px" options.height;
    
// This is used by Editor.reroutePasteEvent
    
var teHack this.textareaHack document.createElement("TEXTAREA");
    
div.appendChild(teHack);
    
teHack.style.position "absolute";
    
teHack.style.left "-10000px";
    
teHack.style.width "10px";

    
// Link back to this object, so that the editor can fetch options
    // and add a reference to itself.
    
frame.CodeMirror this;
    if (
options.domain && internetExplorer) {
      
this.html frameHTML(options);
      
frame.src "javascript:(function(){document.open();" +
        (
options.domain "document.domain="" + options.domain + "";" "") +
        
"document.write(window.frameElement.CodeMirror.html);document.close();})()";
    }
    else {
      
frame.src "javascript:;";
    }

    if (
place.appendChildplace.appendChild(div);
    else 
place(div);
    
div.appendChild(frame);
    if (
options.lineNumbersthis.lineNumbers addLineNumberDiv(divoptions.firstLineNumber);

    
this.win frame.contentWindow;
    if (!
options.domain || !internetExplorer) {
      
this.win.document.open();
      
this.win.document.write(frameHTML(options));
      
this.win.document.close();
    }
  }

  
CodeMirror.prototype = {
    
init: function() {
      if (
this.options.initCallbackthis.options.initCallback(this);
      if (
this.options.lineNumbersthis.activateLineNumbers();
      if (
this.options.reindentOnLoadthis.reindent();
      if (
this.options.height == "dynamic"this.setDynamicHeight();
    },

    
getCode: function() {return this.editor.getCode();},
    
setCode: function(code) {this.editor.importCode(code);},
    
selection: function() {this.focusIfIE(); return this.editor.selectedText();},
    
reindent: function() {this.editor.reindent();},
    
reindentSelection: function() {this.focusIfIE(); this.editor.reindentSelection(null);},

    
focusIfIE: function() {
      
// in IE, a lot of selection-related functionality only works when the frame is focused
      
if (this.win.select.ie_selectionthis.focus();
    },
    
focus: function() {
      
this.win.focus();
      if (
this.editor.selectionSnapshot// IE hack
        
this.win.select.setBookmark(this.win.document.bodythis.editor.selectionSnapshot);
    },
    
replaceSelection: function(text) {
      
this.focus();
      
this.editor.replaceSelection(text);
      return 
true;
    },
    
replaceChars: function(textstartend) {
      
this.editor.replaceChars(textstartend);
    },
    
getSearchCursor: function(stringfromCursorcaseFold) {
      return 
this.editor.getSearchCursor(stringfromCursorcaseFold);
    },

    
undo: function() {this.editor.history.undo();},
    
redo: function() {this.editor.history.redo();},
    
historySize: function() {return this.editor.history.historySize();},
    
clearHistory: function() {this.editor.history.clear();},

    
grabKeys: function(callbackfilter) {this.editor.grabKeys(callbackfilter);},
    
ungrabKeys: function() {this.editor.ungrabKeys();},

    
setParser: function(nameparserConfig) {this.editor.setParser(nameparserConfig);},
    
setSpellcheck: function(on) {this.win.document.body.spellcheck on;},
    
setStylesheet: function(names) {
      if (
typeof names === "string"names = [names];
      var 
activeStylesheets = {};
      var 
matchedNames = {};
      var 
links this.win.document.getElementsByTagName("link");
      
// Create hashes of active stylesheets and matched names.
      // This is O(n^2) but n is expected to be very small.
      
for (var 0linklink links[x]; x++) {
        if (
link.rel.indexOf("stylesheet") !== -1) {
          for (var 
0names.lengthy++) {
            var 
name names[y];
            if (
link.href.substring(link.href.length name.length) === name) {
              
activeStylesheets[link.href] = true;
              
matchedNames[name] = true;
            }
          }
        }
      }
      
// Activate the selected stylesheets and disable the rest.
      
for (var 0linklink links[x]; x++) {
        if (
link.rel.indexOf("stylesheet") !== -1) {
          
link.disabled = !(link.href in activeStylesheets);
        }
      }
      
// Create any new stylesheets.
      
for (var 0names.lengthy++) {
        var 
name names[y];
        if (!(
name in matchedNames)) {
          var 
link this.win.document.createElement("link");
          
link.rel "stylesheet";
          
link.type "text/css";
          
link.href name;
          
this.win.document.getElementsByTagName('head')[0].appendChild(link);
        }
      }
    },
    
setTextWrapping: function(on) {
      if (
on == this.options.textWrapping) return;
      
this.win.document.body.style.whiteSpace on "" "nowrap";
      
this.options.textWrapping on;
      if (
this.lineNumbers) {
        
this.setLineNumbers(false);
        
this.setLineNumbers(true);
      }
    },
    
setIndentUnit: function(unit) {this.win.indentUnit unit;},
    
setUndoDepth: function(depth) {this.editor.history.maxDepth depth;},
    
setTabMode: function(mode) {this.options.tabMode mode;},
    
setEnterMode: function(mode) {this.options.enterMode mode;},
    
setLineNumbers: function(on) {
      if (
on && !this.lineNumbers) {
        
this.lineNumbers addLineNumberDiv(this.wrapping);
        
this.activateLineNumbers();
      }
      else if (!
on && this.lineNumbers) {
        
this.wrapping.removeChild(this.lineNumbers);
        
this.wrapping.style.marginLeft "";
        
this.lineNumbers null;
      }
    },

    
cursorPosition: function(start) {this.focusIfIE(); return this.editor.cursorPosition(start);},
    
firstLine: function() {return this.editor.firstLine();},
    
lastLine: function() {return this.editor.lastLine();},
    
nextLine: function(line) {return this.editor.nextLine(line);},
    
prevLine: function(line) {return this.editor.prevLine(line);},
    
lineContent: function(line) {return this.editor.lineContent(line);},
    
setLineContent: function(linecontent) {this.editor.setLineContent(linecontent);},
    
removeLine: function(line){this.editor.removeLine(line);},
    
insertIntoLine: function(linepositioncontent) {this.editor.insertIntoLine(linepositioncontent);},
    
selectLines: function(startLinestartOffsetendLineendOffset) {
      
this.win.focus();
      
this.editor.selectLines(startLinestartOffsetendLineendOffset);
    },
    
nthLine: function(n) {
      var 
line this.firstLine();
      for (; 
&& line !== falsen--)
        
line this.nextLine(line);
      return 
line;
    },
    
lineNumber: function(line) {
      var 
num 0;
      while (
line !== false) {
        
num++;
        
line this.prevLine(line);
      }
      return 
num;
    },
    
jumpToLine: function(line) {
      if (
typeof line == "number"line this.nthLine(line);
      
this.selectLines(line0);
      
this.win.focus();
    },
    
currentLine: function() { // Deprecated, but still there for backward compatibility
      
return this.lineNumber(this.cursorLine());
    },
    
cursorLine: function() {
      return 
this.cursorPosition().line;
    },
    
cursorCoords: function(start) {return this.editor.cursorCoords(start);},

    
activateLineNumbers: function() {
      var 
frame this.framewin frame.contentWindowdoc win.documentbody doc.body,
          
nums this.lineNumbersscroller nums.firstChildself this;
      var 
barWidth null;

      function 
sizeBar() {
        if (
frame.offsetWidth == 0) return;
        for (var 
root frameroot.parentNoderoot root.parentNode){}
        if (!
nums.parentNode || root != document || !win.Editor) {
          
// Clear event handlers (their nodes might already be collected, so try/catch)
          
try{clear();}catch(e){}
          
clearInterval(sizeInterval);
          return;
        }

        if (
nums.offsetWidth != barWidth) {
          
barWidth nums.offsetWidth;
          
frame.parentNode.style.paddingLeft barWidth "px";
        }
      }
      function 
doScroll() {
        
nums.scrollTop body.scrollTop || doc.documentElement.scrollTop || 0;
      }
      
// Cleanup function, registered by nonWrapping and wrapping.
      
var clear = function(){};
      
sizeBar();
      var 
sizeInterval setInterval(sizeBar500);

      function 
ensureEnoughLineNumbers(fill) {
        var 
lineHeight scroller.firstChild.offsetHeight;
        if (
lineHeight == 0) return;
        var 
targetHeight 50 Math.max(body.offsetHeightMath.max(frame.offsetHeightbody.scrollHeight || 0)),
            
lastNumber Math.ceil(targetHeight lineHeight);
        for (var 
scroller.childNodes.length<= lastNumberi++) {
          var 
div document.createElement("DIV");
          
div.appendChild(document.createTextNode(fill String(self.options.firstLineNumber) : "u00a0"));
          
scroller.appendChild(div);
        }
      }

      function 
nonWrapping() {
        function 
update() {
          
ensureEnoughLineNumbers(true);
          
doScroll();
        }
        
self.updateNumbers update;
        var 
onScroll win.addEventHandler(win"scroll"doScrolltrue),
            
onResize win.addEventHandler(win"resize"updatetrue);
        
clear = function(){
          
onScroll(); onResize();
          if (
self.updateNumbers == updateself.updateNumbers null;
        };
        
update();
      }

      function 
wrapping() {
        var 
nodelineNumnextposchanges = [], styleNums self.options.styleNumbers;

        function 
setNum(nnode) {
          
// Does not typically happen (but can, if you mess with the
          // document during the numbering)
          
if (!lineNumlineNum scroller.appendChild(document.createElement("DIV"));
          if (
styleNumsstyleNums(lineNumnoden);
          
// Changes are accumulated, so that the document layout
          // doesn't have to be recomputed during the pass
          
changes.push(lineNum); changes.push(n);
          
pos lineNum.offsetHeight lineNum.offsetTop;
          
lineNum lineNum.nextSibling;
        }
        function 
commitChanges() {
          for (var 
0changes.length+= 2)
            
changes[i].innerHTML changes[1];
          
changes = [];
        }
        function 
work() {
          if (!
scroller.parentNode || scroller.parentNode != self.lineNumbers) return;

          var 
endTime = new Date().getTime() + self.options.lineNumberTime;
          while (
node) {
            
setNum(next++, node.previousSibling);
            for (; 
node && !win.isBR(node); node node.nextSibling) {
              var 
bott node.offsetTop node.offsetHeight;
              while (
scroller.offsetHeight && bott possetNum("&nbsp;");
            }
            if (
nodenode node.nextSibling;
            if (new 
Date().getTime() > endTime) {
              
commitChanges();
              
pending setTimeout(workself.options.lineNumberDelay);
              return;
            }
          }
          while (
lineNumsetNum(next++);
          
commitChanges();
          
doScroll();
        }
        function 
start(firstTime) {
          
doScroll();
          
ensureEnoughLineNumbers(firstTime);
          
node body.firstChild;
          
lineNum scroller.firstChild;
          
pos 0;
          
next self.options.firstLineNumber;
          
work();
        }

        
start(true);
        var 
pending null;
        function 
update() {
          if (
pendingclearTimeout(pending);
          if (
self.editor.allClean()) start();
          else 
pending setTimeout(update200);
        }
        
self.updateNumbers update;
        var 
onScroll win.addEventHandler(win"scroll"doScrolltrue),
            
onResize win.addEventHandler(win"resize"updatetrue);
        
clear = function(){
          if (
pendingclearTimeout(pending);
          if (
self.updateNumbers == updateself.updateNumbers null;
          
onScroll();
          
onResize();
        };
      }
      (
this.options.textWrapping || this.options.styleNumbers wrapping nonWrapping)();
    },

    
setDynamicHeight: function() {
      var 
self thisactivity self.options.cursorActivitywin self.winbody win.document.body,
          
lineHeight nulltimeout nullvmargin self.frame.offsetTop;
      
body.style.overflowY "hidden";
      
win.document.documentElement.style.overflowY "hidden";
      
this.frame.scrolling "no";

      function 
updateHeight() {
        var 
trailingLines 0node body.lastChildcomputedHeight;
        while (
node && win.isBR(node)) {
          if (!
node.hackBRtrailingLines++;
          
node node.previousSibling;
        }
        if (
node) {
          
lineHeight node.offsetHeight;
          
computedHeight node.offsetTop + (trailingLines) * lineHeight;
        }
        else if (
lineHeight) {
          
computedHeight trailingLines lineHeight;
        }
        if (
computedHeight)
          
self.wrapping.style.height Math.max(vmargin computedHeightself.options.minHeight) + "px";
      }
      
setTimeout(updateHeight300);
      
self.options.cursorActivity = function(x) {
        if (
activityactivity(x);
        
clearTimeout(timeout);
        
timeout setTimeout(updateHeight100);
      };
    }
  };

  
CodeMirror.InvalidLineHandle = {toString: function(){return "CodeMirror.InvalidLineHandle";}};

  
CodeMirror.replace = function(element) {
    if (
typeof element == "string")
      
element document.getElementById(element);
    return function(
newElement) {
      
element.parentNode.replaceChild(newElementelement);
    };
  };

  
CodeMirror.fromTextArea = function(areaoptions) {
    if (
typeof area == "string")
      
area document.getElementById(area);

    
options options || {};
    if (
area.style.width && options.width == null)
      
options.width area.style.width;
    if (
area.style.height && options.height == null)
      
options.height area.style.height;
    if (
options.content == nulloptions.content area.value;

    if (
area.form) {
      function 
updateField() {
        
area.value mirror.getCode();
      }
      if (
typeof area.form.addEventListener == "function")
        
area.form.addEventListener("submit"updateFieldfalse);
      else
        
area.form.attachEvent("onsubmit"updateField);
      var 
realSubmit area.form.submit;
      function 
wrapSubmit() {
        
updateField();
        
// Can't use realSubmit.apply because IE6 is too stupid
        
area.form.submit realSubmit;
        
area.form.submit();
        
area.form.submit wrapSubmit;
      }
      
area.form.submit wrapSubmit;
    }

    function 
insert(frame) {
      if (
area.nextSibling)
        
area.parentNode.insertBefore(framearea.nextSibling);
      else
        
area.parentNode.appendChild(frame);
    }

    
area.style.display "none";
    var 
mirror = new CodeMirror(insertoptions);
    
mirror.toTextArea = function() {
      
area.parentNode.removeChild(mirror.wrapping);
      
area.style.display "";
      if (
area.form) {
        
area.form.submit realSubmit;
        if (
typeof area.form.removeEventListener == "function")
          
area.form.removeEventListener("submit"updateFieldfalse);
        else
          
area.form.detachEvent("onsubmit"updateField);
      }
    };

    return 
mirror;
  };

  
CodeMirror.isProbablySupported = function() {
    
// This is rather awful, but can be useful.
    
var match;
    if (
window.opera)
      return 
Number(window.opera.version()) >= 9.52;
    else if (/
Apple ComputersInc/.test(navigator.vendor) && (match navigator.userAgent.match(/Version/(d+(?:.d+)?)./)))
      return 
Number(match[1]) >= 3;
    else if (
document.selection && window.ActiveXObject && (match navigator.userAgent.match(/MSIE (d+(?:.d*)?)b/)))
      return 
Number(match[1]) >= 6;
    else if (
match navigator.userAgent.match(/gecko/(d{8})/i))
      return 
Number(match[1]) >= 20050901;
    else if (
match navigator.userAgent.match(/AppleWebKit/(d+)/))
      return 
Number(match[1]) >= 525;
    else
      return 
null;
  };

  return 
CodeMirror;
})();
?>
Онлайн: 1
Реклама