Utilizzo di Ace Code Editor è possibile bloccare o rendere in lettura un segmento di codice ma consentire comunque la scrittura o la modifica di altre righe di codice durante una sessione?Ace Editor: Lock o Readonly Segmento di codice
risposta
Qui è l'inizio di una soluzione:
$(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();
}
});
vederlo lavorare in questo violino: http://jsfiddle.net/bzwheeler/btsxgena/
I principali pezzi di lavoro sono:
- creare inizio e ancoraggi ace finali che traccia la posizione di una porzione 'readonly' mentre il documento che lo circonda cambia.
- creare un intervallo per incapsulare gli ancoraggi
- aggiungere un keyhandler personalizzato per verificare se la pressione del tasto imminente incide sull'intervallo di sola lettura e annullarlo in caso affermativo.
- aggiungere i gestori di pasta/tagliati su misura per la protezione contro menu e dei menu del browser azioni taglia/incolla destro del mouse
Non riesco a capire cosa sta succedendo nella funzione "prima", ma so che "origArgs" non è mai definito e causa "preventReadOnly" a vomitare quando tenta di chiamare next() dopo una copia o incolla. – Southerneer
Buona cattura! Ho modificato l'implementazione before() per usare '.call' e per passare 'args' e non' origArgs' che non era definito come notato. – bzwheeler
cosa sta facendo addKeyboardHandler qui? spieghi i pls. – rjohari23
suggerisco un'altra cosa più semplice e affidabile per prevenire gamma da modificare (a controllare!)
var old$tryReplace = editor.$tryReplace;
editor.$tryReplace = function(range, replacement) {
return intersects(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 intersects(range)?false:oldRemove.apply(this, arguments);
}
var oldMoveText = session.moveText;
session.moveText = function(fromRange, toPosition, copy) {
if (intersects(fromRange) || !outsideRange(toPosition)) return fromRange;
return oldMoveText.apply(this, arguments)
}
outsideRange = function (position) {
var s0 = range.start;
if (position.row < s0.row || (position.row == s0.row && position.column <= s0.column)) return true; // position must be before range.start
var e0 = range.end;
if (position.row > e0.row || (position.row == e0.row && position.column >= e0.column)) return true; // or after range.end
return false;
}
intersects = function(withRange) {
var e = withRange.end, s0 = range.start, s = withRange.start, e0 = range.end;
if (e.row < s0.row || (e.row == s0.row && e.column <= s0.column)) return false; // withRange.end must be before range.start
if (s.row > e0.row || (s.row == e0.row && s.column >= e0.column)) return false; // or withRange.start must be after range.end
return true;
}
Hai bisogno di un solo segmento o di molti? il segmento completo può essere cancellato? Se la selezione include parte del segmento in sola lettura e l'utente preme eliminare, il resto del testo selezionato dovrebbe essere cancellato? –
Ho anche bisogno di questa funzionalità! – ufucuk