13

这个问题已经转移到Skulpt 和 CodeMirror 问题,因为我的答案没有回答这个问题。

4

2 回答 2

5

这是代码片段

var delay;

// Initialize CodeMirror editor
var editor = CodeMirror.fromTextArea(document.getElementById('code'), {
  mode: {
    name: "python",
    version: 2,
    singleLineStringErrors: false
  },
  tabMode: 'indent',
  lineNumbers: true,
  lineWrapping: true,
  autoCloseTags: true
});

// Live preview
editor.on("change", function() {
  clearTimeout(delay);
  delay = setTimeout(updatePreview, 300);
});

function updatePreview() {
  var previewFrame = document.getElementById('preview');
  var preview = previewFrame.contentDocument || previewFrame.contentWindow.document;
  preview.open();
  preview.write(editor.getValue());
  preview.close();
}
setTimeout(updatePreview, 300);

function saveTextAsFile() {
  var textToWrite = editor.getValue();
  var textFileAsBlob = new Blob([textToWrite], {
    type: "text/plain;charset=utf-8"
  });
  var fileNameToSaveAs = document.getElementById("pile").value + ".py";

  var downloadLink = document.createElement("a");
  downloadLink.download = fileNameToSaveAs;
  downloadLink.innerHTML = "Download File";
  if (window.webkitURL != null) {
    // Chrome allows the link to be clicked
    // without actually adding it to the DOM.
    downloadLink.href = window.webkitURL.createObjectURL(textFileAsBlob);
  } else {
    // Firefox requires the link to be added to the DOM
    // before it can be clicked.
    downloadLink.href = window.URL.createObjectURL(textFileAsBlob);
    downloadLink.onclick = destroyClickedElement;
    downloadLink.style.display = "none";
    document.body.appendChild(downloadLink);
  }

  downloadLink.click();
}

function destroyClickedElement(event) {
  document.body.removeChild(event.target);
}

function loadfile(input) {
  var reader = new FileReader();
  reader.onload = function(e) {
    editor.setValue(e.target.result);
  };
  reader.readAsText(input.files[0]);
}

var input = document.getElementById("select");

function selectTheme() {
  var theme = input.options[input.selectedIndex].innerHTML;
  editor.setOption("theme", theme);
}

var choice = document.location.search &&
  decodeURIComponent(document.location.search.slice(1));
if (choice) {
  input.value = choice;
  editor.setOption("theme", choice);
}

//COPIED AND EDITED ALL THE BELOW FROM SKULPT
// output functions are configurable.  This one just appends some text
// to a pre element.
function outf(text) {
  var mypre = document.getElementById("output");
  mypre.innerHTML = mypre.innerHTML + text;
}

function builtinRead(x) {
    if (Sk.builtinFiles === undefined || Sk.builtinFiles["files"][x] === undefined)
      throw "File not found: '" + x + "'";
    return Sk.builtinFiles["files"][x];
  }
  // Here's everything you need to run a python program in skulpt
  // grab the code from your textarea
  // get a reference to your pre element for output
  // configure the output function
  // call Sk.importMainWithBody()

function runit() {
  var prog = editor.getValue();
  var mypre = document.getElementById("output");
  mypre.innerHTML = '';
  Sk.pre = "output";
  Sk.configure({
    output: outf,
    read: builtinRead
  });
  (Sk.TurtleGraphics || (Sk.TurtleGraphics = {})).target = 'mycanvas';
  var myPromise = Sk.misceval.asyncToPromise(function() {
    return Sk.importMainWithBody("<stdin>", false, prog, true);
  });
  myPromise.then(function(mod) {
      console.log('success');
    },
    function(err) {
      console.log(err.toString());
    });
}
.CodeMirror {
  float: left;
  width: 50%;
  border: 1px solid black;
}
iframe {
  width: 49%;
  float: left;
  height: 300px;
  border: 1px solid black;
  border-left: 0px;
}
<meta charset="utf-8">

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js" type="text/javascript"></script>
<script src="http://www.skulpt.org/static/skulpt.min.js" type="text/javascript"></script>
<script src="http://www.skulpt.org/static/skulpt-stdlib.js" type="text/javascript"></script>
<script src="https://www.cs.princeton.edu/~dp6/CodeMirror/lib/codemirror.js" type="text/javascript"></script>
<script src="https://www.cs.princeton.edu/~dp6/CodeMirror/mode/python/python.js" type="text/javascript"></script>
<script src="skulpt-codemirror.js" type="text/javascript"></script>
<script src="load-save-py.js" type="text/javascript"></script>
<script src="insert.js" type="text/javascript"></script>
<link href="https://www.cs.princeton.edu/~dp6/CodeMirror/lib/codemirror.css" rel="stylesheet" type="text/css">

<input id="toup" type="file" onchange="loadfile(this)">
<button type="button" onclick="runit()">Run</button>
Enter File name to save as
<input id="pile" placeholder=" ....without .py extension">.py
<button type="button" onclick='saveTextAsFile()'>Save/Download</button>
<br>
<br>
<br>
<textarea id="code" name="code"></textarea>
<br>



<pre id="output"></pre> 
<!-- If you want turtle graphics include a canvas -->
<div id="mycanvas"></div>

在新窗口中打开代码片段并运行它。它运作良好。

这是完整的代码

