function init(PHP) { var JS = {}, d; // Tokenize JS.tokens = CoffeeScript.tokens(PHP.coffee, { rewrite: PHP.rewrite }); // Tokens diff d = JsDiff.diffLines(formatTokens(JS.tokens), formatTokens(PHP.tokens)); $('#tokens .result').innerHTML = formatDiffLines(d); var tokenFailed = d.length > 1 || d[0].removed; $('#tokens .' + (tokenFailed ? 'fail' : 'pass')).style.display = 'block'; // Compile JS.js = CoffeeScript.require['./parser'].parse(JS.tokens).compile(); // Code diff d = JsDiff.diffLines(JS.js, PHP.js); var codeFailed = d.length > 1 || d[0].removed; $('#code .result').innerHTML = formatDiffLines(d); var result = $('#code .' + (codeFailed ? 'fail' : 'pass')); result.style.display = 'block'; if (PHP.error) { result.innerHTML += '
' + PHP.error + ''; } if (parent.testComplete) { parent.testComplete(codeFailed, tokenFailed); } } function $(elem) { return typeof elem == 'string' ? document.querySelector(elem) : elem; } function formatDiffLines(diff) { var html = '', line = [1, 1]; for (var i = 0; i < diff.length; i++) { var d = diff[i], v = trim(d.value).split('\n'); for (var j = 0; j < v.length; j++) { if (d.added) { html += lpad(5) + lpad(line[1]++, 4) + ' +'; v[j] = '' + v[j] + ''; } else if (d.removed) { html += lpad(line[0]++, 4) + lpad(5) + ' -'; v[j] = '' + v[j] + ''; } else { html += lpad(line[0]++, 4) + lpad(line[1]++, 5) + ' '; } html += lpad(1) + v[j] + '
'; } } return html; } function formatTokens(tokens) { var html = [], props = [0, 1, 2, 'call', 'fromThen', 'generated', 'newLine', 'spaced']; for (var i = 0; i < tokens.length; i++) { var token = []; for (var j = 0; j < props.length; j++) { var key = props[j], value = tokens[i] && tokens[i][key]; if (typeof value == 'string') { value = value.replace(/\n/g, '\\n'); } if (typeof key == 'string') { if ( !! value) { token.push(k); } } else { if (key === 1) { var tmp = '', _props = ['generated', 'reserved']; for (var k = 0; k < _props.length; k++) { if (value && value[ _props[k] ]) { tmp += ' ' + _props[k]; } } if (tmp) { value = '< ' + value + tmp + ' >'; } } token.push('"' + value + '"'); } } html.push('[' + token.join(', ') + ']'); } return html.join('\n'); } // Add padding to the left of str until str.length is length. function lpad(str, length) { if (arguments.length === 1) { length = str; str = ''; } var d = length - (str + '').length; while (d-- > 0) { str = ' ' + str; } return str; } // Remove writespace from both sides function trim(str) { return str.replace(/^\n+|\n+$/g,''); }