Downloading and Uploading in CodeMirror Textarea and Skulpt Execution Issues

房东的猫 提交于 2019-12-08 15:17:04

问题


This question has moved to Skulpt and CodeMirror Issues because the answers I had did not answer the question.


回答1:


Here is the code snippet

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>

Open the snippet in a new window and Run it. It works well.

Here is the full code

<!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>



回答2:


Use editor.getValue() and editor.setValue(textFromFileLoaded) rather than getting/setting the value of the "textbox" element itself.

A CodeMirror instance is almost entirely separate from the textarea it is constructed from. As you've seen, it won't notice changes made in the textarea, and won't propagate changes made in the editor to it (except specifically during a form submission).



来源:https://stackoverflow.com/questions/39075483/downloading-and-uploading-in-codemirror-textarea-and-skulpt-execution-issues

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!