简体   繁体   中英

How to make multiple chunk of lines readonly in ace editor

I tried to make parts of code read-only in Ace editor.

I have tried by using code given in 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();
    }
});

I got a problem when I keep pressing backspace it went into the read-only part and there was no editable part left.

How can I make multiple chunks of code read-only and avoid last character from read-only getting deleted.

Also, how to achieve the whole thing dynamically where I have markers in text specifying editable portions ?

Check the below code that allows multiple chunk of lines read-only with Enter at end of range to prevent non reversible delete and drag/drop handled.

 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> 

抱歉:此代码无法处理拖放我上周添加了最后一个提案: Ace编辑器:锁定或只读代码段

This code snippet will prevent the user from editing the first or last line of the editor:

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/

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM