From 34f055d1e07a90d46210daa4d9fbc3024a6c1acc Mon Sep 17 00:00:00 2001 From: aryamadhavi03 Date: Thu, 25 Sep 2025 11:52:28 +0530 Subject: [PATCH] Added Coding Practice Feature with Interactive JS --- demos/coding-practice.html | 191 +++++++++++++++++++++++++++++++++ demos/css/code-practice.css | 206 ++++++++++++++++++++++++++++++++++++ demos/index.html | 3 + demos/js/code-editor.js | 66 ++++++++++++ demos/js/code-executor.js | 133 +++++++++++++++++++++++ 5 files changed, 599 insertions(+) create mode 100644 demos/coding-practice.html create mode 100644 demos/css/code-practice.css create mode 100644 demos/js/code-editor.js create mode 100644 demos/js/code-executor.js diff --git a/demos/coding-practice.html b/demos/coding-practice.html new file mode 100644 index 00000000..240b94ef --- /dev/null +++ b/demos/coding-practice.html @@ -0,0 +1,191 @@ +--- +title: JavaScript Coding Practice +layout: default +--- + + + + + JavaScript Coding Practice + + + + + + + + + + + + + + +
+

JavaScript Coding Practice

+ +

Welcome to the interactive JavaScript coding practice! This tool allows you to write, run, and test JavaScript code directly in your browser.

