【问题标题】:How to make multiple chunk of lines readonly in ace editor如何在ace编辑器中使多行只读
【发布时间】:2016-09-22 13:24:25
【问题描述】:

我尝试在 Ace 编辑器中将部分代码设为只读。

我尝试过使用JsFiddle中给出的代码

$(function() {
    var editor     = ace.edit("editor1")
        , session  = editor.getSession()
        , Range    = require("ace/range").Range
        , range    = new Range(1, 4, 1, 10)
        , markerId = session.addMarker(range, "readonly-highlight");

    session.setMode("ace/mode/javascript");
    editor.keyBinding.addKeyboardHandler({
        handleKeyboard : function(data, hash, keyString, keyCode, event) {
            if (hash === -1 || (keyCode <= 40 && keyCode >= 37)) return false;

            if (intersects(range)) {
                return {command:"null", passEvent:false};
            }
        }
    });

    before(editor, 'onPaste', preventReadonly);
    before(editor, 'onCut',   preventReadonly);

    range.start  = session.doc.createAnchor(range.start);
    range.end    = session.doc.createAnchor(range.end);
    range.end.$insertRight = true;

    function before(obj, method, wrapper) {
        var orig = obj[method];
        obj[method] = function() {
            var args = Array.prototype.slice.call(arguments);
            return wrapper.call(this, function(){
                return orig.apply(obj, args);
            }, args);
        }

        return obj[method];
    }

    function intersects(range) {
        return editor.getSelectionRange().intersects(range);
    }

    function preventReadonly(next, args) {
        if (intersects(range)) return;
        next();
    }
});

我一直按退格键时遇到问题,它进入只读部分并且没有可编辑的部分。

如何将多个代码块设为只读,并避免最后一个只读字符被删除。

另外,如果我在文本中有标记指定可编辑部分,如何动态实现整个事情?

