Difference between revisions of "Widget:CodeExplorer"

From Coder Merlin
Line 74: Line 74:
             }
             }


            // Language and mode
             let currentLanguageData<!--{$exerciseID|validate:int}--> = "";
             let currentLanguageData<!--{$exerciseID|validate:int}--> = "";
             function setCurrentLanguage<!--{$exerciseID|validate:int}-->(language) {
             function setCurrentLanguage<!--{$exerciseID|validate:int}-->(language) {
Line 106: Line 107:
             }
             }


 
            // Live theater sync
             function syncToLiveTheater<!--{$exerciseID|validate:int}-->() {
             function syncToLiveTheater<!--{$exerciseID|validate:int}-->() {
                 setStatusIndicator<!--{$exerciseID|validate:int}-->('yellow');
                 setStatusIndicator<!--{$exerciseID|validate:int}-->('yellow');
Line 133: Line 134:
                       setStatusIndicator<!--{$exerciseID|validate:int}-->('red');
                       setStatusIndicator<!--{$exerciseID|validate:int}-->('red');
                   },
                   },
                   timeout: 2500 // Should be less than repeat interval
                   success: function(data) {
                });
                      let sourceLanguage = Object.keys(data.sourceLanguage)[0];
                     
                      let contents = data.sourceFiles[0].contents;
                response.done(function(responseObject) {
                    let sourceLanguage = Object.keys(responseObject.sourceLanguage)[0];
                    let contents = responseObject.sourceFiles[0].contents;


                    // Set language
                        // Set language
                    setCurrentLanguage<!--{$exerciseID|validate:int}-->(sourceLanguage);
                        setCurrentLanguage<!--{$exerciseID|validate:int}-->(sourceLanguage);


                    // Set content (currently only first file)
                        // Set content (currently only first file)
                    codeEditor<!--{$exerciseID|validate:int}-->.setValue(contents);
                        codeEditor<!--{$exerciseID|validate:int}-->.setValue(contents);


                    // Set status
                        // Set status
                    setStatusIndicator<!--{$exerciseID|validate:int}-->('green');
                        setStatusIndicator<!--{$exerciseID|validate:int}-->('green');
                 });
                  },
                  timeout: 2500 // Should be less than repeat interval
                 });                      
             }
             }