<!doctype html>
<html>
<head>
<meta charset="utf-8">

    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js" type="text/javascript"></script>
    <script src="http://www.skulpt.org/static/skulpt.min.js" type="text/javascript"></script>
    <script src="http://www.skulpt.org/static/skulpt-stdlib.js" type="text/javascript"></script>
    <script src="https://www.cs.princeton.edu/~dp6/CodeMirror/lib/codemirror.js" type="text/javascript"></script>
    <script src="https://www.cs.princeton.edu/~dp6/CodeMirror/mode/python/python.js" type="text/javascript"></script>
    <script src="skulpt-codemirror.js" type="text/javascript"></script>
    <script src="load-save-py.js" type="text/javascript"></script>
    <script src="insert.js" type="text/javascript"></script>
    <link href="https://www.cs.princeton.edu/~dp6/CodeMirror/lib/codemirror.css" rel="stylesheet" type="text/css">
    <title>Python Editor</title>
<style type='text/css'>
.CodeMirror {
    float: left;
    width: 50%;
    border: 1px solid black;}

iframe {
    width: 49%;
    float: left;
    height: 300px;
    border: 1px solid black;
    border-left: 0px;}
</style>
</head>
<body>



    <input id="toup" type="file" onchange="loadfile(this)">
    <button type="button" onclick="runit()">Run</button> 
    Enter File name to save as<input id="pile" placeholder=" ....without .py extension">.py
    <button type="button"  onclick='saveTextAsFile()'>Save/Download</button><br><br><br>
    <textarea id="code" name="code"></textarea><br>



<pre id="output" ></pre> 
<!-- If you want turtle graphics include a canvas -->
<div id="mycanvas"></div> 


<script>
var delay;

// Initialize CodeMirror editor
var editor = CodeMirror.fromTextArea(document.getElementById('code'), {
    mode: {
                name: "python",
                version: 2,
                singleLineStringErrors: false
            },
    tabMode: 'indent',
    lineNumbers: true,
    lineWrapping: true,
    autoCloseTags: true
});

// Live preview
editor.on("change", function() {
    clearTimeout(delay);
    delay = setTimeout(updatePreview, 300);
});

function updatePreview() {
    var previewFrame = document.getElementById('preview');
    var preview =  previewFrame.contentDocument ||  previewFrame.contentWindow.document;
    preview.open();
    preview.write(editor.getValue());
    preview.close();
}
setTimeout(updatePreview, 300);

function saveTextAsFile() {
    var textToWrite = editor.getValue();
    var textFileAsBlob = new Blob([textToWrite], {type:"text/plain;charset=utf-8"});
    var fileNameToSaveAs = document.getElementById("pile").value + ".py";

    var downloadLink = document.createElement("a");
    downloadLink.download = fileNameToSaveAs;
    downloadLink.innerHTML = "Download File";
    if (window.webkitURL != null)
    {
        // Chrome allows the link to be clicked
        // without actually adding it to the DOM.
        downloadLink.href = window.webkitURL.createObjectURL(textFileAsBlob);
    }
    else
    {
        // Firefox requires the link to be added to the DOM
        // before it can be clicked.
        downloadLink.href = window.URL.createObjectURL(textFileAsBlob);
        downloadLink.onclick = destroyClickedElement;
        downloadLink.style.display = "none";
        document.body.appendChild(downloadLink);
    }

    downloadLink.click();}

function destroyClickedElement(event) {
    document.body.removeChild(event.target);}

function loadfile(input){
    var reader = new FileReader();
    reader.onload = function(e) {
        editor.setValue(e.target.result);};
    reader.readAsText(input.files[0]);}

    var input = document.getElementById("select");

    function selectTheme() {
      var theme = input.options[input.selectedIndex].innerHTML;
      editor.setOption("theme", theme);
    }

    var choice = document.location.search &&
               decodeURIComponent(document.location.search.slice(1));
    if (choice) {
      input.value = choice;
      editor.setOption("theme", choice);
    }

    //COPIED AND EDITED ALL THE BELOW FROM SKULPT
    // output functions are configurable.  This one just appends some text
// to a pre element.
function outf(text) { 
    var mypre = document.getElementById("output"); 
    mypre.innerHTML = mypre.innerHTML + text; 
} 
function builtinRead(x) {
    if (Sk.builtinFiles === undefined || Sk.builtinFiles["files"][x] === undefined)
            throw "File not found: '" + x + "'";
    return Sk.builtinFiles["files"][x];
}
// Here's everything you need to run a python program in skulpt
// grab the code from your textarea
// get a reference to your pre element for output
// configure the output function
// call Sk.importMainWithBody()
function runit() { 
   var prog = editor.getValue(); 
   var mypre = document.getElementById("output"); 
   mypre.innerHTML = ''; 
   Sk.pre = "output";
   Sk.configure({output:outf, read:builtinRead}); 
   (Sk.TurtleGraphics || (Sk.TurtleGraphics = {})).target = 'mycanvas';
   var myPromise = Sk.misceval.asyncToPromise(function() {
       return Sk.importMainWithBody("<stdin>", false, prog, true);
   });
   myPromise.then(function(mod) {
       console.log('success');
   },
       function(err) {
       console.log(err.toString());
   });
} 
</script>
</body>
</html>
于 2016-08-24T13:59:45.303 回答
2

使用editor.getValue()editor.setValue(textFromFileLoaded)不是获取/设置“文本框”元素本身的值。

CodeMirror 实例几乎完全独立于构造它的文本区域。如您所见,它不会注意到文本区域中所做的更改,也不会将编辑器中所做的更改传播给它(特别是在表单提交期间除外)。

于 2016-08-28T06:28:35.593 回答