var find = document.getElementById('find'), hidePassing = document.querySelectorAll('#hide_passing input')[0], replace = document.getElementById('replace'), passedCount = document.getElementById('passed-count'), testElements = document.getElementById('tests').getElementsByTagName('dt'), permalink = document.getElementById('permalink'), cases = [], element, i, urlParts; // Loop over the list of test cases and put them in an array for (i = 0; i < testElements.length; i++) { element = testElements[i]; cases[i] = { input: htmlToText(element.innerHTML), output: htmlToText(element.nextSibling.innerHTML) }; // Add the "it should've been X" element to each test case element.parentNode.insertBefore(document.createElement('dd'), element.nextSibling.nextSibling); }; // For validating and live-testing of the regex find.addEventListener('keyup', function(e){ validateRegex(false); }); find.addEventListener('blur', function(e){ validateRegex(true); }); if (replace){ replace.addEventListener('keyup', function(e){ validateRegex(true); }); } // Allow the URL to contain regex and replace values urlParts = location.search.replace('?', '').split(/[\&\=]/); for (i = 0; i < urlParts.length; i += 2){ if (urlParts[i] == 'find' && find) { find.value = decodeURIComponent(urlParts[i + 1]); } if (urlParts[i] == 'replace' && replace) { replace.value = decodeURIComponent(urlParts[i + 1]); } } if (find.value) { validateRegex(true); } // Handle "Hide passing tests" hidePassing.addEventListener('change', function () { document.body.classList.toggle('hide_passing'); window.localStorage.hidePassing = this.checked; }); if (window.localStorage.hidePassing === 'true') { document.body.classList.add('hide_passing'); hidePassing.checked = true; } function validateRegex(warnUser) { var regex = find.value, url = location.origin + location.pathname, passes = 0, fails = 0, element, i, newClass, output, test; url += '?find=' + encodeURIComponent(find.value); if (replace) { url += '&replace=' + encodeURIComponent(replace.value); } permalink.setAttribute('href', url); if (regex === '') { find.className = ''; return false; } // Validating regex using regex... that's meta. if (regex = /^\/(.*)\/([a-z]*)$/.exec(regex)) { try { if (regex[2].indexOf('x') !== -1) { regex[1] = regex[1].replace(/([^\\]|^)\s/g, '$1'); regex[2] = regex[2].replace('x', ''); } regex = new RegExp(regex[1], regex[2]); } catch (error) { if (warnUser) { find.className = 'invalid'; } return false; } // Valid regex! find.className = ''; for (i = 0; i < cases.length; i++) { test = cases[i]; element = testElements[i]; if (replace) { output = test.input.replace(regex, replace.value); element.nextSibling.nextSibling.innerHTML = textToHtml(output); if (output === test.output) { newClass = 'passed'; passes++; } else { newClass = 'failed showfail'; fails++; } } else { if (regex.test(test.input) === (test.output === 'match')) { newClass = 'passed'; passes++; } else { newClass = 'failed'; } } element.nextSibling.className = element.className = newClass; } // Let the user know how many tests they passed passedCount.textContent = passes; if (fails === 0) { document.body.classList.add('all_passing'); } else { document.body.classList.remove('all_passing'); } return true; } else if (warnUser) { find.className = 'invalid'; } return false; } function htmlToText(html) { return html.replace(/\/g, '\n') .replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>'); } function textToHtml(text) { return text.replace(/&/g, '&').replace(/\/g, '>') .replace(/\n/g, '
'); }