Blocklyを試してみようでは簡易的なビジュアルプログラミングのエディタを作成しました。
今回は
この動画のように作成したコードの実行を行えるようにします。
Blocklyを試してみようで作成したコードを下記のように変更します。
HTML
<div id="blocklyDiv" style="width:500px;height:300px;"></div>
を
<div id="blocklyDiv" style="width:500px;height:300px;"></div> <button id="run">実行</button>
のようにボタンタグを追加します。
JavaScript
var workspace = Blockly.inject('blocklyDiv', {toolbox: toolbox});
を
var workspace = Blockly.inject('blocklyDiv', {toolbox: toolbox}); run.addEventListener("click", function(){ var code = Blockly.JavaScript.workspaceToCode(workspace); try { eval(code); } catch (error) { alert("Code ERROR: " + error); } });
のようにHTMLの方で追加したボタンタグにイベントを追加します。
var code = Blockly.JavaScript.workspaceToCode(workspace);
でエディタ内で作成したコードを取得することができ、
eval(code);
でコードの評価と実行を行います。
上記の改修でコードを実行できるようになりました。
eval(code);
でどのような処理が行われているのか?を確認できるようにしてみましょう。
HTML
<div id="blocklyDiv" style="width:500px;height:300px;"></div>
を
<div id="blocklyDiv" style="width:500px;height:300px;"></div> <textarea id="confirm" style="width:500px;height:100px;"></textarea><br>
のようにコード確認用のテキストボックスタグを追加します。
JavaScript
var workspace = Blockly.inject('blocklyDiv', {toolbox: toolbox});
を
var workspace = Blockly.inject('blocklyDiv', {toolbox: toolbox}); workspace.addChangeListener(function(){ var code = Blockly.JavaScript.workspaceToCode(workspace); document.getElementById("confirm").value = code; });
のようにエディタでコードを修正する度に追加したテキストエリアに作成中のコードが出力されるようにしています。
サーバを起動し、エディタを開き、
このようにコードを作成してみます。
テキストエリアの方を確認してみますと、
window.alert('hello');
のようにJavaScriptのコードが出力されています。
実行される内容は同じですが、evalではなく、インタープリタ(Interpreter)として実行できるように改修してみます。
JavaScript の生成と実行 | Blockly | Google for Developerを参考にして、JS-Interpreterを利用します。
JS-InterpreterはCDN経由で読み込むことができます。
js-interpreter CDN by jsDelivr - A CDN for npm and GitHub
※当記事作成時、JS-Interpreterのバージョンは5.1.0になります。
headerでJavaScriptを読み込んでいる箇所に下記のコードを追加します。
<head> <meta charset="UTF-8"> <title>Blockly sample</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/blockly/10.4.1/blockly.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/blockly/10.4.1/blocks_compressed.min.js"></script> </head>
を
<head> <meta charset="UTF-8"> <title>Blockly sample</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/blockly/10.4.1/blockly.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/blockly/10.4.1/blocks_compressed.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/js-interpreter@5.1.0/lib/js-interpreter.min.js"></script> </head>
に変更します。
次に
run.addEventListener("click", function(){ var code = Blockly.JavaScript.workspaceToCode(workspace); try { eval(code); } catch (error) { alert("Code ERROR: " + error); } });
を
run.addEventListener("click", function(){ var code = Blockly.JavaScript.workspaceToCode(workspace); var myInterpreter = new Interpreter(code); myInterpreter.run(); });
に変更します。
これで、Blocklyで作成したコードの実行がevalからインタープリタに変更されました。
ただし、このコードではprintブロックの実行の際にwindow.alertが無いというエラーにハマります。
ここで、インタープリタの動作に改修してprintブロックを実行できるようにします。
var workspace = Blockly.inject('blocklyDiv', {toolbox: toolbox});
の下あたりに
function initApi(interpreter, globalObject) { // Add an API function for the alert() block. var wrapper = function(text) { return alert(arguments.length ? text : ''); }; interpreter.setProperty(globalObject, 'alert', interpreter.createNativeFunction(wrapper)); // Add an API function for the prompt() block. wrapper = function(text) { return prompt(text); }; interpreter.setProperty(globalObject, 'prompt', interpreter.createNativeFunction(wrapper)); }
を追加します。
今回作成しましたinitApi関数を読み込むように
run.addEventListener("click", function(){ var code = Blockly.JavaScript.workspaceToCode(workspace); var myInterpreter = new Interpreter(code); myInterpreter.run(); });
を
run.addEventListener("click", function(){ var code = Blockly.JavaScript.workspaceToCode(workspace); var myInterpreter = new Interpreter(code, initApp); myInterpreter.run(); });
のように変更します。
これでprintブロック実行時にエラーにならずに実行されるようになりました。