インタラクティブなJavaScript編集に [〜#〜] ace [〜#〜] エディターを使用しています。エディターをJavaScriptモードに設定すると、ACEはコードが有効かどうかを自動的に判断し、有効でない場合はエラーメッセージと行番号を強調表示します。
change
イベントハンドラーの実行中に、eval()
を試みる前に、ACEがコードが有効であると見なすかどうかを検出したいと思います。私がそれをするかもしれないと私が思った唯一の方法は:
var jsMode = require("ace/mode/javascript").Mode;
var editor = ace.edit('mycode'), edEl = document.querySelector('#mycode');
editor.getSession().setMode(new jsMode);
editor.getSession().on('change',function(){
// bail out if ACE thinks there's an error
if (edEl.querySelector('div.ace_Gutter-cell.ace_error')) return;
try{
eval(editor.getSession().getValue());
}catch(e){}
});
しかしながら:
change
コールバックが発生した後に発生します。したがって、実際には500ミリ秒以上待つ必要があります(JavaScriptワーカーが起動するまでの遅延)。
editor.getSession().on('change',function(){
setTimeout(function(){
// bail out if ACE thinks there's an error
if (edEl.querySelector('div.ace_Gutter-cell.ace_error')) return;
try{
eval(editor.getSession().getValue());
}catch(e){}
},550); // Must be longer than timeout delay in javascript_worker.js
});
JSモード用の文書化されていないAPIに、エラーがあるかどうかを尋ねるより良い方法はありますか?
アノテーションが変更されると、現在のセッションが発生しますonChangeAnnotationイベント。
その後、新しいセットのアノテーションを次のように取得できます。
var annotations = editor.getSession().getAnnotations();
トリックをするようです。 row askeyと配列asvalueを持つJSONオブジェクトを返します。 value配列には、各行に複数の注釈があるかどうかに応じて、複数のオブジェクトが含まれる場合があります。
構造は次のとおりです(firebugからコピー–私が作成したテストスクリプト用)
// annotations would look like
({
82:[
{/*annotation*/
row:82,
column:22,
text:"Use the array literal notation [].",
type:"warning",
lint:{/*raw output from jslint*/}
}
],
rownumber : [ {anotation1}, {annotation2} ],
...
});
そう..
editor.getSession().on("changeAnnotation", function(){
var annot = editor.getSession().getAnnotations();
for (var key in annot){
if (annot.hasOwnProperty(key))
console.log("[" + annot[key][0].row + " , " + annot[key][0].column + "] - \t" + annot[key][0].text);
}
});
// thanks http://stackoverflow.com/a/684692/1405348 for annot.hasOwnProperty(key) :)
注釈が変更されたときに、現在のエース編集セッションのすべての注釈のリストが表示されます。
お役に立てれば!
DOMをトラバースするよりもおそらく速い解決策を見つけました。エディタのセッションには、使用できるgetAnnotationsメソッドがあります。各注釈には、エラーかどうかを示すタイプがあります。
これが、on'change 'のコールバックを設定する方法です。
function callback() {
var annotation_lists = window.aceEditor.getSession().getAnnotations();
var has_error = false;
// Unfortunately, you get back a list of lists. However, the first list is
// always length one (but not always index 0)
go_through:
for (var l in annotation_lists) {
for (var a in annotation_lists[l]) {
var annotation = annotation_lists[l][a];
console.log(annotation.type);
if (annotation.type === "error") {
has_error = true;
break go_through;
}
}
}
if (!has_error) {
try {
eval(yourCodeFromTextBox);
prevCode = yourCodeFromTextBox;
}
catch (error) {
eval(prevCode);
}
}
}
私の知る限り、注釈には他に2つのタイプがあります。「警告」と「情報」です。これらも確認したい場合に備えて。
多くの場合、コードにはエラーがありますが、アノテーションのリストにはないため、グローバルで(コールバック関数の範囲外で)機能した以前のコードを追跡しました。その場合、エラーのあるコードを評価するとき、それはコードであり、代わりに古いコードを評価します。
2つの評価は遅くなるように見えますが、これまでのところ、パフォーマンスはそれほど悪くないように思えます。
Ace1.1.7でワーカーイベントをサブスクライブできることがわかりました。
Javascriptコードの場合、「jslint」イベントをサブスクライブします。
session.setMode('ace/mode/javascript}');
session.on('changeMode', function() {
if (session.$worker) {
session.$worker.on('jslint', function(lint) {
var messages = lint.data, types;
if (!messages.length) return ok();
types = messages.map(function(item) {
return item.type;
});
types.indexOf('error') !== -1 ? ko() : ok();
});
}
});
JSONコードの場合、「error」および「ok」イベントをサブスクライブします。
session.setMode('ace/mode/json');
session.on('changeMode', function() {
// session.$worker is available when 'changeMode' event triggered
// You could subscribe worker events here, whatever changes to the
// content will trigger 'error' or 'ok' events.
session.$worker.on('error', ko);
session.$worker.on('ok', ok);
});