Line 308: Line 308:
                     let requestString = JSON.stringify(requestObject);
                     let requestString = JSON.stringify(requestObject);


                    setStatusIndicator<!--{$exerciseID|validate:int}-->('yellow');
                     let response = $.ajax({
                     let response = $.ajax({
                         type: "POST",
                         type: "POST",
Line 329: Line 330:
                                     "Internal error: " + textStatus + "<br/>" + errorThrown + "<br/>" +  
                                     "Internal error: " + textStatus + "<br/>" + errorThrown + "<br/>" +  
                                     "</span><br/>");
                                     "</span><br/>");
                            setStatusIndicator<!--{$exerciseID|validate:int}-->('red');
                             }
                             }
                        },
                        success: function(data) {
                            switch (event.target.submitter) {
                                case "execute":
                                    let compilationStatus = data.compilationStatus;
                                    let compilationOutput = compilationStatus.standardOutput;
                                    let compilationError = compilationStatus.standardError;
                                    if (compilationStatus.timedOut) {
                                        compilationError += "error: timed out\n";
                                    }
                                    $("#codeEditorCompilerOutput<!--{$exerciseID|validate:int}-->").
                                        append(markupWarningsAndErrorsHTML(consoleToHTML(compilationError)));
                                    $("#codeEditorCompilerOutput<!--{$exerciseID|validate:int}-->").
                                        append(markupWarningsAndErrorsHTML(consoleToHTML(compilationOutput)));
                                    let executionStatus = data.executionStatus;
                                    let executionOutput = (typeof executionStatus == "object") ? executionStatus.standardOutput : "";
                                    let executionError = (typeof executionStatus == "object") ? executionStatus.standardError : "";
                                    if (typeof executionStatus == "object" && executionStatus.timedOut) {
                                        executionError += "error: timed out\n";
                                    }
                                    $("#codeEditorExecutionOutput<!--{$exerciseID|validate:int}-->").append(consoleToHTML(executionError));
                                    $("#codeEditorExecutionOutput<!--{$exerciseID|validate:int}-->").
                                        append(markupRuntimeStandardOutput(consoleToHTML(executionOutput)));


                                    // Set compilation display
                                    const $button = $("#codeEditorForm<!--{$exerciseID|validate:int}--> .merlin-code-explorer-show-compilation-button");
                                    const $output = $button.parent().siblings(".merlin-code-explorer-combined-output:first");
                                    if (compilationStatus.terminationStatus == 0) {
                                        $output.slideUp();
                                        $button.text("Show Compilation Output");
                                    } else {
                                        $output.slideDown();
                                        $button.text("Hide Compilation Output");
                                    }
                                    break;
                                case "submit":
                                    let standardOutput = (typeof data == "object") ? data.standardOutput : "";
                                    let standardError = (typeof data == "object" && typeof data.standardError == "string") ? "error: " + data.standardError : "";
                                    if (typeof data == "object" && data.timedOut) {
                                        standardError += "error: timed out\n";
                                    }
                                    $("#codeEditorExecutionOutput<!--{$exerciseID|validate:int}-->").append(consoleToHTML(standardOutput));
                                    $("#codeEditorExecutionOutput<!--{$exerciseID|validate:int}-->").
                                        append(markupWarningsAndErrorsHTML(consoleToHTML(standardError)));
                                    break;
                            } // switch
                            setStatusIndicator<!--{$exerciseID|validate:int}-->('green');
                        }, // success
                        complete: function(jqXHR, textStatus, errorThrown) {
                             // Re-enable buttons
                             // Re-enable buttons
                             enableExecuteButton<!--{$exerciseID|validate:int}-->();
                             enableExecuteButton<!--{$exerciseID|validate:int}-->();
Line 337: Line 389:
                                 enableSyncButton<!--{$exerciseID|validate:int}-->();
                                 enableSyncButton<!--{$exerciseID|validate:int}-->();
                                 enableBroadcastButton<!--{$exerciseID|validate:int}-->();
                                 enableBroadcastButton<!--{$exerciseID|validate:int}-->();
                             }  
                             }


                             // Disable animation
                             // Disable animation
                             controlPanel.className = "merlin-code-explorer-control-panel";
                             controlPanel.className = "merlin-code-explorer-control-panel";
                         }
                         }
                     });
                     }); // ajax
 
                    // Collect response data                                                                                                                                                                                                                                                             
                    response.done(function(responseObject) {
                        switch (event.target.submitter) {
                            case "execute":
                                let compilationStatus = responseObject.compilationStatus;
                                let compilationOutput = compilationStatus.standardOutput;
                                let compilationError = compilationStatus.standardError;
                                if (compilationStatus.timedOut) {
                                    compilationError += "error: timed out\n";
                                }
 
                                $("#codeEditorCompilerOutput<!--{$exerciseID|validate:int}-->").
                                    append(markupWarningsAndErrorsHTML(consoleToHTML(compilationError)));
                                $("#codeEditorCompilerOutput<!--{$exerciseID|validate:int}-->").
                                    append(markupWarningsAndErrorsHTML(consoleToHTML(compilationOutput)));
 
                                let executionStatus = responseObject.executionStatus;
                                let executionOutput = (typeof executionStatus == "object") ? executionStatus.standardOutput : "";
                                let executionError = (typeof executionStatus == "object") ? executionStatus.standardError : "";
                                if (typeof executionStatus == "object" && executionStatus.timedOut) {
                                    executionError += "error: timed out\n";
                                }
                                $("#codeEditorExecutionOutput<!--{$exerciseID|validate:int}-->").append(consoleToHTML(executionError));
                                $("#codeEditorExecutionOutput<!--{$exerciseID|validate:int}-->").
                                    append(markupRuntimeStandardOutput(consoleToHTML(executionOutput)));
 
                                // Set compilation display
                                const $button = $("#codeEditorForm<!--{$exerciseID|validate:int}--> .merlin-code-explorer-show-compilation-button");
                                const $output = $button.parent().siblings(".merlin-code-explorer-combined-output:first");
                                if (compilationStatus.terminationStatus == 0) {
                                    $output.slideUp();
                                    $button.text("Show Compilation Output");
                                } else {
                                    $output.slideDown();
                                    $button.text("Hide Compilation Output");
                                }
 
                                break;
                            case "submit":
                                let standardOutput = (typeof responseObject == "object") ? responseObject.standardOutput : "";
                                let standardError = (typeof responseObject == "object" && typeof responseObject.standardError == "string") ? "error: " + responseObject.standardError : "";
                                if (typeof responseObject == "object" && responseObject.timedOut) {
                                    standardError += "error: timed out\n";
                                }
                                $("#codeEditorExecutionOutput<!--{$exerciseID|validate:int}-->").append(consoleToHTML(standardOutput));
                                $("#codeEditorExecutionOutput<!--{$exerciseID|validate:int}-->").
                                    append(markupWarningsAndErrorsHTML(consoleToHTML(standardError)));
                                break;
                        }
                                     
                        // Re-enable buttons
                        enableExecuteButton<!--{$exerciseID|validate:int}-->();
                        if (isCEGIDSet) {
                            enableSubmitButton<!--{$exerciseID|validate:int}-->();
                            enableSyncButton<!--{$exerciseID|validate:int}-->();
                            enableBroadcastButton<!--{$exerciseID|validate:int}-->();
                        }


                        // Disable animation
                }); // submit function
                        controlPanel.className = "merlin-code-explorer-control-panel";
                      });
                });


                 // Show Compilation
                 // Show Compilation button
                 $("#codeEditorForm<!--{$exerciseID|validate:int}--> .merlin-code-explorer-show-compilation-button").click(function () {
                 $("#codeEditorForm<!--{$exerciseID|validate:int}--> .merlin-code-explorer-show-compilation-button").click(function () {
                     const $output = $(this).parent().siblings(".merlin-code-explorer-combined-output:first");
                     const $output = $(this).parent().siblings(".merlin-code-explorer-combined-output:first");

Revision as of 15:17, 3 February 2023

Parameters:

userName
string: The current user's username
sessionID
string: The ID of the current user's session
experienceID
string: The experienceID of the page from which the widget is invoked
codeExplorerGroupID
string: The code explorer group. If empty, the submit button will be disabled.
exerciseID
integer: exercise id for editor, must be unique per page
width
integer|string: percentage (as string, e.g. "100%" or integer size in pixels), null for no change (full width)
height
integer|string: percentage (as string, e.g. "100%" or integer size in pixels), null for no change (~10 lines)
lineNumbers
boolean: true to display line numbers
theme
string: name of theme (which must be loaded via css)
readOnly
boolean: true if editing should be disabled
language
string: language for compiling and highlighting (which must be loaded via js)
initialCode
string: initial code to place in editor

Example:

{{#widget:CodeExplorer
|userName=john-williams
|sessionID=qh0ubrrme911kcg7db0i0ec6lct94h7f
|experienceID=W1020.23
|codeExplorerGroupID=WTRS-8527
|exerciseID=10
|width=null
|height=null
|lineNumbers=true
|theme=vibrant-ink
|readOnly=false
|language=swift
|initialCode=func sayHello() {
    print("Hello, World!")
}
}}