6 lines
31 KiB
JavaScript
6 lines
31 KiB
JavaScript
/**
|
|
* Copyright (c) 2014 by Jamie Peabody, http://www.mergely.com
|
|
* All rights reserved.
|
|
* Version: 3.3.7 2014-08-17
|
|
*/
|
|
Mgly={},Mgly.Timer=function(){var a=this;a.start=function(){a.t0=(new Date).getTime()},a.stop=function(){var b=(new Date).getTime(),c=b-a.t0;return a.t0=b,c},a.start()},Mgly.ChangeExpression=new RegExp(/(^(?![><-])*\d+(?:,\d+)?)([acd])(\d+(?:,\d+)?)/),Mgly.DiffParser=function(a){for(var b=[],c=0,d=a.split(/\n/),e=0;e<d.length;++e)if(0!=d[e].length){var f={},g=Mgly.ChangeExpression.exec(d[e]);if(null!=g){var h=g[1].split(",");f["lhs-line-from"]=h[0]-1,f["lhs-line-to"]=1==h.length?h[0]-1:h[1]-1;var i=g[3].split(",");f["rhs-line-from"]=i[0]-1,f["rhs-line-to"]=1==i.length?i[0]-1:i[1]-1,f.op=g[2],b[c++]=f}}return b},Mgly.sizeOf=function(a){var c,b=0;for(c in a)a.hasOwnProperty(c)&&b++;return b},Mgly.LCS=function(a,b){this.x=a.replace(/[ ]{1}/g,"\n"),this.y=b.replace(/[ ]{1}/g,"\n")},jQuery.extend(Mgly.LCS.prototype,{clear:function(){this.ready=0},diff:function(a,b){for(var c=new Mgly.diff(this.x,this.y,{ignorews:!1}),d=Mgly.DiffParser(c.normal_form()),e=0,f=0,g=0;g<d.length;++g){var h=d[g];if("a"!=h.op){e=c.getLines("lhs").slice(0,h["lhs-line-from"]).join(" ").length,f=h["lhs-line-to"]+1;var i=c.getLines("lhs").slice(h["lhs-line-from"],f).join(" ");"d"==h.op?i+=" ":e>0&&"c"==h.op&&(e+=1),b(e,e+i.length)}if("d"!=h.op){e=c.getLines("rhs").slice(0,h["rhs-line-from"]).join(" ").length,f=h["rhs-line-to"]+1;var j=c.getLines("rhs").slice(h["rhs-line-from"],f).join(" ");"a"==h.op?j+=" ":e>0&&"c"==h.op&&(e+=1),a(e,e+j.length)}}}}),Mgly.CodeifyText=function(a){this._max_code=0,this._diff_codes={},this.ctxs={},this.options={ignorews:!1},jQuery.extend(this,a),this.lhs=a.lhs.split("\n"),this.rhs=a.rhs.split("\n")},jQuery.extend(Mgly.CodeifyText.prototype,{getCodes:function(a){if(!this.ctxs.hasOwnProperty(a)){var b=this._diff_ctx(this[a]);this.ctxs[a]=b,b.codes.length=Object.keys(b.codes).length}return this.ctxs[a].codes},getLines:function(a){return this.ctxs[a].lines},_diff_ctx:function(a){var b={i:0,codes:{},lines:a};return this._codeify(a,b),b},_codeify:function(a,b){this._max_code;for(var d=0;d<a.length;++d){var e=a[d];this.options.ignorews&&(e=e.replace(/\s+/g,""));var f=this._diff_codes[e];void 0!=f?b.codes[d]=f:(this._max_code++,this._diff_codes[e]=this._max_code,b.codes[d]=this._max_code)}}}),Mgly.diff=function(a,b,c){var d=jQuery.extend({ignorews:!1},c);this.codeify=new Mgly.CodeifyText({lhs:a,rhs:b,options:d});var e={codes:this.codeify.getCodes("lhs"),modified:{}},f={codes:this.codeify.getCodes("rhs"),modified:{}},g=e.codes.length+f.codes.length+1,h=Array(2*g+2),i=Array(2*g+2);this._lcs(e,0,e.codes.length,f,0,f.codes.length,i,h),this._optimize(e),this._optimize(f),this.items=this._create_diffs(e,f)},jQuery.extend(Mgly.diff.prototype,{changes:function(){return this.items},getLines:function(a){return this.codeify.getLines(a)},normal_form:function(){for(var a="",b=0;b<this.items.length;++b){var c=this.items[b],d="",e="",f="c";0==c.lhs_deleted_count&&c.rhs_inserted_count>0?f="a":c.lhs_deleted_count>0&&0==c.rhs_inserted_count&&(f="d"),d=1==c.lhs_deleted_count?c.lhs_start+1:0==c.lhs_deleted_count?c.lhs_start:c.lhs_start+1+","+(c.lhs_start+c.lhs_deleted_count),e=1==c.rhs_inserted_count?c.rhs_start+1:0==c.rhs_inserted_count?c.rhs_start:c.rhs_start+1+","+(c.rhs_start+c.rhs_inserted_count),a+=d+f+e+"\n";var g=this.getLines("lhs"),h=this.getLines("rhs");if(h&&g){for(var i=c.lhs_start;i<c.lhs_start+c.lhs_deleted_count;++i)a+="< "+g[i]+"\n";c.rhs_inserted_count&&c.lhs_deleted_count&&(a+="---\n");for(var i=c.rhs_start;i<c.rhs_start+c.rhs_inserted_count;++i)a+="> "+h[i]+"\n"}}return a},_lcs:function(a,b,c,d,e,f,g,h){for(;c>b&&f>e&&a.codes[b]==d.codes[e];)++b,++e;for(;c>b&&f>e&&a.codes[c-1]==d.codes[f-1];)--c,--f;if(b==c)for(;f>e;)d.modified[e++]=!0;else if(e==f)for(;c>b;)a.modified[b++]=!0;else{var i=this._sms(a,b,c,d,e,f,g,h);this._lcs(a,b,i.x,d,e,i.y,g,h),this._lcs(a,i.x,c,d,i.y,f,g,h)}},_sms:function(a,b,c,d,e,f,g,h){var i=a.codes.length+d.codes.length+1,j=b-e,k=c-f,l=c-b-(f-e),m=0!=(1&l),n=i-j,o=i-k,p=(c-b+f-e)/2+1;h[n+j+1]=b,g[o+k-1]=c;for(var q={x:0,y:0},r=0;p>=r;++r){for(var s=j-r;j+r>=s;s+=2){var t,u;for(s==j-r?t=h[n+s+1]:(t=h[n+s-1]+1,j+r>s&&h[n+s+1]>=t&&(t=h[n+s+1])),u=t-s;c>t&&f>u&&a.codes[t]==d.codes[u];)t++,u++;if(h[n+s]=t,m&&s>k-r&&k+r>s&&g[o+s]<=h[n+s])return q.x=h[n+s],q.y=h[n+s]-s,q}for(var s=k-r;k+r>=s;s+=2){var t,u;for(s==k+r?t=g[o+s-1]:(t=g[o+s+1]-1,s>k-r&&g[o+s-1]<t&&(t=g[o+s-1])),u=t-s;t>b&&u>e&&a.codes[t-1]==d.codes[u-1];)t--,u--;if(g[o+s]=t,!m&&s>=j-r&&j+r>=s&&g[o+s]<=h[n+s])return q.x=h[n+s],q.y=h[n+s]-s,q}}throw"the algorithm should never come here."},_optimize:function(a){for(var b=0,c=0;b<a.length;){for(;b<a.length&&(void 0==a.modified[b]||0==a.modified[b]);)b++;for(c=b;c<a.length&&1==a.modified[c];)c++;c<a.length&&a.ctx[b]==a.codes[c]?(a.modified[b]=!1,a.modified[c]=!0):b=c}},_create_diffs:function(a,b){for(var c=[],d=0,e=0,f=0,g=0;f<a.codes.length||g<b.codes.length;)if(f<a.codes.length&&!a.modified[f]&&g<b.codes.length&&!b.modified[g])f++,g++;else{for(d=f,e=g;f<a.codes.length&&(g>=b.codes.length||a.modified[f]);)f++;for(;g<b.codes.length&&(f>=a.codes.length||b.modified[g]);)g++;(f>d||g>e)&&c.push({lhs_start:d,rhs_start:e,lhs_deleted_count:f-d,rhs_inserted_count:g-e})}return c}}),Mgly.mergely=function(a,b){a&&this.init(a,b)},jQuery.extend(Mgly.mergely.prototype,{name:"mergely",init:function(a,b){this.diffView=new Mgly.CodeMirrorDiffView(a,b),this.bind(a)},bind:function(a){this.diffView.bind(a)}}),Mgly.CodeMirrorDiffView=function(a,b){CodeMirror.defineExtension("centerOnCursor",function(){var a=this.cursorCoords(null,"local");this.scrollTo(null,(a.y+a.yBot)/2-this.getScrollerElement().clientHeight/2)}),this.init(a,b)},jQuery.extend(Mgly.CodeMirrorDiffView.prototype,{init:function(a,b){this.settings={autoupdate:!0,autoresize:!0,rhs_margin:"right",lcs:!0,sidebar:!0,viewport:!1,ignorews:!1,fadein:"fast",editor_width:"650px",editor_height:"400px",resize_timeout:500,change_timeout:150,fgcolor:{a:"#4ba3fa",c:"#a3a3a3",d:"#ff7f7f",ca:"#4b73ff",cc:"#434343",cd:"#ff4f4f"},bgcolor:"#eee",vpcolor:"rgba(0, 0, 200, 0.5)",lhs:function(){},rhs:function(){},loaded:function(){},_auto_width:function(a){return a},resize:function(b){var c=b?16:0,d=jQuery(a).parent().width()+c;"auto"==this.width?d=this._auto_width(d):(d=this.width,this.editor_width=d),"auto"==this.height?h=jQuery(a).parent().height():(h=this.height,this.editor_height=h);var e=d/2-16-8,f=h,g=jQuery(a);g.find(".mergely-column").css({width:e+"px"}),g.find(".mergely-column, .mergely-canvas, .mergely-margin, .mergely-column textarea, .CodeMirror-scroll, .cm-s-default").css({height:f+"px"}),g.find(".mergely-canvas").css({height:f+"px"}),g.find(".mergely-column textarea").css({width:e+"px"}),g.css({width:d,height:h,clear:"both"}),"none"==g.css("display")&&(0!=this.fadein?g.fadeIn(this.fadein):g.show(),this.loaded&&this.loaded()),this.resized&&this.resized()},_debug:"",resized:function(){}};var c={mode:"text/plain",readOnly:!1,lineWrapping:!1,lineNumbers:!0,gutters:["merge","CodeMirror-linenumbers"]};this.lhs_cmsettings={},this.rhs_cmsettings={},this.element=jQuery(a),b&&b.cmsettings&&jQuery.extend(this.lhs_cmsettings,c,b.cmsettings,b.lhs_cmsettings),b&&b.cmsettings&&jQuery.extend(this.rhs_cmsettings,c,b.cmsettings,b.rhs_cmsettings),b&&jQuery.extend(this.settings,b),this.element.bind("destroyed",jQuery.proxy(this.teardown,this)),jQuery.data(a,"mergely",this)},unbind:function(){null!=this.changed_timeout&&clearTimeout(this.changed_timeout),this.editor[this.id+"-lhs"].toTextArea(),this.editor[this.id+"-rhs"].toTextArea()},destroy:function(){this.element.unbind("destroyed",this.teardown),this.teardown()},teardown:function(){this.unbind()},lhs:function(a){this.editor[this.id+"-lhs"].setValue(a)},rhs:function(a){this.editor[this.id+"-rhs"].setValue(a)},update:function(){this._changing(this.id+"-lhs",this.id+"-rhs")},unmarkup:function(){this._clear()},scrollToDiff:function(a){this.changes.length&&(this._current_diff="next"==a?Math.min(++this._current_diff,this.changes.length-1):Math.max(--this._current_diff,0),this._scroll_to_change(this.changes[this._current_diff]),this._changed(this.id+"-lhs",this.id+"-rhs"))},mergeCurrentChange:function(a){this.changes.length&&("lhs"!=a||this.lhs_cmsettings.readOnly?"rhs"!=a||this.rhs_cmsettings.readOnly||this._merge_change(this.changes[this._current_diff],"lhs","rhs"):this._merge_change(this.changes[this._current_diff],"rhs","lhs"))},scrollTo:function(a,b){var c=this.editor[this.id+"-lhs"],d=this.editor[this.id+"-rhs"];"lhs"==a?(c.setCursor(b),c.centerOnCursor()):(d.setCursor(b),d.centerOnCursor())},options:function(a){if(!a)return this.settings;if(jQuery.extend(this.settings,a),this.settings.autoresize&&this.resize(),this.settings.autoupdate&&this.update(),this.settings.hasOwnProperty("rhs_margin"))if("left"==this.settings.rhs_margin)this.element.find(".mergely-margin:last-child").insertAfter(this.element.find(".mergely-canvas"));else{var b=this.element.find(".mergely-margin").last();b.appendTo(b.parent())}this.settings.hasOwnProperty("sidebar")&&(this.settings.sidebar?jQuery(this.element).find(".mergely-margin").css({display:"block"}):jQuery(this.element).find(".mergely-margin").css({display:"none"}))},swap:function(){if(!this.lhs_cmsettings.readOnly&&!this.rhs_cmsettings.readOnly){var a=this.editor[this.id+"-lhs"],b=this.editor[this.id+"-rhs"],c=b.getValue();b.setValue(a.getValue()),a.setValue(c)}},merge:function(a){var b=this.editor[this.id+"-lhs"],c=this.editor[this.id+"-rhs"];"lhs"!=a||this.lhs_cmsettings.readOnly?this.rhs_cmsettings.readOnly||c.setValue(b.getValue()):b.setValue(c.getValue())},get:function(a){var b=this.editor[this.id+"-"+a],c=b.getValue();return void 0==c?"":c},clear:function(a){if(!("lhs"==a&&this.lhs_cmsettings.readOnly||"rhs"==a&&this.rhs_cmsettings.readOnly)){var b=this.editor[this.id+"-"+a];b.setValue("")}},cm:function(a){return this.editor[this.id+"-"+a]},search:function(a,b,c){var f,d=this.editor[this.id+"-lhs"],e=this.editor[this.id+"-rhs"];f="lhs"==a?d:e,c="prev"==c?"findPrevious":"findNext",(0==f.getSelection().length||this.prev_query[a]!=b)&&(this.cursor[this.id]=f.getSearchCursor(b,{line:0,ch:0},!1),this.prev_query[a]=b);var g=this.cursor[this.id];g[c]()?f.setSelection(g.from(),g.to()):g=f.getSearchCursor(b,{line:0,ch:0},!1)},resize:function(){this.settings.resize(),this._changing(this.id+"-lhs",this.id+"-rhs"),this._set_top_offset(this.id+"-lhs")},diff:function(){var a=this.editor[this.id+"-lhs"].getValue(),b=this.editor[this.id+"-rhs"].getValue(),c=new Mgly.diff(a,b,this.settings);return c.normal_form()},bind:function(a){jQuery(this.element).hide(),this.id=jQuery(a).attr("id");var b=this.settings.editor_height,c=this.settings.editor_width;this.changed_timeout=null,this.chfns={},this.chfns[this.id+"-lhs"]=[],this.chfns[this.id+"-rhs"]=[],this.prev_query=[],this.cursor=[],this._skipscroll={},this.change_exp=new RegExp(/(\d+(?:,\d+)?)([acd])(\d+(?:,\d+)?)/);var d,e;if(void 0!=jQuery.button)d='<button title="Merge left"></button>',e='<button title="Merge right"></button>';else{var f="opacity:0.4;width:10px;height:15px;background-color:#888;cursor:pointer;text-align:center;color:#eee;border:1px solid: #222;margin-right:5px;margin-top: -2px;";d='<div style="'+f+'" title="Merge left"><</div>',e='<div style="'+f+'" title="Merge right">></div>'}this.merge_rhs_button=jQuery(e),this.merge_lhs_button=jQuery(d),jQuery(this.element).append(jQuery('<div class="mergely-margin" style="height: '+b+'"><canvas id="'+this.id+'-lhs-margin" width="8px" height="'+b+'"></canvas></div>')),jQuery(this.element).append(jQuery('<div style="position:relative;width:'+c+"; height:"+b+'" id="'+this.id+'-editor-lhs" class="mergely-column"><textarea style="" id="'+this.id+'-lhs"></textarea></div>')),jQuery(this.element).append(jQuery('<div class="mergely-canvas" style="height: '+b+'"><canvas id="'+this.id+"-lhs-"+this.id+'-rhs-canvas" style="width:28px" width="28px" height="'+b+'"></canvas></div>'));var g=jQuery('<div class="mergely-margin" style="height: '+b+'"><canvas id="'+this.id+'-rhs-margin" width="8px" height="'+b+'"></canvas></div>');this.settings.sidebar||jQuery(this.element).find(".mergely-margin").css({display:"none"}),"left"==this.settings.rhs_margin&&jQuery(this.element).append(g),jQuery(this.element).append(jQuery('<div style="width:'+c+"; height:"+b+'" id="'+this.id+'-editor-rhs" class="mergely-column"><textarea style="" id="'+this.id+'-rhs"></textarea></div>')),"left"!=this.settings.rhs_margin&&jQuery(this.element).append(g);var h="#"+this.id+" .CodeMirror-gutter-text { padding: 5px 0 0 0; }"+"#"+this.id+" .CodeMirror-lines pre, "+"#"+this.id+" .CodeMirror-gutter-text pre { line-height: 18px; }"+".CodeMirror-linewidget { overflow: hidden; };";this.settings.autoresize&&(h+=this.id+" .CodeMirror-scroll { height: 100%; overflow: auto; }"),h+="\n.CodeMirror { line-height: 18px; }",jQuery('<style type="text/css">'+h+"</style>").appendTo("head");var i=jQuery("#"+this.id+"-rhs").get(0);if(!i)return console.error("rhs textarea not defined - Mergely not initialized properly"),void 0;var j=jQuery("#"+this.id+"-lhs").get(0);if(!i)return console.error("lhs textarea not defined - Mergely not initialized properly"),void 0;var k=this;if(this.editor=[],this.editor[this.id+"-lhs"]=CodeMirror.fromTextArea(j,this.lhs_cmsettings),this.editor[this.id+"-rhs"]=CodeMirror.fromTextArea(i,this.rhs_cmsettings),this.editor[this.id+"-lhs"].on("change",function(){k.settings.autoupdate&&k._changing(k.id+"-lhs",k.id+"-rhs")}),this.editor[this.id+"-lhs"].on("scroll",function(){k._scrolling(k.id+"-lhs")}),this.editor[this.id+"-rhs"].on("change",function(){k.settings.autoupdate&&k._changing(k.id+"-lhs",k.id+"-rhs")}),this.editor[this.id+"-rhs"].on("scroll",function(){k._scrolling(k.id+"-rhs")}),this.settings.autoresize){var l=null,m=function(a){k.settings.resize&&k.settings.resize(a),k.editor[k.id+"-lhs"].refresh(),k.editor[k.id+"-rhs"].refresh(),k.settings.autoupdate&&k._changing(k.id+"-lhs",k.id+"-rhs")};jQuery(window).resize(function(){l&&clearTimeout(l),l=setTimeout(m,k.settings.resize_timeout)}),m(!0)}if(this.settings.lhs){var n=this.editor[this.id+"-lhs"].getDoc().setValue;this.settings.lhs(n.bind(this.editor[this.id+"-lhs"].getDoc()))}if(this.settings.rhs){var n=this.editor[this.id+"-rhs"].getDoc().setValue;this.settings.rhs(n.bind(this.editor[this.id+"-rhs"].getDoc()))}},_scroll_to_change:function(a){if(a){var b=this,c=b.editor[b.id+"-lhs"],d=b.editor[b.id+"-rhs"],e=1*c.getScrollerElement().offsetHeight/2;c.setCursor(Math.max(a["lhs-line-from"],0),0),d.setCursor(Math.max(a["rhs-line-from"],0),0),c.scrollTo(null,0),d.scrollTo(null,0),b._calculate_offsets(b.id+"-lhs",b.id+"-rhs",[a]),c.scrollTo(null,Math.max(a["lhs-y-start"]-e,0)),d.scrollTo(null,Math.max(a["rhs-y-start"]-e,0))}},_scrolling:function(a){if(this._skipscroll[a]===!0)return this._skipscroll[a]=!1,void 0;var b=jQuery(this.editor[a].getScrollerElement());void 0==this.midway&&(this.midway=(b.height()/2+b.offset().top).toFixed(2));var c=this.editor[a].coordsChar({left:0,top:this.midway}),d=b.scrollTop(),e=b.scrollLeft();this.trace("scroll","side",a),this.trace("scroll","midway",this.midway),this.trace("scroll","midline",c),this.trace("scroll","top_to",d),this.trace("scroll","left_to",e);var f=this.id+"-lhs",g=this.id+"-rhs";for(var h in this.editor)if(this.editor.hasOwnProperty(h)&&a!=h){for(var i=a.replace(this.id+"-",""),j=h.replace(this.id+"-",""),k=0,l=null,m=!1,n=0;n<this.changes.length;++n){var o=this.changes[n];c.line>=o[i+"-line-from"]&&(l=o,c.line>=l[i+"-line-to"]&&(o.hasOwnProperty(i+"-y-start")&&o.hasOwnProperty(i+"-y-end")&&o.hasOwnProperty(j+"-y-start")&&o.hasOwnProperty(j+"-y-end")?k+=o[i+"-y-end"]-o[i+"-y-start"]-(o[j+"-y-end"]-o[j+"-y-start"]):m=!0))}var p=this.editor[h].getViewport(),q=!0;if(l&&(this.trace("scroll","last change before midline",l),c.line>=p.from&&c<=p.to&&(q=!1)),this.trace("scroll","scroll",q),q||m){this.trace("scroll","scrolling other side",d-k);var b=jQuery(this.editor[h].getScrollerElement());this._skipscroll[h]=!0,b.scrollTop(d-k).scrollLeft(e)}else this.trace("scroll","not scrolling other side");if(this.settings.autoupdate){var r=new Mgly.Timer;this._calculate_offsets(f,g,this.changes),this.trace("change","offsets time",r.stop()),this._markup_changes(f,g,this.changes),this.trace("change","markup time",r.stop()),this._draw_diff(f,g,this.changes),this.trace("change","draw time",r.stop())}this.trace("scroll","scrolled")}},_changing:function(a,b){this.trace("change","changing-timeout",this.changed_timeout);var c=this;null!=this.changed_timeout&&clearTimeout(this.changed_timeout),this.changed_timeout=setTimeout(function(){var d=new Mgly.Timer;c._changed(a,b),c.trace("change","total time",d.stop())},this.settings.change_timeout)},_changed:function(a,b){this._clear(),this._diff(a,b)},_clear:function(){var a=this;for(var b in this.editor)if(this.editor.hasOwnProperty(b)){var c=this.editor[b],d=a.chfns[b];c.operation(function(){for(var b=new Mgly.Timer,e=0,f=c.lineCount();f>e;++e)c.removeLineClass(e,"background");for(var e=0;e<d.length;++e){var g=d[e];g.lines.length&&a.trace("change","clear text",g.lines[0].text),g.clear()}c.clearGutter("merge"),a.trace("change","clear time",b.stop())})}a.chfns[b]=[];var e=this._draw_info(this.id+"-lhs",this.id+"-rhs"),f=e.clhs.get(0).getContext("2d"),g=e.crhs.get(0).getContext("2d"),h=e.dcanvas.getContext("2d");f.beginPath(),f.fillStyle=this.settings.bgcolor,f.strokeStyle="#888",f.fillRect(0,0,6.5,e.visible_page_height),f.strokeRect(0,0,6.5,e.visible_page_height),g.beginPath(),g.fillStyle=this.settings.bgcolor,g.strokeStyle="#888",g.fillRect(0,0,6.5,e.visible_page_height),g.strokeRect(0,0,6.5,e.visible_page_height),h.beginPath(),h.fillStyle="#fff",h.fillRect(0,0,this.draw_mid_width,e.visible_page_height)},_diff:function(a,b){var c=this.editor[a].getValue(),d=this.editor[b].getValue(),e=new Mgly.Timer,f=new Mgly.diff(c,d,this.settings);this.trace("change","diff time",e.stop()),this.changes=Mgly.DiffParser(f.normal_form()),this.trace("change","parse time",e.stop()),void 0===this._current_diff&&(this._current_diff=0,this._scroll_to_change(this.changes[0])),this.trace("change","scroll_to_change time",e.stop()),this._calculate_offsets(a,b,this.changes),this.trace("change","offsets time",e.stop()),this._markup_changes(a,b,this.changes),this.trace("change","markup time",e.stop()),this._draw_diff(a,b,this.changes),this.trace("change","draw time",e.stop())},_parse_diff:function(a,b,c){this.trace("diff","diff results:\n",c);for(var d=[],e=0,f=c.split(/\n/),g=0;g<f.length;++g)if(0!=f[g].length){var h={},i=this.change_exp.exec(f[g]);if(null!=i){var j=i[1].split(",");h["lhs-line-from"]=j[0]-1,h["lhs-line-to"]=1==j.length?j[0]-1:j[1]-1;var k=i[3].split(",");h["rhs-line-from"]=k[0]-1,h["rhs-line-to"]=1==k.length?k[0]-1:k[1]-1,h["lhs-line-from"]<0&&(h["lhs-line-from"]=0),h["lhs-line-to"]<0&&(h["lhs-line-to"]=0),h["rhs-line-from"]<0&&(h["rhs-line-from"]=0),h["rhs-line-to"]<0&&(h["rhs-line-to"]=0),h.op=i[2],d[e++]=h,this.trace("diff","change",h)}}return d},_get_viewport:function(a,b){var c=this.editor[a].getViewport(),d=this.editor[b].getViewport();return{from:Math.min(c.from,d.from),to:Math.max(c.to,d.to)}},_is_change_in_view:function(a,b){return this.settings.viewport?b["lhs-line-from"]<a.from&&b["lhs-line-to"]<a.to||b["lhs-line-from"]>a.from&&b["lhs-line-to"]>a.to||b["rhs-line-from"]<a.from&&b["rhs-line-to"]<a.to||b["rhs-line-from"]>a.from&&b["rhs-line-to"]>a.to?!1:!0:!0},_set_top_offset:function(a){var b=this.editor[a].getScrollInfo().top;this.editor[a].scrollTo(null,0);var c=jQuery("#"+this.id+" .CodeMirror-measure").first(),d=c.offset().top-4;return d?(this.editor[a].scrollTo(null,b),this.draw_top_offset=.5-d,!0):!1},_calculate_offsets:function(a,b,c){if(null==this.em_height){if(!this._set_top_offset(a))return;this.em_height=this.editor[a].defaultTextHeight(),this.em_height||(console.warn("Failed to calculate offsets, using 18 by default"),this.em_height=18),this.draw_lhs_min=.5;var d=jQuery("#"+a+"-"+b+"-canvas");if(d.length||console.error("failed to find canvas","#"+a+"-"+b+"-canvas"),!d.width())return console.error("canvas width is 0"),void 0;this.draw_mid_width=jQuery("#"+a+"-"+b+"-canvas").width(),this.draw_rhs_max=this.draw_mid_width-.5,this.draw_lhs_width=5,this.draw_rhs_width=5,this.trace("calc","change offsets calculated",{top_offset:this.draw_top_offset,lhs_min:this.draw_lhs_min,rhs_max:this.draw_rhs_max,lhs_width:this.draw_lhs_width,rhs_width:this.draw_rhs_width})}for(var e=this.editor[a].charCoords({line:0}),f=this.editor[b].charCoords({line:0}),g=this._get_viewport(a,b),h=0;h<c.length;++h){var i=c[h];if(this.settings.sidebar||this._is_change_in_view(g,i)){var n,o,p,q,j=i["lhs-line-from"]>=0?i["lhs-line-from"]:0,k=i["lhs-line-to"]>=0?i["lhs-line-to"]:0,l=i["rhs-line-from"]>=0?i["rhs-line-from"]:0,m=i["rhs-line-to"]>=0?i["rhs-line-to"]:0;if(this.editor[a].getOption("lineWrapping")||this.editor[a].getOption("lineWrapping")){var r=this.editor[a].cursorCoords({line:j,ch:0},"page"),s=this.editor[a].getLineHandle(j);n={top:r.top,bottom:r.top+s.height};var t=this.editor[a].cursorCoords({line:k,ch:0},"page"),u=this.editor[a].getLineHandle(k);o={top:t.top,bottom:t.top+u.height};var r=this.editor[b].cursorCoords({line:l,ch:0},"page"),v=this.editor[b].getLineHandle(l);p={top:r.top,bottom:r.top+v.height};var t=this.editor[b].cursorCoords({line:m,ch:0},"page"),w=this.editor[b].getLineHandle(m);q={top:t.top,bottom:t.top+w.height}}else n={top:e.top+j*this.em_height,bottom:e.bottom+j*this.em_height+2},o={top:e.top+k*this.em_height,bottom:e.bottom+k*this.em_height+2},p={top:f.top+l*this.em_height,bottom:f.bottom+l*this.em_height+2},q={top:f.top+m*this.em_height,bottom:f.bottom+m*this.em_height+2};"a"==i.op?l>0&&(n.top=n.bottom,n.bottom+=this.em_height,o=n):"d"==i.op&&j>0&&(p.top=p.bottom,p.bottom+=this.em_height,q=p),i["lhs-y-start"]=this.draw_top_offset+n.top,i["lhs-y-end"]="c"==i.op||"d"==i.op?this.draw_top_offset+o.bottom:this.draw_top_offset+o.top,i["rhs-y-start"]=this.draw_top_offset+p.top,i["rhs-y-end"]="c"==i.op||"a"==i.op?this.draw_top_offset+q.bottom:this.draw_top_offset+q.top,this.trace("calc","change calculated",h,i)}else delete i["lhs-y-start"],delete i["lhs-y-end"],delete i["rhs-y-start"],delete i["rhs-y-end"]}return c},_markup_changes:function(a,b,c){jQuery(".merge-button").remove();var d=this,e=this.editor[a],f=this.editor[b],g=new Mgly.Timer;e.operation(function(){for(var a=0;a<c.length;++a){var b=c[a],g=b["lhs-line-from"]>=0?b["lhs-line-from"]:0,h=b["lhs-line-to"]>=0?b["lhs-line-to"]:0,i=b["rhs-line-from"]>=0?b["rhs-line-from"]:0;b["rhs-line-to"]>=0?b["rhs-line-to"]:0;var k=["mergely","lhs",b.op,"cid-"+a];if(e.addLineClass(g,"background","start"),e.addLineClass(h,"background","end"),0==g&&0==h&&0==i)e.addLineClass(g,"background",k.join(" ")),e.addLineClass(g,"background","first");else for(var l=g;h>=l;++l)e.addLineClass(l,"background",k.join(" ")),e.addLineClass(l,"background",k.join(" "));if(!f.getOption("readOnly")){var m=d.merge_rhs_button.clone();m.button&&m.button({icons:{primary:"ui-icon-triangle-1-e"},text:!1}),m.addClass("merge-button"),m.attr("id","merge-rhs-"+a),e.setGutterMarker(g,"merge",m.get(0))}}});var h=this._get_viewport(a,b);this.trace("change","markup lhs-editor time",g.stop()),f.operation(function(){for(var a=0;a<c.length;++a){var b=c[a],g=b["lhs-line-from"]>=0?b["lhs-line-from"]:0;b["lhs-line-to"]>=0?b["lhs-line-to"]:0;var j=b["rhs-line-from"]>=0?b["rhs-line-from"]:0,k=b["rhs-line-to"]>=0?b["rhs-line-to"]:0;if(d._is_change_in_view(h,b)){var l=["mergely","rhs",b.op,"cid-"+a];if(f.addLineClass(j,"background","start"),f.addLineClass(k,"background","end"),0==j&&0==k&&0==g)f.addLineClass(j,"background",l.join(" ")),f.addLineClass(j,"background","first");else for(var m=j;k>=m;++m)f.addLineClass(m,"background",l.join(" ")),f.addLineClass(m,"background",l.join(" "));if(!e.getOption("readOnly")){var n=d.merge_lhs_button.clone();n.button&&n.button({icons:{primary:"ui-icon-triangle-1-w"},text:!1}),n.addClass("merge-button"),n.attr("id","merge-lhs-"+a),f.setGutterMarker(j,"merge",n.get(0))}}}}),this.trace("change","markup rhs-editor time",g.stop());for(var i=[],j=0;this.settings.lcs&&j<c.length;++j){var k=c[j],l=k["lhs-line-from"]>=0?k["lhs-line-from"]:0,m=k["lhs-line-to"]>=0?k["lhs-line-to"]:0,n=k["rhs-line-from"]>=0?k["rhs-line-from"]:0,o=k["rhs-line-to"]>=0?k["rhs-line-to"]:0;if(this._is_change_in_view(h,k))if("d"==k.op){var p=l,q=m,r=e.lineInfo(q);r&&i.push([e,{line:p,ch:0},{line:q,ch:r.text.length},{className:"mergely ch d lhs"}])}else if("c"==k.op)for(var s=l,t=n,u=0;s>=0&&m>=s||t>=0&&o>=t;++s,++t)if(t+u>o){var v=e.getLine(s);i.push([e,{line:s,ch:0},{line:s,ch:v.length},{className:"mergely ch d lhs"}])}else if(s+u>m){var w=f.getLine(t);i.push([f,{line:t,ch:0},{line:t,ch:w.length},{className:"mergely ch a rhs"}])}else{var v=e.getLine(s),w=f.getLine(t),B=new Mgly.LCS(v,w);B.diff(function(a,b){i.push([f,{line:t,ch:a},{line:t,ch:b},{className:"mergely ch a rhs"}])},removed=function(a,b){i.push([e,{line:s,ch:a},{line:s,ch:b},{className:"mergely ch d lhs"}])})}}this.trace("change","LCS marktext time",g.stop()),e.operation(function(){for(var a=0;a<i.length;++a){var b=i[a];b[0].doc.id==e.getDoc().id&&d.chfns[d.id+"-lhs"].push(b[0].markText(b[1],b[2],b[3]))}}),f.operation(function(){for(var a=0;a<i.length;++a){var b=i[a];b[0].doc.id==f.getDoc().id&&d.chfns[d.id+"-rhs"].push(b[0].markText(b[1],b[2],b[3]))}}),this.trace("change","LCS markup time",g.stop());var C={lhs:e,rhs:f};jQuery(".merge-button").on("click",function(a){var b="rhs",c="lhs",e=jQuery(this).parents("#"+d.id+"-editor-lhs");e.length&&(b="lhs",c="rhs");var f=C[b].coordsChar({left:a.pageX,top:a.pageY}),g=null,h=C[b].lineInfo(f.line);jQuery.each(h.bgClass.split(" "),function(a,b){return 0==b.indexOf("cid-")?(g=parseInt(b.split("-")[1],10),!1):void 0});var i=d.changes[g];return d._merge_change(i,b,c),!1}),this.trace("change","markup buttons time",g.stop())},_merge_change:function(a,b,c){if(a){var d=this.editor[this.id+"-lhs"],e=this.editor[this.id+"-rhs"],f={lhs:d,rhs:e},g=f[b].getRange(CodeMirror.Pos(a[b+"-line-from"],0),CodeMirror.Pos(a[b+"-line-to"]+1,0));if("c"==a.op)f[c].replaceRange(g,CodeMirror.Pos(a[c+"-line-from"],0),CodeMirror.Pos(a[c+"-line-to"]+1,0));else if("rhs"==b)if("a"==a.op)f[c].replaceRange(g,CodeMirror.Pos(a[c+"-line-from"]+1,0),CodeMirror.Pos(a[c+"-line-to"]+1,0));else for(var h=parseInt(a[c+"-line-from"]),i=parseInt(a[c+"-line-to"]),j=i;j>=h;--j)f[c].removeLine(j);else if("lhs"==b)if("a"==a.op)for(var h=parseInt(a[c+"-line-from"]),i=parseInt(a[c+"-line-to"]),j=i;j>=h;--j)f[c].removeLine(j);else f[c].replaceRange(g,CodeMirror.Pos(a[c+"-line-from"]+1,0));f.lhs.setValue(f.lhs.getValue()),f.rhs.setValue(f.rhs.getValue()),this._scroll_to_change(a)}},_draw_info:function(a,b){var c=jQuery(this.editor[a].getScrollerElement()).height(),d=jQuery(this.editor[a].getScrollerElement()).children(":first-child").height(),e=document.getElementById(a+"-"+b+"-canvas");if(void 0==e)throw"Failed to find: "+a+"-"+b+"-canvas";var f=jQuery("#"+this.id+"-lhs-margin"),g=jQuery("#"+this.id+"-rhs-margin");return{visible_page_height:c,gutter_height:d,visible_page_ratio:c/d,margin_ratio:c/d,lhs_scroller:jQuery(this.editor[a].getScrollerElement()),rhs_scroller:jQuery(this.editor[b].getScrollerElement()),lhs_lines:this.editor[a].lineCount(),rhs_lines:this.editor[b].lineCount(),dcanvas:e,clhs:f,crhs:g,lhs_xyoffset:jQuery(f).offset(),rhs_xyoffset:jQuery(g).offset()}},_draw_diff:function(a,b,c){var d=this._draw_info(a,b),e=d.clhs.get(0),f=d.crhs.get(0),g=d.dcanvas.getContext("2d"),h=e.getContext("2d"),i=f.getContext("2d");this.trace("draw","visible_page_height",d.visible_page_height),this.trace("draw","gutter_height",d.gutter_height),this.trace("draw","visible_page_ratio",d.visible_page_ratio),this.trace("draw","lhs-scroller-top",d.lhs_scroller.scrollTop()),this.trace("draw","rhs-scroller-top",d.rhs_scroller.scrollTop()),jQuery.each(jQuery.find("#"+this.id+" canvas"),function(){jQuery(this).get(0).height=d.visible_page_height}),d.clhs.unbind("click"),d.crhs.unbind("click"),h.beginPath(),h.fillStyle=this.settings.bgcolor,h.strokeStyle="#888",h.fillRect(0,0,6.5,d.visible_page_height),h.strokeRect(0,0,6.5,d.visible_page_height),i.beginPath(),i.fillStyle=this.settings.bgcolor,i.strokeStyle="#888",i.fillRect(0,0,6.5,d.visible_page_height),i.strokeRect(0,0,6.5,d.visible_page_height);for(var j=this._get_viewport(a,b),k=0;k<c.length;++k){var l=c[k];this.trace("draw",l);var m=(l["lhs-y-start"]+d.lhs_scroller.scrollTop())*d.visible_page_ratio,n=(l["lhs-y-end"]+d.lhs_scroller.scrollTop())*d.visible_page_ratio+1,o=(l["rhs-y-start"]+d.rhs_scroller.scrollTop())*d.visible_page_ratio,p=(l["rhs-y-end"]+d.rhs_scroller.scrollTop())*d.visible_page_ratio+1;if(this.trace("draw","marker calculated",m,n,o,p),h.beginPath(),h.fillStyle=this.settings.fgcolor[(this._current_diff==k?"c":"")+l.op],h.strokeStyle="#000",h.lineWidth=.5,h.fillRect(1.5,m,4.5,Math.max(n-m,5)),h.strokeRect(1.5,m,4.5,Math.max(n-m,5)),i.beginPath(),i.fillStyle=this.settings.fgcolor[(this._current_diff==k?"c":"")+l.op],i.strokeStyle="#000",i.lineWidth=.5,i.fillRect(1.5,o,4.5,Math.max(p-o,5)),i.strokeRect(1.5,o,4.5,Math.max(p-o,5)),this._is_change_in_view(j,l)){m=l["lhs-y-start"],n=l["lhs-y-end"],o=l["rhs-y-start"],p=l["rhs-y-end"];var q=3;g.beginPath(),g.strokeStyle=this.settings.fgcolor[(this._current_diff==k?"c":"")+l.op],g.lineWidth=this._current_diff==k?1.5:1;var r=this.draw_lhs_width,s=n-m-1,t=this.draw_lhs_min,u=m;g.moveTo(t,u),"Microsoft Internet Explorer"==navigator.appName?(g.lineTo(this.draw_lhs_min+this.draw_lhs_width,m),g.lineTo(this.draw_lhs_min+this.draw_lhs_width,n+1),g.lineTo(this.draw_lhs_min,n+1)):(0>=s?g.lineTo(t+r,u):(g.arcTo(t+r,u,t+r,u+q,q),g.arcTo(t+r,u+s,t+r-q,u+s,q)),g.lineTo(t,u+s)),g.stroke(),r=this.draw_rhs_width,s=p-o-1,t=this.draw_rhs_max,u=o,g.moveTo(t,u),"Microsoft Internet Explorer"==navigator.appName?(g.lineTo(this.draw_rhs_max-this.draw_rhs_width,o),g.lineTo(this.draw_rhs_max-this.draw_rhs_width,p+1),g.lineTo(this.draw_rhs_max,p+1)):(0>=s?g.lineTo(t-r,u):(g.arcTo(t-r,u,t-r,u+q,q),g.arcTo(t-r,u+s,t-q,u+s,q)),g.lineTo(t,u+s)),g.stroke();var v=this.draw_lhs_min+this.draw_lhs_width,w=m+(n+1-m)/2,x=this.draw_rhs_max-this.draw_rhs_width,y=o+(p+1-o)/2;g.moveTo(v,w),w==y?g.lineTo(x,y):g.bezierCurveTo(v+12,w-3,x-12,y-3,x,y),g.stroke()}}h.fillStyle=this.settings.vpcolor,i.fillStyle=this.settings.vpcolor;var z=d.clhs.height()*d.visible_page_ratio,A=d.lhs_scroller.scrollTop()/d.gutter_height*d.clhs.height(),B=d.crhs.height()*d.visible_page_ratio,C=d.rhs_scroller.scrollTop()/d.gutter_height*d.crhs.height();this.trace("draw","cls.height",d.clhs.height()),this.trace("draw","lhs_scroller.scrollTop()",d.lhs_scroller.scrollTop()),this.trace("draw","gutter_height",d.gutter_height),this.trace("draw","visible_page_ratio",d.visible_page_ratio),this.trace("draw","lhs from",A,"lhs to",z),this.trace("draw","rhs from",C,"rhs to",B),h.fillRect(1.5,A,4.5,z),i.fillRect(1.5,C,4.5,B),d.clhs.click(function(a){var b=a.pageY-d.lhs_xyoffset.top-z/2,c=Math.max(0,b/e.height*d.lhs_scroller.get(0).scrollHeight);d.lhs_scroller.scrollTop(c)}),d.crhs.click(function(a){var b=a.pageY-d.rhs_xyoffset.top-B/2,c=Math.max(0,b/f.height*d.rhs_scroller.get(0).scrollHeight);d.rhs_scroller.scrollTop(c)})},trace:function(a){this.settings._debug.indexOf(a)>=0&&(arguments[0]=a+":",console.log([].slice.apply(arguments)))}}),jQuery.pluginMaker=function(a){jQuery.fn[a.prototype.name]=function(b){var c=jQuery.makeArray(arguments),d=c.slice(1),e=void 0;return this.each(function(){var f=jQuery.data(this,a.prototype.name);if(f){if("string"==typeof b)e=f[b].apply(f,d);else if(f.update)return f.update.apply(f,c)}else new a(this,b)}),void 0!=e?e:void 0}},jQuery.pluginMaker(Mgly.mergely); |