$(function(){ // disable Ajax cache $.ajaxSetup({ cache: false }); // repository url text field $('#repository-url').click(function(){ this.select(0, this.value.length); }); // activate tooltip $('img[data-toggle=tooltip]').tooltip(); $('a[data-toggle=tooltip]').tooltip(); $('li[data-toggle=tooltip]').tooltip(); // anchor icon for markdown $('.markdown-head').mouseenter(function(e){ $(e.target).children('a.markdown-anchor-link').show(); }); $('.markdown-head').mouseleave(function(e){ var anchorLink = $(e.target).children('a.markdown-anchor-link'); if(anchorLink.data('active') !== true){ anchorLink.hide(); } }); $('a.markdown-anchor-link').mouseenter(function(e){ $(e.target).data('active', true); }); $('a.markdown-anchor-link').mouseleave(function(e){ $(e.target).data('active', false); $(e.target).hide(); }); // syntax highlighting by google-code-prettify prettyPrint(); }); function displayErrors(data, elem){ var i = 0; $.each(data, function(key, value){ $('#error-' + key.split(".").join("_"), elem).text(value); if(i === 0){ $('#' + key, elem).focus(); } i++; }); } (function($){ $.fn.watch = function(callback){ var timer = null; var prevValue = this.val(); this.on('focus', function(e){ window.clearInterval(timer); timer = window.setInterval(function(){ var newValue = $(e.target).val(); if(prevValue != newValue){ callback(); } prevValue = newValue; }, 10); }); this.on('blur', function(){ window.clearInterval(timer); }); }; })(jQuery); /** * Render diff using jsdifflib. * * @param oldTextId {String} element id of old text * @param newTextId {String} element id of new text * @param outputId {String} element id of output element * @param viewType {Number} 0: split, 1: unified * @param ignoreSpace {Number} 0: include, 1: ignore */ function diffUsingJS(oldTextId, newTextId, outputId, viewType, ignoreSpace) { var old = $('#'+oldTextId), head = $('#'+newTextId); var render = new JsDiffRender({ oldText: old.val(), oldTextName: old.data('file-name'), newText: head.val(), newTextName: head.data('file-name'), ignoreSpace: ignoreSpace, contextSize: 4 }); var diff = render[viewType==1 ? "unified" : "split"](); diff.appendTo($('#'+outputId).html("")); } function jqSelectorEscape(val) { return val.replace(/[!"#$%&'()*+,.\/:;<=>?@\[\\\]^`{|}~]/g, '\\$&'); } function JsDiffRender(params){ var baseTextLines = (params.oldText==="")?[]:params.oldText.split(/\r\n|\r|\n/); var headTextLines = (params.newText==="")?[]:params.newText.split(/\r\n|\r|\n/); var sm, ctx; if(params.ignoreSpace){ var ignoreSpace = function(a){ return a.replace(/\s+/,' ').replace(/^\s+|\s+$/,''); }; sm = new difflib.SequenceMatcher( $.map(baseTextLines, ignoreSpace), $.map(headTextLines, ignoreSpace)); ctx = this.flatten(sm.get_opcodes(), headTextLines, baseTextLines, function(text){ return ignoreSpace(text) === ""; }); }else{ sm = new difflib.SequenceMatcher(baseTextLines, headTextLines); ctx = this.flatten(sm.get_opcodes(), headTextLines, baseTextLines, function(){ return false; }); } var oplines = this.fold(ctx, params.contextSize); function prettyDom(text, fileName){ var dom = null; return function(ln){ if(dom===null){ var html = prettyPrintOne( text.replace(/&/g,'&').replace(/</g,'<').replace(/"/g,'"').replace(/>/g,'>'), (/\.([^.]*)$/.exec(fileName)||[])[1], true); var re = /<li[^>]*id="?L([0-9]+)"?[^>]*>(.*?)<\/li>/gi, h; dom=[]; while(h=re.exec(html)){ dom[h[1]]=h[2]; } } return dom[ln]; }; } return this.renders(oplines, prettyDom(params.oldText, params.oldTextName), prettyDom(params.newText, params.newTextName)); } $.extend(JsDiffRender.prototype,{ renders: function(oplines, baseTextDom, headTextDom){ return { split:function(){ var table = $('<table class="diff">'); table.attr({add:oplines.add, del:oplines.del}); var tbody = $('<tbody>').appendTo(table); for(var i=0;i<oplines.length;i++){ var o = oplines[i]; switch(o.change){ case 'skip': $('<tr>').html('<th class="skip"></th><td colspan="3" class="skip">...</td>').appendTo(tbody); break; case 'delete': case 'insert': case 'equal': $('<tr>').append( lineNum('old',o.base, o.change), $('<td class="body">').html(o.base ? baseTextDom(o.base): "").addClass(o.change), lineNum('old',o.head, o.change), $('<td class="body">').html(o.head ? headTextDom(o.head): "").addClass(o.change) ).appendTo(tbody); break; case 'replace': var ld = lineDiff(baseTextDom(o.base), headTextDom(o.head)); $('<tr>').append( lineNum('old',o.base, 'delete'), $('<td class="body">').append(ld.base).addClass('delete'), lineNum('old',o.head, 'insert'), $('<td class="body">').append(ld.head).addClass('insert') ).appendTo(tbody); break; } } return table; }, unified:function(){ var table = $('<table class="diff inlinediff">'); table.attr({add:oplines.add, del:oplines.del}); var tbody = $('<tbody>').appendTo(table); for(var i=0;i<oplines.length;i++){ var o = oplines[i]; switch(o.change){ case 'skip': tbody.append($('<tr>').html('<th colspan="2" class="skip"></th><td class="skip"></td>')); break; case 'delete': case 'insert': case 'equal': tbody.append($('<tr>').append( lineNum('old',o.base, o.change), lineNum('new',o.head, o.change), $('<td class="body">').addClass(o.change).html(o.head ? headTextDom(o.head) : baseTextDom(o.base)))); break; case 'replace': var deletes = []; while(oplines[i] && oplines[i].change == 'replace'){ if(oplines[i].base && oplines[i].head){ var ld = lineDiff(baseTextDom(oplines[i].base), headTextDom(oplines[i].head)); tbody.append($('<tr>').append(lineNum('old', oplines[i].base, 'delete'),'<th class="delete">',$('<td class="body delete">').append(ld.base))); deletes.push($('<tr>').append('<th class="insert">',lineNum('new',oplines[i].head, 'insert'),$('<td class="body insert">').append(ld.head))); }else if(oplines[i].base){ tbody.append($('<tr>').append(lineNum('old', oplines[i].base, 'delete'),'<th class="delete">',$('<td class="body delete">').html(baseTextDom(oplines[i].base)))); }else if(oplines[i].head){ deletes.push($('<tr>').append('<th class="insert">',lineNum('new',oplines[i].head, 'insert'),$('<td class="body insert">').html(headTextDom(oplines[i].head)))); } i++; } tbody.append(deletes); i--; break; } } return table; } }; function lineNum(type, num, klass){ var cell = $('<th class="line-num">').addClass(type+'line').addClass(klass); if(num){ cell.attr('line-number',num); } return cell; } function lineDiff(b,n){ var bc = $('<diff>').html(b).children(); var nc = $('<diff>').html(n).children(); var textE = function(){ return $(this).text(); }; var sm = new difflib.SequenceMatcher(bc.map(textE), nc.map(textE)); var op = sm.get_opcodes(); if(op.length==1 || sm.ratio()<0.5){ return {base:bc,head:nc}; } var ret = { base : [], head: []}; for(var i=0;i<op.length;i++){ var o = op[i]; switch(o[0]){ case 'equal': ret.base=ret.base.concat(bc.slice(o[1],o[2])); ret.head=ret.head.concat(nc.slice(o[3],o[4])); break; case 'delete': case 'insert': case 'replace': if(o[2]!=o[1]){ ret.base.push($('<del>').append(bc.slice(o[1],o[2]))); } if(o[4]!=o[3]){ ret.head.push($('<ins>').append(nc.slice(o[3],o[4]))); } break; } } return ret; } }, flatten: function(opcodes, headTextLines, baseTextLines, isIgnoreLine){ var ret = [], add=0, del=0; for (var idx = 0; idx < opcodes.length; idx++) { var code = opcodes[idx]; var change = code[0]; var b = code[1]; var n = code[3]; var rowcnt = Math.max(code[2] - b, code[4] - n); for (var i = 0; i < rowcnt; i++) { switch(change){ case 'insert': add++; ret.push({ change:(isIgnoreLine(headTextLines[n]) ? 'equal' : change), head: ++n }); break; case 'delete': del++; ret.push({ change: (isIgnoreLine(baseTextLines[b]) ? 'equal' : change), base: ++b }); break; case 'replace': add++; del++; var r = {change: change}; if(n<code[4]){ r.head = ++n; } if(b<code[2]){ r.base = ++b; } ret.push(r); break; default: ret.push({ change:change, head: ++n, base: ++b }); } } } ret.add=add; ret.del=del; return ret; }, fold: function(oplines, contextSize){ var ret = [], skips=[], bskip = contextSize; for(var i=0;i<oplines.length;i++){ var o = oplines[i]; if(o.change=='equal'){ if(bskip < contextSize){ bskip ++; ret.push(o); }else{ skips.push(o); } }else{ if(skips.length > contextSize){ ret.push({ change:'skip', start:skips[0], end:skips[skips.length-contextSize] }); } ret = ret.concat(skips.splice(- contextSize)); ret.push(o); skips = []; bskip = 0; } } if(skips.length > contextSize){ ret.push({ change:'skip', start:skips[0], end:skips[skips.length-contextSize] }); } ret.add = oplines.add; ret.del = oplines.del; return ret; } });