13

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

Community
  • 1
  • 1
  • Possible duplicate of [Skulpt and CodeMirror Issues](http://stackoverflow.com/questions/39598668/skulpt-and-codemirror-issues) –  Oct 04 '16 at 05:29

2 Answers2

6

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>
DannyBoi
  • 636
  • 1
  • 7
  • 23
  • the file loads, but it creates a new blank textarea underneath. –  Aug 24 '16 at 18:27
  • how would I delete the original one? –  Aug 24 '16 at 18:57
  • and also (like I asked in the description of the bounty) can you give me the full javascript and html I would use instead of my old code –  Aug 24 '16 at 19:03
  • @DanielHarrin.....just to be clear. If I can get a code that is working directly on the browser but not on jsFiddle, will I still be eligible for the bounty? – DannyBoi Aug 25 '16 at 13:26
  • yes, as long as you paste the full code in your answer –  Aug 25 '16 at 13:52
  • @DanielHarrin.....I have edited my answer with my full code, let me know if it is what you are looking for. – DannyBoi Aug 25 '16 at 14:28
  • that works, but it makes a new textarea in doing so above the old one - can we delete the old one? –  Aug 25 '16 at 14:30
  • also, can the `copytoeditor()` function be called when the open button is clicked to save there having to be another button? –  Aug 25 '16 at 14:33
  • yep, I can't get rid of that duplicate textarea, can you? –  Aug 25 '16 at 15:13
  • yes, I think that is a problem. Having a look at this [link](http://stackoverflow.com/q/17646555/6395782) . It pulls up the Codemirror straight away, however, we still have to do a soft refresh to get the code on. – DannyBoi Aug 25 '16 at 15:30
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/121863/discussion-between-daniel-harrin-and-dannyboi). –  Aug 25 '16 at 17:56
  • @DanielHarrin..... The code is now working , a small tweak did the trick , `editor.setValue(e.target.result);` I found the solution here [link](http://stackoverflow.com/a/17959261/6395782) – DannyBoi Aug 26 '16 at 03:19
  • ok, so now can you change the code example so it includes my code please? –  Aug 26 '16 at 05:27
  • you have not used by code example to base your answer on - the html is not the same as mine, and the python.js is replaced with xml.js etc –  Aug 26 '16 at 17:37
  • I need an alteration - you made a mistake - you based the code in your answer on this question(http://stackoverflow.com/questions/17646555/filereader-and-codemirror-load-file-complication?noredirect=1&lq=1), not mine! –  Aug 30 '16 at 08:23
  • If you can fix this, you are in the running for getting the bounty –  Aug 30 '16 at 08:24
  • im actually stuck with the run() function,rest all is fine. pyhton mode dosent seem to be working, i tried a simple Hello World. – DannyBoi Aug 30 '16 at 09:37
  • so how can we fix it? I see that someone else has answered, maybe their answer can help (they don't have source code with theirs) –  Aug 30 '16 at 10:13
  • by the way the skulpt does not have `run()`, it has `runit()` –  Aug 30 '16 at 10:14
  • I gave you the bounty but my question is still not answered - please can you get it working in Python please. –  Aug 31 '16 at 05:37
  • @DanielHarrin...thanks. With a little help from skulpt site and [link](http://stackoverflow.com/a/39188587/6395782) i got it to work. I never knew such things were possible, Thanks. – DannyBoi Aug 31 '16 at 13:39
  • it works, but it is not based on my original code / layout. Please keep html css the same, only change the javascript. Thanks –  Aug 31 '16 at 15:50
  • I have just given you 100 reputation, please can you edit your answer because I have edited my question. –  Sep 13 '16 at 05:29
  • What operating system are you using? And what is not working? – DannyBoi Sep 13 '16 at 11:57
  • I am using windows 10 chrome. When I awarded you the 50 rep, it was a different question to this one. Please read my question again as it has changed alot since you answered the first time. –  Sep 13 '16 at 14:49
  • i have now given you 150 of my rep, so you can fix it –  Sep 16 '16 at 12:53
  • you'll have to give me sometime, I have no clue about $$$ J query – DannyBoi Sep 17 '16 at 01:32
  • ok no problem, take your time , or maybe someone else can help? –  Sep 17 '16 at 05:34
  • This question has moved, please look at the new question: http://stackoverflow.com/questions/39598668/skulpt-and-codemirror-issues –  Sep 20 '16 at 15:58
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).

Telic
  • 357
  • 1
  • 6
  • can you give a sample jsFiddle / or some full code that works based on my question –  Aug 28 '16 at 17:06
  • This question has moved, please look at the new question: http://stackoverflow.com/questions/39598668/skulpt-and-codemirror-issues –  Sep 20 '16 at 15:58