【问题讨论】:

    标签: javascript editor ace-editor


    【解决方案1】:

    检查下面的代码,该代码允许在范围末尾使用 Enter 以只读方式读取多个行块,以防止不可逆的删除和拖放处理。

    function set_readonly(editor,readonly_ranges) {
          var  session  = editor.getSession()
              , Range    = require("ace/range").Range;
              ranges    = [];
    
          function before(obj, method, wrapper) {
            var orig = obj[method];
            obj[method] = function() {
              var args = Array.prototype.slice.call(arguments);
              return wrapper.call(this, function(){
                  return orig.apply(obj, args);
              }, args);
            }
            return obj[method];
          }
          function intersects(range) {
              return editor.getSelectionRange().intersects(range);
          }
          function intersectsRange(newRange) {
            for (i=0;i<ranges.length;i++)
              if(newRange.intersects(ranges[i]))
                return true;
            return false;
          }
          function preventReadonly(next, args) {
              for(i=0;i<ranges.length;i++){if (intersects(ranges[i])) return;}
              next();
          }
          function onEnd(position){
            var row = position["row"],column=position["column"];
            for (i=0;i<ranges.length;i++)
              if(ranges[i].end["row"] == row && ranges[i].end["column"]==column)
                return true;
            return false;
          }
          function outSideRange(position){
            var row = position["row"],column=position["column"];
            for (i=0;i<ranges.length;i++){
              if(ranges[i].start["row"]< row && ranges[i].end["row"]>row)
                  return false;
              if(ranges[i].start["row"]==row && ranges[i].start["column"]<column){
                  if(ranges[i].end["row"] != row || ranges[i].end["column"]>column)
                    return false;
              }
              else if(ranges[i].end["row"] == row&&ranges[i].end["column"]>column){
                    return false;
              }
            }
            return true; 
          }
          for(i=0;i<readonly_ranges.length;i++){
            ranges.push(new Range(...readonly_ranges[i]));
          }
          ranges.forEach(function(range){session.addMarker(range, "readonly-highlight");});
          session.setMode("ace/mode/javascript");
          editor.keyBinding.addKeyboardHandler({
              handleKeyboard : function(data, hash, keyString, keyCode, event) {
                if (Math.abs(keyCode) == 13 && onEnd(editor.getCursorPosition())){
                  return false;
                }
                if (hash === -1 || (keyCode <= 40 && keyCode >= 37)) return false;
                for(i=0;i<ranges.length;i++){
                  if (intersects(ranges[i])) {
                      return {command:"null", passEvent:false};
                  }
                }
              }
          });
          before(editor, 'onPaste', preventReadonly);
          before(editor, 'onCut',   preventReadonly);
          for(i=0;i<ranges.length;i++){
            ranges[i].start  = session.doc.createAnchor(ranges[i].start);
            ranges[i].end    = session.doc.createAnchor(ranges[i].end);
            ranges[i].end.$insertRight = true;
           }
    
          var old$tryReplace = editor.$tryReplace;
          editor.$tryReplace = function(range, replacement) {
              return intersectsRange(range)?null:old$tryReplace.apply(this, arguments);                        
          }
          var session = editor.getSession();
          var oldInsert = session.insert;
          session.insert = function(position, text) {
              return oldInsert.apply(this, [position, outSideRange(position)?text:""]);
          }
          var oldRemove = session.remove;
          session.remove = function(range) {
              return intersectsRange(range)?false:oldRemove.apply(this, arguments);                        
          }
          var oldMoveText = session.moveText;
          session.moveText = function(fromRange, toPosition, copy) {
              if (intersectsRange(fromRange) || !outSideRange(toPosition)) return fromRange;
              return oldMoveText.apply(this, arguments);
          }
    
    }
    function refresheditor(id,content,readonly) {
          var temp_id=id+'_temp';
          document.getElementById(id).innerHTML="<div id='"+temp_id+"'></div>";
          document.getElementById(temp_id).innerHTML=content;
          var editor     = ace.edit(temp_id);
          set_readonly(editor,readonly);
    
    }
    
    function get_readonly_by_editable_tag(id,content){
      var text= content.split("\n");
      var starts=[0],ends=[];
      text.forEach(function(line,index){
        if((line.indexOf("&lt;editable&gt;") !== -1))ends.push(index);
        if((line.indexOf("&lt;/editable&gt;") !== -1))starts.push(index+1);
      });
      ends.push(text.length);
      var readonly_ranges=[];
      for(i=0;i<starts.length;i++){
        readonly_ranges.push([starts[i],0,ends[i],0])
      }
      refresheditor(id,content,readonly_ranges);
    }
    var content=document.getElementById("code").innerHTML;
    function readonly_lines(id,content,line_numbers){
      var readonly_ranges=[];
      all_lines= line_numbers.sort();
     
      for(i=0;i<line_numbers.length;i++){
        readonly_ranges.push([line_numbers[i]-1,0,line_numbers[i],0]);
      }
      refresheditor(id,content,readonly_ranges);
    }
    get_readonly_by_editable_tag("myeditor",content)
    //readonly_lines("myeditor",content,[5,7,9]);
    .ace_editor {
        width:100%;
        height:300px;
    }
    .readonly-highlight{
        background-color: red;
        opacity: 0.2;
        position: absolute;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://ace.c9.io/build/src/ace.js"></script>
    <link rel="stylesheet" type="text/css" href="http://jsfiddle.net/css/normalize.css">
    <link rel="stylesheet" type="text/css" href="http://jsfiddle.net/css/result-light.css">
    
    <button onclick="get_readonly_by_editable_tag('myeditor',content)">Readonly by tags</button>
    <button onclick="readonly_lines('myeditor',content,[3,7])">Readonly lines 3 and 7 </button>
      <div id="myeditor" ></div>
      <div id="code" style="display:none;">//&lt;editable&gt;
    //&lt;/editable&gt;
    function refresheditor() {
       //&lt;editable&gt;
       document.getElementById("myeditor").innerHTML="&lt;div id='editor'&gt;&lt;/div&gt;";
       document.getElementById("editor").innerHTML=document.getElementById("code").innerHTML;
       //&lt;/editable&gt;
        var editor     = ace.edit("editor")
            , session  = editor.getSession()
            , Range    = require("ace/range").Range;
            ranges    = [];
            var text= document.getElementById("code").innerHTML.split("\n");
            var starts=[0],ends=[];
            text.forEach(function(line,index){
              if((line.indexOf("&amp;lt;editable&amp;gt;") !== -1))ends.push(index);
              if((line.indexOf("&amp;lt;/editable&amp;gt;") !== -1))starts.push(index+1);
            });
            ends.push(text.length);
            for(i=0;i&lt;starts.length;i++){
              ranges.push(new Range(starts[i], 0,ends[i] ,0));
            }
            ranges.forEach(function(range){session.addMarker(range, "readonly-highlight");});
        session.setMode("ace/mode/javascript");
        //&lt;editable&gt;
        editor.keyBinding.addKeyboardHandler({
            handleKeyboard : function(data, hash, keyString, keyCode, event) {
                var pos=editor.getCursorPosition();
                if (Math.abs(keyCode) == 13){
    		 for (i=0;i&lt;ranges.length;i++){
    			if((ranges[i].end["row"]==pos["row"])&&(ranges[i].end["column"]==pos["column"])){ return false;}
    		 }
    	    }
                if (hash === -1 || (keyCode &lt;= 40 && keyCode &gt;= 37)) return false;
                for(i=0;i&lt;ranges.length;i++){
                  if (intersects(ranges[i])) {
                      return {command:"null", passEvent:false};
                  }
                }
            }
        });
        //&lt;/editable&gt;
        before(editor, 'onPaste', preventReadonly);
        before(editor, 'onCut',   preventReadonly);
        for(i=0;i&lt;ranges.length;i++){
          ranges[i].start  = session.doc.createAnchor(ranges[i].start);
          ranges[i].end    = session.doc.createAnchor(ranges[i].end);
          ranges[i].end.$insertRight = true;
         }
        function before(obj, method, wrapper) {
            var orig = obj[method];
            obj[method] = function() {
                var args = Array.prototype.slice.call(arguments);
                return wrapper.call(this, function(){
                    return orig.apply(obj, args);
                }, args);
            }
            return obj[method];
        }
        function intersects(range) {
            return editor.getSelectionRange().intersects(range);
        }
        function preventReadonly(next, args) {
            for(i=0;i&lt;ranges.length;i++){if (intersects(ranges[i])) return;}
            next();
        }
    }
    refresheditor();
            
    </div>

    【讨论】:

    • 如果您记录每一行,那就太好了。
    • 先生。 A 能否请您为上述代码编写文档。
    • 如何在不解析文本或使用 的情况下将特定的行号设为只读。
    • 不能在 angularjs 中工作。你能帮帮我吗
    • @Mr.A 请帮我在 Angularjs 中修复它
    【解决方案2】:

    这段代码 sn-p 将阻止用户编辑编辑器的第一行或最后一行:

    editor.commands.on("exec", function(e) { 
      var rowCol = editor.selection.getCursor();
      if ((rowCol.row == 0) || ((rowCol.row + 1) == editor.session.getLength())) {
        e.preventDefault();
        e.stopPropagation();
      }
    });
    

    https://jsfiddle.net/tripflex/y0huvc1b/

    来源: https://groups.google.com/forum/#!topic/ace-discuss/yffGsSG7GSA

    【讨论】:

    • 第一行和最后一行不阻止拖放...您可以选择并拖放选择进行编辑
    【解决方案3】:

    抱歉:此代码不处理拖放 我上周添加了最后一个提案:Ace Editor: Lock or Readonly Code Segment

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-11-25
      • 1970-01-01
      • 1970-01-01
      • 2014-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多