+ +
+ + +
+ +
+
Hello World
+
+ Write a JavaScript function that returns the string "Hello, World!". +
+
+ +
+
+ JavaScript Code Editor +
+ +
+ + +
+
+
Output will appear here...
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/demos/css/code-practice.css b/demos/css/code-practice.css new file mode 100644 index 00000000..f04d3c48 --- /dev/null +++ b/demos/css/code-practice.css @@ -0,0 +1,206 @@ +/** + * Styles for the JavaScript Coding Practice feature + */ + +/* Main container styles */ +.code-practice-container { + max-width: 1200px; + margin: 0 auto; + padding: 20px; + font-family: Arial, sans-serif; +} + +/* Code editor container */ +.code-editor-container { + display: flex; + flex-direction: column; + margin: 20px 0; + border: 1px solid #ccc; + border-radius: 5px; + overflow: hidden; + box-shadow: 0 2px 5px rgba(0,0,0,0.1); +} + +/* Code editor header */ +.code-editor-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 10px 15px; + background-color: #2c3e50; + color: white; + font-weight: bold; +} + +/* Editor area - when CodeMirror is not available */ +.code-editor { + width: 100%; + height: 300px; + font-family: 'Courier New', monospace; + font-size: 14px; + padding: 10px; + border: none; + resize: vertical; + background-color: #272822; + color: #f8f8f2; +} + +/* CodeMirror specific styles */ +.CodeMirror { + height: auto; + min-height: 300px; + font-family: 'Courier New', monospace; + font-size: 14px; + line-height: 1.5; +} + +/* Output container */ +.output-container { + padding: 15px; + background-color: #f9f9f9; + border-top: 1px solid #ccc; + min-height: 100px; + max-height: 200px; + overflow-y: auto; + font-family: 'Courier New', monospace; +} + +/* Button container */ +.button-container { + display: flex; + justify-content: space-between; + padding: 10px 15px; + background-color: #f5f5f5; + border-top: 1px solid #ccc; +} + +/* Run button */ +.run-button { + padding: 8px 16px; + background-color: #27ae60; + color: white; + border: none; + border-radius: 4px; + cursor: pointer; + font-weight: bold; + transition: background-color 0.2s; +} + +.run-button:hover { + background-color: #2ecc71; +} + +/* Reset button */ +.reset-button { + padding: 8px 16px; + background-color: #e74c3c; + color: white; + border: none; + border-radius: 4px; + cursor: pointer; + font-weight: bold; + transition: background-color 0.2s; +} + +.reset-button:hover { + background-color: #c0392b; +} + +/* Challenge container */ +.challenge-container { + margin: 20px 0; + padding: 20px; + background-color: #ecf0f1; + border-left: 5px solid #3498db; + border-radius: 4px; +} + +/* Challenge title */ +.challenge-title { + font-size: 20px; + font-weight: bold; + margin-bottom: 15px; + color: #2c3e50; +} + +/* Challenge description */ +.challenge-description { + margin-bottom: 15px; + line-height: 1.5; + color: #34495e; +} + +/* Challenge selector */ +.challenge-selector { + margin: 20px 0; +} + +.challenge-selector select { + padding: 8px 12px; + border: 1px solid #ccc; + border-radius: 4px; + background-color: white; + font-size: 16px; + min-width: 200px; +} + +/* Test results */ +.test-results { + margin-top: 20px; + padding: 15px; + background-color: #f8f9fa; + border-radius: 4px; + border: 1px solid #e9ecef; +} + +.test-results h3 { + margin-top: 0; + color: #2c3e50; +} + +.test-item { + margin: 8px 0; + padding: 8px; + border-radius: 4px; +} + +.test-pass { + background-color: #d4edda; + color: #155724; +} + +.test-fail { + background-color: #f8d7da; + color: #721c24; +} + +/* Console output styling */ +.console-log { + padding: 2px 0; + font-family: 'Courier New', monospace; +} + +.console-error { + color: #e74c3c; + font-weight: bold; +} + +/* Responsive adjustments */ +@media (max-width: 768px) { + .code-editor-container { + margin: 10px 0; + } + + .challenge-selector select { + width: 100%; + } + + .button-container { + flex-direction: column; + gap: 10px; + } + + .run-button, .reset-button { + width: 100%; + } +} \ No newline at end of file diff --git a/demos/index.html b/demos/index.html index 29bafe2d..ad9c2e23 100644 --- a/demos/index.html +++ b/demos/index.html @@ -45,6 +45,9 @@

Web Services

  • yahoo
  • +

    Learning

    +
  • Coding Practice
  • +

    Code sugar

  • AMD
  • Promises/A+
  • \ No newline at end of file diff --git a/demos/js/code-editor.js b/demos/js/code-editor.js new file mode 100644 index 00000000..3cc33bdd --- /dev/null +++ b/demos/js/code-editor.js @@ -0,0 +1,66 @@ +/** + * JavaScript Code Editor Implementation + * Uses CodeMirror for syntax highlighting and code editing features + */ + +let editor; // Global editor instance + +// Initialize the code editor with CodeMirror +function initCodeEditor() { + // Get the textarea element + const codeEditorElement = document.getElementById('code-editor'); + + // If CodeMirror is available, replace the textarea with CodeMirror + if (typeof CodeMirror !== 'undefined') { + // Initialize CodeMirror + editor = CodeMirror.fromTextArea(codeEditorElement, { + mode: 'javascript', + theme: 'monokai', + lineNumbers: true, + autoCloseBrackets: true, + matchBrackets: true, + indentUnit: 4, + tabSize: 4, + indentWithTabs: false, + extraKeys: { + "Tab": function(cm) { + if (cm.somethingSelected()) { + cm.indentSelection("add"); + } else { + cm.replaceSelection(" ".repeat(cm.getOption("indentUnit")), "end", "+input"); + } + } + } + }); + + // Set initial content + editor.setValue(challenges[document.getElementById('challenge-select').value].initialCode); + + // Auto-resize editor based on content + editor.setSize(null, 'auto'); + editor.setOption('viewportMargin', Infinity); + } +} + +// Get code from the editor +function getCode() { + if (editor) { + return editor.getValue(); + } else { + return document.getElementById('code-editor').value; + } +} + +// Set code in the editor +function setCode(code) { + if (editor) { + editor.setValue(code); + } else { + document.getElementById('code-editor').value = code; + } +} + +// Update the editor when a new challenge is selected +function updateEditorContent(code) { + setCode(code); +} \ No newline at end of file diff --git a/demos/js/code-executor.js b/demos/js/code-executor.js new file mode 100644 index 00000000..c7915500 --- /dev/null +++ b/demos/js/code-executor.js @@ -0,0 +1,133 @@ +/** + * JavaScript Code Execution Functionality + * Handles running code, capturing output, and running tests + */ + +// Run the code entered by the user +function executeCode(code) { + const output = document.getElementById('output'); + output.innerHTML = ''; + + // Capture console.log output + const originalConsoleLog = console.log; + const originalConsoleError = console.error; + const originalConsoleWarn = console.warn; + const logs = []; + + // Override console methods to capture output + console.log = function() { + const args = Array.from(arguments).join(' '); + logs.push({ type: 'log', content: args }); + originalConsoleLog.apply(console, arguments); + }; + + console.error = function() { + const args = Array.from(arguments).join(' '); + logs.push({ type: 'error', content: args }); + originalConsoleError.apply(console, arguments); + }; + + console.warn = function() { + const args = Array.from(arguments).join(' '); + logs.push({ type: 'warn', content: args }); + originalConsoleWarn.apply(console, arguments); + }; + + try { + // Create a sandbox function to execute the code + // This helps prevent some global scope issues + const sandboxFn = new Function(code); + sandboxFn(); + + // Display the output + displayLogs(logs, output); + + return { success: true, logs }; + } catch (error) { + // Display the error + const errorElement = document.createElement('div'); + errorElement.className = 'console-error'; + errorElement.textContent = error.toString(); + output.appendChild(errorElement); + + logs.push({ type: 'error', content: error.toString() }); + return { success: false, error: error.toString(), logs }; + } finally { + // Restore console methods + console.log = originalConsoleLog; + console.error = originalConsoleError; + console.warn = originalConsoleWarn; + } +} + +// Display logs in the output container +function displayLogs(logs, outputContainer) { + logs.forEach(log => { + const logElement = document.createElement('div'); + logElement.className = `console-${log.type}`; + logElement.textContent = log.content; + outputContainer.appendChild(logElement); + }); +} + +// Run tests for the current challenge +function runTests(challengeId) { + const challenge = challenges[challengeId]; + const testResultsElement = document.getElementById('test-results'); + testResultsElement.innerHTML = ''; + + // Create test results container + const testsContainer = document.createElement('div'); + testsContainer.className = 'test-results'; + testsContainer.innerHTML = '

    Test Results:

    '; + testResultsElement.appendChild(testsContainer); + + // Run each test + const testResults = []; + challenge.tests.forEach(test => { + const testElement = document.createElement('div'); + let passed = false; + let errorMessage = null; + + try { + passed = eval(test.test); + } catch (error) { + passed = false; + errorMessage = error.toString(); + } + + testElement.className = passed ? 'test-item test-pass' : 'test-item test-fail'; + testElement.innerHTML = `${passed ? '✓' : '✗'} ${test.name}`; + + if (errorMessage) { + const errorElement = document.createElement('div'); + errorElement.className = 'test-error'; + errorElement.textContent = errorMessage; + testElement.appendChild(errorElement); + } + + testsContainer.appendChild(testElement); + testResults.push({ name: test.name, passed, errorMessage }); + }); + + return testResults; +} + +// Main function to run code and tests +function runCode() { + const code = getCode(); // Get code from editor + const output = document.getElementById('output'); + const challengeId = document.getElementById('challenge-select').value; + + // Clear previous output and test results + output.innerHTML = ''; + document.getElementById('test-results').innerHTML = ''; + + // Execute the code + const result = executeCode(code); + + // If code executed successfully, run tests + if (result.success) { + runTests(challengeId); + } +} \ No newline at end of file