function updateResults(elem) { if ($(elem).length ===0){return false;}; var resultsContainer = $(elem).find('[data-id="results"]')[0]; var codeHtml = $(elem).find('.code-html')[0].value.trim(); var codeCss = $(elem).find('.code-css')[0].value.trim(); var codeJs = $(elem).find('.code-js')[0].value.trim(); resultsContainer.innerHTML = ""; var iDoc = document.createElement('html'); var iHead = document.createElement('head'); var iBody = document.createElement('body'); var codeFrame = document.createElement('iframe'); codeFrame.setAttribute("width", "100%"); codeFrame.setAttribute("height", "100%"); resultsContainer.appendChild(codeFrame); var jqueryNode = document.createElement("script"); jqueryNode.setAttribute("type", "text/javascript"); // TODO: fix eslint runner to handle erb snippets // jqueryNode.setAttribute("src", "<%= "//#{ENV['full_app_url']}#{javascript_path "jquery"}" %>"); jqueryNode.setAttribute("src", "https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"); iHead.appendChild(jqueryNode); var codeStyle = document.createElement("style"); codeStyle.setAttribute("type", "text/css"); var rulesNode = document.createTextNode(codeCss); codeStyle.appendChild(rulesNode); iHead.appendChild(codeStyle); iDoc.appendChild(iHead); iBody.innerHTML = codeHtml; iDoc.appendChild(iBody); var codeScript = document.createElement("script"); codeScript.setAttribute("type", "text/javascript"); var scriptNode = document.createTextNode("setTimeout(function(){ " + codeJs + "}, 800);"); codeScript.appendChild(scriptNode); iDoc.appendChild(codeScript); codeFrame.contentWindow.document.open(); codeFrame.contentWindow.document.appendChild(iDoc); codeFrame.contentWindow.document.close(); } function indentSelection(e){ if(e.keyCode === 9){ e.preventDefault(); var indent = " "; var cursor = e.target.selectionStart; var val = e.target.value; var valStart = val.substring(0, e.target.selectionStart); var valEnd = val.substring(e.target.selectionEnd, val.length); var selected = val.substring(e.target.selectionStart, e.target.selectionEnd); var resetCursor = function(start, end){ e.target.selectionStart = start; e.target.selectionEnd = end; }; var indented; if(e.shiftKey){ //de-indent if(selected.length > 0 && (/\n/.test(selected))){ //multi line indented = selected.split(/\n/).map(function(line){ if(line.length > 0 && line.substring(0, indent.length) === indent){ line = line.substring(indent.length, line.length); } return line; }).join("\n"); e.target.value = valStart + indented + val.substring(e.target.selectionEnd, val.length); resetCursor(cursor, cursor + indented.length); } else { if(valStart.substring(valStart.length - indent.length) === indent){ e.target.value = valStart.substring(0, valStart.length - indent.length) + valEnd; resetCursor(cursor, cursor - indent.length); } else if(valEnd.substring(0, indent.length) === indent) { e.target.value = valStart + valEnd.substring(indent.length, valEnd.length); resetCursor(cursor, cursor); } } } else { //indent if(selected.length > 0 && (/\n/.test(selected))){ //multi line indented = selected.split(/\n/).map(function(line){ if(line.length > 0){ line = indent + line; } return line; }).join("\n"); e.target.value = valStart + indented + val.substring(e.target.selectionEnd, val.length); resetCursor(cursor, cursor + indented.length); } else { e.target.value = valStart + indent + selected + valEnd; resetCursor(cursor + indent.length, cursor + indent.length); } } } } var timer = 0; $(function(){ // wait a half second before updating results // restart the timer if they resume typing $('html').on('keyup', '.code-input textarea', function(){ var elem = $(this).closest("[data-id=live-coder-answer]"); if (timer) { clearTimeout(timer); } timer = setTimeout(updateResults(elem), 500); }); $("[data-id=live-coder-answer]").each(function(){ updateResults(this); }); $("html").on('keydown', "textarea[data-id^=code-]", function(e){ indentSelection(e); }); $(".code-input textarea").linedtextarea(); });