diff --git a/bower.json b/bower.json
index 71533c0..6a77ede 100644
--- a/bower.json
+++ b/bower.json
@@ -1,6 +1,6 @@
{
"name": "Mergely",
- "version": "3.3.10",
+ "version": "3.4.0",
"homepage": "https://github.com/wickedest/Mergely",
"description": "Merge and diff documents online",
"main": [
@@ -29,8 +29,8 @@
"url": "git://github.com/wickedest/Mergely"
},
"dependencies": {
- "mergely": "https://github.com/wickedest/Mergely.git#3.3.10",
+ "mergely": "https://github.com/wickedest/Mergely.git#3.4.0",
"jquery": "<=2.1.3",
- "codemirror": "<=4.6.0"
+ "codemirror": "<=5.11.0"
}
}
diff --git a/editor/editor.js b/editor/editor.js
index a748c43..3aa2114 100644
--- a/editor/editor.js
+++ b/editor/editor.js
@@ -146,7 +146,7 @@ $(document).ready(function() {
var color_defaults = {
cb: 'cccccc', cg: 'fafafa',
ab: 'a3d1ff', ag: 'ddeeff',
- db: 'ff7f7f', dg: 'edc0c0'
+ db: 'ff7f7f', dg: 'ffe9e9'
};
applyParameterCss(false);
diff --git a/editor/editor.min.js b/editor/editor.min.js
index 0ea4732..2d8af0d 100644
--- a/editor/editor.min.js
+++ b/editor/editor.min.js
@@ -1,6 +1,6 @@
/**
- * Copyright (c) 2015 by Jamie Peabody, http://www.mergely.com
+ * Copyright (c) 2016 by Jamie Peabody, http://www.mergely.com
* All rights reserved.
- * Version: 3.3.10 2015-06-28
+ * Version: 3.4.0 2016-02-07
*/
-$(document).ready(function(){function a(){var a={};return window.location.search.substr(1).split("&").forEach(function(b){if(""!==b){var c=b.split("=");a[c[0]]=2===c.length&&c[1].search(/^(true|1)$/i)>=0?!0:2===c.length&&c[1].search(/^(false|0)$/i)>=0?!1:c[1]&&decodeURIComponent(c[1].replace(/\+/g," "))}}),{get:function(b,c){return a.hasOwnProperty(b)?a[b]:c}}}function f(a){if(!a.length)return!1;var b=$("#mergely"),c=a.find(".find"),d=c.find('input[type="text"]'),e=a.attr("id").indexOf("-lhs")>0?"lhs":"rhs",f=b.mergely("options").autoupdate;c.slideDown("fast",function(){d.focus(),b.mergely("options",{autoupdate:!1}),b.mergely("unmarkup")}),c.find(".find-prev").click(function(){b.mergely("search",e,d.val(),"prev")}),c.find(".find-next").click(function(){b.mergely("search",e,d.val(),"next")}),c.find(".find-close").click(function(){c.css("display","none"),b.mergely("options",{autoupdate:f})}),d.keydown(function(a){return 13!=a.which&&27!=a.which?!0:(27==a.which&&(c.css("display","none"),b.mergely("options",{autoupdate:f})),b.mergely("search",e,d.val()),!1)})}function u(a){if("file-new"==a)window.location="/editor";else if("file-save"==a){var b=g.mergely("diff");if(-1===navigator.userAgent.toLowerCase().indexOf("msie")){""==key&&(key="".random(8));var c=jQuery("",{href:"data:application/stream;base64,"+window.btoa(unescape(encodeURIComponent(b))),target:"_blank",text:"clickme",id:key});c.attr("download",key+".diff"),jQuery("body").append(c);var d=$("a#"+key);d[0].click(),d.remove()}else{var e=new Blob([b]);window.navigator.msSaveOrOpenBlob(e,key+".diff")}}else if("file-share"==a)v(g);else if("file-import"==a)x(g);else if("edit-left-undo"==a)g.mergely("cm","lhs").getDoc().undo();else if("edit-left-redo"==a)g.mergely("cm","lhs").getDoc().redo();else if("edit-right-undo"==a)g.mergely("cm","rhs").getDoc().undo();else if("edit-right-redo"==a)g.mergely("cm","rhs").getDoc().redo();else if("edit-left-find"==a)f(g.find("#mergely-editor-lhs"));else if("edit-left-merge-right"==a)g.mergely("mergeCurrentChange","rhs");else if("edit-left-merge-right-file"==a)g.mergely("merge","rhs");else if(["edit-left-readonly","edit-right-readonly","options-autodiff","options-sidebars","options-swapmargin","options-viewport","options-ignorews","options-wrap","options-linenumbers"].indexOf(a)>=0)s[a].set(!s[a].get()),h.wickedmenu("update",a);else if("edit-left-clear"==a)g.mergely("clear","lhs");else if("edit-right-find"==a)f(g.find("#mergely-editor-rhs"));else if("edit-right-merge-left"==a)g.mergely("mergeCurrentChange","lhs");else if("edit-right-merge-left-file"==a)g.mergely("merge","lhs");else if("edit-right-clear"==a)g.mergely("clear","rhs");else if("options-colors"==a)y(g);else if("view-swap"==a)g.mergely("swap");else if("view-refresh"==a)g.mergely("update");else if("view-change-next"==a)g.mergely("scrollToDiff","next");else if("view-change-prev"==a)g.mergely("scrollToDiff","prev");else if("view-clear"==a)g.mergely("unmarkup");else if(0==a.indexOf("examples-")){var i={test1:{lhs:"one\ntwo\nthree",rhs:"two\nthree"},test2:{lhs:"two\nthree",rhs:"one\ntwo\nthree"},test3:{lhs:"one\nthree",rhs:"one\ntwo\nthree"},test4:{lhs:"one\ntwo\nthree",rhs:"one\nthree"},test5:{lhs:"to bee, or not to be",rhs:"to be, or not to bee"},test6:{lhs:"to be, or not to be z",rhs:"to be, to be"},test7:{lhs:"remained, & to assume",rhs:"and to assume"},test8:{lhs:"to be, or not to be",rhs:"to be, or not to be"}},j=a.split("examples-")[1];g.mergely("lhs",i[j].lhs),g.mergely("rhs",i[j].rhs)}return!1}function v(a){function d(a,d){$.ajax({type:"POST",async:!0,dataType:"text",url:"/ajax/handle_file.php",data:{key:key,name:a,content:d},success:function(){if(++c,2==c){var d="/ajax/handle_save.php?key="+key;b&&(d+="&nkey="+"".random(8)),$.ajax({type:"GET",async:!1,dataType:"text",url:d,success:function(a){a.length&&(window.location.href="/"+$.trim(a)+"/")},error:function(){}})}},error:function(a,b,c){alert(c)}})}function e(){var b=a.mergely("get","lhs"),c=a.mergely("get","rhs");d("lhs",b),d("rhs",c)}var b="fork"==$(this).attr("id");""==key&&(key="".random(8));var c=0;$("#dialog-confirm").dialog({resizable:!1,width:350,modal:!0,buttons:{"Save for Sharing":function(){$(this).dialog("close"),e()},Cancel:function(){$(this).dialog("close")}}})}function w(a,b,c){$.ajax({type:"GET",dataType:"text",data:{url:c},url:"/ajax/handle_crossdomain.php",contentType:"text/plain",success:function(c){a.mergely(b,c)},error:function(a,b,c){console.error("error",a,b,c)}})}function x(a){function b(a){function f(a,b){e.trigger(a,b)}var c=a.files[0],d=new FileReader,e=$(a);d.onloadstart=function(){f("start")},d.onprogress=function(a){f("progress",a)},d.onload=function(a){f("loaded",a.target.result)},d.onerror=function(a){alert(a.target.error.name)};try{d.readAsText(c,"UTF-8")}catch(g){console.error(g),alert(g)}}var c={};$("#file-lhs, #file-rhs").change(function(a){var d=new RegExp(".*[\\\\/](.*)$"),e=d.exec($(this).val()),f=e?e[1]:"unknown",g=$("#"+a.target.id+"-progress");b(a.target),$(a.target).bind("start",function(){$(a.target).css("display","none"),g.css("display","inline-block")}),$(a.target).bind("progress",function(a,b){var c=100*(b.loaded/b.total);g.find("> .progress-label").text(c+"%"),g.progressbar("value",c)}),$(a.target).bind("loaded",function(b,d){g.progressbar("value",100),g.find("> .progress-label").text(f),c[a.target.id]=d})}),$("#file-lhs-progress").progressbar({value:0}),$("#file-rhs-progress").progressbar({value:0}),$("#dialog-upload .tabs").tabs(),$("#dialog-upload").dialog({dialogClass:"no-title",resizable:!1,width:"450px",modal:!0,buttons:{Import:function(){$(this).dialog("close");var b={lhs:$("#url-lhs").val(),rhs:$("#url-rhs").val()};for(var d in b){var e=b[d];e&&w(a,d,e)}c.hasOwnProperty("file-lhs")&&a.mergely("lhs",c["file-lhs"]),c.hasOwnProperty("file-rhs")&&a.mergely("rhs",c["file-rhs"])},Cancel:function(){$(this).dialog("close")}}})}function y(){var b=$('C'),c=$('C'),d=$('C');$("body").append(b),$("body").append(c),$("body").append(d);var e={"c-border":{id:"#c-border",getColor:function(){return d.css("border-top-color")},setColor:function(a){$("#"+this.id).val(a)}},"c-bg":{id:"#c-bg",getColor:function(){return d.css("background-color")},setColor:function(a){$("#"+this.id).val(a)}},"a-border":{id:"#a-border",getColor:function(){return c.css("border-top-color")},setColor:function(a){$("#"+this.id).val(a)}},"a-bg":{id:"#a-bg",getColor:function(){return c.css("background-color")},setColor:function(a){$("#"+this.id).val(a)}},"d-border":{id:"#d-border",getColor:function(){return b.css("border-top-color")},setColor:function(a){$("#"+this.id).val(a)}},"d-bg":{id:"#d-bg",getColor:function(){return b.css("background-color")},setColor:function(a){$("#"+this.id).val(a)}}};$.each(e,function(a,b){$(b.id).val(b.getColor())});var f=$.farbtastic("#picker");$(".colorwell").each(function(){f.linkTo(this)}).focus(function(){var a=$(this);f.linkTo(this);var b=e[a.attr("id")];f.setColor(b.getColor())}),$("#dialog-colors").dialog({width:490,modal:!0,buttons:{Apply:function(){var a=$("#c-border").val(),b=$("#a-border").val(),c=$("#d-border").val(),d=$("#a-bg").val(),e=$("#d-bg").val(),f=$("#c-bg").val(),g=z(a,f,b,d,c,e);B(g,a,f,b,d,c,e,!0)},Reset:function(){},Close:function(){$(this).dialog("close")}}})}function z(a,b,c,d,e,f){var g=".mergely.a.rhs.start{border-top-color:"+c+";}\n .mergely.a.lhs.start.end,\n .mergely.a.rhs.end{border-bottom-color:"+c+";}\n .mergely.a.rhs{background-color:"+d+";}\n .mergely.d.lhs{background-color:"+f+";}\n .mergely.d.lhs.end,\n .mergely.d.rhs.start.end{border-bottom-color:"+e+";}\n .mergely.d.rhs.start.end.first{border-top-color:"+e+";}\n .mergely.d.lhs.start{border-top-color:"+e+";}\n .mergely.c.lhs,\n .mergely.c.rhs{background-color:"+b+";}\n .mergely.c.lhs.start,\n .mergely.c.rhs.start{border-top-color:"+a+";}\n .mergely.c.lhs.end,\n .mergely.c.rhs.end{border-bottom-color:"+a+";}\n .mergely.ch.a.rhs{background-color:"+d+";}\n .mergely.ch.d.lhs{background-color:"+f+";color: #888;}";return g}function A(a){var c="#"+b.get("cb",o.cb),d="#"+b.get("cg",o.cg),e="#"+b.get("ab",o.ab),f="#"+b.get("ag",o.ag),g="#"+b.get("db",o.db),h="#"+b.get("dg",o.dg);B(z(c,d,e,f,g,h),c,d,e,f,g,h,a)}function B(a,b,c,d,e,f,h,i){$('").appendTo("head"),g.mergely("options",{fgcolor:{a:d,c:b,d:f}});var j=D("cb",b.replace(/#/g,""),o.cb);j=D("cg",c.replace(/#/g,""),o.cg,j),j=D("ab",d.replace(/#/g,""),o.ab,j),j=D("ag",e.replace(/#/g,""),o.ag,j),j=D("db",f.replace(/#/g,""),o.db,j),j=D("dg",h.replace(/#/g,""),o.dg,j),i&&C(j)}function C(a){var b=[location.protocol,"//",location.host,location.pathname].join("");window.history.pushState({},null,b+a)}function D(a,b,c,d){var e=a+"="+b,f="?"+e;return d||(d=document.location.search),keyRegex=new RegExp("([?&])"+a+"[^&]*"),f=b===c?d.replace(keyRegex,""):null!==d.match(keyRegex)?d.replace(keyRegex,"$1"+e):d+"&"+e}var b=a();if(b.get("test",!1)){for(var c=$("
Tests"),d=$(""),e=1;8>=e;++e)d.append($('- Test '+e+"
"));c.append(d),$("#main-menu").append(c)}$(document).keydown(function(a){if("f"!=String.fromCharCode(a.which).toLowerCase()||!a.ctrlKey)return!0;a.preventDefault();var b=window.getSelection().getRangeAt(0),c=$(b.commonAncestorContainer).parents(".mergely-column");return f(c),!1}),String.prototype.random=function(a){for(var b="0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz",c="",d=0;a>d;d++){var e=Math.floor(Math.random()*b.length);c+=b.substring(e,e+1)}return c},$("body").css("visibility","");var g=$("#mergely"),h=$("#main-menu"),i=$("#toolbar");if(g.mergely({width:"auto",height:"auto",cmsettings:{lineNumbers:!0,readOnly:isSample}}),b.get("lhs",null)){var j=b.get("lhs");w(g,"lhs",j)}if(b.get("rhs",null)){var j=b.get("rhs");w(g,"rhs",j)}var k={},l={au:"autoupdate",ws:"ignorews",sb:"sidebar",vp:"viewport",wl:"wrap_lines",ln:"line_numbers"},m=!1;for(var n in l)l.hasOwnProperty(n)&&null!==b.get(n,null)&&(k[l[n]]=b.get(n),m=!0);null!==b.get("rm",null)&&(k.rhs_margin=b.get("rm")?"left":"right"),m&&g.mergely("options",k);var o={cb:"cccccc",cg:"fafafa",ab:"a3d1ff",ag:"ddeeff",db:"ff7f7f",dg:"edc0c0"};A(!1),window.addEventListener("popstate",function(c){c.state&&(b=a(),A(!1))}),8==key.length&&$.when($.ajax({type:"GET",async:!0,dataType:"text",data:{key:key,name:"lhs"},url:"/ajax/handle_get.php",success:function(a){g.mergely("lhs",a)},error:function(){}}),$.ajax({type:"GET",async:!0,dataType:"text",data:{key:key,name:"rhs"},url:"/ajax/handle_get.php",success:function(a){g.mergely("rhs",a)},error:function(){}})).done(function(){var a=window.location.hash.substring(1);if(a){var b=a.match(/([lr]hs)([0-9]+)/);b&&3==b.length&&(console.log(b),g.mergely("scrollTo",b[1],parseInt(b[2],10)))}});var p=$(".find"),q=p.clone().attr("id","mergely-editor-lhs-find"),r=p.clone().attr("id","mergely-editor-rhs-find");$("#mergely-editor-lhs").append(q),$("#mergely-editor-rhs").append(r),p.remove();var s={"options-autodiff":{get:function(){return g.mergely("options").autoupdate},set:function(){var b=!g.mergely("options").autoupdate;g.mergely("options",{autoupdate:b});var c=D("au",b?1:0,1);C(c)}},"options-ignorews":{get:function(){return g.mergely("options").ignorews},set:function(){var b=!g.mergely("options").ignorews;g.mergely("options",{ignorews:b});var c=D("ws",b?1:0,0);C(c)}},"options-sidebars":{get:function(){return console.log("sidebar",this),g.mergely("options").sidebar},set:function(){var b=!g.mergely("options").sidebar;g.mergely("options",{sidebar:b});var c=D("sb",b?1:0,1);C(c)}},"options-viewport":{get:function(){return console.log("viewport",this),g.mergely("options").viewport},set:function(){var b=!g.mergely("options").viewport;g.mergely("options",{viewport:b});var c=D("vp",b?1:0,1);C(c)}},"options-swapmargin":{get:function(){return"left"==g.mergely("options").rhs_margin},set:function(){var b="left"==g.mergely("options").rhs_margin?"right":"left";g.mergely("options",{rhs_margin:b});var c=D("rm","left"==b?1:0,0);C(c)}},"options-linenumbers":{get:function(){return console.log("wrap",this),g.mergely("options").line_numbers},set:function(){var b=!g.mergely("options").line_numbers;g.mergely("options",{line_numbers:b});var c=D("ln",b?1:0,1);C(c)}},"options-wrap":{get:function(){return console.log("wrap",this),g.mergely("options").wrap_lines},set:function(){var b=!g.mergely("options").wrap_lines;g.mergely("options",{wrap_lines:b});var c=D("wl",b?1:0,0);C(c)}},"edit-left-readonly":{get:function(){return g.mergely("cm","lhs").getOption("readOnly")},set:function(a){g.mergely("cm","lhs").setOption("readOnly",a)}},"edit-right-readonly":{get:function(){return g.mergely("cm","rhs").getOption("readOnly")},set:function(a){g.mergely("cm","rhs").setOption("readOnly",a)}}},t={hasIcon:function(a){return s.hasOwnProperty(a)},getIcon:function(a){return s[a].get()?"icon-check":void 0}};h.wickedmenu(t).bind("selected",function(a,b){return u(b)}),i.wickedtoolbar({}).bind("selected",function(a,b){return b?u(b.replace(/^tb-/,"")):!1}),i.find("li[title]").tipsy({opacity:1}),h.find("li[title]").tipsy({opacity:1,delayIn:1e3,gravity:"w"})});
\ No newline at end of file
+$(document).ready(function(){function a(){var a={};return window.location.search.substr(1).split("&").forEach(function(b){if(""!==b){var c=b.split("=");2===c.length&&c[1].search(/^(true|1)$/i)>=0?a[c[0]]=!0:2===c.length&&c[1].search(/^(false|0)$/i)>=0?a[c[0]]=!1:a[c[0]]=c[1]&&decodeURIComponent(c[1].replace(/\+/g," "))}}),{get:function(b,c){return a.hasOwnProperty(b)?a[b]:c}}}function f(a){if(!a.length)return!1;var b=$("#mergely"),c=a.find(".find"),d=c.find('input[type="text"]'),e=a.attr("id").indexOf("-lhs")>0?"lhs":"rhs",f=b.mergely("options").autoupdate;c.slideDown("fast",function(){d.focus(),b.mergely("options",{autoupdate:!1}),b.mergely("unmarkup")}),c.find(".find-prev").click(function(){b.mergely("search",e,d.val(),"prev")}),c.find(".find-next").click(function(){b.mergely("search",e,d.val(),"next")}),c.find(".find-close").click(function(){c.css("display","none"),b.mergely("options",{autoupdate:f})}),d.keydown(function(a){return 13!=a.which&&27!=a.which?!0:(27==a.which&&(c.css("display","none"),b.mergely("options",{autoupdate:f})),b.mergely("search",e,d.val()),!1)})}function u(a){if("file-new"==a)window.location="/editor";else if("file-save"==a){var b=g.mergely("diff");if(-1===navigator.userAgent.toLowerCase().indexOf("msie")){""==key&&(key="".random(8));var c=jQuery("",{href:"data:application/stream;base64,"+window.btoa(unescape(encodeURIComponent(b))),target:"_blank",text:"clickme",id:key});c.attr("download",key+".diff"),jQuery("body").append(c);var d=$("a#"+key);d[0].click(),d.remove()}else{var e=new Blob([b]);window.navigator.msSaveOrOpenBlob(e,key+".diff")}}else if("file-share"==a)v(g);else if("file-import"==a)x(g);else if("edit-left-undo"==a)g.mergely("cm","lhs").getDoc().undo();else if("edit-left-redo"==a)g.mergely("cm","lhs").getDoc().redo();else if("edit-right-undo"==a)g.mergely("cm","rhs").getDoc().undo();else if("edit-right-redo"==a)g.mergely("cm","rhs").getDoc().redo();else if("edit-left-find"==a)f(g.find("#mergely-editor-lhs"));else if("edit-left-merge-right"==a)g.mergely("mergeCurrentChange","rhs");else if("edit-left-merge-right-file"==a)g.mergely("merge","rhs");else if(["edit-left-readonly","edit-right-readonly","options-autodiff","options-sidebars","options-swapmargin","options-viewport","options-ignorews","options-wrap","options-linenumbers"].indexOf(a)>=0)s[a].set(!s[a].get()),h.wickedmenu("update",a);else if("edit-left-clear"==a)g.mergely("clear","lhs");else if("edit-right-find"==a)f(g.find("#mergely-editor-rhs"));else if("edit-right-merge-left"==a)g.mergely("mergeCurrentChange","lhs");else if("edit-right-merge-left-file"==a)g.mergely("merge","lhs");else if("edit-right-clear"==a)g.mergely("clear","rhs");else if("options-colors"==a)y(g);else if("view-swap"==a)g.mergely("swap");else if("view-refresh"==a)g.mergely("update");else if("view-change-next"==a)g.mergely("scrollToDiff","next");else if("view-change-prev"==a)g.mergely("scrollToDiff","prev");else if("view-clear"==a)g.mergely("unmarkup");else if(0==a.indexOf("examples-")){var i={test1:{lhs:"one\ntwo\nthree",rhs:"two\nthree"},test2:{lhs:"two\nthree",rhs:"one\ntwo\nthree"},test3:{lhs:"one\nthree",rhs:"one\ntwo\nthree"},test4:{lhs:"one\ntwo\nthree",rhs:"one\nthree"},test5:{lhs:"to bee, or not to be",rhs:"to be, or not to bee"},test6:{lhs:"to be, or not to be z",rhs:"to be, to be"},test7:{lhs:"remained, & to assume",rhs:"and to assume"},test8:{lhs:"to be, or not to be",rhs:"to be, or not to be"}},j=a.split("examples-")[1];g.mergely("lhs",i[j].lhs),g.mergely("rhs",i[j].rhs)}return!1}function v(a){function d(a,d){$.ajax({type:"POST",async:!0,dataType:"text",url:"/ajax/handle_file.php",data:{key:key,name:a,content:d},success:function(a){if(++c,2==c){var d="/ajax/handle_save.php?key="+key;b&&(d+="&nkey="+"".random(8)),$.ajax({type:"GET",async:!1,dataType:"text",url:d,success:function(a){a.length&&(window.location.href="/"+$.trim(a)+"/")},error:function(a,b,c){}})}},error:function(a,b,c){alert(c)}})}function e(){var b=a.mergely("get","lhs"),c=a.mergely("get","rhs");d("lhs",b),d("rhs",c)}var b="fork"==$(this).attr("id");""==key&&(key="".random(8));var c=0;$("#dialog-confirm").dialog({resizable:!1,width:350,modal:!0,buttons:{"Save for Sharing":function(){$(this).dialog("close"),e()},Cancel:function(){$(this).dialog("close")}}})}function w(a,b,c){$.ajax({type:"GET",dataType:"text",data:{url:c},url:"/ajax/handle_crossdomain.php",contentType:"text/plain",success:function(c){a.mergely(b,c)},error:function(a,b,c){console.error("error",a,b,c)}})}function x(a){function b(a,b){function f(a,b){e.trigger(a,b)}var c=a.files[0],d=new FileReader,e=$(a);d.onloadstart=function(a){f("start")},d.onprogress=function(a){f("progress",a)},d.onload=function(a){f("loaded",a.target.result)},d.onerror=function(a){alert(a.target.error.name)};try{d.readAsText(c,"UTF-8")}catch(g){console.error(g),alert(g)}}var c={};$("#file-lhs, #file-rhs").change(function(a){var d=new RegExp(".*[\\\\/](.*)$"),e=d.exec($(this).val()),f=e?e[1]:"unknown",g=$("#"+a.target.id+"-progress");b(a.target),$(a.target).bind("start",function(b){$(a.target).css("display","none"),g.css("display","inline-block")}),$(a.target).bind("progress",function(a,b){var c=b.loaded/b.total*100;g.find("> .progress-label").text(c+"%"),g.progressbar("value",c)}),$(a.target).bind("loaded",function(b,d){g.progressbar("value",100),g.find("> .progress-label").text(f),c[a.target.id]=d})}),$("#file-lhs-progress").progressbar({value:0}),$("#file-rhs-progress").progressbar({value:0}),$("#dialog-upload .tabs").tabs(),$("#dialog-upload").dialog({dialogClass:"no-title",resizable:!1,width:"450px",modal:!0,buttons:{Import:function(){$(this).dialog("close");var b={lhs:$("#url-lhs").val(),rhs:$("#url-rhs").val()};for(var d in b){var e=b[d];e&&w(a,d,e)}c.hasOwnProperty("file-lhs")&&a.mergely("lhs",c["file-lhs"]),c.hasOwnProperty("file-rhs")&&a.mergely("rhs",c["file-rhs"])},Cancel:function(){$(this).dialog("close")}}})}function y(a){var b=$('C'),c=$('C'),d=$('C');$("body").append(b),$("body").append(c),$("body").append(d);var e={"c-border":{id:"#c-border",getColor:function(){return d.css("border-top-color")},setColor:function(a){$("#"+this.id).val(a)}},"c-bg":{id:"#c-bg",getColor:function(){return d.css("background-color")},setColor:function(a){$("#"+this.id).val(a)}},"a-border":{id:"#a-border",getColor:function(){return c.css("border-top-color")},setColor:function(a){$("#"+this.id).val(a)}},"a-bg":{id:"#a-bg",getColor:function(){return c.css("background-color")},setColor:function(a){$("#"+this.id).val(a)}},"d-border":{id:"#d-border",getColor:function(){return b.css("border-top-color")},setColor:function(a){$("#"+this.id).val(a)}},"d-bg":{id:"#d-bg",getColor:function(){return b.css("background-color")},setColor:function(a){$("#"+this.id).val(a)}}};$.each(e,function(a,b){$(b.id).val(b.getColor())});var f=$.farbtastic("#picker");$(".colorwell").each(function(){f.linkTo(this)}).focus(function(){var a=$(this);f.linkTo(this);var b=e[a.attr("id")];f.setColor(b.getColor())}),$("#dialog-colors").dialog({width:490,modal:!0,buttons:{Apply:function(){var a=$("#c-border").val(),b=$("#a-border").val(),c=$("#d-border").val(),d=$("#a-bg").val(),e=$("#d-bg").val(),f=$("#c-bg").val(),g=z(a,f,b,d,c,e);B(g,a,f,b,d,c,e,!0)},Reset:function(){},Close:function(){$(this).dialog("close")}}})}function z(a,b,c,d,e,f){var g=".mergely.a.rhs.start{border-top-color:"+c+";}\n .mergely.a.lhs.start.end,\n .mergely.a.rhs.end{border-bottom-color:"+c+";}\n .mergely.a.rhs{background-color:"+d+";}\n .mergely.d.lhs{background-color:"+f+";}\n .mergely.d.lhs.end,\n .mergely.d.rhs.start.end{border-bottom-color:"+e+";}\n .mergely.d.rhs.start.end.first{border-top-color:"+e+";}\n .mergely.d.lhs.start{border-top-color:"+e+";}\n .mergely.c.lhs,\n .mergely.c.rhs{background-color:"+b+";}\n .mergely.c.lhs.start,\n .mergely.c.rhs.start{border-top-color:"+a+";}\n .mergely.c.lhs.end,\n .mergely.c.rhs.end{border-bottom-color:"+a+";}\n .mergely.ch.a.rhs{background-color:"+d+";}\n .mergely.ch.d.lhs{background-color:"+f+";color: #888;}";return g}function A(a){var c="#"+b.get("cb",o.cb),d="#"+b.get("cg",o.cg),e="#"+b.get("ab",o.ab),f="#"+b.get("ag",o.ag),g="#"+b.get("db",o.db),h="#"+b.get("dg",o.dg);B(z(c,d,e,f,g,h),c,d,e,f,g,h,a)}function B(a,b,c,d,e,f,h,i){$('").appendTo("head"),g.mergely("options",{fgcolor:{a:d,c:b,d:f}});var j=D("cb",b.replace(/#/g,""),o.cb);j=D("cg",c.replace(/#/g,""),o.cg,j),j=D("ab",d.replace(/#/g,""),o.ab,j),j=D("ag",e.replace(/#/g,""),o.ag,j),j=D("db",f.replace(/#/g,""),o.db,j),j=D("dg",h.replace(/#/g,""),o.dg,j),i&&C(j)}function C(a){var b=[location.protocol,"//",location.host,location.pathname].join("");window.history.pushState({},null,b+a)}function D(a,b,c,d){var e=a+"="+b,f="?"+e;return d||(d=document.location.search),keyRegex=new RegExp("([?&])"+a+"[^&]*"),f=b===c?d.replace(keyRegex,""):null!==d.match(keyRegex)?d.replace(keyRegex,"$1"+e):d+"&"+e}var b=a();if(b.get("test",!1)){for(var c=$("- Tests
"),d=$(""),e=1;8>=e;++e)d.append($('- Test '+e+"
"));c.append(d),$("#main-menu").append(c)}$(document).keydown(function(a){if("f"!=String.fromCharCode(a.which).toLowerCase()||!a.ctrlKey)return!0;a.preventDefault();var b=window.getSelection().getRangeAt(0),c=$(b.commonAncestorContainer).parents(".mergely-column");return f(c),!1}),String.prototype.random=function(a){for(var b="0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz",c="",d=0;a>d;d++){var e=Math.floor(Math.random()*b.length);c+=b.substring(e,e+1)}return c},$("body").css("visibility","");var g=$("#mergely"),h=$("#main-menu"),i=$("#toolbar");if(g.mergely({width:"auto",height:"auto",cmsettings:{lineNumbers:!0,readOnly:isSample}}),b.get("lhs",null)){var j=b.get("lhs");w(g,"lhs",j)}if(b.get("rhs",null)){var j=b.get("rhs");w(g,"rhs",j)}var k={},l={au:"autoupdate",ws:"ignorews",sb:"sidebar",vp:"viewport",wl:"wrap_lines",ln:"line_numbers"},m=!1;for(var n in l)l.hasOwnProperty(n)&&null!==b.get(n,null)&&(k[l[n]]=b.get(n),m=!0);null!==b.get("rm",null)&&(k.rhs_margin=b.get("rm")?"left":"right"),m&&g.mergely("options",k);var o={cb:"cccccc",cg:"fafafa",ab:"a3d1ff",ag:"ddeeff",db:"ff7f7f",dg:"ffe9e9"};A(!1),window.addEventListener("popstate",function(c){c.state&&(b=a(),A(!1))}),8==key.length&&$.when($.ajax({type:"GET",async:!0,dataType:"text",data:{key:key,name:"lhs"},url:"/ajax/handle_get.php",success:function(a){g.mergely("lhs",a)},error:function(a,b,c){}}),$.ajax({type:"GET",async:!0,dataType:"text",data:{key:key,name:"rhs"},url:"/ajax/handle_get.php",success:function(a){g.mergely("rhs",a)},error:function(a,b,c){}})).done(function(){var a=window.location.hash.substring(1);if(a){var b=a.match(/([lr]hs)([0-9]+)/);b&&3==b.length&&(console.log(b),g.mergely("scrollTo",b[1],parseInt(b[2],10)))}});var p=$(".find"),q=p.clone().attr("id","mergely-editor-lhs-find"),r=p.clone().attr("id","mergely-editor-rhs-find");$("#mergely-editor-lhs").append(q),$("#mergely-editor-rhs").append(r),p.remove();var s={"options-autodiff":{get:function(){return g.mergely("options").autoupdate},set:function(a){var b=!g.mergely("options").autoupdate;g.mergely("options",{autoupdate:b});var c=D("au",b?1:0,1);C(c)}},"options-ignorews":{get:function(){return g.mergely("options").ignorews},set:function(a){var b=!g.mergely("options").ignorews;g.mergely("options",{ignorews:b});var c=D("ws",b?1:0,0);C(c)}},"options-sidebars":{get:function(){return console.log("sidebar",this),g.mergely("options").sidebar},set:function(a){var b=!g.mergely("options").sidebar;g.mergely("options",{sidebar:b});var c=D("sb",b?1:0,1);C(c)}},"options-viewport":{get:function(){return console.log("viewport",this),g.mergely("options").viewport},set:function(a){var b=!g.mergely("options").viewport;g.mergely("options",{viewport:b});var c=D("vp",b?1:0,1);C(c)}},"options-swapmargin":{get:function(){return"left"==g.mergely("options").rhs_margin},set:function(a){var b="left"==g.mergely("options").rhs_margin?"right":"left";g.mergely("options",{rhs_margin:b});var c=D("rm","left"==b?1:0,0);C(c)}},"options-linenumbers":{get:function(){return console.log("wrap",this),g.mergely("options").line_numbers},set:function(a){var b=!g.mergely("options").line_numbers;g.mergely("options",{line_numbers:b});var c=D("ln",b?1:0,1);C(c)}},"options-wrap":{get:function(){return console.log("wrap",this),g.mergely("options").wrap_lines},set:function(a){var b=!g.mergely("options").wrap_lines;g.mergely("options",{wrap_lines:b});var c=D("wl",b?1:0,0);C(c)}},"edit-left-readonly":{get:function(){return g.mergely("cm","lhs").getOption("readOnly")},set:function(a){g.mergely("cm","lhs").setOption("readOnly",a)}},"edit-right-readonly":{get:function(){return g.mergely("cm","rhs").getOption("readOnly")},set:function(a){g.mergely("cm","rhs").setOption("readOnly",a)}}},t={hasIcon:function(a){return s.hasOwnProperty(a)},getIcon:function(a){return s[a].get()?"icon-check":void 0}};h.wickedmenu(t).bind("selected",function(a,b){return u(b)}),i.wickedtoolbar({}).bind("selected",function(a,b){return b?u(b.replace(/^tb-/,"")):!1}),i.find("li[title]").tipsy({opacity:1}),h.find("li[title]").tipsy({opacity:1,delayIn:1e3,gravity:"w"})});
\ No newline at end of file
diff --git a/lib/codemirror.css b/lib/codemirror.css
index 6b9ca02..1067b3e 100755
--- a/lib/codemirror.css
+++ b/lib/codemirror.css
@@ -4,10 +4,7 @@
/* Set height, width, borders, and global font properties here */
font-family: monospace;
height: 300px;
-}
-.CodeMirror-scroll {
- /* Set scrolling behaviour here */
- overflow: auto;
+ color: black;
}
/* PADDING */
@@ -36,8 +33,7 @@
min-width: 20px;
text-align: right;
color: #999;
- -moz-box-sizing: content-box;
- box-sizing: content-box;
+ white-space: nowrap;
}
.CodeMirror-guttermarker { color: black; }
@@ -45,19 +41,21 @@
/* CURSOR */
-.CodeMirror div.CodeMirror-cursor {
+.CodeMirror-cursor {
border-left: 1px solid black;
+ border-right: none;
+ width: 0;
}
/* Shown when moving in bi-directional text */
.CodeMirror div.CodeMirror-secondarycursor {
border-left: 1px solid silver;
}
-.CodeMirror.cm-keymap-fat-cursor div.CodeMirror-cursor {
+.cm-fat-cursor .CodeMirror-cursor {
width: auto;
border: 0;
background: #7e7;
}
-.CodeMirror.cm-keymap-fat-cursor div.CodeMirror-cursors {
+.cm-fat-cursor div.CodeMirror-cursors {
z-index: 1;
}
@@ -67,27 +65,28 @@
-webkit-animation: blink 1.06s steps(1) infinite;
-moz-animation: blink 1.06s steps(1) infinite;
animation: blink 1.06s steps(1) infinite;
+ background-color: #7e7;
}
@-moz-keyframes blink {
- 0% { background: #7e7; }
- 50% { background: none; }
- 100% { background: #7e7; }
+ 0% {}
+ 50% { background-color: transparent; }
+ 100% {}
}
@-webkit-keyframes blink {
- 0% { background: #7e7; }
- 50% { background: none; }
- 100% { background: #7e7; }
+ 0% {}
+ 50% { background-color: transparent; }
+ 100% {}
}
@keyframes blink {
- 0% { background: #7e7; }
- 50% { background: none; }
- 100% { background: #7e7; }
+ 0% {}
+ 50% { background-color: transparent; }
+ 100% {}
}
/* Can style cursor different in overwrite (non-insert) mode */
-div.CodeMirror-overwrite div.CodeMirror-cursor {}
+.CodeMirror-overwrite .CodeMirror-cursor {}
-.cm-tab { display: inline-block; }
+.cm-tab { display: inline-block; text-decoration: inherit; }
.CodeMirror-ruler {
border-left: 1px solid #ccc;
@@ -96,6 +95,15 @@ div.CodeMirror-overwrite div.CodeMirror-cursor {}
/* DEFAULT THEME */
+.cm-s-default .cm-header {color: blue;}
+.cm-s-default .cm-quote {color: #090;}
+.cm-negative {color: #d44;}
+.cm-positive {color: #292;}
+.cm-header, .cm-strong {font-weight: bold;}
+.cm-em {font-style: italic;}
+.cm-link {text-decoration: underline;}
+.cm-strikethrough {text-decoration: line-through;}
+
.cm-s-default .cm-keyword {color: #708;}
.cm-s-default .cm-atom {color: #219;}
.cm-s-default .cm-number {color: #164;}
@@ -115,20 +123,14 @@ div.CodeMirror-overwrite div.CodeMirror-cursor {}
.cm-s-default .cm-bracket {color: #997;}
.cm-s-default .cm-tag {color: #170;}
.cm-s-default .cm-attribute {color: #00c;}
-.cm-s-default .cm-header {color: blue;}
-.cm-s-default .cm-quote {color: #090;}
.cm-s-default .cm-hr {color: #999;}
.cm-s-default .cm-link {color: #00c;}
-.cm-negative {color: #d44;}
-.cm-positive {color: #292;}
-.cm-header, .cm-strong {font-weight: bold;}
-.cm-em {font-style: italic;}
-.cm-link {text-decoration: underline;}
-
.cm-s-default .cm-error {color: #f00;}
.cm-invalidchar {color: #f00;}
+.CodeMirror-composing { border-bottom: 2px solid; }
+
/* Default styles for common addons */
div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
@@ -142,14 +144,13 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
the editor. You probably shouldn't touch them. */
.CodeMirror {
- line-height: 1;
position: relative;
overflow: hidden;
background: white;
- color: black;
}
.CodeMirror-scroll {
+ overflow: scroll !important; /* Things will break if this is overridden */
/* 30px is the magic margin used to hide the element's real scrollbars */
/* See overflow: hidden in .CodeMirror */
margin-bottom: -30px; margin-right: -30px;
@@ -157,18 +158,14 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
height: 100%;
outline: none; /* Prevent dragging from highlighting the element */
position: relative;
- -moz-box-sizing: content-box;
- box-sizing: content-box;
}
.CodeMirror-sizer {
position: relative;
border-right: 30px solid transparent;
- -moz-box-sizing: content-box;
- box-sizing: content-box;
}
/* The fake, visible scrollbars. Used to force redraw during scrolling
- before actuall scrolling happens, thus preventing shaking and
+ before actual scrolling happens, thus preventing shaking and
flickering artifacts. */
.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
position: absolute;
@@ -194,26 +191,38 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
.CodeMirror-gutters {
position: absolute; left: 0; top: 0;
- padding-bottom: 30px;
z-index: 3;
}
.CodeMirror-gutter {
white-space: normal;
height: 100%;
- -moz-box-sizing: content-box;
- box-sizing: content-box;
- padding-bottom: 30px;
- margin-bottom: -32px;
display: inline-block;
+ margin-bottom: -30px;
/* Hack to make IE7 behave */
*zoom:1;
*display:inline;
}
+.CodeMirror-gutter-wrapper {
+ position: absolute;
+ z-index: 4;
+ background: none !important;
+ border: none !important;
+}
+.CodeMirror-gutter-background {
+ position: absolute;
+ top: 0; bottom: 0;
+ z-index: 4;
+}
.CodeMirror-gutter-elt {
position: absolute;
cursor: default;
z-index: 4;
}
+.CodeMirror-gutter-wrapper {
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ user-select: none;
+}
.CodeMirror-lines {
cursor: text;
@@ -234,6 +243,7 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
z-index: 2;
position: relative;
overflow: visible;
+ -webkit-tap-highlight-color: transparent;
}
.CodeMirror-wrap pre {
word-wrap: break-word;
@@ -255,8 +265,18 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
.CodeMirror-widget {}
-.CodeMirror-wrap .CodeMirror-scroll {
- overflow-x: hidden;
+.CodeMirror-code {
+ outline: none;
+}
+
+/* Force content-box sizing for the elements where we expect it */
+.CodeMirror-scroll,
+.CodeMirror-sizer,
+.CodeMirror-gutter,
+.CodeMirror-gutters,
+.CodeMirror-linenumber {
+ -moz-box-sizing: content-box;
+ box-sizing: content-box;
}
.CodeMirror-measure {
@@ -266,19 +286,19 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
overflow: hidden;
visibility: hidden;
}
-.CodeMirror-measure pre { position: static; }
-.CodeMirror div.CodeMirror-cursor {
- position: absolute;
- border-right: none;
- width: 0;
-}
+.CodeMirror-cursor { position: absolute; }
+.CodeMirror-measure pre { position: static; }
div.CodeMirror-cursors {
visibility: hidden;
position: relative;
z-index: 3;
}
+div.CodeMirror-dragcursors {
+ visibility: visible;
+}
+
.CodeMirror-focused div.CodeMirror-cursors {
visibility: visible;
}
@@ -286,6 +306,8 @@ div.CodeMirror-cursors {
.CodeMirror-selected { background: #d9d9d9; }
.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
.CodeMirror-crosshair { cursor: crosshair; }
+.CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }
+.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }
.cm-searching {
background: #ffa;
@@ -305,5 +327,8 @@ div.CodeMirror-cursors {
}
}
+/* See issue #2901 */
+.cm-tab-wrap-hack:after { content: ''; }
+
/* Help users use markselection to safely style text background */
span.CodeMirror-selectedtext { background: none; }
diff --git a/lib/codemirror.js b/lib/codemirror.js
index 97f6668..090e421 100755
--- a/lib/codemirror.js
+++ b/lib/codemirror.js
@@ -13,7 +13,7 @@
else if (typeof define == "function" && define.amd) // AMD
return define([], mod);
else // Plain browser env
- this.CodeMirror = mod();
+ (this || window).CodeMirror = mod();
})(function() {
"use strict";
@@ -21,29 +21,29 @@
// Kludges for bugs and behavior differences that can't be feature
// detected are enabled based on userAgent etc sniffing.
+ var userAgent = navigator.userAgent;
+ var platform = navigator.platform;
- var gecko = /gecko\/\d/i.test(navigator.userAgent);
- // ie_uptoN means Internet Explorer version N or lower
- var ie_upto10 = /MSIE \d/.test(navigator.userAgent);
- var ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent);
+ var gecko = /gecko\/\d/i.test(userAgent);
+ var ie_upto10 = /MSIE \d/.test(userAgent);
+ var ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(userAgent);
var ie = ie_upto10 || ie_11up;
var ie_version = ie && (ie_upto10 ? document.documentMode || 6 : ie_11up[1]);
- var webkit = /WebKit\//.test(navigator.userAgent);
- var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(navigator.userAgent);
- var chrome = /Chrome\//.test(navigator.userAgent);
- var presto = /Opera\//.test(navigator.userAgent);
+ var webkit = /WebKit\//.test(userAgent);
+ var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(userAgent);
+ var chrome = /Chrome\//.test(userAgent);
+ var presto = /Opera\//.test(userAgent);
var safari = /Apple Computer/.test(navigator.vendor);
- var khtml = /KHTML\//.test(navigator.userAgent);
- var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(navigator.userAgent);
- var phantom = /PhantomJS/.test(navigator.userAgent);
+ var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(userAgent);
+ var phantom = /PhantomJS/.test(userAgent);
- var ios = /AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent);
+ var ios = /AppleWebKit/.test(userAgent) && /Mobile\/\w+/.test(userAgent);
// This is woefully incomplete. Suggestions for alternative methods welcome.
- var mobile = ios || /Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(navigator.userAgent);
- var mac = ios || /Mac/.test(navigator.platform);
- var windows = /win/i.test(navigator.platform);
+ var mobile = ios || /Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(userAgent);
+ var mac = ios || /Mac/.test(platform);
+ var windows = /win/i.test(platform);
- var presto_version = presto && navigator.userAgent.match(/Version\/(\d*\.\d*)/);
+ var presto_version = presto && userAgent.match(/Version\/(\d*\.\d*)/);
if (presto_version) presto_version = Number(presto_version[1]);
if (presto_version && presto_version >= 15) { presto = false; webkit = true; }
// Some browsers use the wrong event properties to signal cmd/ctrl on OS X
@@ -61,56 +61,70 @@
function CodeMirror(place, options) {
if (!(this instanceof CodeMirror)) return new CodeMirror(place, options);
- this.options = options = options || {};
+ this.options = options = options ? copyObj(options) : {};
// Determine effective options based on given values and defaults.
copyObj(defaults, options, false);
setGuttersForLineNumbers(options);
var doc = options.value;
- if (typeof doc == "string") doc = new Doc(doc, options.mode);
+ if (typeof doc == "string") doc = new Doc(doc, options.mode, null, options.lineSeparator);
this.doc = doc;
- var display = this.display = new Display(place, doc);
+ var input = new CodeMirror.inputStyles[options.inputStyle](this);
+ var display = this.display = new Display(place, doc, input);
display.wrapper.CodeMirror = this;
updateGutters(this);
themeChanged(this);
if (options.lineWrapping)
this.display.wrapper.className += " CodeMirror-wrap";
- if (options.autofocus && !mobile) focusInput(this);
+ if (options.autofocus && !mobile) display.input.focus();
+ initScrollbars(this);
this.state = {
keyMaps: [], // stores maps added by addKeyMap
overlays: [], // highlighting overlays, as added by addOverlay
modeGen: 0, // bumped when mode/overlay changes, used to invalidate highlighting info
- overwrite: false, focused: false,
+ overwrite: false,
+ delayingBlurEvent: false,
+ focused: false,
suppressEdits: false, // used to disable editing during key handlers when in readOnly mode
- pasteIncoming: false, cutIncoming: false, // help recognize paste/cut edits in readInput
+ pasteIncoming: false, cutIncoming: false, // help recognize paste/cut edits in input.poll
+ selectingText: false,
draggingText: false,
- highlight: new Delayed() // stores highlight worker timeout
+ highlight: new Delayed(), // stores highlight worker timeout
+ keySeq: null, // Unfinished key sequence
+ specialChars: null
};
+ var cm = this;
+
// Override magic textarea content restore that IE sometimes does
// on our hidden textarea on reload
- if (ie && ie_version < 11) setTimeout(bind(resetInput, this, true), 20);
+ if (ie && ie_version < 11) setTimeout(function() { cm.display.input.reset(true); }, 20);
registerEventHandlers(this);
ensureGlobalHandlers();
- var cm = this;
- runInOp(this, function() {
- cm.curOp.forceUpdate = true;
- attachDoc(cm, doc);
+ startOperation(this);
+ this.curOp.forceUpdate = true;
+ attachDoc(this, doc);
- if ((options.autofocus && !mobile) || activeElt() == display.input)
- setTimeout(bind(onFocus, cm), 20);
- else
- onBlur(cm);
+ if ((options.autofocus && !mobile) || cm.hasFocus())
+ setTimeout(bind(onFocus, this), 20);
+ else
+ onBlur(this);
- for (var opt in optionHandlers) if (optionHandlers.hasOwnProperty(opt))
- optionHandlers[opt](cm, options[opt], Init);
- maybeUpdateLineNumberWidth(cm);
- for (var i = 0; i < initHooks.length; ++i) initHooks[i](cm);
- });
+ for (var opt in optionHandlers) if (optionHandlers.hasOwnProperty(opt))
+ optionHandlers[opt](this, options[opt], Init);
+ maybeUpdateLineNumberWidth(this);
+ if (options.finishInit) options.finishInit(this);
+ for (var i = 0; i < initHooks.length; ++i) initHooks[i](this);
+ endOperation(this);
+ // Suppress optimizelegibility in Webkit, since it breaks text
+ // measuring on line wrapping boundaries.
+ if (webkit && options.lineWrapping &&
+ getComputedStyle(display.lineDiv).textRendering == "optimizelegibility")
+ display.lineDiv.style.textRendering = "auto";
}
// DISPLAY CONSTRUCTOR
@@ -119,32 +133,17 @@
// and content drawing. It holds references to DOM nodes and
// display-related state.
- function Display(place, doc) {
+ function Display(place, doc, input) {
var d = this;
+ this.input = input;
- // The semihidden textarea that is focused when the editor is
- // focused, and receives input.
- var input = d.input = elt("textarea", null, null, "position: absolute; padding: 0; width: 1px; height: 1em; outline: none");
- // The textarea is kept positioned near the cursor to prevent the
- // fact that it'll be scrolled into view on input from scrolling
- // our fake cursor out of view. On webkit, when wrap=off, paste is
- // very slow. So make the area wide instead.
- if (webkit) input.style.width = "1000px";
- else input.setAttribute("wrap", "off");
- // If border: 0; -- iOS fails to open keyboard (issue #1287)
- if (ios) input.style.border = "1px solid black";
- input.setAttribute("autocorrect", "off"); input.setAttribute("autocapitalize", "off"); input.setAttribute("spellcheck", "false");
-
- // Wraps and hides input textarea
- d.inputDiv = elt("div", [input], null, "overflow: hidden; position: relative; width: 3px; height: 0px;");
- // The fake scrollbar elements.
- d.scrollbarH = elt("div", [elt("div", null, null, "height: 100%; min-height: 1px")], "CodeMirror-hscrollbar");
- d.scrollbarV = elt("div", [elt("div", null, null, "min-width: 1px")], "CodeMirror-vscrollbar");
// Covers bottom-right square when both scrollbars are present.
d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler");
+ d.scrollbarFiller.setAttribute("cm-not-content", "true");
// Covers bottom of gutter when coverGutterNextToScrollbar is on
// and h scrollbar is present.
d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler");
+ d.gutterFiller.setAttribute("cm-not-content", "true");
// Will contain the actual code, positioned to cover the viewport.
d.lineDiv = elt("div", null, "CodeMirror-code");
// Elements are added to these to represent selection and cursors.
@@ -161,10 +160,11 @@
d.mover = elt("div", [elt("div", [d.lineSpace], "CodeMirror-lines")], null, "position: relative");
// Set to the height of the document, allowing scrolling.
d.sizer = elt("div", [d.mover], "CodeMirror-sizer");
+ d.sizerWidth = null;
// Behavior of elts with overflow: auto and padding is
// inconsistent across browsers. This is used to ensure the
// scrollable area is big enough.
- d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerCutOff + "px; width: 1px;");
+ d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerGap + "px; width: 1px;");
// Will contain the gutters, if any.
d.gutters = elt("div", null, "CodeMirror-gutters");
d.lineGutter = null;
@@ -172,56 +172,44 @@
d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll");
d.scroller.setAttribute("tabIndex", "-1");
// The element in which the editor lives.
- d.wrapper = elt("div", [d.inputDiv, d.scrollbarH, d.scrollbarV,
- d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror");
+ d.wrapper = elt("div", [d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror");
// Work around IE7 z-index bug (not perfect, hence IE7 not really being supported)
if (ie && ie_version < 8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0; }
- // Needed to hide big blue blinking cursor on Mobile Safari
- if (ios) input.style.width = "0px";
- if (!webkit) d.scroller.draggable = true;
- // Needed to handle Tab key in KHTML
- if (khtml) { d.inputDiv.style.height = "1px"; d.inputDiv.style.position = "absolute"; }
- // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8).
- if (ie && ie_version < 8) d.scrollbarH.style.minHeight = d.scrollbarV.style.minWidth = "18px";
+ if (!webkit && !(gecko && mobile)) d.scroller.draggable = true;
- if (place.appendChild) place.appendChild(d.wrapper);
- else place(d.wrapper);
+ if (place) {
+ if (place.appendChild) place.appendChild(d.wrapper);
+ else place(d.wrapper);
+ }
// Current rendered range (may be bigger than the view window).
d.viewFrom = d.viewTo = doc.first;
+ d.reportedViewFrom = d.reportedViewTo = doc.first;
// Information about the rendered lines.
d.view = [];
+ d.renderedView = null;
// Holds info about a single rendered line when it was rendered
// for measurement, while not in view.
d.externalMeasured = null;
// Empty space (in pixels) above the view
d.viewOffset = 0;
- d.lastSizeC = 0;
+ d.lastWrapHeight = d.lastWrapWidth = 0;
d.updateLineNumbers = null;
+ d.nativeBarWidth = d.barHeight = d.barWidth = 0;
+ d.scrollbarsClipped = false;
+
// Used to only resize the line number gutter when necessary (when
// the amount of lines crosses a boundary that makes its width change)
d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null;
- // See readInput and resetInput
- d.prevInput = "";
// Set to true when a non-horizontal-scrolling line widget is
// added. As an optimization, line widget aligning is skipped when
// this is false.
d.alignWidgets = false;
- // Flag that indicates whether we expect input to appear real soon
- // now (after some event like 'keypress' or 'input') and are
- // polling intensively.
- d.pollingFast = false;
- // Self-resetting timeout for the poller
- d.poll = new Delayed();
d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null;
- // Tracks when resetInput has punted to just putting a short
- // string into the textarea instead of the full selection.
- d.inaccurateSelection = false;
-
// Tracks the maximum line length so that the horizontal scrollbar
// can be kept static when scrolling.
d.maxLine = null;
@@ -237,6 +225,10 @@
// Used to track whether anything happened since the context menu
// was opened.
d.selForContextMenu = null;
+
+ d.activeTouch = null;
+
+ input.init(d);
}
// STATE UPDATES
@@ -263,6 +255,7 @@
if (cm.options.lineWrapping) {
addClass(cm.display.wrapper, "CodeMirror-wrap");
cm.display.sizer.style.minWidth = "";
+ cm.display.sizerWidth = null;
} else {
rmClass(cm.display.wrapper, "CodeMirror-wrap");
findMaxLine(cm);
@@ -302,12 +295,6 @@
});
}
- function keyMapChanged(cm) {
- var map = keyMap[cm.options.keyMap], style = map.style;
- cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-keymap-\S+/g, "") +
- (style ? " cm-keymap-" + style : "");
- }
-
function themeChanged(cm) {
cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-s-\S+/g, "") +
cm.options.theme.replace(/(^|\s)\s*/g, " cm-s-");
@@ -340,7 +327,6 @@
function updateGutterSpace(cm) {
var width = cm.display.gutters.offsetWidth;
cm.display.sizer.style.marginLeft = width + "px";
- cm.display.scrollbarH.style.left = cm.options.fixedGutter ? width + "px" : 0;
}
// Compute the character length of a line, taking into account
@@ -393,78 +379,181 @@
// SCROLLBARS
- function hScrollbarTakesSpace(cm) {
- return cm.display.scroller.clientHeight - cm.display.wrapper.clientHeight < scrollerCutOff - 3;
- }
-
// Prepare DOM reads needed to update the scrollbars. Done in one
// shot to minimize update/measure roundtrips.
function measureForScrollbars(cm) {
- var scroll = cm.display.scroller;
+ var d = cm.display, gutterW = d.gutters.offsetWidth;
+ var docH = Math.round(cm.doc.height + paddingVert(cm.display));
return {
- clientHeight: scroll.clientHeight,
- barHeight: cm.display.scrollbarV.clientHeight,
- scrollWidth: scroll.scrollWidth, clientWidth: scroll.clientWidth,
- hScrollbarTakesSpace: hScrollbarTakesSpace(cm),
- barWidth: cm.display.scrollbarH.clientWidth,
- docHeight: Math.round(cm.doc.height + paddingVert(cm.display))
+ clientHeight: d.scroller.clientHeight,
+ viewHeight: d.wrapper.clientHeight,
+ scrollWidth: d.scroller.scrollWidth, clientWidth: d.scroller.clientWidth,
+ viewWidth: d.wrapper.clientWidth,
+ barLeft: cm.options.fixedGutter ? gutterW : 0,
+ docHeight: docH,
+ scrollHeight: docH + scrollGap(cm) + d.barHeight,
+ nativeBarWidth: d.nativeBarWidth,
+ gutterWidth: gutterW
};
}
+ function NativeScrollbars(place, scroll, cm) {
+ this.cm = cm;
+ var vert = this.vert = elt("div", [elt("div", null, null, "min-width: 1px")], "CodeMirror-vscrollbar");
+ var horiz = this.horiz = elt("div", [elt("div", null, null, "height: 100%; min-height: 1px")], "CodeMirror-hscrollbar");
+ place(vert); place(horiz);
+
+ on(vert, "scroll", function() {
+ if (vert.clientHeight) scroll(vert.scrollTop, "vertical");
+ });
+ on(horiz, "scroll", function() {
+ if (horiz.clientWidth) scroll(horiz.scrollLeft, "horizontal");
+ });
+
+ this.checkedZeroWidth = false;
+ // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8).
+ if (ie && ie_version < 8) this.horiz.style.minHeight = this.vert.style.minWidth = "18px";
+ }
+
+ NativeScrollbars.prototype = copyObj({
+ update: function(measure) {
+ var needsH = measure.scrollWidth > measure.clientWidth + 1;
+ var needsV = measure.scrollHeight > measure.clientHeight + 1;
+ var sWidth = measure.nativeBarWidth;
+
+ if (needsV) {
+ this.vert.style.display = "block";
+ this.vert.style.bottom = needsH ? sWidth + "px" : "0";
+ var totalHeight = measure.viewHeight - (needsH ? sWidth : 0);
+ // A bug in IE8 can cause this value to be negative, so guard it.
+ this.vert.firstChild.style.height =
+ Math.max(0, measure.scrollHeight - measure.clientHeight + totalHeight) + "px";
+ } else {
+ this.vert.style.display = "";
+ this.vert.firstChild.style.height = "0";
+ }
+
+ if (needsH) {
+ this.horiz.style.display = "block";
+ this.horiz.style.right = needsV ? sWidth + "px" : "0";
+ this.horiz.style.left = measure.barLeft + "px";
+ var totalWidth = measure.viewWidth - measure.barLeft - (needsV ? sWidth : 0);
+ this.horiz.firstChild.style.width =
+ (measure.scrollWidth - measure.clientWidth + totalWidth) + "px";
+ } else {
+ this.horiz.style.display = "";
+ this.horiz.firstChild.style.width = "0";
+ }
+
+ if (!this.checkedZeroWidth && measure.clientHeight > 0) {
+ if (sWidth == 0) this.zeroWidthHack();
+ this.checkedZeroWidth = true;
+ }
+
+ return {right: needsV ? sWidth : 0, bottom: needsH ? sWidth : 0};
+ },
+ setScrollLeft: function(pos) {
+ if (this.horiz.scrollLeft != pos) this.horiz.scrollLeft = pos;
+ if (this.disableHoriz) this.enableZeroWidthBar(this.horiz, this.disableHoriz);
+ },
+ setScrollTop: function(pos) {
+ if (this.vert.scrollTop != pos) this.vert.scrollTop = pos;
+ if (this.disableVert) this.enableZeroWidthBar(this.vert, this.disableVert);
+ },
+ zeroWidthHack: function() {
+ var w = mac && !mac_geMountainLion ? "12px" : "18px";
+ this.horiz.style.height = this.vert.style.width = w;
+ this.horiz.style.pointerEvents = this.vert.style.pointerEvents = "none";
+ this.disableHoriz = new Delayed;
+ this.disableVert = new Delayed;
+ },
+ enableZeroWidthBar: function(bar, delay) {
+ bar.style.pointerEvents = "auto";
+ function maybeDisable() {
+ // To find out whether the scrollbar is still visible, we
+ // check whether the element under the pixel in the bottom
+ // left corner of the scrollbar box is the scrollbar box
+ // itself (when the bar is still visible) or its filler child
+ // (when the bar is hidden). If it is still visible, we keep
+ // it enabled, if it's hidden, we disable pointer events.
+ var box = bar.getBoundingClientRect();
+ var elt = document.elementFromPoint(box.left + 1, box.bottom - 1);
+ if (elt != bar) bar.style.pointerEvents = "none";
+ else delay.set(1000, maybeDisable);
+ }
+ delay.set(1000, maybeDisable);
+ },
+ clear: function() {
+ var parent = this.horiz.parentNode;
+ parent.removeChild(this.horiz);
+ parent.removeChild(this.vert);
+ }
+ }, NativeScrollbars.prototype);
+
+ function NullScrollbars() {}
+
+ NullScrollbars.prototype = copyObj({
+ update: function() { return {bottom: 0, right: 0}; },
+ setScrollLeft: function() {},
+ setScrollTop: function() {},
+ clear: function() {}
+ }, NullScrollbars.prototype);
+
+ CodeMirror.scrollbarModel = {"native": NativeScrollbars, "null": NullScrollbars};
+
+ function initScrollbars(cm) {
+ if (cm.display.scrollbars) {
+ cm.display.scrollbars.clear();
+ if (cm.display.scrollbars.addClass)
+ rmClass(cm.display.wrapper, cm.display.scrollbars.addClass);
+ }
+
+ cm.display.scrollbars = new CodeMirror.scrollbarModel[cm.options.scrollbarStyle](function(node) {
+ cm.display.wrapper.insertBefore(node, cm.display.scrollbarFiller);
+ // Prevent clicks in the scrollbars from killing focus
+ on(node, "mousedown", function() {
+ if (cm.state.focused) setTimeout(function() { cm.display.input.focus(); }, 0);
+ });
+ node.setAttribute("cm-not-content", "true");
+ }, function(pos, axis) {
+ if (axis == "horizontal") setScrollLeft(cm, pos);
+ else setScrollTop(cm, pos);
+ }, cm);
+ if (cm.display.scrollbars.addClass)
+ addClass(cm.display.wrapper, cm.display.scrollbars.addClass);
+ }
+
+ function updateScrollbars(cm, measure) {
+ if (!measure) measure = measureForScrollbars(cm);
+ var startWidth = cm.display.barWidth, startHeight = cm.display.barHeight;
+ updateScrollbarsInner(cm, measure);
+ for (var i = 0; i < 4 && startWidth != cm.display.barWidth || startHeight != cm.display.barHeight; i++) {
+ if (startWidth != cm.display.barWidth && cm.options.lineWrapping)
+ updateHeightsInViewport(cm);
+ updateScrollbarsInner(cm, measureForScrollbars(cm));
+ startWidth = cm.display.barWidth; startHeight = cm.display.barHeight;
+ }
+ }
+
// Re-synchronize the fake scrollbars with the actual size of the
// content.
- function updateScrollbars(cm, measure) {
- if (!measure) measure = measureForScrollbars(cm);
- var d = cm.display, sWidth = scrollbarWidth(d.measure);
- var scrollHeight = measure.docHeight + scrollerCutOff;
- var needsH = measure.scrollWidth > measure.clientWidth;
- if (needsH && measure.scrollWidth <= measure.clientWidth + 1 &&
- sWidth > 0 && !measure.hScrollbarTakesSpace)
- needsH = false; // (Issue #2562)
- var needsV = scrollHeight > measure.clientHeight;
+ function updateScrollbarsInner(cm, measure) {
+ var d = cm.display;
+ var sizes = d.scrollbars.update(measure);
- if (needsV) {
- d.scrollbarV.style.display = "block";
- d.scrollbarV.style.bottom = needsH ? sWidth + "px" : "0";
- // A bug in IE8 can cause this value to be negative, so guard it.
- d.scrollbarV.firstChild.style.height =
- Math.max(0, scrollHeight - measure.clientHeight + (measure.barHeight || d.scrollbarV.clientHeight)) + "px";
- } else {
- d.scrollbarV.style.display = "";
- d.scrollbarV.firstChild.style.height = "0";
- }
- if (needsH) {
- d.scrollbarH.style.display = "block";
- d.scrollbarH.style.right = needsV ? sWidth + "px" : "0";
- d.scrollbarH.firstChild.style.width =
- (measure.scrollWidth - measure.clientWidth + (measure.barWidth || d.scrollbarH.clientWidth)) + "px";
- } else {
- d.scrollbarH.style.display = "";
- d.scrollbarH.firstChild.style.width = "0";
- }
- if (needsH && needsV) {
+ d.sizer.style.paddingRight = (d.barWidth = sizes.right) + "px";
+ d.sizer.style.paddingBottom = (d.barHeight = sizes.bottom) + "px";
+
+ if (sizes.right && sizes.bottom) {
d.scrollbarFiller.style.display = "block";
- d.scrollbarFiller.style.height = d.scrollbarFiller.style.width = sWidth + "px";
+ d.scrollbarFiller.style.height = sizes.bottom + "px";
+ d.scrollbarFiller.style.width = sizes.right + "px";
} else d.scrollbarFiller.style.display = "";
- if (needsH && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) {
+ if (sizes.bottom && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) {
d.gutterFiller.style.display = "block";
- d.gutterFiller.style.height = sWidth + "px";
- d.gutterFiller.style.width = d.gutters.offsetWidth + "px";
+ d.gutterFiller.style.height = sizes.bottom + "px";
+ d.gutterFiller.style.width = measure.gutterWidth + "px";
} else d.gutterFiller.style.display = "";
-
- if (!cm.state.checkedOverlayScrollbar && measure.clientHeight > 0) {
- if (sWidth === 0) {
- var w = mac && !mac_geMountainLion ? "12px" : "18px";
- d.scrollbarV.style.minWidth = d.scrollbarH.style.minHeight = w;
- var barMouseDown = function(e) {
- if (e_target(e) != d.scrollbarV && e_target(e) != d.scrollbarH)
- operation(cm, onMouseDown)(e);
- };
- on(d.scrollbarV, "mousedown", barMouseDown);
- on(d.scrollbarH, "mousedown", barMouseDown);
- }
- cm.state.checkedOverlayScrollbar = true;
- }
}
// Compute the lines that are visible in a given viewport (defaults
@@ -480,12 +569,13 @@
// forces those lines into the viewport (if possible).
if (viewport && viewport.ensure) {
var ensureFrom = viewport.ensure.from.line, ensureTo = viewport.ensure.to.line;
- if (ensureFrom < from)
- return {from: ensureFrom,
- to: lineAtHeight(doc, heightAtLine(getLine(doc, ensureFrom)) + display.wrapper.clientHeight)};
- if (Math.min(ensureTo, doc.lastLine()) >= to)
- return {from: lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight),
- to: ensureTo};
+ if (ensureFrom < from) {
+ from = ensureFrom;
+ to = lineAtHeight(doc, heightAtLine(getLine(doc, ensureFrom)) + display.wrapper.clientHeight);
+ } else if (Math.min(ensureTo, doc.lastLine()) >= to) {
+ from = lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight);
+ to = ensureTo;
+ }
}
return {from: from, to: Math.max(to, from + 1)};
}
@@ -521,7 +611,7 @@
"CodeMirror-linenumber CodeMirror-gutter-elt"));
var innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW;
display.lineGutter.style.width = "";
- display.lineNumInnerWidth = Math.max(innerW, display.lineGutter.offsetWidth - padding);
+ display.lineNumInnerWidth = Math.max(innerW, display.lineGutter.offsetWidth - padding) + 1;
display.lineNumWidth = display.lineNumInnerWidth + padding;
display.lineNumChars = display.lineNumInnerWidth ? last.length : -1;
display.lineGutter.style.width = display.lineNumWidth + "px";
@@ -552,10 +642,31 @@
this.visible = visibleLines(display, cm.doc, viewport);
this.editorIsHidden = !display.wrapper.offsetWidth;
this.wrapperHeight = display.wrapper.clientHeight;
- this.oldViewFrom = display.viewFrom; this.oldViewTo = display.viewTo;
- this.oldScrollerWidth = display.scroller.clientWidth;
+ this.wrapperWidth = display.wrapper.clientWidth;
+ this.oldDisplayWidth = displayWidth(cm);
this.force = force;
this.dims = getDimensions(cm);
+ this.events = [];
+ }
+
+ DisplayUpdate.prototype.signal = function(emitter, type) {
+ if (hasHandler(emitter, type))
+ this.events.push(arguments);
+ };
+ DisplayUpdate.prototype.finish = function() {
+ for (var i = 0; i < this.events.length; i++)
+ signal.apply(null, this.events[i]);
+ };
+
+ function maybeClipScrollbars(cm) {
+ var display = cm.display;
+ if (!display.scrollbarsClipped && display.scroller.offsetWidth) {
+ display.nativeBarWidth = display.scroller.offsetWidth - display.scroller.clientWidth;
+ display.heightForcer.style.height = scrollGap(cm) + "px";
+ display.sizer.style.marginBottom = -display.nativeBarWidth + "px";
+ display.sizer.style.borderRightWidth = scrollGap(cm) + "px";
+ display.scrollbarsClipped = true;
+ }
}
// Does the actual updating of the line display. Bails out
@@ -563,6 +674,7 @@
// false.
function updateDisplayIfNeeded(cm, update) {
var display = cm.display, doc = cm.doc;
+
if (update.editorIsHidden) {
resetView(cm);
return false;
@@ -572,7 +684,7 @@
if (!update.force &&
update.visible.from >= display.viewFrom && update.visible.to <= display.viewTo &&
(display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo) &&
- countDirtyView(cm) == 0)
+ display.renderedView == display.view && countDirtyView(cm) == 0)
return false;
if (maybeUpdateLineNumberWidth(cm)) {
@@ -592,7 +704,7 @@
}
var different = from != display.viewFrom || to != display.viewTo ||
- display.lastSizeC != update.wrapperHeight;
+ display.lastWrapHeight != update.wrapperHeight || display.lastWrapWidth != update.wrapperWidth;
adjustView(cm, from, to);
display.viewOffset = heightAtLine(getLine(cm.doc, display.viewFrom));
@@ -600,7 +712,7 @@
cm.display.mover.style.top = display.viewOffset + "px";
var toUpdate = countDirtyView(cm);
- if (!different && toUpdate == 0 && !update.force &&
+ if (!different && toUpdate == 0 && !update.force && display.renderedView == display.view &&
(display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo))
return false;
@@ -610,17 +722,20 @@
if (toUpdate > 4) display.lineDiv.style.display = "none";
patchDisplay(cm, display.updateLineNumbers, update.dims);
if (toUpdate > 4) display.lineDiv.style.display = "";
+ display.renderedView = display.view;
// There might have been a widget with a focused element that got
// hidden or updated, if so re-focus it.
if (focused && activeElt() != focused && focused.offsetHeight) focused.focus();
// Prevent selection and cursors from interfering with the scroll
- // width.
+ // width and height.
removeChildren(display.cursorDiv);
removeChildren(display.selectionDiv);
+ display.gutters.style.height = display.sizer.style.minHeight = 0;
if (different) {
- display.lastSizeC = update.wrapperHeight;
+ display.lastWrapHeight = update.wrapperHeight;
+ display.lastWrapWidth = update.wrapperWidth;
startWorker(cm, 400);
}
@@ -630,16 +745,12 @@
}
function postUpdateDisplay(cm, update) {
- var force = update.force, viewport = update.viewport;
+ var viewport = update.viewport;
for (var first = true;; first = false) {
- if (first && cm.options.lineWrapping && update.oldScrollerWidth != cm.display.scroller.clientWidth) {
- force = true;
- } else {
- force = false;
+ if (!first || !cm.options.lineWrapping || update.oldDisplayWidth == displayWidth(cm)) {
// Clip forced viewport to actual scrollable area.
if (viewport && viewport.top != null)
- viewport = {top: Math.min(cm.doc.height + paddingVert(cm.display) - scrollerCutOff -
- cm.display.scroller.clientHeight, viewport.top)};
+ viewport = {top: Math.min(cm.doc.height + paddingVert(cm.display) - displayHeight(cm), viewport.top)};
// Updated line heights might result in the drawn area not
// actually covering the viewport. Keep looping until it does.
update.visible = visibleLines(cm.display, cm.doc, viewport);
@@ -654,9 +765,11 @@
updateScrollbars(cm, barMeasure);
}
- signalLater(cm, "update", cm);
- if (cm.display.viewFrom != update.oldViewFrom || cm.display.viewTo != update.oldViewTo)
- signalLater(cm, "viewportChange", cm, cm.display.viewFrom, cm.display.viewTo);
+ update.signal(cm, "update", cm);
+ if (cm.display.viewFrom != cm.display.reportedViewFrom || cm.display.viewTo != cm.display.reportedViewTo) {
+ update.signal(cm, "viewportChange", cm, cm.display.viewFrom, cm.display.viewTo);
+ cm.display.reportedViewFrom = cm.display.viewFrom; cm.display.reportedViewTo = cm.display.viewTo;
+ }
}
function updateDisplaySimple(cm, viewport) {
@@ -668,21 +781,15 @@
updateSelection(cm);
setDocumentHeight(cm, barMeasure);
updateScrollbars(cm, barMeasure);
+ update.finish();
}
}
function setDocumentHeight(cm, measure) {
- cm.display.sizer.style.minHeight = cm.display.heightForcer.style.top = measure.docHeight + "px";
- cm.display.gutters.style.height = Math.max(measure.docHeight, measure.clientHeight - scrollerCutOff) + "px";
- }
-
- function checkForWebkitWidthBug(cm, measure) {
- // Work around Webkit bug where it sometimes reserves space for a
- // non-existing phantom scrollbar in the scroller (Issue #2420)
- if (cm.display.sizer.offsetWidth + cm.display.gutters.offsetWidth < cm.display.scroller.clientWidth - 1) {
- cm.display.sizer.style.minHeight = cm.display.heightForcer.style.top = "0px";
- cm.display.gutters.style.height = measure.docHeight + "px";
- }
+ cm.display.sizer.style.minHeight = measure.docHeight + "px";
+ var total = measure.docHeight + cm.display.barHeight;
+ cm.display.heightForcer.style.top = total + "px";
+ cm.display.gutters.style.height = Math.max(total + scrollGap(cm), measure.clientHeight) + "px";
}
// Read the actual heights of the rendered lines, and update their
@@ -716,16 +823,17 @@
// given line.
function updateWidgetHeight(line) {
if (line.widgets) for (var i = 0; i < line.widgets.length; ++i)
- line.widgets[i].height = line.widgets[i].node.offsetHeight;
+ line.widgets[i].height = line.widgets[i].node.parentNode.offsetHeight;
}
// Do a bulk-read of the DOM positions and sizes needed to draw the
// view, so that we don't interleave reading and writing to the DOM.
function getDimensions(cm) {
var d = cm.display, left = {}, width = {};
+ var gutterLeft = d.gutters.clientLeft;
for (var n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) {
- left[cm.options.gutters[i]] = n.offsetLeft;
- width[cm.options.gutters[i]] = n.offsetWidth;
+ left[cm.options.gutters[i]] = n.offsetLeft + n.clientLeft + gutterLeft;
+ width[cm.options.gutters[i]] = n.clientWidth;
}
return {fixedPos: compensateForHScroll(d),
gutterTotalWidth: d.gutters.offsetWidth,
@@ -758,7 +866,7 @@
for (var i = 0; i < view.length; i++) {
var lineView = view[i];
if (lineView.hidden) {
- } else if (!lineView.node) { // Not drawn yet
+ } else if (!lineView.node || lineView.node.parentNode != container) { // Not drawn yet
var node = buildLineElement(cm, lineView, lineN, dims);
container.insertBefore(node, cur);
} else { // Already drawn
@@ -789,7 +897,7 @@
if (type == "text") updateLineText(cm, lineView);
else if (type == "gutter") updateLineGutter(cm, lineView, lineN, dims);
else if (type == "class") updateLineClasses(lineView);
- else if (type == "widget") updateLineWidgets(lineView, dims);
+ else if (type == "widget") updateLineWidgets(cm, lineView, dims);
}
lineView.changes = null;
}
@@ -864,13 +972,26 @@
lineView.node.removeChild(lineView.gutter);
lineView.gutter = null;
}
+ if (lineView.gutterBackground) {
+ lineView.node.removeChild(lineView.gutterBackground);
+ lineView.gutterBackground = null;
+ }
+ if (lineView.line.gutterClass) {
+ var wrap = ensureLineWrapped(lineView);
+ lineView.gutterBackground = elt("div", null, "CodeMirror-gutter-background " + lineView.line.gutterClass,
+ "left: " + (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) +
+ "px; width: " + dims.gutterTotalWidth + "px");
+ wrap.insertBefore(lineView.gutterBackground, lineView.text);
+ }
var markers = lineView.line.gutterMarkers;
if (cm.options.lineNumbers || markers) {
var wrap = ensureLineWrapped(lineView);
- var gutterWrap = lineView.gutter =
- wrap.insertBefore(elt("div", null, "CodeMirror-gutter-wrapper", "position: absolute; left: " +
- (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px"),
- lineView.text);
+ var gutterWrap = lineView.gutter = elt("div", null, "CodeMirror-gutter-wrapper", "left: " +
+ (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px");
+ cm.display.input.setUneditable(gutterWrap);
+ wrap.insertBefore(gutterWrap, lineView.text);
+ if (lineView.line.gutterClass)
+ gutterWrap.className += " " + lineView.line.gutterClass;
if (cm.options.lineNumbers && (!markers || !markers["CodeMirror-linenumbers"]))
lineView.lineNumber = gutterWrap.appendChild(
elt("div", lineNumberFor(cm.options, lineN),
@@ -886,14 +1007,14 @@
}
}
- function updateLineWidgets(lineView, dims) {
+ function updateLineWidgets(cm, lineView, dims) {
if (lineView.alignable) lineView.alignable = null;
for (var node = lineView.node.firstChild, next; node; node = next) {
var next = node.nextSibling;
if (node.className == "CodeMirror-linewidget")
lineView.node.removeChild(node);
}
- insertLineWidgets(lineView, dims);
+ insertLineWidgets(cm, lineView, dims);
}
// Build a line's DOM representation from scratch
@@ -905,25 +1026,26 @@
updateLineClasses(lineView);
updateLineGutter(cm, lineView, lineN, dims);
- insertLineWidgets(lineView, dims);
+ insertLineWidgets(cm, lineView, dims);
return lineView.node;
}
// A lineView may contain multiple logical lines (when merged by
// collapsed spans). The widgets for all of them need to be drawn.
- function insertLineWidgets(lineView, dims) {
- insertLineWidgetsFor(lineView.line, lineView, dims, true);
+ function insertLineWidgets(cm, lineView, dims) {
+ insertLineWidgetsFor(cm, lineView.line, lineView, dims, true);
if (lineView.rest) for (var i = 0; i < lineView.rest.length; i++)
- insertLineWidgetsFor(lineView.rest[i], lineView, dims, false);
+ insertLineWidgetsFor(cm, lineView.rest[i], lineView, dims, false);
}
- function insertLineWidgetsFor(line, lineView, dims, allowAbove) {
+ function insertLineWidgetsFor(cm, line, lineView, dims, allowAbove) {
if (!line.widgets) return;
var wrap = ensureLineWrapped(lineView);
for (var i = 0, ws = line.widgets; i < ws.length; ++i) {
var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget");
- if (!widget.handleMouseEvents) node.ignoreEvents = true;
+ if (!widget.handleMouseEvents) node.setAttribute("cm-ignore-events", "true");
positionLineWidget(widget, node, lineView, dims);
+ cm.display.input.setUneditable(node);
if (allowAbove && widget.above)
wrap.insertBefore(node, lineView.gutter || lineView.text);
else
@@ -966,6 +1088,921 @@
function maxPos(a, b) { return cmp(a, b) < 0 ? b : a; }
function minPos(a, b) { return cmp(a, b) < 0 ? a : b; }
+ // INPUT HANDLING
+
+ function ensureFocus(cm) {
+ if (!cm.state.focused) { cm.display.input.focus(); onFocus(cm); }
+ }
+
+ // This will be set to an array of strings when copying, so that,
+ // when pasting, we know what kind of selections the copied text
+ // was made out of.
+ var lastCopied = null;
+
+ function applyTextInput(cm, inserted, deleted, sel, origin) {
+ var doc = cm.doc;
+ cm.display.shift = false;
+ if (!sel) sel = doc.sel;
+
+ var paste = cm.state.pasteIncoming || origin == "paste";
+ var textLines = doc.splitLines(inserted), multiPaste = null;
+ // When pasing N lines into N selections, insert one line per selection
+ if (paste && sel.ranges.length > 1) {
+ if (lastCopied && lastCopied.join("\n") == inserted) {
+ if (sel.ranges.length % lastCopied.length == 0) {
+ multiPaste = [];
+ for (var i = 0; i < lastCopied.length; i++)
+ multiPaste.push(doc.splitLines(lastCopied[i]));
+ }
+ } else if (textLines.length == sel.ranges.length) {
+ multiPaste = map(textLines, function(l) { return [l]; });
+ }
+ }
+
+ // Normal behavior is to insert the new text into every selection
+ for (var i = sel.ranges.length - 1; i >= 0; i--) {
+ var range = sel.ranges[i];
+ var from = range.from(), to = range.to();
+ if (range.empty()) {
+ if (deleted && deleted > 0) // Handle deletion
+ from = Pos(from.line, from.ch - deleted);
+ else if (cm.state.overwrite && !paste) // Handle overwrite
+ to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + lst(textLines).length));
+ }
+ var updateInput = cm.curOp.updateInput;
+ var changeEvent = {from: from, to: to, text: multiPaste ? multiPaste[i % multiPaste.length] : textLines,
+ origin: origin || (paste ? "paste" : cm.state.cutIncoming ? "cut" : "+input")};
+ makeChange(cm.doc, changeEvent);
+ signalLater(cm, "inputRead", cm, changeEvent);
+ }
+ if (inserted && !paste)
+ triggerElectric(cm, inserted);
+
+ ensureCursorVisible(cm);
+ cm.curOp.updateInput = updateInput;
+ cm.curOp.typing = true;
+ cm.state.pasteIncoming = cm.state.cutIncoming = false;
+ }
+
+ function handlePaste(e, cm) {
+ var pasted = e.clipboardData && e.clipboardData.getData("text/plain");
+ if (pasted) {
+ e.preventDefault();
+ if (!cm.isReadOnly() && !cm.options.disableInput)
+ runInOp(cm, function() { applyTextInput(cm, pasted, 0, null, "paste"); });
+ return true;
+ }
+ }
+
+ function triggerElectric(cm, inserted) {
+ // When an 'electric' character is inserted, immediately trigger a reindent
+ if (!cm.options.electricChars || !cm.options.smartIndent) return;
+ var sel = cm.doc.sel;
+
+ for (var i = sel.ranges.length - 1; i >= 0; i--) {
+ var range = sel.ranges[i];
+ if (range.head.ch > 100 || (i && sel.ranges[i - 1].head.line == range.head.line)) continue;
+ var mode = cm.getModeAt(range.head);
+ var indented = false;
+ if (mode.electricChars) {
+ for (var j = 0; j < mode.electricChars.length; j++)
+ if (inserted.indexOf(mode.electricChars.charAt(j)) > -1) {
+ indented = indentLine(cm, range.head.line, "smart");
+ break;
+ }
+ } else if (mode.electricInput) {
+ if (mode.electricInput.test(getLine(cm.doc, range.head.line).text.slice(0, range.head.ch)))
+ indented = indentLine(cm, range.head.line, "smart");
+ }
+ if (indented) signalLater(cm, "electricInput", cm, range.head.line);
+ }
+ }
+
+ function copyableRanges(cm) {
+ var text = [], ranges = [];
+ for (var i = 0; i < cm.doc.sel.ranges.length; i++) {
+ var line = cm.doc.sel.ranges[i].head.line;
+ var lineRange = {anchor: Pos(line, 0), head: Pos(line + 1, 0)};
+ ranges.push(lineRange);
+ text.push(cm.getRange(lineRange.anchor, lineRange.head));
+ }
+ return {text: text, ranges: ranges};
+ }
+
+ function disableBrowserMagic(field) {
+ field.setAttribute("autocorrect", "off");
+ field.setAttribute("autocapitalize", "off");
+ field.setAttribute("spellcheck", "false");
+ }
+
+ // TEXTAREA INPUT STYLE
+
+ function TextareaInput(cm) {
+ this.cm = cm;
+ // See input.poll and input.reset
+ this.prevInput = "";
+
+ // Flag that indicates whether we expect input to appear real soon
+ // now (after some event like 'keypress' or 'input') and are
+ // polling intensively.
+ this.pollingFast = false;
+ // Self-resetting timeout for the poller
+ this.polling = new Delayed();
+ // Tracks when input.reset has punted to just putting a short
+ // string into the textarea instead of the full selection.
+ this.inaccurateSelection = false;
+ // Used to work around IE issue with selection being forgotten when focus moves away from textarea
+ this.hasSelection = false;
+ this.composing = null;
+ };
+
+ function hiddenTextarea() {
+ var te = elt("textarea", null, null, "position: absolute; padding: 0; width: 1px; height: 1em; outline: none");
+ var div = elt("div", [te], null, "overflow: hidden; position: relative; width: 3px; height: 0px;");
+ // The textarea is kept positioned near the cursor to prevent the
+ // fact that it'll be scrolled into view on input from scrolling
+ // our fake cursor out of view. On webkit, when wrap=off, paste is
+ // very slow. So make the area wide instead.
+ if (webkit) te.style.width = "1000px";
+ else te.setAttribute("wrap", "off");
+ // If border: 0; -- iOS fails to open keyboard (issue #1287)
+ if (ios) te.style.border = "1px solid black";
+ disableBrowserMagic(te);
+ return div;
+ }
+
+ TextareaInput.prototype = copyObj({
+ init: function(display) {
+ var input = this, cm = this.cm;
+
+ // Wraps and hides input textarea
+ var div = this.wrapper = hiddenTextarea();
+ // The semihidden textarea that is focused when the editor is
+ // focused, and receives input.
+ var te = this.textarea = div.firstChild;
+ display.wrapper.insertBefore(div, display.wrapper.firstChild);
+
+ // Needed to hide big blue blinking cursor on Mobile Safari (doesn't seem to work in iOS 8 anymore)
+ if (ios) te.style.width = "0px";
+
+ on(te, "input", function() {
+ if (ie && ie_version >= 9 && input.hasSelection) input.hasSelection = null;
+ input.poll();
+ });
+
+ on(te, "paste", function(e) {
+ if (signalDOMEvent(cm, e) || handlePaste(e, cm)) return
+
+ cm.state.pasteIncoming = true;
+ input.fastPoll();
+ });
+
+ function prepareCopyCut(e) {
+ if (signalDOMEvent(cm, e)) return
+ if (cm.somethingSelected()) {
+ lastCopied = cm.getSelections();
+ if (input.inaccurateSelection) {
+ input.prevInput = "";
+ input.inaccurateSelection = false;
+ te.value = lastCopied.join("\n");
+ selectInput(te);
+ }
+ } else if (!cm.options.lineWiseCopyCut) {
+ return;
+ } else {
+ var ranges = copyableRanges(cm);
+ lastCopied = ranges.text;
+ if (e.type == "cut") {
+ cm.setSelections(ranges.ranges, null, sel_dontScroll);
+ } else {
+ input.prevInput = "";
+ te.value = ranges.text.join("\n");
+ selectInput(te);
+ }
+ }
+ if (e.type == "cut") cm.state.cutIncoming = true;
+ }
+ on(te, "cut", prepareCopyCut);
+ on(te, "copy", prepareCopyCut);
+
+ on(display.scroller, "paste", function(e) {
+ if (eventInWidget(display, e) || signalDOMEvent(cm, e)) return;
+ cm.state.pasteIncoming = true;
+ input.focus();
+ });
+
+ // Prevent normal selection in the editor (we handle our own)
+ on(display.lineSpace, "selectstart", function(e) {
+ if (!eventInWidget(display, e)) e_preventDefault(e);
+ });
+
+ on(te, "compositionstart", function() {
+ var start = cm.getCursor("from");
+ if (input.composing) input.composing.range.clear()
+ input.composing = {
+ start: start,
+ range: cm.markText(start, cm.getCursor("to"), {className: "CodeMirror-composing"})
+ };
+ });
+ on(te, "compositionend", function() {
+ if (input.composing) {
+ input.poll();
+ input.composing.range.clear();
+ input.composing = null;
+ }
+ });
+ },
+
+ prepareSelection: function() {
+ // Redraw the selection and/or cursor
+ var cm = this.cm, display = cm.display, doc = cm.doc;
+ var result = prepareSelection(cm);
+
+ // Move the hidden textarea near the cursor to prevent scrolling artifacts
+ if (cm.options.moveInputWithCursor) {
+ var headPos = cursorCoords(cm, doc.sel.primary().head, "div");
+ var wrapOff = display.wrapper.getBoundingClientRect(), lineOff = display.lineDiv.getBoundingClientRect();
+ result.teTop = Math.max(0, Math.min(display.wrapper.clientHeight - 10,
+ headPos.top + lineOff.top - wrapOff.top));
+ result.teLeft = Math.max(0, Math.min(display.wrapper.clientWidth - 10,
+ headPos.left + lineOff.left - wrapOff.left));
+ }
+
+ return result;
+ },
+
+ showSelection: function(drawn) {
+ var cm = this.cm, display = cm.display;
+ removeChildrenAndAdd(display.cursorDiv, drawn.cursors);
+ removeChildrenAndAdd(display.selectionDiv, drawn.selection);
+ if (drawn.teTop != null) {
+ this.wrapper.style.top = drawn.teTop + "px";
+ this.wrapper.style.left = drawn.teLeft + "px";
+ }
+ },
+
+ // Reset the input to correspond to the selection (or to be empty,
+ // when not typing and nothing is selected)
+ reset: function(typing) {
+ if (this.contextMenuPending) return;
+ var minimal, selected, cm = this.cm, doc = cm.doc;
+ if (cm.somethingSelected()) {
+ this.prevInput = "";
+ var range = doc.sel.primary();
+ minimal = hasCopyEvent &&
+ (range.to().line - range.from().line > 100 || (selected = cm.getSelection()).length > 1000);
+ var content = minimal ? "-" : selected || cm.getSelection();
+ this.textarea.value = content;
+ if (cm.state.focused) selectInput(this.textarea);
+ if (ie && ie_version >= 9) this.hasSelection = content;
+ } else if (!typing) {
+ this.prevInput = this.textarea.value = "";
+ if (ie && ie_version >= 9) this.hasSelection = null;
+ }
+ this.inaccurateSelection = minimal;
+ },
+
+ getField: function() { return this.textarea; },
+
+ supportsTouch: function() { return false; },
+
+ focus: function() {
+ if (this.cm.options.readOnly != "nocursor" && (!mobile || activeElt() != this.textarea)) {
+ try { this.textarea.focus(); }
+ catch (e) {} // IE8 will throw if the textarea is display: none or not in DOM
+ }
+ },
+
+ blur: function() { this.textarea.blur(); },
+
+ resetPosition: function() {
+ this.wrapper.style.top = this.wrapper.style.left = 0;
+ },
+
+ receivedFocus: function() { this.slowPoll(); },
+
+ // Poll for input changes, using the normal rate of polling. This
+ // runs as long as the editor is focused.
+ slowPoll: function() {
+ var input = this;
+ if (input.pollingFast) return;
+ input.polling.set(this.cm.options.pollInterval, function() {
+ input.poll();
+ if (input.cm.state.focused) input.slowPoll();
+ });
+ },
+
+ // When an event has just come in that is likely to add or change
+ // something in the input textarea, we poll faster, to ensure that
+ // the change appears on the screen quickly.
+ fastPoll: function() {
+ var missed = false, input = this;
+ input.pollingFast = true;
+ function p() {
+ var changed = input.poll();
+ if (!changed && !missed) {missed = true; input.polling.set(60, p);}
+ else {input.pollingFast = false; input.slowPoll();}
+ }
+ input.polling.set(20, p);
+ },
+
+ // Read input from the textarea, and update the document to match.
+ // When something is selected, it is present in the textarea, and
+ // selected (unless it is huge, in which case a placeholder is
+ // used). When nothing is selected, the cursor sits after previously
+ // seen text (can be empty), which is stored in prevInput (we must
+ // not reset the textarea when typing, because that breaks IME).
+ poll: function() {
+ var cm = this.cm, input = this.textarea, prevInput = this.prevInput;
+ // Since this is called a *lot*, try to bail out as cheaply as
+ // possible when it is clear that nothing happened. hasSelection
+ // will be the case when there is a lot of text in the textarea,
+ // in which case reading its value would be expensive.
+ if (this.contextMenuPending || !cm.state.focused ||
+ (hasSelection(input) && !prevInput && !this.composing) ||
+ cm.isReadOnly() || cm.options.disableInput || cm.state.keySeq)
+ return false;
+
+ var text = input.value;
+ // If nothing changed, bail.
+ if (text == prevInput && !cm.somethingSelected()) return false;
+ // Work around nonsensical selection resetting in IE9/10, and
+ // inexplicable appearance of private area unicode characters on
+ // some key combos in Mac (#2689).
+ if (ie && ie_version >= 9 && this.hasSelection === text ||
+ mac && /[\uf700-\uf7ff]/.test(text)) {
+ cm.display.input.reset();
+ return false;
+ }
+
+ if (cm.doc.sel == cm.display.selForContextMenu) {
+ var first = text.charCodeAt(0);
+ if (first == 0x200b && !prevInput) prevInput = "\u200b";
+ if (first == 0x21da) { this.reset(); return this.cm.execCommand("undo"); }
+ }
+ // Find the part of the input that is actually new
+ var same = 0, l = Math.min(prevInput.length, text.length);
+ while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) ++same;
+
+ var self = this;
+ runInOp(cm, function() {
+ applyTextInput(cm, text.slice(same), prevInput.length - same,
+ null, self.composing ? "*compose" : null);
+
+ // Don't leave long text in the textarea, since it makes further polling slow
+ if (text.length > 1000 || text.indexOf("\n") > -1) input.value = self.prevInput = "";
+ else self.prevInput = text;
+
+ if (self.composing) {
+ self.composing.range.clear();
+ self.composing.range = cm.markText(self.composing.start, cm.getCursor("to"),
+ {className: "CodeMirror-composing"});
+ }
+ });
+ return true;
+ },
+
+ ensurePolled: function() {
+ if (this.pollingFast && this.poll()) this.pollingFast = false;
+ },
+
+ onKeyPress: function() {
+ if (ie && ie_version >= 9) this.hasSelection = null;
+ this.fastPoll();
+ },
+
+ onContextMenu: function(e) {
+ var input = this, cm = input.cm, display = cm.display, te = input.textarea;
+ var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop;
+ if (!pos || presto) return; // Opera is difficult.
+
+ // Reset the current text selection only if the click is done outside of the selection
+ // and 'resetSelectionOnContextMenu' option is true.
+ var reset = cm.options.resetSelectionOnContextMenu;
+ if (reset && cm.doc.sel.contains(pos) == -1)
+ operation(cm, setSelection)(cm.doc, simpleSelection(pos), sel_dontScroll);
+
+ var oldCSS = te.style.cssText;
+ input.wrapper.style.position = "absolute";
+ te.style.cssText = "position: fixed; width: 30px; height: 30px; top: " + (e.clientY - 5) +
+ "px; left: " + (e.clientX - 5) + "px; z-index: 1000; background: " +
+ (ie ? "rgba(255, 255, 255, .05)" : "transparent") +
+ "; outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);";
+ if (webkit) var oldScrollY = window.scrollY; // Work around Chrome issue (#2712)
+ display.input.focus();
+ if (webkit) window.scrollTo(null, oldScrollY);
+ display.input.reset();
+ // Adds "Select all" to context menu in FF
+ if (!cm.somethingSelected()) te.value = input.prevInput = " ";
+ input.contextMenuPending = true;
+ display.selForContextMenu = cm.doc.sel;
+ clearTimeout(display.detectingSelectAll);
+
+ // Select-all will be greyed out if there's nothing to select, so
+ // this adds a zero-width space so that we can later check whether
+ // it got selected.
+ function prepareSelectAllHack() {
+ if (te.selectionStart != null) {
+ var selected = cm.somethingSelected();
+ var extval = "\u200b" + (selected ? te.value : "");
+ te.value = "\u21da"; // Used to catch context-menu undo
+ te.value = extval;
+ input.prevInput = selected ? "" : "\u200b";
+ te.selectionStart = 1; te.selectionEnd = extval.length;
+ // Re-set this, in case some other handler touched the
+ // selection in the meantime.
+ display.selForContextMenu = cm.doc.sel;
+ }
+ }
+ function rehide() {
+ input.contextMenuPending = false;
+ input.wrapper.style.position = "relative";
+ te.style.cssText = oldCSS;
+ if (ie && ie_version < 9) display.scrollbars.setScrollTop(display.scroller.scrollTop = scrollPos);
+
+ // Try to detect the user choosing select-all
+ if (te.selectionStart != null) {
+ if (!ie || (ie && ie_version < 9)) prepareSelectAllHack();
+ var i = 0, poll = function() {
+ if (display.selForContextMenu == cm.doc.sel && te.selectionStart == 0 &&
+ te.selectionEnd > 0 && input.prevInput == "\u200b")
+ operation(cm, commands.selectAll)(cm);
+ else if (i++ < 10) display.detectingSelectAll = setTimeout(poll, 500);
+ else display.input.reset();
+ };
+ display.detectingSelectAll = setTimeout(poll, 200);
+ }
+ }
+
+ if (ie && ie_version >= 9) prepareSelectAllHack();
+ if (captureRightClick) {
+ e_stop(e);
+ var mouseup = function() {
+ off(window, "mouseup", mouseup);
+ setTimeout(rehide, 20);
+ };
+ on(window, "mouseup", mouseup);
+ } else {
+ setTimeout(rehide, 50);
+ }
+ },
+
+ readOnlyChanged: function(val) {
+ if (!val) this.reset();
+ },
+
+ setUneditable: nothing,
+
+ needsContentAttribute: false
+ }, TextareaInput.prototype);
+
+ // CONTENTEDITABLE INPUT STYLE
+
+ function ContentEditableInput(cm) {
+ this.cm = cm;
+ this.lastAnchorNode = this.lastAnchorOffset = this.lastFocusNode = this.lastFocusOffset = null;
+ this.polling = new Delayed();
+ this.gracePeriod = false;
+ }
+
+ ContentEditableInput.prototype = copyObj({
+ init: function(display) {
+ var input = this, cm = input.cm;
+ var div = input.div = display.lineDiv;
+ disableBrowserMagic(div);
+
+ on(div, "paste", function(e) {
+ if (!signalDOMEvent(cm, e)) handlePaste(e, cm);
+ })
+
+ on(div, "compositionstart", function(e) {
+ var data = e.data;
+ input.composing = {sel: cm.doc.sel, data: data, startData: data};
+ if (!data) return;
+ var prim = cm.doc.sel.primary();
+ var line = cm.getLine(prim.head.line);
+ var found = line.indexOf(data, Math.max(0, prim.head.ch - data.length));
+ if (found > -1 && found <= prim.head.ch)
+ input.composing.sel = simpleSelection(Pos(prim.head.line, found),
+ Pos(prim.head.line, found + data.length));
+ });
+ on(div, "compositionupdate", function(e) {
+ input.composing.data = e.data;
+ });
+ on(div, "compositionend", function(e) {
+ var ours = input.composing;
+ if (!ours) return;
+ if (e.data != ours.startData && !/\u200b/.test(e.data))
+ ours.data = e.data;
+ // Need a small delay to prevent other code (input event,
+ // selection polling) from doing damage when fired right after
+ // compositionend.
+ setTimeout(function() {
+ if (!ours.handled)
+ input.applyComposition(ours);
+ if (input.composing == ours)
+ input.composing = null;
+ }, 50);
+ });
+
+ on(div, "touchstart", function() {
+ input.forceCompositionEnd();
+ });
+
+ on(div, "input", function() {
+ if (input.composing) return;
+ if (cm.isReadOnly() || !input.pollContent())
+ runInOp(input.cm, function() {regChange(cm);});
+ });
+
+ function onCopyCut(e) {
+ if (signalDOMEvent(cm, e)) return
+ if (cm.somethingSelected()) {
+ lastCopied = cm.getSelections();
+ if (e.type == "cut") cm.replaceSelection("", null, "cut");
+ } else if (!cm.options.lineWiseCopyCut) {
+ return;
+ } else {
+ var ranges = copyableRanges(cm);
+ lastCopied = ranges.text;
+ if (e.type == "cut") {
+ cm.operation(function() {
+ cm.setSelections(ranges.ranges, 0, sel_dontScroll);
+ cm.replaceSelection("", null, "cut");
+ });
+ }
+ }
+ // iOS exposes the clipboard API, but seems to discard content inserted into it
+ if (e.clipboardData && !ios) {
+ e.preventDefault();
+ e.clipboardData.clearData();
+ e.clipboardData.setData("text/plain", lastCopied.join("\n"));
+ } else {
+ // Old-fashioned briefly-focus-a-textarea hack
+ var kludge = hiddenTextarea(), te = kludge.firstChild;
+ cm.display.lineSpace.insertBefore(kludge, cm.display.lineSpace.firstChild);
+ te.value = lastCopied.join("\n");
+ var hadFocus = document.activeElement;
+ selectInput(te);
+ setTimeout(function() {
+ cm.display.lineSpace.removeChild(kludge);
+ hadFocus.focus();
+ }, 50);
+ }
+ }
+ on(div, "copy", onCopyCut);
+ on(div, "cut", onCopyCut);
+ },
+
+ prepareSelection: function() {
+ var result = prepareSelection(this.cm, false);
+ result.focus = this.cm.state.focused;
+ return result;
+ },
+
+ showSelection: function(info) {
+ if (!info || !this.cm.display.view.length) return;
+ if (info.focus) this.showPrimarySelection();
+ this.showMultipleSelections(info);
+ },
+
+ showPrimarySelection: function() {
+ var sel = window.getSelection(), prim = this.cm.doc.sel.primary();
+ var curAnchor = domToPos(this.cm, sel.anchorNode, sel.anchorOffset);
+ var curFocus = domToPos(this.cm, sel.focusNode, sel.focusOffset);
+ if (curAnchor && !curAnchor.bad && curFocus && !curFocus.bad &&
+ cmp(minPos(curAnchor, curFocus), prim.from()) == 0 &&
+ cmp(maxPos(curAnchor, curFocus), prim.to()) == 0)
+ return;
+
+ var start = posToDOM(this.cm, prim.from());
+ var end = posToDOM(this.cm, prim.to());
+ if (!start && !end) return;
+
+ var view = this.cm.display.view;
+ var old = sel.rangeCount && sel.getRangeAt(0);
+ if (!start) {
+ start = {node: view[0].measure.map[2], offset: 0};
+ } else if (!end) { // FIXME dangerously hacky
+ var measure = view[view.length - 1].measure;
+ var map = measure.maps ? measure.maps[measure.maps.length - 1] : measure.map;
+ end = {node: map[map.length - 1], offset: map[map.length - 2] - map[map.length - 3]};
+ }
+
+ try { var rng = range(start.node, start.offset, end.offset, end.node); }
+ catch(e) {} // Our model of the DOM might be outdated, in which case the range we try to set can be impossible
+ if (rng) {
+ if (!gecko && this.cm.state.focused) {
+ sel.collapse(start.node, start.offset);
+ if (!rng.collapsed) sel.addRange(rng);
+ } else {
+ sel.removeAllRanges();
+ sel.addRange(rng);
+ }
+ if (old && sel.anchorNode == null) sel.addRange(old);
+ else if (gecko) this.startGracePeriod();
+ }
+ this.rememberSelection();
+ },
+
+ startGracePeriod: function() {
+ var input = this;
+ clearTimeout(this.gracePeriod);
+ this.gracePeriod = setTimeout(function() {
+ input.gracePeriod = false;
+ if (input.selectionChanged())
+ input.cm.operation(function() { input.cm.curOp.selectionChanged = true; });
+ }, 20);
+ },
+
+ showMultipleSelections: function(info) {
+ removeChildrenAndAdd(this.cm.display.cursorDiv, info.cursors);
+ removeChildrenAndAdd(this.cm.display.selectionDiv, info.selection);
+ },
+
+ rememberSelection: function() {
+ var sel = window.getSelection();
+ this.lastAnchorNode = sel.anchorNode; this.lastAnchorOffset = sel.anchorOffset;
+ this.lastFocusNode = sel.focusNode; this.lastFocusOffset = sel.focusOffset;
+ },
+
+ selectionInEditor: function() {
+ var sel = window.getSelection();
+ if (!sel.rangeCount) return false;
+ var node = sel.getRangeAt(0).commonAncestorContainer;
+ return contains(this.div, node);
+ },
+
+ focus: function() {
+ if (this.cm.options.readOnly != "nocursor") this.div.focus();
+ },
+ blur: function() { this.div.blur(); },
+ getField: function() { return this.div; },
+
+ supportsTouch: function() { return true; },
+
+ receivedFocus: function() {
+ var input = this;
+ if (this.selectionInEditor())
+ this.pollSelection();
+ else
+ runInOp(this.cm, function() { input.cm.curOp.selectionChanged = true; });
+
+ function poll() {
+ if (input.cm.state.focused) {
+ input.pollSelection();
+ input.polling.set(input.cm.options.pollInterval, poll);
+ }
+ }
+ this.polling.set(this.cm.options.pollInterval, poll);
+ },
+
+ selectionChanged: function() {
+ var sel = window.getSelection();
+ return sel.anchorNode != this.lastAnchorNode || sel.anchorOffset != this.lastAnchorOffset ||
+ sel.focusNode != this.lastFocusNode || sel.focusOffset != this.lastFocusOffset;
+ },
+
+ pollSelection: function() {
+ if (!this.composing && !this.gracePeriod && this.selectionChanged()) {
+ var sel = window.getSelection(), cm = this.cm;
+ this.rememberSelection();
+ var anchor = domToPos(cm, sel.anchorNode, sel.anchorOffset);
+ var head = domToPos(cm, sel.focusNode, sel.focusOffset);
+ if (anchor && head) runInOp(cm, function() {
+ setSelection(cm.doc, simpleSelection(anchor, head), sel_dontScroll);
+ if (anchor.bad || head.bad) cm.curOp.selectionChanged = true;
+ });
+ }
+ },
+
+ pollContent: function() {
+ var cm = this.cm, display = cm.display, sel = cm.doc.sel.primary();
+ var from = sel.from(), to = sel.to();
+ if (from.line < display.viewFrom || to.line > display.viewTo - 1) return false;
+
+ var fromIndex;
+ if (from.line == display.viewFrom || (fromIndex = findViewIndex(cm, from.line)) == 0) {
+ var fromLine = lineNo(display.view[0].line);
+ var fromNode = display.view[0].node;
+ } else {
+ var fromLine = lineNo(display.view[fromIndex].line);
+ var fromNode = display.view[fromIndex - 1].node.nextSibling;
+ }
+ var toIndex = findViewIndex(cm, to.line);
+ if (toIndex == display.view.length - 1) {
+ var toLine = display.viewTo - 1;
+ var toNode = display.lineDiv.lastChild;
+ } else {
+ var toLine = lineNo(display.view[toIndex + 1].line) - 1;
+ var toNode = display.view[toIndex + 1].node.previousSibling;
+ }
+
+ var newText = cm.doc.splitLines(domTextBetween(cm, fromNode, toNode, fromLine, toLine));
+ var oldText = getBetween(cm.doc, Pos(fromLine, 0), Pos(toLine, getLine(cm.doc, toLine).text.length));
+ while (newText.length > 1 && oldText.length > 1) {
+ if (lst(newText) == lst(oldText)) { newText.pop(); oldText.pop(); toLine--; }
+ else if (newText[0] == oldText[0]) { newText.shift(); oldText.shift(); fromLine++; }
+ else break;
+ }
+
+ var cutFront = 0, cutEnd = 0;
+ var newTop = newText[0], oldTop = oldText[0], maxCutFront = Math.min(newTop.length, oldTop.length);
+ while (cutFront < maxCutFront && newTop.charCodeAt(cutFront) == oldTop.charCodeAt(cutFront))
+ ++cutFront;
+ var newBot = lst(newText), oldBot = lst(oldText);
+ var maxCutEnd = Math.min(newBot.length - (newText.length == 1 ? cutFront : 0),
+ oldBot.length - (oldText.length == 1 ? cutFront : 0));
+ while (cutEnd < maxCutEnd &&
+ newBot.charCodeAt(newBot.length - cutEnd - 1) == oldBot.charCodeAt(oldBot.length - cutEnd - 1))
+ ++cutEnd;
+
+ newText[newText.length - 1] = newBot.slice(0, newBot.length - cutEnd);
+ newText[0] = newText[0].slice(cutFront);
+
+ var chFrom = Pos(fromLine, cutFront);
+ var chTo = Pos(toLine, oldText.length ? lst(oldText).length - cutEnd : 0);
+ if (newText.length > 1 || newText[0] || cmp(chFrom, chTo)) {
+ replaceRange(cm.doc, newText, chFrom, chTo, "+input");
+ return true;
+ }
+ },
+
+ ensurePolled: function() {
+ this.forceCompositionEnd();
+ },
+ reset: function() {
+ this.forceCompositionEnd();
+ },
+ forceCompositionEnd: function() {
+ if (!this.composing || this.composing.handled) return;
+ this.applyComposition(this.composing);
+ this.composing.handled = true;
+ this.div.blur();
+ this.div.focus();
+ },
+ applyComposition: function(composing) {
+ if (this.cm.isReadOnly())
+ operation(this.cm, regChange)(this.cm)
+ else if (composing.data && composing.data != composing.startData)
+ operation(this.cm, applyTextInput)(this.cm, composing.data, 0, composing.sel);
+ },
+
+ setUneditable: function(node) {
+ node.contentEditable = "false"
+ },
+
+ onKeyPress: function(e) {
+ e.preventDefault();
+ if (!this.cm.isReadOnly())
+ operation(this.cm, applyTextInput)(this.cm, String.fromCharCode(e.charCode == null ? e.keyCode : e.charCode), 0);
+ },
+
+ readOnlyChanged: function(val) {
+ this.div.contentEditable = String(val != "nocursor")
+ },
+
+ onContextMenu: nothing,
+ resetPosition: nothing,
+
+ needsContentAttribute: true
+ }, ContentEditableInput.prototype);
+
+ function posToDOM(cm, pos) {
+ var view = findViewForLine(cm, pos.line);
+ if (!view || view.hidden) return null;
+ var line = getLine(cm.doc, pos.line);
+ var info = mapFromLineView(view, line, pos.line);
+
+ var order = getOrder(line), side = "left";
+ if (order) {
+ var partPos = getBidiPartAt(order, pos.ch);
+ side = partPos % 2 ? "right" : "left";
+ }
+ var result = nodeAndOffsetInLineMap(info.map, pos.ch, side);
+ result.offset = result.collapse == "right" ? result.end : result.start;
+ return result;
+ }
+
+ function badPos(pos, bad) { if (bad) pos.bad = true; return pos; }
+
+ function domToPos(cm, node, offset) {
+ var lineNode;
+ if (node == cm.display.lineDiv) {
+ lineNode = cm.display.lineDiv.childNodes[offset];
+ if (!lineNode) return badPos(cm.clipPos(Pos(cm.display.viewTo - 1)), true);
+ node = null; offset = 0;
+ } else {
+ for (lineNode = node;; lineNode = lineNode.parentNode) {
+ if (!lineNode || lineNode == cm.display.lineDiv) return null;
+ if (lineNode.parentNode && lineNode.parentNode == cm.display.lineDiv) break;
+ }
+ }
+ for (var i = 0; i < cm.display.view.length; i++) {
+ var lineView = cm.display.view[i];
+ if (lineView.node == lineNode)
+ return locateNodeInLineView(lineView, node, offset);
+ }
+ }
+
+ function locateNodeInLineView(lineView, node, offset) {
+ var wrapper = lineView.text.firstChild, bad = false;
+ if (!node || !contains(wrapper, node)) return badPos(Pos(lineNo(lineView.line), 0), true);
+ if (node == wrapper) {
+ bad = true;
+ node = wrapper.childNodes[offset];
+ offset = 0;
+ if (!node) {
+ var line = lineView.rest ? lst(lineView.rest) : lineView.line;
+ return badPos(Pos(lineNo(line), line.text.length), bad);
+ }
+ }
+
+ var textNode = node.nodeType == 3 ? node : null, topNode = node;
+ if (!textNode && node.childNodes.length == 1 && node.firstChild.nodeType == 3) {
+ textNode = node.firstChild;
+ if (offset) offset = textNode.nodeValue.length;
+ }
+ while (topNode.parentNode != wrapper) topNode = topNode.parentNode;
+ var measure = lineView.measure, maps = measure.maps;
+
+ function find(textNode, topNode, offset) {
+ for (var i = -1; i < (maps ? maps.length : 0); i++) {
+ var map = i < 0 ? measure.map : maps[i];
+ for (var j = 0; j < map.length; j += 3) {
+ var curNode = map[j + 2];
+ if (curNode == textNode || curNode == topNode) {
+ var line = lineNo(i < 0 ? lineView.line : lineView.rest[i]);
+ var ch = map[j] + offset;
+ if (offset < 0 || curNode != textNode) ch = map[j + (offset ? 1 : 0)];
+ return Pos(line, ch);
+ }
+ }
+ }
+ }
+ var found = find(textNode, topNode, offset);
+ if (found) return badPos(found, bad);
+
+ // FIXME this is all really shaky. might handle the few cases it needs to handle, but likely to cause problems
+ for (var after = topNode.nextSibling, dist = textNode ? textNode.nodeValue.length - offset : 0; after; after = after.nextSibling) {
+ found = find(after, after.firstChild, 0);
+ if (found)
+ return badPos(Pos(found.line, found.ch - dist), bad);
+ else
+ dist += after.textContent.length;
+ }
+ for (var before = topNode.previousSibling, dist = offset; before; before = before.previousSibling) {
+ found = find(before, before.firstChild, -1);
+ if (found)
+ return badPos(Pos(found.line, found.ch + dist), bad);
+ else
+ dist += after.textContent.length;
+ }
+ }
+
+ function domTextBetween(cm, from, to, fromLine, toLine) {
+ var text = "", closing = false, lineSep = cm.doc.lineSeparator();
+ function recognizeMarker(id) { return function(marker) { return marker.id == id; }; }
+ function walk(node) {
+ if (node.nodeType == 1) {
+ var cmText = node.getAttribute("cm-text");
+ if (cmText != null) {
+ if (cmText == "") cmText = node.textContent.replace(/\u200b/g, "");
+ text += cmText;
+ return;
+ }
+ var markerID = node.getAttribute("cm-marker"), range;
+ if (markerID) {
+ var found = cm.findMarks(Pos(fromLine, 0), Pos(toLine + 1, 0), recognizeMarker(+markerID));
+ if (found.length && (range = found[0].find()))
+ text += getBetween(cm.doc, range.from, range.to).join(lineSep);
+ return;
+ }
+ if (node.getAttribute("contenteditable") == "false") return;
+ for (var i = 0; i < node.childNodes.length; i++)
+ walk(node.childNodes[i]);
+ if (/^(pre|div|p)$/i.test(node.nodeName))
+ closing = true;
+ } else if (node.nodeType == 3) {
+ var val = node.nodeValue;
+ if (!val) return;
+ if (closing) {
+ text += lineSep;
+ closing = false;
+ }
+ text += val;
+ }
+ }
+ for (;;) {
+ walk(from);
+ if (from == to) break;
+ from = from.nextSibling;
+ }
+ return text;
+ }
+
+ CodeMirror.inputStyles = {"textarea": TextareaInput, "contenteditable": ContentEditableInput};
+
// SELECTION / CURSOR
// Selection objects are immutable. A new one is created every time
@@ -1122,7 +2159,7 @@
// Give beforeSelectionChange handlers a change to influence a
// selection update.
- function filterSelectionChange(doc, sel) {
+ function filterSelectionChange(doc, sel, options) {
var obj = {
ranges: sel.ranges,
update: function(ranges) {
@@ -1130,7 +2167,8 @@
for (var i = 0; i < ranges.length; i++)
this.ranges[i] = new Range(clipPos(doc, ranges[i].anchor),
clipPos(doc, ranges[i].head));
- }
+ },
+ origin: options && options.origin
};
signal(doc, "beforeSelectionChange", doc, obj);
if (doc.cm) signal(doc.cm, "beforeSelectionChange", doc.cm, obj);
@@ -1156,7 +2194,7 @@
function setSelectionNoUndo(doc, sel, options) {
if (hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange"))
- sel = filterSelectionChange(doc, sel);
+ sel = filterSelectionChange(doc, sel, options);
var bias = options && options.bias ||
(cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1);
@@ -1190,8 +2228,9 @@
var out;
for (var i = 0; i < sel.ranges.length; i++) {
var range = sel.ranges[i];
- var newAnchor = skipAtomic(doc, range.anchor, bias, mayClear);
- var newHead = skipAtomic(doc, range.head, bias, mayClear);
+ var old = sel.ranges.length == doc.sel.ranges.length && doc.sel.ranges[i];
+ var newAnchor = skipAtomic(doc, range.anchor, old && old.anchor, bias, mayClear);
+ var newHead = skipAtomic(doc, range.head, old && old.head, bias, mayClear);
if (out || newAnchor != range.anchor || newHead != range.head) {
if (!out) out = sel.ranges.slice(0, i);
out[i] = new Range(newAnchor, newHead);
@@ -1200,103 +2239,88 @@
return out ? normalizeSelection(out, sel.primIndex) : sel;
}
- // Ensure a given position is not inside an atomic range.
- function skipAtomic(doc, pos, bias, mayClear) {
- var flipped = false, curPos = pos;
- var dir = bias || 1;
- doc.cantEdit = false;
- search: for (;;) {
- var line = getLine(doc, curPos.line);
- if (line.markedSpans) {
- for (var i = 0; i < line.markedSpans.length; ++i) {
- var sp = line.markedSpans[i], m = sp.marker;
- if ((sp.from == null || (m.inclusiveLeft ? sp.from <= curPos.ch : sp.from < curPos.ch)) &&
- (sp.to == null || (m.inclusiveRight ? sp.to >= curPos.ch : sp.to > curPos.ch))) {
- if (mayClear) {
- signal(m, "beforeCursorEnter");
- if (m.explicitlyCleared) {
- if (!line.markedSpans) break;
- else {--i; continue;}
- }
- }
- if (!m.atomic) continue;
- var newPos = m.find(dir < 0 ? -1 : 1);
- if (cmp(newPos, curPos) == 0) {
- newPos.ch += dir;
- if (newPos.ch < 0) {
- if (newPos.line > doc.first) newPos = clipPos(doc, Pos(newPos.line - 1));
- else newPos = null;
- } else if (newPos.ch > line.text.length) {
- if (newPos.line < doc.first + doc.size - 1) newPos = Pos(newPos.line + 1, 0);
- else newPos = null;
- }
- if (!newPos) {
- if (flipped) {
- // Driven in a corner -- no valid cursor position found at all
- // -- try again *with* clearing, if we didn't already
- if (!mayClear) return skipAtomic(doc, pos, bias, true);
- // Otherwise, turn off editing until further notice, and return the start of the doc
- doc.cantEdit = true;
- return Pos(doc.first, 0);
- }
- flipped = true; newPos = pos; dir = -dir;
- }
- }
- curPos = newPos;
- continue search;
+ function skipAtomicInner(doc, pos, oldPos, dir, mayClear) {
+ var line = getLine(doc, pos.line);
+ if (line.markedSpans) for (var i = 0; i < line.markedSpans.length; ++i) {
+ var sp = line.markedSpans[i], m = sp.marker;
+ if ((sp.from == null || (m.inclusiveLeft ? sp.from <= pos.ch : sp.from < pos.ch)) &&
+ (sp.to == null || (m.inclusiveRight ? sp.to >= pos.ch : sp.to > pos.ch))) {
+ if (mayClear) {
+ signal(m, "beforeCursorEnter");
+ if (m.explicitlyCleared) {
+ if (!line.markedSpans) break;
+ else {--i; continue;}
}
}
+ if (!m.atomic) continue;
+
+ if (oldPos) {
+ var near = m.find(dir < 0 ? 1 : -1), diff;
+ if (dir < 0 ? m.inclusiveRight : m.inclusiveLeft) near = movePos(doc, near, -dir, line);
+ if (near && near.line == pos.line && (diff = cmp(near, oldPos)) && (dir < 0 ? diff < 0 : diff > 0))
+ return skipAtomicInner(doc, near, pos, dir, mayClear);
+ }
+
+ var far = m.find(dir < 0 ? -1 : 1);
+ if (dir < 0 ? m.inclusiveLeft : m.inclusiveRight) far = movePos(doc, far, dir, line);
+ return far ? skipAtomicInner(doc, far, pos, dir, mayClear) : null;
}
- return curPos;
+ }
+ return pos;
+ }
+
+ // Ensure a given position is not inside an atomic range.
+ function skipAtomic(doc, pos, oldPos, bias, mayClear) {
+ var dir = bias || 1;
+ var found = skipAtomicInner(doc, pos, oldPos, dir, mayClear) ||
+ (!mayClear && skipAtomicInner(doc, pos, oldPos, dir, true)) ||
+ skipAtomicInner(doc, pos, oldPos, -dir, mayClear) ||
+ (!mayClear && skipAtomicInner(doc, pos, oldPos, -dir, true));
+ if (!found) {
+ doc.cantEdit = true;
+ return Pos(doc.first, 0);
+ }
+ return found;
+ }
+
+ function movePos(doc, pos, dir, line) {
+ if (dir < 0 && pos.ch == 0) {
+ if (pos.line > doc.first) return clipPos(doc, Pos(pos.line - 1));
+ else return null;
+ } else if (dir > 0 && pos.ch == (line || getLine(doc, pos.line)).text.length) {
+ if (pos.line < doc.first + doc.size - 1) return Pos(pos.line + 1, 0);
+ else return null;
+ } else {
+ return new Pos(pos.line, pos.ch + dir);
}
}
// SELECTION DRAWING
- // Redraw the selection and/or cursor
- function drawSelection(cm) {
- var display = cm.display, doc = cm.doc, result = {};
+ function updateSelection(cm) {
+ cm.display.input.showSelection(cm.display.input.prepareSelection());
+ }
+
+ function prepareSelection(cm, primary) {
+ var doc = cm.doc, result = {};
var curFragment = result.cursors = document.createDocumentFragment();
var selFragment = result.selection = document.createDocumentFragment();
for (var i = 0; i < doc.sel.ranges.length; i++) {
+ if (primary === false && i == doc.sel.primIndex) continue;
var range = doc.sel.ranges[i];
var collapsed = range.empty();
if (collapsed || cm.options.showCursorWhenSelecting)
- drawSelectionCursor(cm, range, curFragment);
+ drawSelectionCursor(cm, range.head, curFragment);
if (!collapsed)
drawSelectionRange(cm, range, selFragment);
}
-
- // Move the hidden textarea near the cursor to prevent scrolling artifacts
- if (cm.options.moveInputWithCursor) {
- var headPos = cursorCoords(cm, doc.sel.primary().head, "div");
- var wrapOff = display.wrapper.getBoundingClientRect(), lineOff = display.lineDiv.getBoundingClientRect();
- result.teTop = Math.max(0, Math.min(display.wrapper.clientHeight - 10,
- headPos.top + lineOff.top - wrapOff.top));
- result.teLeft = Math.max(0, Math.min(display.wrapper.clientWidth - 10,
- headPos.left + lineOff.left - wrapOff.left));
- }
-
return result;
}
- function showSelection(cm, drawn) {
- removeChildrenAndAdd(cm.display.cursorDiv, drawn.cursors);
- removeChildrenAndAdd(cm.display.selectionDiv, drawn.selection);
- if (drawn.teTop != null) {
- cm.display.inputDiv.style.top = drawn.teTop + "px";
- cm.display.inputDiv.style.left = drawn.teLeft + "px";
- }
- }
-
- function updateSelection(cm) {
- showSelection(cm, drawSelection(cm));
- }
-
// Draws a cursor for the given range
- function drawSelectionCursor(cm, range, output) {
- var pos = cursorCoords(cm, range.head, "div", null, null, !cm.options.singleCursorHeightPerLine);
+ function drawSelectionCursor(cm, head, output) {
+ var pos = cursorCoords(cm, head, "div", null, null, !cm.options.singleCursorHeightPerLine);
var cursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor"));
cursor.style.left = pos.left + "px";
@@ -1317,7 +2341,8 @@
function drawSelectionRange(cm, range, output) {
var display = cm.display, doc = cm.doc;
var fragment = document.createDocumentFragment();
- var padding = paddingH(cm.display), leftSide = padding.left, rightSide = display.lineSpace.offsetWidth - padding.right;
+ var padding = paddingH(cm.display), leftSide = padding.left;
+ var rightSide = Math.max(display.sizerWidth, displayWidth(cm) - display.sizer.offsetLeft) - padding.right;
function add(left, top, width, bottom) {
if (top < 0) top = 0;
@@ -1419,8 +2444,8 @@
doc.iter(doc.frontier, Math.min(doc.first + doc.size, cm.display.viewTo + 500), function(line) {
if (doc.frontier >= cm.display.viewFrom) { // Visible
- var oldStyles = line.styles;
- var highlighted = highlightLine(cm, line, state, true);
+ var oldStyles = line.styles, tooLong = line.text.length > cm.options.maxHighlightLength;
+ var highlighted = highlightLine(cm, line, tooLong ? copyState(doc.mode, state) : state, true);
line.styles = highlighted.styles;
var oldCls = line.styleClasses, newCls = highlighted.classes;
if (newCls) line.styleClasses = newCls;
@@ -1429,9 +2454,10 @@
oldCls != newCls && (!oldCls || !newCls || oldCls.bgClass != newCls.bgClass || oldCls.textClass != newCls.textClass);
for (var i = 0; !ischange && i < oldStyles.length; ++i) ischange = oldStyles[i] != line.styles[i];
if (ischange) changedLines.push(doc.frontier);
- line.stateAfter = copyState(doc.mode, state);
+ line.stateAfter = tooLong ? state : copyState(doc.mode, state);
} else {
- processLine(cm, line.text, state);
+ if (line.text.length <= cm.options.maxHighlightLength)
+ processLine(cm, line.text, state);
line.stateAfter = doc.frontier % 5 == 0 ? copyState(doc.mode, state) : null;
}
++doc.frontier;
@@ -1496,13 +2522,21 @@
return data;
}
+ function scrollGap(cm) { return scrollerGap - cm.display.nativeBarWidth; }
+ function displayWidth(cm) {
+ return cm.display.scroller.clientWidth - scrollGap(cm) - cm.display.barWidth;
+ }
+ function displayHeight(cm) {
+ return cm.display.scroller.clientHeight - scrollGap(cm) - cm.display.barHeight;
+ }
+
// Ensure the lineView.wrapping.heights array is populated. This is
// an array of bottom offsets for the lines that make up a drawn
// line. When lineWrapping is on, there might be more than one
// height.
function ensureLineHeights(cm, lineView, rect) {
var wrapping = cm.options.lineWrapping;
- var curWidth = wrapping && cm.display.scroller.clientWidth;
+ var curWidth = wrapping && displayWidth(cm);
if (!lineView.measure.heights || wrapping && lineView.measure.width != curWidth) {
var heights = lineView.measure.heights = [];
if (wrapping) {
@@ -1568,10 +2602,12 @@
function prepareMeasureForLine(cm, line) {
var lineN = lineNo(line);
var view = findViewForLine(cm, lineN);
- if (view && !view.text)
+ if (view && !view.text) {
view = null;
- else if (view && view.changes)
+ } else if (view && view.changes) {
updateLineForChanges(cm, view, lineN, getDimensions(cm));
+ cm.curOp.forceUpdate = true;
+ }
if (!view)
view = updateExternalMeasurement(cm, line);
@@ -1607,9 +2643,7 @@
var nullRect = {left: 0, right: 0, top: 0, bottom: 0};
- function measureCharInner(cm, prepared, ch, bias) {
- var map = prepared.map;
-
+ function nodeAndOffsetInLineMap(map, ch, bias) {
var node, start, end, collapse;
// First, search the line map for the text node corresponding to,
// or closest to, the target character.
@@ -1643,13 +2677,19 @@
break;
}
}
+ return {node: node, start: start, end: end, collapse: collapse, coverStart: mStart, coverEnd: mEnd};
+ }
+
+ function measureCharInner(cm, prepared, ch, bias) {
+ var place = nodeAndOffsetInLineMap(prepared.map, ch, bias);
+ var node = place.node, start = place.start, end = place.end, collapse = place.collapse;
var rect;
if (node.nodeType == 3) { // If it is a text node, use a range to retrieve the coordinates.
for (var i = 0; i < 4; i++) { // Retry a maximum of 4 times when nonsense rectangles are returned
- while (start && isExtendingChar(prepared.line.text.charAt(mStart + start))) --start;
- while (mStart + end < mEnd && isExtendingChar(prepared.line.text.charAt(mStart + end))) ++end;
- if (ie && ie_version < 9 && start == 0 && end == mEnd - mStart) {
+ while (start && isExtendingChar(prepared.line.text.charAt(place.coverStart + start))) --start;
+ while (place.coverStart + end < place.coverEnd && isExtendingChar(prepared.line.text.charAt(place.coverStart + end))) ++end;
+ if (ie && ie_version < 9 && start == 0 && end == place.coverEnd - place.coverStart) {
rect = node.parentNode.getBoundingClientRect();
} else if (ie && cm.options.lineWrapping) {
var rects = range(node, start, end).getClientRects();
@@ -1737,7 +2777,8 @@
// Converts a {top, bottom, left, right} box from line-local
// coordinates into another coordinate system. Context may be one of
- // "line", "div" (display.lineDiv), "local"/null (editor), or "page".
+ // "line", "div" (display.lineDiv), "local"/null (editor), "window",
+ // or "page".
function intoCoordSystem(cm, lineObj, rect, context) {
if (lineObj.widgets) for (var i = 0; i < lineObj.widgets.length; ++i) if (lineObj.widgets[i].above) {
var size = widgetHeight(lineObj.widgets[i]);
@@ -1960,6 +3001,7 @@
updateMaxLine: false, // Set when the widest line needs to be determined anew
scrollLeft: null, scrollTop: null, // Intermediate scroll position, not pushed to DOM yet
scrollToPos: null, // Used to scroll to a specific position
+ focus: false,
id: ++nextOpId // Unique ID
};
if (operationGroup) {
@@ -1978,12 +3020,12 @@
var callbacks = group.delayedCallbacks, i = 0;
do {
for (; i < callbacks.length; i++)
- callbacks[i]();
+ callbacks[i].call(null);
for (var j = 0; j < group.ops.length; j++) {
var op = group.ops[j];
if (op.cursorActivityHandlers)
while (op.cursorActivityCalled < op.cursorActivityHandlers.length)
- op.cursorActivityHandlers[op.cursorActivityCalled++](op.cm);
+ op.cursorActivityHandlers[op.cursorActivityCalled++].call(null, op.cm);
}
} while (i < callbacks.length);
}
@@ -2020,6 +3062,7 @@
function endOperation_R1(op) {
var cm = op.cm, display = cm.display;
+ maybeClipScrollbars(cm);
if (op.updateMaxLine) findMaxLine(cm);
op.mustUpdate = op.viewChanged || op.forceUpdate || op.scrollTop != null ||
@@ -2045,12 +3088,14 @@
// updateDisplay_W2 will use these properties to do the actual resizing
if (display.maxLineChanged && !cm.options.lineWrapping) {
op.adjustWidthTo = measureChar(cm, display.maxLine, display.maxLine.text.length).left + 3;
- op.maxScrollLeft = Math.max(0, display.sizer.offsetLeft + op.adjustWidthTo +
- scrollerCutOff - display.scroller.clientWidth);
+ cm.display.sizerWidth = op.adjustWidthTo;
+ op.barMeasure.scrollWidth =
+ Math.max(display.scroller.clientWidth, display.sizer.offsetLeft + op.adjustWidthTo + scrollGap(cm) + cm.display.barWidth);
+ op.maxScrollLeft = Math.max(0, display.sizer.offsetLeft + op.adjustWidthTo - displayWidth(cm));
}
if (op.updatedDisplay || op.selectionChanged)
- op.newSelectionNodes = drawSelection(cm);
+ op.preparedSelection = display.input.prepareSelection();
}
function endOperation_W2(op) {
@@ -2063,8 +3108,8 @@
cm.display.maxLineChanged = false;
}
- if (op.newSelectionNodes)
- showSelection(cm, op.newSelectionNodes);
+ if (op.preparedSelection)
+ cm.display.input.showSelection(op.preparedSelection);
if (op.updatedDisplay)
setDocumentHeight(cm, op.barMeasure);
if (op.updatedDisplay || op.startHeight != cm.doc.height)
@@ -2073,15 +3118,14 @@
if (op.selectionChanged) restartBlink(cm);
if (cm.state.focused && op.updateInput)
- resetInput(cm, op.typing);
+ cm.display.input.reset(op.typing);
+ if (op.focus && op.focus == activeElt() && (!document.hasFocus || document.hasFocus()))
+ ensureFocus(op.cm);
}
function endOperation_finish(op) {
var cm = op.cm, display = cm.display, doc = cm.doc;
- if (op.adjustWidthTo != null && Math.abs(op.barMeasure.scrollWidth - cm.display.scroller.scrollWidth) > 1)
- updateScrollbars(cm);
-
if (op.updatedDisplay) postUpdateDisplay(cm, op.update);
// Abort mouse wheel delta measurement, when scrolling explicitly
@@ -2090,12 +3134,14 @@
// Propagate the scroll position to the actual DOM scroller
if (op.scrollTop != null && (display.scroller.scrollTop != op.scrollTop || op.forceScroll)) {
- var top = Math.max(0, Math.min(display.scroller.scrollHeight - display.scroller.clientHeight, op.scrollTop));
- display.scroller.scrollTop = display.scrollbarV.scrollTop = doc.scrollTop = top;
+ doc.scrollTop = Math.max(0, Math.min(display.scroller.scrollHeight - display.scroller.clientHeight, op.scrollTop));
+ display.scrollbars.setScrollTop(doc.scrollTop);
+ display.scroller.scrollTop = doc.scrollTop;
}
if (op.scrollLeft != null && (display.scroller.scrollLeft != op.scrollLeft || op.forceScroll)) {
- var left = Math.max(0, Math.min(display.scroller.scrollWidth - display.scroller.clientWidth, op.scrollLeft));
- display.scroller.scrollLeft = display.scrollbarH.scrollLeft = doc.scrollLeft = left;
+ doc.scrollLeft = Math.max(0, Math.min(display.scroller.scrollWidth - displayWidth(cm), op.scrollLeft));
+ display.scrollbars.setScrollLeft(doc.scrollLeft);
+ display.scroller.scrollLeft = doc.scrollLeft;
alignHorizontally(cm);
}
// If we need to scroll a specific position into view, do so.
@@ -2116,19 +3162,11 @@
if (display.wrapper.offsetHeight)
doc.scrollTop = cm.display.scroller.scrollTop;
- // Apply workaround for two webkit bugs
- if (op.updatedDisplay && webkit) {
- if (cm.options.lineWrapping)
- checkForWebkitWidthBug(cm, op.barMeasure); // (Issue #2420)
- if (op.barMeasure.scrollWidth > op.barMeasure.clientWidth &&
- op.barMeasure.scrollWidth < op.barMeasure.clientWidth + 1 &&
- !hScrollbarTakesSpace(cm))
- updateScrollbars(cm); // (Issue #2562)
- }
-
// Fire change events, and delayed event handlers
if (op.changeObjs)
signal(cm, "changes", cm, op.changeObjs);
+ if (op.update)
+ op.update.finish();
}
// Run the given function in an operation
@@ -2354,166 +3392,6 @@
return dirty;
}
- // INPUT HANDLING
-
- // Poll for input changes, using the normal rate of polling. This
- // runs as long as the editor is focused.
- function slowPoll(cm) {
- if (cm.display.pollingFast) return;
- cm.display.poll.set(cm.options.pollInterval, function() {
- readInput(cm);
- if (cm.state.focused) slowPoll(cm);
- });
- }
-
- // When an event has just come in that is likely to add or change
- // something in the input textarea, we poll faster, to ensure that
- // the change appears on the screen quickly.
- function fastPoll(cm) {
- var missed = false;
- cm.display.pollingFast = true;
- function p() {
- var changed = readInput(cm);
- if (!changed && !missed) {missed = true; cm.display.poll.set(60, p);}
- else {cm.display.pollingFast = false; slowPoll(cm);}
- }
- cm.display.poll.set(20, p);
- }
-
- // This will be set to an array of strings when copying, so that,
- // when pasting, we know what kind of selections the copied text
- // was made out of.
- var lastCopied = null;
-
- // Read input from the textarea, and update the document to match.
- // When something is selected, it is present in the textarea, and
- // selected (unless it is huge, in which case a placeholder is
- // used). When nothing is selected, the cursor sits after previously
- // seen text (can be empty), which is stored in prevInput (we must
- // not reset the textarea when typing, because that breaks IME).
- function readInput(cm) {
- var input = cm.display.input, prevInput = cm.display.prevInput, doc = cm.doc;
- // Since this is called a *lot*, try to bail out as cheaply as
- // possible when it is clear that nothing happened. hasSelection
- // will be the case when there is a lot of text in the textarea,
- // in which case reading its value would be expensive.
- if (!cm.state.focused || (hasSelection(input) && !prevInput) || isReadOnly(cm) || cm.options.disableInput)
- return false;
- // See paste handler for more on the fakedLastChar kludge
- if (cm.state.pasteIncoming && cm.state.fakedLastChar) {
- input.value = input.value.substring(0, input.value.length - 1);
- cm.state.fakedLastChar = false;
- }
- var text = input.value;
- // If nothing changed, bail.
- if (text == prevInput && !cm.somethingSelected()) return false;
- // Work around nonsensical selection resetting in IE9/10, and
- // inexplicable appearance of private area unicode characters on
- // some key combos in Mac (#2689).
- if (ie && ie_version >= 9 && cm.display.inputHasSelection === text ||
- mac && /[\uf700-\uf7ff]/.test(text)) {
- resetInput(cm);
- return false;
- }
-
- var withOp = !cm.curOp;
- if (withOp) startOperation(cm);
- cm.display.shift = false;
-
- if (text.charCodeAt(0) == 0x200b && doc.sel == cm.display.selForContextMenu && !prevInput)
- prevInput = "\u200b";
- // Find the part of the input that is actually new
- var same = 0, l = Math.min(prevInput.length, text.length);
- while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) ++same;
- var inserted = text.slice(same), textLines = splitLines(inserted);
-
- // When pasing N lines into N selections, insert one line per selection
- var multiPaste = null;
- if (cm.state.pasteIncoming && doc.sel.ranges.length > 1) {
- if (lastCopied && lastCopied.join("\n") == inserted)
- multiPaste = doc.sel.ranges.length % lastCopied.length == 0 && map(lastCopied, splitLines);
- else if (textLines.length == doc.sel.ranges.length)
- multiPaste = map(textLines, function(l) { return [l]; });
- }
-
- // Normal behavior is to insert the new text into every selection
- for (var i = doc.sel.ranges.length - 1; i >= 0; i--) {
- var range = doc.sel.ranges[i];
- var from = range.from(), to = range.to();
- // Handle deletion
- if (same < prevInput.length)
- from = Pos(from.line, from.ch - (prevInput.length - same));
- // Handle overwrite
- else if (cm.state.overwrite && range.empty() && !cm.state.pasteIncoming)
- to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + lst(textLines).length));
- var updateInput = cm.curOp.updateInput;
- var changeEvent = {from: from, to: to, text: multiPaste ? multiPaste[i % multiPaste.length] : textLines,
- origin: cm.state.pasteIncoming ? "paste" : cm.state.cutIncoming ? "cut" : "+input"};
- makeChange(cm.doc, changeEvent);
- signalLater(cm, "inputRead", cm, changeEvent);
- // When an 'electric' character is inserted, immediately trigger a reindent
- if (inserted && !cm.state.pasteIncoming && cm.options.electricChars &&
- cm.options.smartIndent && range.head.ch < 100 &&
- (!i || doc.sel.ranges[i - 1].head.line != range.head.line)) {
- var mode = cm.getModeAt(range.head);
- var end = changeEnd(changeEvent);
- if (mode.electricChars) {
- for (var j = 0; j < mode.electricChars.length; j++)
- if (inserted.indexOf(mode.electricChars.charAt(j)) > -1) {
- indentLine(cm, end.line, "smart");
- break;
- }
- } else if (mode.electricInput) {
- if (mode.electricInput.test(getLine(doc, end.line).text.slice(0, end.ch)))
- indentLine(cm, end.line, "smart");
- }
- }
- }
- ensureCursorVisible(cm);
- cm.curOp.updateInput = updateInput;
- cm.curOp.typing = true;
-
- // Don't leave long text in the textarea, since it makes further polling slow
- if (text.length > 1000 || text.indexOf("\n") > -1) input.value = cm.display.prevInput = "";
- else cm.display.prevInput = text;
- if (withOp) endOperation(cm);
- cm.state.pasteIncoming = cm.state.cutIncoming = false;
- return true;
- }
-
- // Reset the input to correspond to the selection (or to be empty,
- // when not typing and nothing is selected)
- function resetInput(cm, typing) {
- var minimal, selected, doc = cm.doc;
- if (cm.somethingSelected()) {
- cm.display.prevInput = "";
- var range = doc.sel.primary();
- minimal = hasCopyEvent &&
- (range.to().line - range.from().line > 100 || (selected = cm.getSelection()).length > 1000);
- var content = minimal ? "-" : selected || cm.getSelection();
- cm.display.input.value = content;
- if (cm.state.focused) selectInput(cm.display.input);
- if (ie && ie_version >= 9) cm.display.inputHasSelection = content;
- } else if (!typing) {
- cm.display.prevInput = cm.display.input.value = "";
- if (ie && ie_version >= 9) cm.display.inputHasSelection = null;
- }
- cm.display.inaccurateSelection = minimal;
- }
-
- function focusInput(cm) {
- if (cm.options.readOnly != "nocursor" && (!mobile || activeElt() != cm.display.input))
- cm.display.input.focus();
- }
-
- function ensureFocus(cm) {
- if (!cm.state.focused) { focusInput(cm); onFocus(cm); }
- }
-
- function isReadOnly(cm) {
- return cm.options.readOnly || cm.doc.cantEdit;
- }
-
// EVENT HANDLERS
// Attach the necessary event handlers when initializing the editor
@@ -2532,15 +3410,64 @@
}));
else
on(d.scroller, "dblclick", function(e) { signalDOMEvent(cm, e) || e_preventDefault(e); });
- // Prevent normal selection in the editor (we handle our own)
- on(d.lineSpace, "selectstart", function(e) {
- if (!eventInWidget(d, e)) e_preventDefault(e);
- });
// Some browsers fire contextmenu *after* opening the menu, at
// which point we can't mess with it anymore. Context menu is
// handled in onMouseDown for these browsers.
if (!captureRightClick) on(d.scroller, "contextmenu", function(e) {onContextMenu(cm, e);});
+ // Used to suppress mouse event handling when a touch happens
+ var touchFinished, prevTouch = {end: 0};
+ function finishTouch() {
+ if (d.activeTouch) {
+ touchFinished = setTimeout(function() {d.activeTouch = null;}, 1000);
+ prevTouch = d.activeTouch;
+ prevTouch.end = +new Date;
+ }
+ };
+ function isMouseLikeTouchEvent(e) {
+ if (e.touches.length != 1) return false;
+ var touch = e.touches[0];
+ return touch.radiusX <= 1 && touch.radiusY <= 1;
+ }
+ function farAway(touch, other) {
+ if (other.left == null) return true;
+ var dx = other.left - touch.left, dy = other.top - touch.top;
+ return dx * dx + dy * dy > 20 * 20;
+ }
+ on(d.scroller, "touchstart", function(e) {
+ if (!signalDOMEvent(cm, e) && !isMouseLikeTouchEvent(e)) {
+ clearTimeout(touchFinished);
+ var now = +new Date;
+ d.activeTouch = {start: now, moved: false,
+ prev: now - prevTouch.end <= 300 ? prevTouch : null};
+ if (e.touches.length == 1) {
+ d.activeTouch.left = e.touches[0].pageX;
+ d.activeTouch.top = e.touches[0].pageY;
+ }
+ }
+ });
+ on(d.scroller, "touchmove", function() {
+ if (d.activeTouch) d.activeTouch.moved = true;
+ });
+ on(d.scroller, "touchend", function(e) {
+ var touch = d.activeTouch;
+ if (touch && !eventInWidget(d, e) && touch.left != null &&
+ !touch.moved && new Date - touch.start < 300) {
+ var pos = cm.coordsChar(d.activeTouch, "page"), range;
+ if (!touch.prev || farAway(touch, touch.prev)) // Single tap
+ range = new Range(pos, pos);
+ else if (!touch.prev.prev || farAway(touch, touch.prev.prev)) // Double tap
+ range = cm.findWordAt(pos);
+ else // Triple tap
+ range = new Range(Pos(pos.line, 0), clipPos(cm.doc, Pos(pos.line + 1, 0)));
+ cm.setSelection(range.anchor, range.head);
+ cm.focus();
+ e_preventDefault(e);
+ }
+ finishTouch();
+ });
+ on(d.scroller, "touchcancel", finishTouch);
+
// Sync scrolling between fake scrollbars and real scrollable
// area, ensure viewport is updated when scrolling.
on(d.scroller, "scroll", function() {
@@ -2550,111 +3477,51 @@
signal(cm, "scroll", cm);
}
});
- on(d.scrollbarV, "scroll", function() {
- if (d.scroller.clientHeight) setScrollTop(cm, d.scrollbarV.scrollTop);
- });
- on(d.scrollbarH, "scroll", function() {
- if (d.scroller.clientHeight) setScrollLeft(cm, d.scrollbarH.scrollLeft);
- });
// Listen to wheel events in order to try and update the viewport on time.
on(d.scroller, "mousewheel", function(e){onScrollWheel(cm, e);});
on(d.scroller, "DOMMouseScroll", function(e){onScrollWheel(cm, e);});
- // Prevent clicks in the scrollbars from killing focus
- function reFocus() { if (cm.state.focused) setTimeout(bind(focusInput, cm), 0); }
- on(d.scrollbarH, "mousedown", reFocus);
- on(d.scrollbarV, "mousedown", reFocus);
// Prevent wrapper from ever scrolling
on(d.wrapper, "scroll", function() { d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; });
- on(d.input, "keyup", function(e) { onKeyUp.call(cm, e); });
- on(d.input, "input", function() {
- if (ie && ie_version >= 9 && cm.display.inputHasSelection) cm.display.inputHasSelection = null;
- fastPoll(cm);
- });
- on(d.input, "keydown", operation(cm, onKeyDown));
- on(d.input, "keypress", operation(cm, onKeyPress));
- on(d.input, "focus", bind(onFocus, cm));
- on(d.input, "blur", bind(onBlur, cm));
+ d.dragFunctions = {
+ enter: function(e) {if (!signalDOMEvent(cm, e)) e_stop(e);},
+ over: function(e) {if (!signalDOMEvent(cm, e)) { onDragOver(cm, e); e_stop(e); }},
+ start: function(e){onDragStart(cm, e);},
+ drop: operation(cm, onDrop),
+ leave: function() {clearDragCursor(cm);}
+ };
- function drag_(e) {
- if (!signalDOMEvent(cm, e)) e_stop(e);
- }
- if (cm.options.dragDrop) {
- on(d.scroller, "dragstart", function(e){onDragStart(cm, e);});
- on(d.scroller, "dragenter", drag_);
- on(d.scroller, "dragover", drag_);
- on(d.scroller, "drop", operation(cm, onDrop));
- }
- on(d.scroller, "paste", function(e) {
- if (eventInWidget(d, e)) return;
- cm.state.pasteIncoming = true;
- focusInput(cm);
- fastPoll(cm);
- });
- on(d.input, "paste", function() {
- // Workaround for webkit bug https://bugs.webkit.org/show_bug.cgi?id=90206
- // Add a char to the end of textarea before paste occur so that
- // selection doesn't span to the end of textarea.
- if (webkit && !cm.state.fakedLastChar && !(new Date - cm.state.lastMiddleDown < 200)) {
- var start = d.input.selectionStart, end = d.input.selectionEnd;
- d.input.value += "$";
- // The selection end needs to be set before the start, otherwise there
- // can be an intermediate non-empty selection between the two, which
- // can override the middle-click paste buffer on linux and cause the
- // wrong thing to get pasted.
- d.input.selectionEnd = end;
- d.input.selectionStart = start;
- cm.state.fakedLastChar = true;
- }
- cm.state.pasteIncoming = true;
- fastPoll(cm);
- });
+ var inp = d.input.getField();
+ on(inp, "keyup", function(e) { onKeyUp.call(cm, e); });
+ on(inp, "keydown", operation(cm, onKeyDown));
+ on(inp, "keypress", operation(cm, onKeyPress));
+ on(inp, "focus", bind(onFocus, cm));
+ on(inp, "blur", bind(onBlur, cm));
+ }
- function prepareCopyCut(e) {
- if (cm.somethingSelected()) {
- lastCopied = cm.getSelections();
- if (d.inaccurateSelection) {
- d.prevInput = "";
- d.inaccurateSelection = false;
- d.input.value = lastCopied.join("\n");
- selectInput(d.input);
- }
- } else {
- var text = [], ranges = [];
- for (var i = 0; i < cm.doc.sel.ranges.length; i++) {
- var line = cm.doc.sel.ranges[i].head.line;
- var lineRange = {anchor: Pos(line, 0), head: Pos(line + 1, 0)};
- ranges.push(lineRange);
- text.push(cm.getRange(lineRange.anchor, lineRange.head));
- }
- if (e.type == "cut") {
- cm.setSelections(ranges, null, sel_dontScroll);
- } else {
- d.prevInput = "";
- d.input.value = text.join("\n");
- selectInput(d.input);
- }
- lastCopied = text;
- }
- if (e.type == "cut") cm.state.cutIncoming = true;
+ function dragDropChanged(cm, value, old) {
+ var wasOn = old && old != CodeMirror.Init;
+ if (!value != !wasOn) {
+ var funcs = cm.display.dragFunctions;
+ var toggle = value ? on : off;
+ toggle(cm.display.scroller, "dragstart", funcs.start);
+ toggle(cm.display.scroller, "dragenter", funcs.enter);
+ toggle(cm.display.scroller, "dragover", funcs.over);
+ toggle(cm.display.scroller, "dragleave", funcs.leave);
+ toggle(cm.display.scroller, "drop", funcs.drop);
}
- on(d.input, "cut", prepareCopyCut);
- on(d.input, "copy", prepareCopyCut);
-
- // Needed to handle Tab key in KHTML
- if (khtml) on(d.sizer, "mouseup", function() {
- if (activeElt() == d.input) d.input.blur();
- focusInput(cm);
- });
}
// Called when the window resizes
function onResize(cm) {
- // Might be a text scaling operation, clear size caches.
var d = cm.display;
+ if (d.lastWrapHeight == d.wrapper.clientHeight && d.lastWrapWidth == d.wrapper.clientWidth)
+ return;
+ // Might be a text scaling operation, clear size caches.
d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null;
+ d.scrollbarsClipped = false;
cm.setSize();
}
@@ -2663,7 +3530,9 @@
// Return true when the given mouse event happened in a widget
function eventInWidget(display, e) {
for (var n = e_target(e); n != display.wrapper; n = n.parentNode) {
- if (!n || n.ignoreEvents || n.parentNode == display.sizer && n != display.mover) return true;
+ if (!n || (n.nodeType == 1 && n.getAttribute("cm-ignore-events") == "true") ||
+ (n.parentNode == display.sizer && n != display.mover))
+ return true;
}
}
@@ -2674,11 +3543,8 @@
// coordinates beyond the right of the text.
function posFromMouse(cm, e, liberal, forRect) {
var display = cm.display;
- if (!liberal) {
- var target = e_target(e);
- if (target == display.scrollbarH || target == display.scrollbarV ||
- target == display.scrollbarFiller || target == display.gutterFiller) return null;
- }
+ if (!liberal && e_target(e).getAttribute("cm-not-content") == "true") return null;
+
var x, y, space = display.lineSpace.getBoundingClientRect();
// Fails unpredictably on IE[67] when mouse is dragged around quickly.
try { x = e.clientX - space.left; y = e.clientY - space.top; }
@@ -2697,8 +3563,8 @@
// middle-click-paste. Or it might be a click on something we should
// not interfere with, such as a scrollbar or widget.
function onMouseDown(e) {
- if (signalDOMEvent(this, e)) return;
var cm = this, display = cm.display;
+ if (signalDOMEvent(cm, e) || display.activeTouch && display.input.supportsTouch()) return;
display.shift = e.shiftKey;
if (eventInWidget(display, e)) {
@@ -2716,7 +3582,10 @@
switch (e_button(e)) {
case 1:
- if (start)
+ // #3261: make sure, that we're not starting a second selection
+ if (cm.state.selectingText)
+ cm.state.selectingText(e);
+ else if (start)
leftButtonDown(cm, e, start);
else if (e_target(e) == display.scroller)
e_preventDefault(e);
@@ -2724,18 +3593,20 @@
case 2:
if (webkit) cm.state.lastMiddleDown = +new Date;
if (start) extendSelection(cm.doc, start);
- setTimeout(bind(focusInput, cm), 20);
+ setTimeout(function() {display.input.focus();}, 20);
e_preventDefault(e);
break;
case 3:
if (captureRightClick) onContextMenu(cm, e);
+ else delayBlurEvent(cm);
break;
}
}
var lastClick, lastDoubleClick;
function leftButtonDown(cm, e, start) {
- setTimeout(bind(ensureFocus, cm), 0);
+ if (ie) setTimeout(bind(ensureFocus, cm), 0);
+ else cm.curOp.focus = activeElt();
var now = +new Date, type;
if (lastDoubleClick && lastDoubleClick.time > now - 400 && cmp(lastDoubleClick.pos, start) == 0) {
@@ -2748,9 +3619,11 @@
lastClick = {time: now, pos: start};
}
- var sel = cm.doc.sel, modifier = mac ? e.metaKey : e.ctrlKey;
- if (cm.options.dragDrop && dragAndDrop && !isReadOnly(cm) &&
- type == "single" && sel.contains(start) > -1 && sel.somethingSelected())
+ var sel = cm.doc.sel, modifier = mac ? e.metaKey : e.ctrlKey, contained;
+ if (cm.options.dragDrop && dragAndDrop && !cm.isReadOnly() &&
+ type == "single" && (contained = sel.contains(start)) > -1 &&
+ (cmp((contained = sel.ranges[contained]).from(), start) < 0 || start.xRel > 0) &&
+ (cmp(contained.to(), start) > 0 || start.xRel < 0))
leftButtonStartDrag(cm, e, start, modifier);
else
leftButtonSelect(cm, e, start, type, modifier);
@@ -2759,7 +3632,7 @@
// Start a text drag. When it ends, see if any dragging actually
// happen, and treat as a click if it didn't.
function leftButtonStartDrag(cm, e, start, modifier) {
- var display = cm.display;
+ var display = cm.display, startTime = +new Date;
var dragEnd = operation(cm, function(e2) {
if (webkit) display.scroller.draggable = false;
cm.state.draggingText = false;
@@ -2767,12 +3640,13 @@
off(display.scroller, "drop", dragEnd);
if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) {
e_preventDefault(e2);
- if (!modifier)
+ if (!modifier && +new Date - 200 < startTime)
extendSelection(cm.doc, start);
- focusInput(cm);
- // Work around unexplainable focus problem in IE9 (#2127)
- if (ie && ie_version == 9)
- setTimeout(function() {document.body.focus(); focusInput(cm);}, 20);
+ // Work around unexplainable focus problem in IE9 (#2127) and Chrome (#3081)
+ if (webkit || ie && ie_version == 9)
+ setTimeout(function() {document.body.focus(); display.input.focus();}, 20);
+ else
+ display.input.focus();
}
});
// Let the drag handler handle this.
@@ -2789,15 +3663,16 @@
var display = cm.display, doc = cm.doc;
e_preventDefault(e);
- var ourRange, ourIndex, startSel = doc.sel;
+ var ourRange, ourIndex, startSel = doc.sel, ranges = startSel.ranges;
if (addNew && !e.shiftKey) {
ourIndex = doc.sel.contains(start);
if (ourIndex > -1)
- ourRange = doc.sel.ranges[ourIndex];
+ ourRange = ranges[ourIndex];
else
ourRange = new Range(start, start);
} else {
ourRange = doc.sel.primary();
+ ourIndex = doc.sel.primIndex;
}
if (e.altKey) {
@@ -2825,12 +3700,16 @@
ourIndex = 0;
setSelection(doc, new Selection([ourRange], 0), sel_mouse);
startSel = doc.sel;
- } else if (ourIndex > -1) {
- replaceOneSelection(doc, ourIndex, ourRange, sel_mouse);
- } else {
- ourIndex = doc.sel.ranges.length;
- setSelection(doc, normalizeSelection(doc.sel.ranges.concat([ourRange]), ourIndex),
+ } else if (ourIndex == -1) {
+ ourIndex = ranges.length;
+ setSelection(doc, normalizeSelection(ranges.concat([ourRange]), ourIndex),
{scroll: false, origin: "*mouse"});
+ } else if (ranges.length > 1 && ranges[ourIndex].empty() && type == "single" && !e.shiftKey) {
+ setSelection(doc, normalizeSelection(ranges.slice(0, ourIndex).concat(ranges.slice(ourIndex + 1)), 0),
+ {scroll: false, origin: "*mouse"});
+ startSel = doc.sel;
+ } else {
+ replaceOneSelection(doc, ourIndex, ourRange, sel_mouse);
}
var lastPos = start;
@@ -2889,7 +3768,7 @@
var cur = posFromMouse(cm, e, true, type == "rect");
if (!cur) return;
if (cmp(cur, lastPos) != 0) {
- ensureFocus(cm);
+ cm.curOp.focus = activeElt();
extendTo(cur);
var visible = visibleLines(display, doc);
if (cur.line >= visible.to || cur.line < visible.from)
@@ -2905,9 +3784,10 @@
}
function done(e) {
+ cm.state.selectingText = false;
counter = Infinity;
e_preventDefault(e);
- focusInput(cm);
+ display.input.focus();
off(document, "mousemove", move);
off(document, "mouseup", up);
doc.history.lastSelOrigin = null;
@@ -2918,13 +3798,14 @@
else extend(e);
});
var up = operation(cm, done);
+ cm.state.selectingText = up;
on(document, "mousemove", move);
on(document, "mouseup", up);
}
// Determines whether an event happened in the gutter, and fires the
// handlers for the corresponding event.
- function gutterEvent(cm, e, type, prevent, signalfn) {
+ function gutterEvent(cm, e, type, prevent) {
try { var mX = e.clientX, mY = e.clientY; }
catch(e) { return false; }
if (mX >= Math.floor(cm.display.gutters.getBoundingClientRect().right)) return false;
@@ -2941,14 +3822,14 @@
if (g && g.getBoundingClientRect().right >= mX) {
var line = lineAtHeight(cm.doc, mY);
var gutter = cm.options.gutters[i];
- signalfn(cm, type, cm, line, gutter, e);
+ signal(cm, type, cm, line, gutter, e);
return e_defaultPrevented(e);
}
}
}
function clickInGutter(cm, e) {
- return gutterEvent(cm, e, "gutterClick", true, signalLater);
+ return gutterEvent(cm, e, "gutterClick", true);
}
// Kludge to work around strange IE behavior where it'll sometimes
@@ -2957,23 +3838,32 @@
function onDrop(e) {
var cm = this;
+ clearDragCursor(cm);
if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e))
return;
e_preventDefault(e);
if (ie) lastDrop = +new Date;
var pos = posFromMouse(cm, e, true), files = e.dataTransfer.files;
- if (!pos || isReadOnly(cm)) return;
+ if (!pos || cm.isReadOnly()) return;
// Might be a file drop, in which case we simply extract the text
// and insert it.
if (files && files.length && window.FileReader && window.File) {
var n = files.length, text = Array(n), read = 0;
var loadFile = function(file, i) {
+ if (cm.options.allowDropFileTypes &&
+ indexOf(cm.options.allowDropFileTypes, file.type) == -1)
+ return;
+
var reader = new FileReader;
reader.onload = operation(cm, function() {
- text[i] = reader.result;
+ var content = reader.result;
+ if (/[\x00-\x08\x0e-\x1f]{2}/.test(content)) content = "";
+ text[i] = content;
if (++read == n) {
pos = clipPos(cm.doc, pos);
- var change = {from: pos, to: pos, text: splitLines(text.join("\n")), origin: "paste"};
+ var change = {from: pos, to: pos,
+ text: cm.doc.splitLines(text.join(cm.doc.lineSeparator())),
+ origin: "paste"};
makeChange(cm.doc, change);
setSelectionReplaceHistory(cm.doc, simpleSelection(pos, changeEnd(change)));
}
@@ -2986,19 +3876,19 @@
if (cm.state.draggingText && cm.doc.sel.contains(pos) > -1) {
cm.state.draggingText(e);
// Ensure the editor is re-focused
- setTimeout(bind(focusInput, cm), 20);
+ setTimeout(function() {cm.display.input.focus();}, 20);
return;
}
try {
var text = e.dataTransfer.getData("Text");
if (text) {
- if (cm.state.draggingText && !(mac ? e.metaKey : e.ctrlKey))
+ if (cm.state.draggingText && !(mac ? e.altKey : e.ctrlKey))
var selected = cm.listSelections();
setSelectionNoUndo(cm.doc, simpleSelection(pos, pos));
if (selected) for (var i = 0; i < selected.length; ++i)
replaceRange(cm.doc, "", selected[i].anchor, selected[i].head, "drag");
cm.replaceSelection(text, "around", "paste");
- focusInput(cm);
+ cm.display.input.focus();
}
}
catch(e){}
@@ -3027,6 +3917,25 @@
}
}
+ function onDragOver(cm, e) {
+ var pos = posFromMouse(cm, e);
+ if (!pos) return;
+ var frag = document.createDocumentFragment();
+ drawSelectionCursor(cm, pos, frag);
+ if (!cm.display.dragCursor) {
+ cm.display.dragCursor = elt("div", null, "CodeMirror-cursors CodeMirror-dragcursors");
+ cm.display.lineSpace.insertBefore(cm.display.dragCursor, cm.display.cursorDiv);
+ }
+ removeChildrenAndAdd(cm.display.dragCursor, frag);
+ }
+
+ function clearDragCursor(cm) {
+ if (cm.display.dragCursor) {
+ cm.display.lineSpace.removeChild(cm.display.dragCursor);
+ cm.display.dragCursor = null;
+ }
+ }
+
// SCROLL EVENTS
// Sync the scrollable area and scrollbars, ensure the viewport
@@ -3036,7 +3945,7 @@
cm.doc.scrollTop = val;
if (!gecko) updateDisplaySimple(cm, {top: val});
if (cm.display.scroller.scrollTop != val) cm.display.scroller.scrollTop = val;
- if (cm.display.scrollbarV.scrollTop != val) cm.display.scrollbarV.scrollTop = val;
+ cm.display.scrollbars.setScrollTop(val);
if (gecko) updateDisplaySimple(cm);
startWorker(cm, 100);
}
@@ -3048,7 +3957,7 @@
cm.doc.scrollLeft = val;
alignHorizontally(cm);
if (cm.display.scroller.scrollLeft != val) cm.display.scroller.scrollLeft = val;
- if (cm.display.scrollbarH.scrollLeft != val) cm.display.scrollbarH.scrollLeft = val;
+ cm.display.scrollbars.setScrollLeft(val);
}
// Since the delta values reported on mouse wheel events are
@@ -3072,16 +3981,28 @@
else if (chrome) wheelPixelsPerUnit = -.7;
else if (safari) wheelPixelsPerUnit = -1/3;
- function onScrollWheel(cm, e) {
+ var wheelEventDelta = function(e) {
var dx = e.wheelDeltaX, dy = e.wheelDeltaY;
if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) dx = e.detail;
if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) dy = e.detail;
else if (dy == null) dy = e.wheelDelta;
+ return {x: dx, y: dy};
+ };
+ CodeMirror.wheelEventPixels = function(e) {
+ var delta = wheelEventDelta(e);
+ delta.x *= wheelPixelsPerUnit;
+ delta.y *= wheelPixelsPerUnit;
+ return delta;
+ };
+
+ function onScrollWheel(cm, e) {
+ var delta = wheelEventDelta(e), dx = delta.x, dy = delta.y;
var display = cm.display, scroll = display.scroller;
// Quit if there's nothing to scroll here
- if (!(dx && scroll.scrollWidth > scroll.clientWidth ||
- dy && scroll.scrollHeight > scroll.clientHeight)) return;
+ var canScrollX = scroll.scrollWidth > scroll.clientWidth;
+ var canScrollY = scroll.scrollHeight > scroll.clientHeight;
+ if (!(dx && canScrollX || dy && canScrollY)) return;
// Webkit browsers on OS X abort momentum scrolls when the target
// of the scroll event is removed from the scrollable element.
@@ -3105,10 +4026,15 @@
// scrolling entirely here. It'll be slightly off from native, but
// better than glitching out.
if (dx && !gecko && !presto && wheelPixelsPerUnit != null) {
- if (dy)
+ if (dy && canScrollY)
setScrollTop(cm, Math.max(0, Math.min(scroll.scrollTop + dy * wheelPixelsPerUnit, scroll.scrollHeight - scroll.clientHeight)));
setScrollLeft(cm, Math.max(0, Math.min(scroll.scrollLeft + dx * wheelPixelsPerUnit, scroll.scrollWidth - scroll.clientWidth)));
- e_preventDefault(e);
+ // Only prevent default scrolling if vertical scrolling is
+ // actually possible. Otherwise, it causes vertical scroll
+ // jitter on OSX trackpads when deltaX is small and deltaY
+ // is large (issue #3579)
+ if (!dy || (dy && canScrollY))
+ e_preventDefault(e);
display.wheelStartX = null; // Abort measurement, if in progress
return;
}
@@ -3154,10 +4080,10 @@
}
// Ensure previous input has been read, so that the handler sees a
// consistent view of the document
- if (cm.display.pollingFast && readInput(cm)) cm.display.pollingFast = false;
+ cm.display.input.ensurePolled();
var prevShift = cm.display.shift, done = false;
try {
- if (isReadOnly(cm)) cm.state.suppressEdits = true;
+ if (cm.isReadOnly()) cm.state.suppressEdits = true;
if (dropShift) cm.display.shift = false;
done = bound(cm) != Pass;
} finally {
@@ -3167,68 +4093,76 @@
return done;
}
- // Collect the currently active keymaps.
- function allKeyMaps(cm) {
- var maps = cm.state.keyMaps.slice(0);
- if (cm.options.extraKeys) maps.push(cm.options.extraKeys);
- maps.push(cm.options.keyMap);
- return maps;
+ function lookupKeyForEditor(cm, name, handle) {
+ for (var i = 0; i < cm.state.keyMaps.length; i++) {
+ var result = lookupKey(name, cm.state.keyMaps[i], handle, cm);
+ if (result) return result;
+ }
+ return (cm.options.extraKeys && lookupKey(name, cm.options.extraKeys, handle, cm))
+ || lookupKey(name, cm.options.keyMap, handle, cm);
+ }
+
+ var stopSeq = new Delayed;
+ function dispatchKey(cm, name, e, handle) {
+ var seq = cm.state.keySeq;
+ if (seq) {
+ if (isModifierKey(name)) return "handled";
+ stopSeq.set(50, function() {
+ if (cm.state.keySeq == seq) {
+ cm.state.keySeq = null;
+ cm.display.input.reset();
+ }
+ });
+ name = seq + " " + name;
+ }
+ var result = lookupKeyForEditor(cm, name, handle);
+
+ if (result == "multi")
+ cm.state.keySeq = name;
+ if (result == "handled")
+ signalLater(cm, "keyHandled", cm, name, e);
+
+ if (result == "handled" || result == "multi") {
+ e_preventDefault(e);
+ restartBlink(cm);
+ }
+
+ if (seq && !result && /\'$/.test(name)) {
+ e_preventDefault(e);
+ return true;
+ }
+ return !!result;
}
- var maybeTransition;
// Handle a key from the keydown event.
function handleKeyBinding(cm, e) {
- // Handle automatic keymap transitions
- var startMap = getKeyMap(cm.options.keyMap), next = startMap.auto;
- clearTimeout(maybeTransition);
- if (next && !isModifierKey(e)) maybeTransition = setTimeout(function() {
- if (getKeyMap(cm.options.keyMap) == startMap) {
- cm.options.keyMap = (next.call ? next.call(null, cm) : next);
- keyMapChanged(cm);
- }
- }, 50);
-
- var name = keyName(e, true), handled = false;
+ var name = keyName(e, true);
if (!name) return false;
- var keymaps = allKeyMaps(cm);
- if (e.shiftKey) {
+ if (e.shiftKey && !cm.state.keySeq) {
// First try to resolve full name (including 'Shift-'). Failing
// that, see if there is a cursor-motion command (starting with
// 'go') bound to the keyname without 'Shift-'.
- handled = lookupKey("Shift-" + name, keymaps, function(b) {return doHandleBinding(cm, b, true);})
- || lookupKey(name, keymaps, function(b) {
- if (typeof b == "string" ? /^go[A-Z]/.test(b) : b.motion)
- return doHandleBinding(cm, b);
- });
+ return dispatchKey(cm, "Shift-" + name, e, function(b) {return doHandleBinding(cm, b, true);})
+ || dispatchKey(cm, name, e, function(b) {
+ if (typeof b == "string" ? /^go[A-Z]/.test(b) : b.motion)
+ return doHandleBinding(cm, b);
+ });
} else {
- handled = lookupKey(name, keymaps, function(b) { return doHandleBinding(cm, b); });
+ return dispatchKey(cm, name, e, function(b) { return doHandleBinding(cm, b); });
}
-
- if (handled) {
- e_preventDefault(e);
- restartBlink(cm);
- signalLater(cm, "keyHandled", cm, name, e);
- }
- return handled;
}
// Handle a key from the keypress event
function handleCharBinding(cm, e, ch) {
- var handled = lookupKey("'" + ch + "'", allKeyMaps(cm),
- function(b) { return doHandleBinding(cm, b, true); });
- if (handled) {
- e_preventDefault(e);
- restartBlink(cm);
- signalLater(cm, "keyHandled", cm, "'" + ch + "'", e);
- }
- return handled;
+ return dispatchKey(cm, "'" + ch + "'", e,
+ function(b) { return doHandleBinding(cm, b, true); });
}
var lastStoppedKey = null;
function onKeyDown(e) {
var cm = this;
- ensureFocus(cm);
+ cm.curOp.focus = activeElt();
if (signalDOMEvent(cm, e)) return;
// IE does strange things with escape.
if (ie && ie_version < 11 && e.keyCode == 27) e.returnValue = false;
@@ -3269,36 +4203,49 @@
function onKeyPress(e) {
var cm = this;
- if (signalDOMEvent(cm, e) || e.ctrlKey && !e.altKey || mac && e.metaKey) return;
+ if (eventInWidget(cm.display, e) || signalDOMEvent(cm, e) || e.ctrlKey && !e.altKey || mac && e.metaKey) return;
var keyCode = e.keyCode, charCode = e.charCode;
if (presto && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return;}
- if (((presto && (!e.which || e.which < 10)) || khtml) && handleKeyBinding(cm, e)) return;
+ if ((presto && (!e.which || e.which < 10)) && handleKeyBinding(cm, e)) return;
var ch = String.fromCharCode(charCode == null ? keyCode : charCode);
if (handleCharBinding(cm, e, ch)) return;
- if (ie && ie_version >= 9) cm.display.inputHasSelection = null;
- fastPoll(cm);
+ cm.display.input.onKeyPress(e);
}
// FOCUS/BLUR EVENTS
+ function delayBlurEvent(cm) {
+ cm.state.delayingBlurEvent = true;
+ setTimeout(function() {
+ if (cm.state.delayingBlurEvent) {
+ cm.state.delayingBlurEvent = false;
+ onBlur(cm);
+ }
+ }, 100);
+ }
+
function onFocus(cm) {
+ if (cm.state.delayingBlurEvent) cm.state.delayingBlurEvent = false;
+
if (cm.options.readOnly == "nocursor") return;
if (!cm.state.focused) {
signal(cm, "focus", cm);
cm.state.focused = true;
addClass(cm.display.wrapper, "CodeMirror-focused");
- // The prevInput test prevents this from firing when a context
- // menu is closed (since the resetInput would kill the
+ // This test prevents this from firing when a context
+ // menu is closed (since the input reset would kill the
// select-all detection hack)
if (!cm.curOp && cm.display.selForContextMenu != cm.doc.sel) {
- resetInput(cm);
- if (webkit) setTimeout(bind(resetInput, cm, true), 0); // Issue #1730
+ cm.display.input.reset();
+ if (webkit) setTimeout(function() { cm.display.input.reset(true); }, 20); // Issue #1730
}
+ cm.display.input.receivedFocus();
}
- slowPoll(cm);
restartBlink(cm);
}
function onBlur(cm) {
+ if (cm.state.delayingBlurEvent) return;
+
if (cm.state.focused) {
signal(cm, "blur", cm);
cm.state.focused = false;
@@ -3314,83 +4261,14 @@
// textarea (making it as unobtrusive as possible) to let the
// right-click take effect on it.
function onContextMenu(cm, e) {
+ if (eventInWidget(cm.display, e) || contextMenuInGutter(cm, e)) return;
if (signalDOMEvent(cm, e, "contextmenu")) return;
- var display = cm.display;
- if (eventInWidget(display, e) || contextMenuInGutter(cm, e)) return;
-
- var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop;
- if (!pos || presto) return; // Opera is difficult.
-
- // Reset the current text selection only if the click is done outside of the selection
- // and 'resetSelectionOnContextMenu' option is true.
- var reset = cm.options.resetSelectionOnContextMenu;
- if (reset && cm.doc.sel.contains(pos) == -1)
- operation(cm, setSelection)(cm.doc, simpleSelection(pos), sel_dontScroll);
-
- var oldCSS = display.input.style.cssText;
- display.inputDiv.style.position = "absolute";
- display.input.style.cssText = "position: fixed; width: 30px; height: 30px; top: " + (e.clientY - 5) +
- "px; left: " + (e.clientX - 5) + "px; z-index: 1000; background: " +
- (ie ? "rgba(255, 255, 255, .05)" : "transparent") +
- "; outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);";
- if (webkit) var oldScrollY = window.scrollY; // Work around Chrome issue (#2712)
- focusInput(cm);
- if (webkit) window.scrollTo(null, oldScrollY);
- resetInput(cm);
- // Adds "Select all" to context menu in FF
- if (!cm.somethingSelected()) display.input.value = display.prevInput = " ";
- display.selForContextMenu = cm.doc.sel;
- clearTimeout(display.detectingSelectAll);
-
- // Select-all will be greyed out if there's nothing to select, so
- // this adds a zero-width space so that we can later check whether
- // it got selected.
- function prepareSelectAllHack() {
- if (display.input.selectionStart != null) {
- var selected = cm.somethingSelected();
- var extval = display.input.value = "\u200b" + (selected ? display.input.value : "");
- display.prevInput = selected ? "" : "\u200b";
- display.input.selectionStart = 1; display.input.selectionEnd = extval.length;
- // Re-set this, in case some other handler touched the
- // selection in the meantime.
- display.selForContextMenu = cm.doc.sel;
- }
- }
- function rehide() {
- display.inputDiv.style.position = "relative";
- display.input.style.cssText = oldCSS;
- if (ie && ie_version < 9) display.scrollbarV.scrollTop = display.scroller.scrollTop = scrollPos;
- slowPoll(cm);
-
- // Try to detect the user choosing select-all
- if (display.input.selectionStart != null) {
- if (!ie || (ie && ie_version < 9)) prepareSelectAllHack();
- var i = 0, poll = function() {
- if (display.selForContextMenu == cm.doc.sel && display.input.selectionStart == 0)
- operation(cm, commands.selectAll)(cm);
- else if (i++ < 10) display.detectingSelectAll = setTimeout(poll, 500);
- else resetInput(cm);
- };
- display.detectingSelectAll = setTimeout(poll, 200);
- }
- }
-
- if (ie && ie_version >= 9) prepareSelectAllHack();
- if (captureRightClick) {
- e_stop(e);
- var mouseup = function() {
- off(window, "mouseup", mouseup);
- setTimeout(rehide, 20);
- };
- on(window, "mouseup", mouseup);
- } else {
- setTimeout(rehide, 50);
- }
+ cm.display.input.onContextMenu(e);
}
function contextMenuInGutter(cm, e) {
if (!hasHandler(cm, "gutterContextMenu")) return false;
- return gutterEvent(cm, e, "gutterContextMenu", false, signal);
+ return gutterEvent(cm, e, "gutterContextMenu", false);
}
// UPDATING
@@ -3670,7 +4548,9 @@
var lendiff = change.text.length - (to.line - from.line) - 1;
// Remember that these lines changed, for updating the display
- if (from.line == to.line && change.text.length == 1 && !isWholeLineUpdate(cm.doc, change))
+ if (change.full)
+ regChange(cm);
+ else if (from.line == to.line && change.text.length == 1 && !isWholeLineUpdate(cm.doc, change))
regLineChange(cm, from.line, "text");
else
regChange(cm, from.line, to.line + 1, lendiff);
@@ -3692,7 +4572,7 @@
function replaceRange(doc, code, from, to, origin) {
if (!to) to = from;
if (cmp(to, from) < 0) { var tmp = to; to = from; from = tmp; }
- if (typeof code == "string") code = splitLines(code);
+ if (typeof code == "string") code = doc.splitLines(code);
makeChange(doc, {from: from, to: to, text: code, origin: origin});
}
@@ -3701,13 +4581,15 @@
// If an editor sits on the top or bottom of the window, partially
// scrolled out of view, this ensures that the cursor is visible.
function maybeScrollWindow(cm, coords) {
+ if (signalDOMEvent(cm, "scrollCursorIntoView")) return;
+
var display = cm.display, box = display.sizer.getBoundingClientRect(), doScroll = null;
if (coords.top + box.top < 0) doScroll = true;
else if (coords.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) doScroll = false;
if (doScroll != null && !phantom) {
var scrollNode = elt("div", "\u200b", null, "position: absolute; top: " +
(coords.top - display.viewOffset - paddingTop(cm.display)) + "px; height: " +
- (coords.bottom - coords.top + scrollerCutOff) + "px; left: " +
+ (coords.bottom - coords.top + scrollGap(cm) + display.barHeight) + "px; left: " +
coords.left + "px; width: 2px;");
cm.display.lineSpace.appendChild(scrollNode);
scrollNode.scrollIntoView(doScroll);
@@ -3720,7 +4602,7 @@
// measured, the position of something may 'drift' during drawing).
function scrollPosIntoView(cm, pos, end, margin) {
if (margin == null) margin = 0;
- for (;;) {
+ for (var limit = 0; limit < 5; limit++) {
var changed = false, coords = cursorCoords(cm, pos);
var endCoords = !end || end == pos ? coords : cursorCoords(cm, end);
var scrollPos = calculateScrollPos(cm, Math.min(coords.left, endCoords.left),
@@ -3736,8 +4618,9 @@
setScrollLeft(cm, scrollPos.scrollLeft);
if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) changed = true;
}
- if (!changed) return coords;
+ if (!changed) break;
}
+ return coords;
}
// Scroll a given set of coordinates into view (immediately).
@@ -3755,7 +4638,7 @@
var display = cm.display, snapMargin = textHeight(cm.display);
if (y1 < 0) y1 = 0;
var screentop = cm.curOp && cm.curOp.scrollTop != null ? cm.curOp.scrollTop : display.scroller.scrollTop;
- var screen = display.scroller.clientHeight - scrollerCutOff, result = {};
+ var screen = displayHeight(cm), result = {};
if (y2 - y1 > screen) y2 = y1 + screen;
var docBottom = cm.doc.height + paddingVert(display);
var atTop = y1 < snapMargin, atBottom = y2 > docBottom - snapMargin;
@@ -3767,16 +4650,15 @@
}
var screenleft = cm.curOp && cm.curOp.scrollLeft != null ? cm.curOp.scrollLeft : display.scroller.scrollLeft;
- var screenw = display.scroller.clientWidth - scrollerCutOff - display.gutters.offsetWidth;
+ var screenw = displayWidth(cm) - (cm.options.fixedGutter ? display.gutters.offsetWidth : 0);
var tooWide = x2 - x1 > screenw;
- if (tooWide) x2 = y1 + screen;
+ if (tooWide) x2 = x1 + screenw;
if (x1 < 10)
result.scrollLeft = 0;
else if (x1 < screenleft)
result.scrollLeft = Math.max(0, x1 - (tooWide ? 0 : 10));
else if (x2 > screenw + screenleft - 3)
result.scrollLeft = x2 + (tooWide ? 0 : 10) - screenw;
-
return result;
}
@@ -3869,6 +4751,8 @@
if (indentString != curSpaceString) {
replaceRange(doc, indentString, Pos(n, 0), Pos(n, curSpaceString.length), "+input");
+ line.stateAfter = null;
+ return true;
} else {
// Ensure that, if the cursor was in the whitespace at the start
// of the line, it is moved to the end of that space.
@@ -3881,7 +4765,6 @@
}
}
}
- line.stateAfter = null;
}
// Utility for applying a change to a line by handle or number,
@@ -3933,10 +4816,9 @@
function findPosH(doc, pos, dir, unit, visually) {
var line = pos.line, ch = pos.ch, origDir = dir;
var lineObj = getLine(doc, line);
- var possible = true;
function findNextLine() {
var l = line + dir;
- if (l < doc.first || l >= doc.first + doc.size) return (possible = false);
+ if (l < doc.first || l >= doc.first + doc.size) return false
line = l;
return lineObj = getLine(doc, l);
}
@@ -3946,14 +4828,16 @@
if (!boundToLine && findNextLine()) {
if (visually) ch = (dir < 0 ? lineRight : lineLeft)(lineObj);
else ch = dir < 0 ? lineObj.text.length : 0;
- } else return (possible = false);
+ } else return false
} else ch = next;
return true;
}
- if (unit == "char") moveOnce();
- else if (unit == "column") moveOnce(true);
- else if (unit == "word" || unit == "group") {
+ if (unit == "char") {
+ moveOnce()
+ } else if (unit == "column") {
+ moveOnce(true)
+ } else if (unit == "word" || unit == "group") {
var sawType = null, group = unit == "group";
var helper = doc.cm && doc.cm.getHelper(pos, "wordChars");
for (var first = true;; first = false) {
@@ -3973,8 +4857,8 @@
if (dir > 0 && !moveOnce(!first)) break;
}
}
- var result = skipAtomic(doc, Pos(line, ch), origDir, true);
- if (!possible) result.hitSide = true;
+ var result = skipAtomic(doc, Pos(line, ch), pos, origDir, true);
+ if (!cmp(pos, result)) result.hitSide = true;
return result;
}
@@ -4010,7 +4894,7 @@
CodeMirror.prototype = {
constructor: CodeMirror,
- focus: function(){window.focus(); focusInput(this); fastPoll(this);},
+ focus: function(){window.focus(); this.display.input.focus();},
setOption: function(option, value) {
var options = this.options, old = options[option];
@@ -4024,12 +4908,12 @@
getDoc: function() {return this.doc;},
addKeyMap: function(map, bottom) {
- this.state.keyMaps[bottom ? "push" : "unshift"](map);
+ this.state.keyMaps[bottom ? "push" : "unshift"](getKeyMap(map));
},
removeKeyMap: function(map) {
var maps = this.state.keyMaps;
for (var i = 0; i < maps.length; ++i)
- if (maps[i] == map || (typeof maps[i] != "string" && maps[i].name == map)) {
+ if (maps[i] == map || maps[i].name == map) {
maps.splice(i, 1);
return true;
}
@@ -4086,20 +4970,11 @@
// Fetch the parser token for a given character. Useful for hacks
// that want to inspect the mode state (say, for completion).
getTokenAt: function(pos, precise) {
- var doc = this.doc;
- pos = clipPos(doc, pos);
- var state = getStateBefore(this, pos.line, precise), mode = this.doc.mode;
- var line = getLine(doc, pos.line);
- var stream = new StringStream(line.text, this.options.tabSize);
- while (stream.pos < pos.ch && !stream.eol()) {
- stream.start = stream.pos;
- var style = readToken(mode, stream, state);
- }
- return {start: stream.start,
- end: stream.pos,
- string: stream.current(),
- type: style || null,
- state: state};
+ return takeToken(this, pos, precise);
+ },
+
+ getLineTokens: function(line, precise) {
+ return takeToken(this, Pos(line), precise, true);
},
getTokenTypeAt: function(pos) {
@@ -4130,7 +5005,7 @@
getHelpers: function(pos, type) {
var found = [];
- if (!helpers.hasOwnProperty(type)) return helpers;
+ if (!helpers.hasOwnProperty(type)) return found;
var help = helpers[type], mode = this.getModeAt(pos);
if (typeof mode[type] == "string") {
if (help[mode[type]]) found.push(help[mode[type]]);
@@ -4180,10 +5055,15 @@
return lineAtHeight(this.doc, height + this.display.viewOffset);
},
heightAtLine: function(line, mode) {
- var end = false, last = this.doc.first + this.doc.size - 1;
- if (line < this.doc.first) line = this.doc.first;
- else if (line > last) { line = last; end = true; }
- var lineObj = getLine(this.doc, line);
+ var end = false, lineObj;
+ if (typeof line == "number") {
+ var last = this.doc.first + this.doc.size - 1;
+ if (line < this.doc.first) line = this.doc.first;
+ else if (line > last) { line = last; end = true; }
+ lineObj = getLine(this.doc, line);
+ } else {
+ lineObj = line;
+ }
return intoCoordSystem(this, lineObj, {top: 0, left: 0}, mode || "page").top +
(end ? this.doc.height - heightAtLine(lineObj) : 0);
},
@@ -4212,12 +5092,6 @@
});
}),
- addLineWidget: methodOp(function(handle, node, options) {
- return addLineWidget(this, handle, node, options);
- }),
-
- removeLineWidget: function(widget) { widget.clear(); },
-
lineInfo: function(line) {
if (typeof line == "number") {
if (!isLine(this.doc, line)) return null;
@@ -4240,6 +5114,8 @@
pos = cursorCoords(this, clipPos(this.doc, pos));
var top = pos.bottom, left = pos.left;
node.style.position = "absolute";
+ node.setAttribute("cm-ignore-events", "true");
+ this.display.input.setUneditable(node);
display.sizer.appendChild(node);
if (vert == "over") {
top = pos.top;
@@ -4274,9 +5150,11 @@
execCommand: function(cmd) {
if (commands.hasOwnProperty(cmd))
- return commands[cmd](this);
+ return commands[cmd].call(null, this);
},
+ triggerElectric: methodOp(function(text) { triggerElectric(this, text); }),
+
findPosH: function(from, amount, unit, visually) {
var dir = 1;
if (amount < 0) { dir = -1; amount = -amount; }
@@ -4366,7 +5244,8 @@
signal(this, "overwriteToggle", this, this.state.overwrite);
},
- hasFocus: function() { return activeElt() == this.display.input; },
+ hasFocus: function() { return this.display.input.getField() == activeElt(); },
+ isReadOnly: function() { return !!(this.options.readOnly || this.doc.cantEdit); },
scrollTo: methodOp(function(x, y) {
if (x != null || y != null) resolveScrollToPos(this);
@@ -4374,10 +5253,11 @@
if (y != null) this.curOp.scrollTop = y;
}),
getScrollInfo: function() {
- var scroller = this.display.scroller, co = scrollerCutOff;
+ var scroller = this.display.scroller;
return {left: scroller.scrollLeft, top: scroller.scrollTop,
- height: scroller.scrollHeight - co, width: scroller.scrollWidth - co,
- clientHeight: scroller.clientHeight - co, clientWidth: scroller.clientWidth - co};
+ height: scroller.scrollHeight - scrollGap(this) - this.display.barHeight,
+ width: scroller.scrollWidth - scrollGap(this) - this.display.barWidth,
+ clientHeight: displayHeight(this), clientWidth: displayWidth(this)};
},
scrollIntoView: methodOp(function(range, margin) {
@@ -4441,14 +5321,14 @@
old.cm = null;
attachDoc(this, doc);
clearCaches(this);
- resetInput(this);
+ this.display.input.reset();
this.scrollTo(doc.scrollLeft, doc.scrollTop);
this.curOp.forceScroll = true;
signalLater(this, "swapDoc", this, old);
return old;
}),
- getInputField: function(){return this.display.input;},
+ getInputField: function(){return this.display.input.getField();},
getWrapperElement: function(){return this.display.wrapper;},
getScrollerElement: function(){return this.display.scroller;},
getGutterElement: function(){return this.display.gutters;}
@@ -4489,12 +5369,31 @@
clearCaches(cm);
regChange(cm);
}, true);
- option("specialChars", /[\t\u0000-\u0019\u00ad\u200b-\u200f\u2028\u2029\ufeff]/g, function(cm, val) {
- cm.options.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g");
- cm.refresh();
- }, true);
+ option("lineSeparator", null, function(cm, val) {
+ cm.doc.lineSep = val;
+ if (!val) return;
+ var newBreaks = [], lineNo = cm.doc.first;
+ cm.doc.iter(function(line) {
+ for (var pos = 0;;) {
+ var found = line.text.indexOf(val, pos);
+ if (found == -1) break;
+ pos = found + val.length;
+ newBreaks.push(Pos(lineNo, found));
+ }
+ lineNo++;
+ });
+ for (var i = newBreaks.length - 1; i >= 0; i--)
+ replaceRange(cm.doc, val, newBreaks[i], Pos(newBreaks[i].line, newBreaks[i].ch + val.length))
+ });
+ option("specialChars", /[\t\u0000-\u0019\u00ad\u200b-\u200f\u2028\u2029\ufeff]/g, function(cm, val, old) {
+ cm.state.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g");
+ if (old != CodeMirror.Init) cm.refresh();
+ });
option("specialCharPlaceholder", defaultSpecialCharPlaceholder, function(cm) {cm.refresh();}, true);
option("electricChars", true);
+ option("inputStyle", mobile ? "contenteditable" : "textarea", function() {
+ throw new Error("inputStyle can not (yet) be changed in a running editor"); // FIXME
+ }, true);
option("rtlMoveVisually", !windows);
option("wholeLineUpdateBefore", true);
@@ -4502,7 +5401,12 @@
themeChanged(cm);
guttersChanged(cm);
}, true);
- option("keyMap", "default", keyMapChanged);
+ option("keyMap", "default", function(cm, val, old) {
+ var next = getKeyMap(val);
+ var prev = old != CodeMirror.Init && getKeyMap(old);
+ if (prev && prev.detach) prev.detach(cm, next);
+ if (next.attach) next.attach(cm, prev || null);
+ });
option("extraKeys", null);
option("lineWrapping", false, wrappingChanged, true);
@@ -4514,7 +5418,13 @@
cm.display.gutters.style.left = val ? compensateForHScroll(cm.display) + "px" : "0";
cm.refresh();
}, true);
- option("coverGutterNextToScrollbar", false, updateScrollbars, true);
+ option("coverGutterNextToScrollbar", false, function(cm) {updateScrollbars(cm);}, true);
+ option("scrollbarStyle", "native", function(cm) {
+ initScrollbars(cm);
+ updateScrollbars(cm);
+ cm.display.scrollbars.setScrollTop(cm.doc.scrollTop);
+ cm.display.scrollbars.setScrollLeft(cm.doc.scrollLeft);
+ }, true);
option("lineNumbers", false, function(cm) {
setGuttersForLineNumbers(cm.options);
guttersChanged(cm);
@@ -4524,6 +5434,7 @@
option("showCursorWhenSelecting", false, updateSelection, true);
option("resetSelectionOnContextMenu", true);
+ option("lineWiseCopyCut", true);
option("readOnly", false, function(cm, val) {
if (val == "nocursor") {
@@ -4532,11 +5443,12 @@
cm.display.disabled = true;
} else {
cm.display.disabled = false;
- if (!val) resetInput(cm);
}
+ cm.display.input.readOnlyChanged(val)
});
- option("disableInput", false, function(cm, val) {if (!val) resetInput(cm);}, true);
- option("dragDrop", true);
+ option("disableInput", false, function(cm, val) {if (!val) cm.display.input.reset();}, true);
+ option("dragDrop", true, dragDropChanged);
+ option("allowDropFileTypes", null);
option("cursorBlinkRate", 530);
option("cursorScrollMargin", 0);
@@ -4552,11 +5464,11 @@
option("viewportMargin", 10, function(cm){cm.refresh();}, true);
option("maxHighlightLength", 10000, resetModeState, true);
option("moveInputWithCursor", true, function(cm, val) {
- if (!val) cm.display.inputDiv.style.top = cm.display.inputDiv.style.left = 0;
+ if (!val) cm.display.input.resetPosition();
});
option("tabindex", null, function(cm, val) {
- cm.display.input.tabIndex = val || "";
+ cm.display.input.getField().tabIndex = val || "";
});
option("autofocus", null);
@@ -4570,10 +5482,8 @@
// load a mode. (Preferred mechanism is the require/define calls.)
CodeMirror.defineMode = function(name, mode) {
if (!CodeMirror.defaults.mode && name != "null") CodeMirror.defaults.mode = name;
- if (arguments.length > 2) {
- mode.dependencies = [];
- for (var i = 2; i < arguments.length; ++i) mode.dependencies.push(arguments[i]);
- }
+ if (arguments.length > 2)
+ mode.dependencies = Array.prototype.slice.call(arguments, 2);
modes[name] = mode;
};
@@ -4826,7 +5736,8 @@
} else if (cur.line > cm.doc.first) {
var prev = getLine(cm.doc, cur.line - 1).text;
if (prev)
- cm.replaceRange(line.charAt(0) + "\n" + prev.charAt(prev.length - 1),
+ cm.replaceRange(line.charAt(0) + cm.doc.lineSeparator() +
+ prev.charAt(prev.length - 1),
Pos(cur.line - 1, prev.length - 1), Pos(cur.line, 1), "+transpose");
}
}
@@ -4840,18 +5751,20 @@
var len = cm.listSelections().length;
for (var i = 0; i < len; i++) {
var range = cm.listSelections()[i];
- cm.replaceRange("\n", range.anchor, range.head, "+input");
+ cm.replaceRange(cm.doc.lineSeparator(), range.anchor, range.head, "+input");
cm.indentLine(range.from().line + 1, null, true);
- ensureCursorVisible(cm);
}
+ ensureCursorVisible(cm);
});
},
toggleOverwrite: function(cm) {cm.toggleOverwrite();}
};
+
// STANDARD KEYMAPS
var keyMap = CodeMirror.keyMap = {};
+
keyMap.basic = {
"Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown",
"End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown",
@@ -4865,7 +5778,7 @@
// are simply ignored.
keyMap.pcDefault = {
"Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo",
- "Ctrl-Home": "goDocStart", "Ctrl-Up": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Down": "goDocEnd",
+ "Ctrl-Home": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Up": "goLineUp", "Ctrl-Down": "goLineDown",
"Ctrl-Left": "goGroupLeft", "Ctrl-Right": "goGroupRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd",
"Ctrl-Backspace": "delGroupBefore", "Ctrl-Delete": "delGroupAfter", "Ctrl-S": "save", "Ctrl-F": "find",
"Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll",
@@ -4873,16 +5786,6 @@
"Ctrl-U": "undoSelection", "Shift-Ctrl-U": "redoSelection", "Alt-U": "redoSelection",
fallthrough: "basic"
};
- keyMap.macDefault = {
- "Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo",
- "Cmd-Home": "goDocStart", "Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goGroupLeft",
- "Alt-Right": "goGroupRight", "Cmd-Left": "goLineLeft", "Cmd-Right": "goLineRight", "Alt-Backspace": "delGroupBefore",
- "Ctrl-Alt-Backspace": "delGroupAfter", "Alt-Delete": "delGroupAfter", "Cmd-S": "save", "Cmd-F": "find",
- "Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll",
- "Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delWrappedLineLeft", "Cmd-Delete": "delWrappedLineRight",
- "Cmd-U": "undoSelection", "Shift-Cmd-U": "redoSelection",
- fallthrough: ["basic", "emacsy"]
- };
// Very basic readline/emacs-style bindings, which are standard on Mac.
keyMap.emacsy = {
"Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown",
@@ -4890,70 +5793,117 @@
"Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp", "Ctrl-D": "delCharAfter", "Ctrl-H": "delCharBefore",
"Alt-D": "delWordAfter", "Alt-Backspace": "delWordBefore", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars"
};
+ keyMap.macDefault = {
+ "Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo",
+ "Cmd-Home": "goDocStart", "Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goGroupLeft",
+ "Alt-Right": "goGroupRight", "Cmd-Left": "goLineLeft", "Cmd-Right": "goLineRight", "Alt-Backspace": "delGroupBefore",
+ "Ctrl-Alt-Backspace": "delGroupAfter", "Alt-Delete": "delGroupAfter", "Cmd-S": "save", "Cmd-F": "find",
+ "Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll",
+ "Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delWrappedLineLeft", "Cmd-Delete": "delWrappedLineRight",
+ "Cmd-U": "undoSelection", "Shift-Cmd-U": "redoSelection", "Ctrl-Up": "goDocStart", "Ctrl-Down": "goDocEnd",
+ fallthrough: ["basic", "emacsy"]
+ };
keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault;
// KEYMAP DISPATCH
- function getKeyMap(val) {
- if (typeof val == "string") return keyMap[val];
- else return val;
+ function normalizeKeyName(name) {
+ var parts = name.split(/-(?!$)/), name = parts[parts.length - 1];
+ var alt, ctrl, shift, cmd;
+ for (var i = 0; i < parts.length - 1; i++) {
+ var mod = parts[i];
+ if (/^(cmd|meta|m)$/i.test(mod)) cmd = true;
+ else if (/^a(lt)?$/i.test(mod)) alt = true;
+ else if (/^(c|ctrl|control)$/i.test(mod)) ctrl = true;
+ else if (/^s(hift)$/i.test(mod)) shift = true;
+ else throw new Error("Unrecognized modifier name: " + mod);
+ }
+ if (alt) name = "Alt-" + name;
+ if (ctrl) name = "Ctrl-" + name;
+ if (cmd) name = "Cmd-" + name;
+ if (shift) name = "Shift-" + name;
+ return name;
}
- // Given an array of keymaps and a key name, call handle on any
- // bindings found, until that returns a truthy value, at which point
- // we consider the key handled. Implements things like binding a key
- // to false stopping further handling and keymap fallthrough.
- var lookupKey = CodeMirror.lookupKey = function(name, maps, handle) {
- function lookup(map) {
- map = getKeyMap(map);
- var found = map[name];
- if (found === false) return "stop";
- if (found != null && handle(found)) return true;
- if (map.nofallthrough) return "stop";
+ // This is a kludge to keep keymaps mostly working as raw objects
+ // (backwards compatibility) while at the same time support features
+ // like normalization and multi-stroke key bindings. It compiles a
+ // new normalized keymap, and then updates the old object to reflect
+ // this.
+ CodeMirror.normalizeKeyMap = function(keymap) {
+ var copy = {};
+ for (var keyname in keymap) if (keymap.hasOwnProperty(keyname)) {
+ var value = keymap[keyname];
+ if (/^(name|fallthrough|(de|at)tach)$/.test(keyname)) continue;
+ if (value == "...") { delete keymap[keyname]; continue; }
- var fallthrough = map.fallthrough;
- if (fallthrough == null) return false;
- if (Object.prototype.toString.call(fallthrough) != "[object Array]")
- return lookup(fallthrough);
- for (var i = 0; i < fallthrough.length; ++i) {
- var done = lookup(fallthrough[i]);
- if (done) return done;
+ var keys = map(keyname.split(" "), normalizeKeyName);
+ for (var i = 0; i < keys.length; i++) {
+ var val, name;
+ if (i == keys.length - 1) {
+ name = keys.join(" ");
+ val = value;
+ } else {
+ name = keys.slice(0, i + 1).join(" ");
+ val = "...";
+ }
+ var prev = copy[name];
+ if (!prev) copy[name] = val;
+ else if (prev != val) throw new Error("Inconsistent bindings for " + name);
}
- return false;
+ delete keymap[keyname];
}
+ for (var prop in copy) keymap[prop] = copy[prop];
+ return keymap;
+ };
- for (var i = 0; i < maps.length; ++i) {
- var done = lookup(maps[i]);
- if (done) return done != "stop";
+ var lookupKey = CodeMirror.lookupKey = function(key, map, handle, context) {
+ map = getKeyMap(map);
+ var found = map.call ? map.call(key, context) : map[key];
+ if (found === false) return "nothing";
+ if (found === "...") return "multi";
+ if (found != null && handle(found)) return "handled";
+
+ if (map.fallthrough) {
+ if (Object.prototype.toString.call(map.fallthrough) != "[object Array]")
+ return lookupKey(key, map.fallthrough, handle, context);
+ for (var i = 0; i < map.fallthrough.length; i++) {
+ var result = lookupKey(key, map.fallthrough[i], handle, context);
+ if (result) return result;
+ }
}
};
// Modifier key presses don't count as 'real' key presses for the
// purpose of keymap fallthrough.
- var isModifierKey = CodeMirror.isModifierKey = function(event) {
- var name = keyNames[event.keyCode];
+ var isModifierKey = CodeMirror.isModifierKey = function(value) {
+ var name = typeof value == "string" ? value : keyNames[value.keyCode];
return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod";
};
// Look up the name of a key as indicated by an event object.
var keyName = CodeMirror.keyName = function(event, noShift) {
if (presto && event.keyCode == 34 && event["char"]) return false;
- var name = keyNames[event.keyCode];
+ var base = keyNames[event.keyCode], name = base;
if (name == null || event.altGraphKey) return false;
- if (event.altKey) name = "Alt-" + name;
- if (flipCtrlCmd ? event.metaKey : event.ctrlKey) name = "Ctrl-" + name;
- if (flipCtrlCmd ? event.ctrlKey : event.metaKey) name = "Cmd-" + name;
- if (!noShift && event.shiftKey) name = "Shift-" + name;
+ if (event.altKey && base != "Alt") name = "Alt-" + name;
+ if ((flipCtrlCmd ? event.metaKey : event.ctrlKey) && base != "Ctrl") name = "Ctrl-" + name;
+ if ((flipCtrlCmd ? event.ctrlKey : event.metaKey) && base != "Cmd") name = "Cmd-" + name;
+ if (!noShift && event.shiftKey && base != "Shift") name = "Shift-" + name;
return name;
};
+ function getKeyMap(val) {
+ return typeof val == "string" ? keyMap[val] : val;
+ }
+
// FROMTEXTAREA
CodeMirror.fromTextArea = function(textarea, options) {
- if (!options) options = {};
+ options = options ? copyObj(options) : {};
options.value = textarea.value;
- if (!options.tabindex && textarea.tabindex)
- options.tabindex = textarea.tabindex;
+ if (!options.tabindex && textarea.tabIndex)
+ options.tabindex = textarea.tabIndex;
if (!options.placeholder && textarea.placeholder)
options.placeholder = textarea.placeholder;
// Set autofocus to true if this textarea is focused, or if it has
@@ -4981,22 +5931,26 @@
}
}
+ options.finishInit = function(cm) {
+ cm.save = save;
+ cm.getTextArea = function() { return textarea; };
+ cm.toTextArea = function() {
+ cm.toTextArea = isNaN; // Prevent this from being ran twice
+ save();
+ textarea.parentNode.removeChild(cm.getWrapperElement());
+ textarea.style.display = "";
+ if (textarea.form) {
+ off(textarea.form, "submit", save);
+ if (typeof textarea.form.submit == "function")
+ textarea.form.submit = realSubmit;
+ }
+ };
+ };
+
textarea.style.display = "none";
var cm = CodeMirror(function(node) {
textarea.parentNode.insertBefore(node, textarea.nextSibling);
}, options);
- cm.save = save;
- cm.getTextArea = function() { return textarea; };
- cm.toTextArea = function() {
- save();
- textarea.parentNode.removeChild(cm.getWrapperElement());
- textarea.style.display = "";
- if (textarea.form) {
- off(textarea.form, "submit", save);
- if (typeof textarea.form.submit == "function")
- textarea.form.submit = realSubmit;
- }
- };
return cm;
};
@@ -5089,10 +6043,13 @@
// marker continues beyond the start/end of the line. Markers have
// links back to the lines they currently touch.
+ var nextMarkerId = 0;
+
var TextMarker = CodeMirror.TextMarker = function(doc, type) {
this.lines = [];
this.type = type;
this.doc = doc;
+ this.id = ++nextMarkerId;
};
eventMixin(TextMarker);
@@ -5224,7 +6181,7 @@
// Showing up as a widget implies collapsed (widget replaces text)
marker.collapsed = true;
marker.widgetNode = elt("span", [marker.replacedWith], "CodeMirror-widget");
- if (!options.handleMouseEvents) marker.widgetNode.ignoreEvents = true;
+ if (!options.handleMouseEvents) marker.widgetNode.setAttribute("cm-ignore-events", "true");
if (options.insertLeft) marker.widgetNode.insertLeft = true;
}
if (marker.collapsed) {
@@ -5268,7 +6225,7 @@
if (updateMaxLine) cm.curOp.updateMaxLine = true;
if (marker.collapsed)
regChange(cm, from.line, to.line + 1);
- else if (marker.className || marker.title || marker.startStyle || marker.endStyle)
+ else if (marker.className || marker.title || marker.startStyle || marker.endStyle || marker.css)
for (var i = from.line; i <= to.line; i++) regLineChange(cm, i, "text");
if (marker.atomic) reCheckSelection(cm.doc);
signalLater(cm, "markerAdded", cm, marker);
@@ -5408,6 +6365,7 @@
// spans partially within the change. Returns an array of span
// arrays with one element for each line in (after) the change.
function stretchSpansOverChange(doc, change) {
+ if (change.full) return null;
var oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans;
var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans;
if (!oldFirst && !oldLast) return null;
@@ -5675,10 +6633,10 @@
// Line widgets are block elements displayed above or below a line.
- var LineWidget = CodeMirror.LineWidget = function(cm, node, options) {
+ var LineWidget = CodeMirror.LineWidget = function(doc, node, options) {
if (options) for (var opt in options) if (options.hasOwnProperty(opt))
this[opt] = options[opt];
- this.cm = cm;
+ this.doc = doc;
this.node = node;
};
eventMixin(LineWidget);
@@ -5689,50 +6647,55 @@
}
LineWidget.prototype.clear = function() {
- var cm = this.cm, ws = this.line.widgets, line = this.line, no = lineNo(line);
+ var cm = this.doc.cm, ws = this.line.widgets, line = this.line, no = lineNo(line);
if (no == null || !ws) return;
for (var i = 0; i < ws.length; ++i) if (ws[i] == this) ws.splice(i--, 1);
if (!ws.length) line.widgets = null;
var height = widgetHeight(this);
- runInOp(cm, function() {
+ updateLineHeight(line, Math.max(0, line.height - height));
+ if (cm) runInOp(cm, function() {
adjustScrollWhenAboveVisible(cm, line, -height);
regLineChange(cm, no, "widget");
- updateLineHeight(line, Math.max(0, line.height - height));
});
};
LineWidget.prototype.changed = function() {
- var oldH = this.height, cm = this.cm, line = this.line;
+ var oldH = this.height, cm = this.doc.cm, line = this.line;
this.height = null;
var diff = widgetHeight(this) - oldH;
if (!diff) return;
- runInOp(cm, function() {
+ updateLineHeight(line, line.height + diff);
+ if (cm) runInOp(cm, function() {
cm.curOp.forceUpdate = true;
adjustScrollWhenAboveVisible(cm, line, diff);
- updateLineHeight(line, line.height + diff);
});
};
function widgetHeight(widget) {
if (widget.height != null) return widget.height;
+ var cm = widget.doc.cm;
+ if (!cm) return 0;
if (!contains(document.body, widget.node)) {
var parentStyle = "position: relative;";
if (widget.coverGutter)
- parentStyle += "margin-left: -" + widget.cm.getGutterElement().offsetWidth + "px;";
- removeChildrenAndAdd(widget.cm.display.measure, elt("div", [widget.node], null, parentStyle));
+ parentStyle += "margin-left: -" + cm.display.gutters.offsetWidth + "px;";
+ if (widget.noHScroll)
+ parentStyle += "width: " + cm.display.wrapper.clientWidth + "px;";
+ removeChildrenAndAdd(cm.display.measure, elt("div", [widget.node], null, parentStyle));
}
- return widget.height = widget.node.offsetHeight;
+ return widget.height = widget.node.parentNode.offsetHeight;
}
- function addLineWidget(cm, handle, node, options) {
- var widget = new LineWidget(cm, node, options);
- if (widget.noHScroll) cm.display.alignWidgets = true;
- changeLine(cm.doc, handle, "widget", function(line) {
+ function addLineWidget(doc, handle, node, options) {
+ var widget = new LineWidget(doc, node, options);
+ var cm = doc.cm;
+ if (cm && widget.noHScroll) cm.display.alignWidgets = true;
+ changeLine(doc, handle, "widget", function(line) {
var widgets = line.widgets || (line.widgets = []);
if (widget.insertAt == null) widgets.push(widget);
else widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget);
widget.line = line;
- if (!lineIsHidden(cm.doc, line)) {
- var aboveVisible = heightAtLine(line) < cm.doc.scrollTop;
+ if (cm && !lineIsHidden(doc, line)) {
+ var aboveVisible = heightAtLine(line) < doc.scrollTop;
updateLineHeight(line, line.height + widgetHeight(widget));
if (aboveVisible) addToScrollPos(cm, null, widget.height);
cm.curOp.forceUpdate = true;
@@ -5795,20 +6758,44 @@
if (inner.mode.blankLine) return inner.mode.blankLine(inner.state);
}
- function readToken(mode, stream, state) {
+ function readToken(mode, stream, state, inner) {
for (var i = 0; i < 10; i++) {
+ if (inner) inner[0] = CodeMirror.innerMode(mode, state).mode;
var style = mode.token(stream, state);
if (stream.pos > stream.start) return style;
}
throw new Error("Mode " + mode.name + " failed to advance stream.");
}
+ // Utility for getTokenAt and getLineTokens
+ function takeToken(cm, pos, precise, asArray) {
+ function getObj(copy) {
+ return {start: stream.start, end: stream.pos,
+ string: stream.current(),
+ type: style || null,
+ state: copy ? copyState(doc.mode, state) : state};
+ }
+
+ var doc = cm.doc, mode = doc.mode, style;
+ pos = clipPos(doc, pos);
+ var line = getLine(doc, pos.line), state = getStateBefore(cm, pos.line, precise);
+ var stream = new StringStream(line.text, cm.options.tabSize), tokens;
+ if (asArray) tokens = [];
+ while ((asArray || stream.pos < pos.ch) && !stream.eol()) {
+ stream.start = stream.pos;
+ style = readToken(mode, stream, state);
+ if (asArray) tokens.push(getObj(true));
+ }
+ return asArray ? tokens : getObj();
+ }
+
// Run the given mode's parser over a line, calling f for each token.
function runMode(cm, text, mode, state, f, lineClasses, forceToEnd) {
var flattenSpans = mode.flattenSpans;
if (flattenSpans == null) flattenSpans = cm.options.flattenSpans;
var curStart = 0, curStyle = null;
var stream = new StringStream(text, cm.options.tabSize), style;
+ var inner = cm.options.addModeClass && [null];
if (text == "") extractLineClasses(callBlankLine(mode, state), lineClasses);
while (!stream.eol()) {
if (stream.pos > cm.options.maxHighlightLength) {
@@ -5817,15 +6804,18 @@
stream.pos = text.length;
style = null;
} else {
- style = extractLineClasses(readToken(mode, stream, state), lineClasses);
+ style = extractLineClasses(readToken(mode, stream, state, inner), lineClasses);
}
- if (cm.options.addModeClass) {
- var mName = CodeMirror.innerMode(mode, state).mode.name;
+ if (inner) {
+ var mName = inner[0].name;
if (mName) style = "m-" + (style ? mName + " " + style : mName);
}
if (!flattenSpans || curStyle != style) {
- if (curStart < stream.start) f(stream.start, curStyle);
- curStart = stream.start; curStyle = style;
+ while (curStart < stream.start) {
+ curStart = Math.min(stream.start, curStart + 50000);
+ f(curStart, curStyle);
+ }
+ curStyle = style;
}
stream.start = stream.pos;
}
@@ -5879,12 +6869,15 @@
return {styles: st, classes: lineClasses.bgClass || lineClasses.textClass ? lineClasses : null};
}
- function getLineStyles(cm, line) {
+ function getLineStyles(cm, line, updateFrontier) {
if (!line.styles || line.styles[0] != cm.state.modeGen) {
- var result = highlightLine(cm, line, line.stateAfter = getStateBefore(cm, lineNo(line)));
+ var state = getStateBefore(cm, lineNo(line));
+ var result = highlightLine(cm, line, line.text.length > cm.options.maxHighlightLength ? copyState(cm.doc.mode, state) : state);
+ line.stateAfter = state;
line.styles = result.styles;
if (result.classes) line.styleClasses = result.classes;
else if (line.styleClasses) line.styleClasses = null;
+ if (updateFrontier === cm.doc.frontier) cm.doc.frontier++;
}
return line.styles;
}
@@ -5897,7 +6890,7 @@
var stream = new StringStream(text, cm.options.tabSize);
stream.start = stream.pos = startAt || 0;
if (text == "") callBlankLine(mode, state);
- while (!stream.eol() && stream.pos <= cm.options.maxHighlightLength) {
+ while (!stream.eol()) {
readToken(mode, stream, state);
stream.start = stream.pos;
}
@@ -5924,7 +6917,9 @@
// is needed on Webkit to be able to get line-level bounding
// rectangles for it (in measureChar).
var content = elt("span", null, null, webkit ? "padding-right: .1px" : null);
- var builder = {pre: elt("pre", [content]), content: content, col: 0, pos: 0, cm: cm};
+ var builder = {pre: elt("pre", [content], "CodeMirror-line"), content: content,
+ col: 0, pos: 0, cm: cm,
+ splitSpaces: (ie || webkit) && cm.getOption("lineWrapping")};
lineView.measure = {};
// Iterate over the logical lines that make up this visual line.
@@ -5934,12 +6929,11 @@
builder.addToken = buildToken;
// Optionally wire in some hacks into the token-rendering
// algorithm, to deal with browser quirks.
- if ((ie || webkit) && cm.getOption("lineWrapping"))
- builder.addToken = buildTokenSplitSpaces(builder.addToken);
if (hasBadBidiRects(cm.display.measure) && (order = getOrder(line)))
builder.addToken = buildTokenBadBidi(builder.addToken, order);
builder.map = [];
- insertLineContent(line, builder, getLineStyles(cm, line));
+ var allowFrontierUpdate = lineView != cm.display.externalMeasured && lineNo(line);
+ insertLineContent(line, builder, getLineStyles(cm, line, allowFrontierUpdate));
if (line.styleClasses) {
if (line.styleClasses.bgClass)
builder.bgClass = joinClasses(line.styleClasses.bgClass, builder.bgClass || "");
@@ -5961,26 +6955,33 @@
}
}
+ // See issue #2901
+ if (webkit && /\bcm-tab\b/.test(builder.content.lastChild.className))
+ builder.content.className = "cm-tab-wrap-hack";
+
signal(cm, "renderLine", cm, lineView.line, builder.pre);
if (builder.pre.className)
builder.textClass = joinClasses(builder.pre.className, builder.textClass || "");
+
return builder;
}
function defaultSpecialCharPlaceholder(ch) {
var token = elt("span", "\u2022", "cm-invalidchar");
token.title = "\\u" + ch.charCodeAt(0).toString(16);
+ token.setAttribute("aria-label", token.title);
return token;
}
// Build up the DOM representation for a single token, and add it to
// the line map. Takes care to render special characters separately.
- function buildToken(builder, text, style, startStyle, endStyle, title) {
+ function buildToken(builder, text, style, startStyle, endStyle, title, css) {
if (!text) return;
- var special = builder.cm.options.specialChars, mustWrap = false;
+ var displayText = builder.splitSpaces ? text.replace(/ {3,}/g, splitSpaces) : text;
+ var special = builder.cm.state.specialChars, mustWrap = false;
if (!special.test(text)) {
builder.col += text.length;
- var content = document.createTextNode(text);
+ var content = document.createTextNode(displayText);
builder.map.push(builder.pos, builder.pos + text.length, content);
if (ie && ie_version < 9) mustWrap = true;
builder.pos += text.length;
@@ -5991,7 +6992,7 @@
var m = special.exec(text);
var skipped = m ? m.index - pos : text.length - pos;
if (skipped) {
- var txt = document.createTextNode(text.slice(pos, pos + skipped));
+ var txt = document.createTextNode(displayText.slice(pos, pos + skipped));
if (ie && ie_version < 9) content.appendChild(elt("span", [txt]));
else content.appendChild(txt);
builder.map.push(builder.pos, builder.pos + skipped, txt);
@@ -6003,9 +7004,16 @@
if (m[0] == "\t") {
var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize;
var txt = content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab"));
+ txt.setAttribute("role", "presentation");
+ txt.setAttribute("cm-text", "\t");
builder.col += tabWidth;
+ } else if (m[0] == "\r" || m[0] == "\n") {
+ var txt = content.appendChild(elt("span", m[0] == "\r" ? "\u240d" : "\u2424", "cm-invalidchar"));
+ txt.setAttribute("cm-text", m[0]);
+ builder.col += 1;
} else {
var txt = builder.cm.options.specialCharPlaceholder(m[0]);
+ txt.setAttribute("cm-text", m[0]);
if (ie && ie_version < 9) content.appendChild(elt("span", [txt]));
else content.appendChild(txt);
builder.col += 1;
@@ -6014,33 +7022,28 @@
builder.pos++;
}
}
- if (style || startStyle || endStyle || mustWrap) {
+ if (style || startStyle || endStyle || mustWrap || css) {
var fullStyle = style || "";
if (startStyle) fullStyle += startStyle;
if (endStyle) fullStyle += endStyle;
- var token = elt("span", [content], fullStyle);
+ var token = elt("span", [content], fullStyle, css);
if (title) token.title = title;
return builder.content.appendChild(token);
}
builder.content.appendChild(content);
}
- function buildTokenSplitSpaces(inner) {
- function split(old) {
- var out = " ";
- for (var i = 0; i < old.length - 2; ++i) out += i % 2 ? " " : "\u00a0";
- out += " ";
- return out;
- }
- return function(builder, text, style, startStyle, endStyle, title) {
- inner(builder, text.replace(/ {3,}/g, split), style, startStyle, endStyle, title);
- };
+ function splitSpaces(old) {
+ var out = " ";
+ for (var i = 0; i < old.length - 2; ++i) out += i % 2 ? " " : "\u00a0";
+ out += " ";
+ return out;
}
// Work around nonsense dimensions being reported for stretches of
// right-to-left text.
function buildTokenBadBidi(inner, order) {
- return function(builder, text, style, startStyle, endStyle, title) {
+ return function(builder, text, style, startStyle, endStyle, title, css) {
style = style ? style + " cm-force-border" : "cm-force-border";
var start = builder.pos, end = start + text.length;
for (;;) {
@@ -6049,8 +7052,8 @@
var part = order[i];
if (part.to > start && part.from <= start) break;
}
- if (part.to >= end) return inner(builder, text, style, startStyle, endStyle, title);
- inner(builder, text.slice(0, part.to - start), style, startStyle, null, title);
+ if (part.to >= end) return inner(builder, text, style, startStyle, endStyle, title, css);
+ inner(builder, text.slice(0, part.to - start), style, startStyle, null, title, css);
startStyle = null;
text = text.slice(part.to - start);
start = part.to;
@@ -6060,8 +7063,14 @@
function buildCollapsedSpan(builder, size, marker, ignoreWidget) {
var widget = !ignoreWidget && marker.widgetNode;
+ if (widget) builder.map.push(builder.pos, builder.pos + size, widget);
+ if (!ignoreWidget && builder.cm.display.input.needsContentAttribute) {
+ if (!widget)
+ widget = builder.content.appendChild(document.createElement("span"));
+ widget.setAttribute("cm-marker", marker.id);
+ }
if (widget) {
- builder.map.push(builder.pos, builder.pos + size, widget);
+ builder.cm.display.input.setUneditable(widget);
builder.content.appendChild(widget);
}
builder.pos += size;
@@ -6077,35 +7086,44 @@
return;
}
- var len = allText.length, pos = 0, i = 1, text = "", style;
+ var len = allText.length, pos = 0, i = 1, text = "", style, css;
var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, title, collapsed;
for (;;) {
if (nextChange == pos) { // Update current marker set
- spanStyle = spanEndStyle = spanStartStyle = title = "";
+ spanStyle = spanEndStyle = spanStartStyle = title = css = "";
collapsed = null; nextChange = Infinity;
- var foundBookmarks = [];
+ var foundBookmarks = [], endStyles
for (var j = 0; j < spans.length; ++j) {
var sp = spans[j], m = sp.marker;
- if (sp.from <= pos && (sp.to == null || sp.to > pos)) {
- if (sp.to != null && nextChange > sp.to) { nextChange = sp.to; spanEndStyle = ""; }
+ if (m.type == "bookmark" && sp.from == pos && m.widgetNode) {
+ foundBookmarks.push(m);
+ } else if (sp.from <= pos && (sp.to == null || sp.to > pos || m.collapsed && sp.to == pos && sp.from == pos)) {
+ if (sp.to != null && sp.to != pos && nextChange > sp.to) {
+ nextChange = sp.to;
+ spanEndStyle = "";
+ }
if (m.className) spanStyle += " " + m.className;
+ if (m.css) css = (css ? css + ";" : "") + m.css;
if (m.startStyle && sp.from == pos) spanStartStyle += " " + m.startStyle;
- if (m.endStyle && sp.to == nextChange) spanEndStyle += " " + m.endStyle;
+ if (m.endStyle && sp.to == nextChange) (endStyles || (endStyles = [])).push(m.endStyle, sp.to)
if (m.title && !title) title = m.title;
if (m.collapsed && (!collapsed || compareCollapsedMarkers(collapsed.marker, m) < 0))
collapsed = sp;
} else if (sp.from > pos && nextChange > sp.from) {
nextChange = sp.from;
}
- if (m.type == "bookmark" && sp.from == pos && m.widgetNode) foundBookmarks.push(m);
}
+ if (endStyles) for (var j = 0; j < endStyles.length; j += 2)
+ if (endStyles[j + 1] == nextChange) spanEndStyle += " " + endStyles[j]
+
+ if (!collapsed || collapsed.from == pos) for (var j = 0; j < foundBookmarks.length; ++j)
+ buildCollapsedSpan(builder, 0, foundBookmarks[j]);
if (collapsed && (collapsed.from || 0) == pos) {
buildCollapsedSpan(builder, (collapsed.to == null ? len + 1 : collapsed.to) - pos,
collapsed.marker, collapsed.from == null);
if (collapsed.to == null) return;
+ if (collapsed.to == pos) collapsed = false;
}
- if (!collapsed && foundBookmarks.length) for (var j = 0; j < foundBookmarks.length; ++j)
- buildCollapsedSpan(builder, 0, foundBookmarks[j]);
}
if (pos >= len) break;
@@ -6116,7 +7134,7 @@
if (!collapsed) {
var tokenText = end > upto ? text.slice(0, upto - pos) : text;
builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle,
- spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "", title);
+ spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "", title, css);
}
if (end >= upto) {text = text.slice(upto - pos); pos = upto; break;}
pos = end;
@@ -6145,17 +7163,24 @@
updateLine(line, text, spans, estimateHeight);
signalLater(line, "change", line, change);
}
+ function linesFor(start, end) {
+ for (var i = start, result = []; i < end; ++i)
+ result.push(new Line(text[i], spansFor(i), estimateHeight));
+ return result;
+ }
var from = change.from, to = change.to, text = change.text;
var firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line);
var lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line;
// Adjust the line structure
- if (isWholeLineUpdate(doc, change)) {
+ if (change.full) {
+ doc.insert(0, linesFor(0, text.length));
+ doc.remove(text.length, doc.size - text.length);
+ } else if (isWholeLineUpdate(doc, change)) {
// This is a whole-line replace. Treated specially to make
// sure line objects move the way they are supposed to.
- for (var i = 0, added = []; i < text.length - 1; ++i)
- added.push(new Line(text[i], spansFor(i), estimateHeight));
+ var added = linesFor(0, text.length - 1);
update(lastLine, lastLine.text, lastSpans);
if (nlines) doc.remove(from.line, nlines);
if (added.length) doc.insert(from.line, added);
@@ -6163,8 +7188,7 @@
if (text.length == 1) {
update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans);
} else {
- for (var added = [], i = 1; i < text.length - 1; ++i)
- added.push(new Line(text[i], spansFor(i), estimateHeight));
+ var added = linesFor(1, text.length - 1);
added.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight));
update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
doc.insert(from.line + 1, added);
@@ -6175,8 +7199,7 @@
} else {
update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans);
- for (var i = 1, added = []; i < text.length - 1; ++i)
- added.push(new Line(text[i], spansFor(i), estimateHeight));
+ var added = linesFor(1, text.length - 1);
if (nlines > 1) doc.remove(from.line + 1, nlines - 1);
doc.insert(from.line + 1, added);
}
@@ -6336,8 +7359,8 @@
};
var nextDocId = 0;
- var Doc = CodeMirror.Doc = function(text, mode, firstLine) {
- if (!(this instanceof Doc)) return new Doc(text, mode, firstLine);
+ var Doc = CodeMirror.Doc = function(text, mode, firstLine, lineSep) {
+ if (!(this instanceof Doc)) return new Doc(text, mode, firstLine, lineSep);
if (firstLine == null) firstLine = 0;
BranchChunk.call(this, [new LeafChunk([new Line("", null)])]);
@@ -6351,8 +7374,10 @@
this.history = new History(null);
this.id = ++nextDocId;
this.modeOption = mode;
+ this.lineSep = lineSep;
+ this.extend = false;
- if (typeof text == "string") text = splitLines(text);
+ if (typeof text == "string") text = this.splitLines(text);
updateDoc(this, {from: start, to: start, text: text});
setSelection(this, simpleSelection(start), sel_dontScroll);
};
@@ -6382,12 +7407,12 @@
getValue: function(lineSep) {
var lines = getLines(this, this.first, this.first + this.size);
if (lineSep === false) return lines;
- return lines.join(lineSep || "\n");
+ return lines.join(lineSep || this.lineSeparator());
},
setValue: docMethodOp(function(code) {
var top = Pos(this.first, 0), last = this.first + this.size - 1;
makeChange(this, {from: top, to: Pos(last, getLine(this, last).text.length),
- text: splitLines(code), origin: "setValue"}, true);
+ text: this.splitLines(code), origin: "setValue", full: true}, true);
setSelection(this, simpleSelection(top));
}),
replaceRange: function(code, from, to, origin) {
@@ -6398,7 +7423,7 @@
getRange: function(from, to, lineSep) {
var lines = getBetween(this, clipPos(this, from), clipPos(this, to));
if (lineSep === false) return lines;
- return lines.join(lineSep || "\n");
+ return lines.join(lineSep || this.lineSeparator());
},
getLine: function(line) {var l = this.getLineHandle(line); return l && l.text;},
@@ -6438,10 +7463,11 @@
extendSelection(this, clipPos(this, head), other && clipPos(this, other), options);
}),
extendSelections: docMethodOp(function(heads, options) {
- extendSelections(this, clipPosArray(this, heads, options));
+ extendSelections(this, clipPosArray(this, heads), options);
}),
extendSelectionsBy: docMethodOp(function(f, options) {
- extendSelections(this, map(this.sel.ranges, f), options);
+ var heads = map(this.sel.ranges, f);
+ extendSelections(this, clipPosArray(this, heads), options);
}),
setSelections: docMethodOp(function(ranges, primary, options) {
if (!ranges.length) return;
@@ -6464,13 +7490,13 @@
lines = lines ? lines.concat(sel) : sel;
}
if (lineSep === false) return lines;
- else return lines.join(lineSep || "\n");
+ else return lines.join(lineSep || this.lineSeparator());
},
getSelections: function(lineSep) {
var parts = [], ranges = this.sel.ranges;
for (var i = 0; i < ranges.length; i++) {
var sel = getBetween(this, ranges[i].from(), ranges[i].to());
- if (lineSep !== false) sel = sel.join(lineSep || "\n");
+ if (lineSep !== false) sel = sel.join(lineSep || this.lineSeparator());
parts[i] = sel;
}
return parts;
@@ -6485,7 +7511,7 @@
var changes = [], sel = this.sel;
for (var i = 0; i < sel.ranges.length; i++) {
var range = sel.ranges[i];
- changes[i] = {from: range.from(), to: range.to(), text: splitLines(code[i]), origin: origin};
+ changes[i] = {from: range.from(), to: range.to(), text: this.splitLines(code[i]), origin: origin};
}
var newSel = collapse && collapse != "end" && computeReplacedSel(this, changes, collapse);
for (var i = changes.length - 1; i >= 0; i--)
@@ -6532,22 +7558,26 @@
},
addLineClass: docMethodOp(function(handle, where, cls) {
- return changeLine(this, handle, "class", function(line) {
- var prop = where == "text" ? "textClass" : where == "background" ? "bgClass" : "wrapClass";
+ return changeLine(this, handle, where == "gutter" ? "gutter" : "class", function(line) {
+ var prop = where == "text" ? "textClass"
+ : where == "background" ? "bgClass"
+ : where == "gutter" ? "gutterClass" : "wrapClass";
if (!line[prop]) line[prop] = cls;
- else if (new RegExp("(?:^|\\s)" + cls + "(?:$|\\s)").test(line[prop])) return false;
+ else if (classTest(cls).test(line[prop])) return false;
else line[prop] += " " + cls;
return true;
});
}),
removeLineClass: docMethodOp(function(handle, where, cls) {
- return changeLine(this, handle, "class", function(line) {
- var prop = where == "text" ? "textClass" : where == "background" ? "bgClass" : "wrapClass";
+ return changeLine(this, handle, where == "gutter" ? "gutter" : "class", function(line) {
+ var prop = where == "text" ? "textClass"
+ : where == "background" ? "bgClass"
+ : where == "gutter" ? "gutterClass" : "wrapClass";
var cur = line[prop];
if (!cur) return false;
else if (cls == null) line[prop] = null;
else {
- var found = cur.match(new RegExp("(?:^|\\s+)" + cls + "(?:$|\\s+)"));
+ var found = cur.match(classTest(cls));
if (!found) return false;
var end = found.index + found[0].length;
line[prop] = cur.slice(0, found.index) + (!found.index || end == cur.length ? "" : " ") + cur.slice(end) || null;
@@ -6556,13 +7586,19 @@
});
}),
+ addLineWidget: docMethodOp(function(handle, node, options) {
+ return addLineWidget(this, handle, node, options);
+ }),
+ removeLineWidget: function(widget) { widget.clear(); },
+
markText: function(from, to, options) {
- return markText(this, clipPos(this, from), clipPos(this, to), options, "range");
+ return markText(this, clipPos(this, from), clipPos(this, to), options, options && options.type || "range");
},
setBookmark: function(pos, options) {
var realOpts = {replacedWith: options && (options.nodeType == null ? options.widget : options),
insertLeft: options && options.insertLeft,
- clearWhenEmpty: false, shared: options && options.shared};
+ clearWhenEmpty: false, shared: options && options.shared,
+ handleMouseEvents: options && options.handleMouseEvents};
pos = clipPos(this, pos);
return markText(this, pos, pos, realOpts, "bookmark");
},
@@ -6625,7 +7661,8 @@
},
copy: function(copyHistory) {
- var doc = new Doc(getLines(this, this.first, this.first + this.size), this.modeOption, this.first);
+ var doc = new Doc(getLines(this, this.first, this.first + this.size),
+ this.modeOption, this.first, this.lineSep);
doc.scrollTop = this.scrollTop; doc.scrollLeft = this.scrollLeft;
doc.sel = this.sel;
doc.extend = false;
@@ -6641,7 +7678,7 @@
var from = this.first, to = this.first + this.size;
if (options.from != null && options.from > from) from = options.from;
if (options.to != null && options.to < to) to = options.to;
- var copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from);
+ var copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from, this.lineSep);
if (options.sharedHist) copy.history = this.history;
(this.linked || (this.linked = [])).push({doc: copy, sharedHist: options.sharedHist});
copy.linked = [{doc: this, isParent: true, sharedHist: options.sharedHist}];
@@ -6670,14 +7707,20 @@
iterLinkedDocs: function(f) {linkedDocs(this, f);},
getMode: function() {return this.mode;},
- getEditor: function() {return this.cm;}
+ getEditor: function() {return this.cm;},
+
+ splitLines: function(str) {
+ if (this.lineSep) return str.split(this.lineSep);
+ return splitLinesAuto(str);
+ },
+ lineSeparator: function() { return this.lineSep || "\n"; }
});
// Public alias.
Doc.prototype.eachLine = Doc.prototype.iter;
// Set up methods on CodeMirror's prototype to redirect to the editor's document.
- var dontDelegate = "iter insert remove copy getEditor".split(" ");
+ var dontDelegate = "iter insert remove copy getEditor constructor".split(" ");
for (var prop in Doc.prototype) if (Doc.prototype.hasOwnProperty(prop) && indexOf(dontDelegate, prop) < 0)
CodeMirror.prototype[prop] = (function(method) {
return function() {return method.apply(this.doc, arguments);};
@@ -7110,24 +8153,30 @@
}
};
+ var noHandlers = []
+ function getHandlers(emitter, type, copy) {
+ var arr = emitter._handlers && emitter._handlers[type]
+ if (copy) return arr && arr.length > 0 ? arr.slice() : noHandlers
+ else return arr || noHandlers
+ }
+
var off = CodeMirror.off = function(emitter, type, f) {
if (emitter.removeEventListener)
emitter.removeEventListener(type, f, false);
else if (emitter.detachEvent)
emitter.detachEvent("on" + type, f);
else {
- var arr = emitter._handlers && emitter._handlers[type];
- if (!arr) return;
- for (var i = 0; i < arr.length; ++i)
- if (arr[i] == f) { arr.splice(i, 1); break; }
+ var handlers = getHandlers(emitter, type, false)
+ for (var i = 0; i < handlers.length; ++i)
+ if (handlers[i] == f) { handlers.splice(i, 1); break; }
}
};
var signal = CodeMirror.signal = function(emitter, type /*, values...*/) {
- var arr = emitter._handlers && emitter._handlers[type];
- if (!arr) return;
+ var handlers = getHandlers(emitter, type, true)
+ if (!handlers.length) return;
var args = Array.prototype.slice.call(arguments, 2);
- for (var i = 0; i < arr.length; ++i) arr[i].apply(null, args);
+ for (var i = 0; i < handlers.length; ++i) handlers[i].apply(null, args);
};
var orphanDelayedCallbacks = null;
@@ -7140,8 +8189,8 @@
// them to be executed when the last operation ends, or, if no
// operation is active, when a timeout fires.
function signalLater(emitter, type /*, values...*/) {
- var arr = emitter._handlers && emitter._handlers[type];
- if (!arr) return;
+ var arr = getHandlers(emitter, type, false)
+ if (!arr.length) return;
var args = Array.prototype.slice.call(arguments, 2), list;
if (operationGroup) {
list = operationGroup.delayedCallbacks;
@@ -7166,6 +8215,8 @@
// registering a (non-DOM) handler on the editor for the event name,
// and preventDefault-ing the event in that handler.
function signalDOMEvent(cm, e, override) {
+ if (typeof e == "string")
+ e = {type: e, preventDefault: function() { this.defaultPrevented = true; }};
signal(cm, override || e.type, cm, e);
return e_defaultPrevented(e) || e.codemirrorIgnore;
}
@@ -7179,8 +8230,7 @@
}
function hasHandler(emitter, type) {
- var arr = emitter._handlers && emitter._handlers[type];
- return arr && arr.length > 0;
+ return getHandlers(emitter, type).length > 0
}
// Add on and off methods to a constructor's prototype, to make
@@ -7193,7 +8243,7 @@
// MISC UTILITIES
// Number of pixels added to scroller and sizer to hide scrollbar
- var scrollerCutOff = 30;
+ var scrollerGap = 30;
// Returned or thrown by various protocols to signal 'I'm not
// handling this'.
@@ -7227,7 +8277,7 @@
// The inverse of countColumn -- find the offset that corresponds to
// a particular column.
- function findColumn(string, goal, tabSize) {
+ var findColumn = CodeMirror.findColumn = function(string, goal, tabSize) {
for (var pos = 0, col = 0;;) {
var nextTab = string.indexOf("\t", pos);
if (nextTab == -1) nextTab = string.length;
@@ -7261,22 +8311,21 @@
if (array[i] == elt) return i;
return -1;
}
- if ([].indexOf) indexOf = function(array, elt) { return array.indexOf(elt); };
function map(array, f) {
var out = [];
for (var i = 0; i < array.length; i++) out[i] = f(array[i], i);
return out;
}
- if ([].map) map = function(array, f) { return array.map(f); };
+
+ function nothing() {}
function createObj(base, props) {
var inst;
if (Object.create) {
inst = Object.create(base);
} else {
- var ctor = function() {};
- ctor.prototype = base;
- inst = new ctor();
+ nothing.prototype = base;
+ inst = new nothing();
}
if (props) copyObj(props, inst);
return inst;
@@ -7295,7 +8344,7 @@
return function(){return f.apply(null, args);};
}
- var nonASCIISingleCaseWordChar = /[\u00df\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/;
+ var nonASCIISingleCaseWordChar = /[\u00df\u0587\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/;
var isWordCharBasic = CodeMirror.isWordChar = function(ch) {
return /\w/.test(ch) || ch > "\x80" &&
(ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch));
@@ -7331,15 +8380,16 @@
}
var range;
- if (document.createRange) range = function(node, start, end) {
+ if (document.createRange) range = function(node, start, end, endNode) {
var r = document.createRange();
- r.setEnd(node, end);
+ r.setEnd(endNode || node, end);
r.setStart(node, start);
return r;
};
else range = function(node, start, end) {
var r = document.body.createTextRange();
- r.moveToElementText(node.parentNode);
+ try { r.moveToElementText(node.parentNode); }
+ catch(e) { return r; }
r.collapse(true);
r.moveEnd("character", end);
r.moveStart("character", start);
@@ -7356,14 +8406,23 @@
return removeChildren(parent).appendChild(e);
}
- function contains(parent, child) {
+ var contains = CodeMirror.contains = function(parent, child) {
+ if (child.nodeType == 3) // Android browser always returns false when child is a textnode
+ child = child.parentNode;
if (parent.contains)
return parent.contains(child);
- while (child = child.parentNode)
+ do {
+ if (child.nodeType == 11) child = child.host;
if (child == parent) return true;
- }
+ } while (child = child.parentNode);
+ };
- function activeElt() { return document.activeElement; }
+ function activeElt() {
+ var activeElement = document.activeElement;
+ while (activeElement && activeElement.root && activeElement.root.activeElement)
+ activeElement = activeElement.root.activeElement;
+ return activeElement;
+ }
// Older versions of IE throws unspecified error when touching
// document.activeElement in some cases (during loading, in iframe)
if (ie && ie_version < 11) activeElt = function() {
@@ -7371,14 +8430,19 @@
catch(e) { return document.body; }
};
- function classTest(cls) { return new RegExp("\\b" + cls + "\\b\\s*"); }
- function rmClass(node, cls) {
- var test = classTest(cls);
- if (test.test(node.className)) node.className = node.className.replace(test, "");
- }
- function addClass(node, cls) {
- if (!classTest(cls).test(node.className)) node.className += " " + cls;
- }
+ function classTest(cls) { return new RegExp("(^|\\s)" + cls + "(?:$|\\s)\\s*"); }
+ var rmClass = CodeMirror.rmClass = function(node, cls) {
+ var current = node.className;
+ var match = classTest(cls).exec(current);
+ if (match) {
+ var after = current.slice(match.index + match[0].length);
+ node.className = current.slice(0, match.index) + (after ? match[1] + after : "");
+ }
+ };
+ var addClass = CodeMirror.addClass = function(node, cls) {
+ var current = node.className;
+ if (!classTest(cls).test(current)) node.className += (current ? " " : "") + cls;
+ };
function joinClasses(a, b) {
var as = a.split(" ");
for (var i = 0; i < as.length; i++)
@@ -7413,7 +8477,6 @@
on(window, "resize", function() {
if (resizeTimer == null) resizeTimer = setTimeout(function() {
resizeTimer = null;
- knownScrollbarWidth = null;
forEachCodeMirror(onResize);
}, 100);
});
@@ -7434,16 +8497,6 @@
return "draggable" in div || "dragDrop" in div;
}();
- var knownScrollbarWidth;
- function scrollbarWidth(measure) {
- if (knownScrollbarWidth != null) return knownScrollbarWidth;
- var test = elt("div", null, null, "width: 50px; height: 50px; overflow-x: scroll");
- removeChildrenAndAdd(measure, test);
- if (test.offsetWidth)
- knownScrollbarWidth = test.offsetHeight - test.clientHeight;
- return knownScrollbarWidth || 0;
- }
-
var zwspSupported;
function zeroWidthElement(measure) {
if (zwspSupported == null) {
@@ -7452,8 +8505,10 @@
if (measure.firstChild.offsetHeight != 0)
zwspSupported = test.offsetWidth <= 1 && test.offsetHeight > 2 && !(ie && ie_version < 8);
}
- if (zwspSupported) return elt("span", "\u200b");
- else return elt("span", "\u00a0", null, "display: inline-block; width: 1px; margin-right: -1px");
+ var node = zwspSupported ? elt("span", "\u200b") :
+ elt("span", "\u00a0", null, "display: inline-block; width: 1px; margin-right: -1px");
+ node.setAttribute("cm-text", "");
+ return node;
}
// Feature-detect IE's crummy client rect reporting for bidi text
@@ -7469,7 +8524,7 @@
// See if "".split is the broken IE version, if so, provide an
// alternative way to split lines.
- var splitLines = CodeMirror.splitLines = "\n\nb".split(/\n/).length != 3 ? function(string) {
+ var splitLinesAuto = CodeMirror.splitLines = "\n\nb".split(/\n/).length != 3 ? function(string) {
var pos = 0, result = [], l = string.length;
while (pos <= l) {
var nl = string.indexOf("\n", pos);
@@ -7515,14 +8570,16 @@
// KEY NAMES
- var keyNames = {3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt",
- 19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End",
- 36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert",
- 46: "Delete", 59: ";", 61: "=", 91: "Mod", 92: "Mod", 93: "Mod", 107: "=", 109: "-", 127: "Delete",
- 173: "-", 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\",
- 221: "]", 222: "'", 63232: "Up", 63233: "Down", 63234: "Left", 63235: "Right", 63272: "Delete",
- 63273: "Home", 63275: "End", 63276: "PageUp", 63277: "PageDown", 63302: "Insert"};
- CodeMirror.keyNames = keyNames;
+ var keyNames = CodeMirror.keyNames = {
+ 3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt",
+ 19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End",
+ 36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert",
+ 46: "Delete", 59: ";", 61: "=", 91: "Mod", 92: "Mod", 93: "Mod",
+ 106: "*", 107: "=", 109: "-", 110: ".", 111: "/", 127: "Delete",
+ 173: "-", 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\",
+ 221: "]", 222: "'", 63232: "Up", 63233: "Down", 63234: "Left", 63235: "Right", 63272: "Delete",
+ 63273: "Home", 63275: "End", 63276: "PageUp", 63277: "PageDown", 63302: "Insert"
+ };
(function() {
// Number keys
for (var i = 0; i < 10; i++) keyNames[i + 48] = keyNames[i + 96] = String(i);
@@ -7816,6 +8873,8 @@
lst(order).to -= m[0].length;
order.push(new BidiSpan(0, len - m[0].length, len));
}
+ if (order[0].level == 2)
+ order.unshift(new BidiSpan(1, order[0].to, order[0].to));
if (order[0].level != lst(order).level)
order.push(new BidiSpan(order[0].level, len, len));
@@ -7825,7 +8884,7 @@
// THE END
- CodeMirror.version = "4.6.0";
+ CodeMirror.version = "5.11.0";
return CodeMirror;
});
diff --git a/lib/codemirror.min.js b/lib/codemirror.min.js
index 56b4b56..e3fa5d0 100755
--- a/lib/codemirror.min.js
+++ b/lib/codemirror.min.js
@@ -1,5 +1,5 @@
-!function(a){if("object"==typeof exports&&"object"==typeof module)module.exports=a();else{if("function"==typeof define&&define.amd)return define([],a);this.CodeMirror=a()}}(function(){"use strict";function w(a,b){if(!(this instanceof w))return new w(a,b);this.options=b=b||{},Og(ie,b,!1),K(b);var c=b.value;"string"==typeof c&&(c=new Jf(c,b.mode)),this.doc=c;var f=this.display=new x(a,c);f.wrapper.CodeMirror=this,G(this),E(this),b.lineWrapping&&(this.display.wrapper.className+=" CodeMirror-wrap"),b.autofocus&&!o&&ad(this),this.state={keyMaps:[],overlays:[],modeGen:0,overwrite:!1,focused:!1,suppressEdits:!1,pasteIncoming:!1,cutIncoming:!1,draggingText:!1,highlight:new Eg},d&&11>e&&setTimeout(Pg(_c,this,!0),20),dd(this),gh();var g=this;Kc(this,function(){g.curOp.forceUpdate=!0,Nf(g,c),b.autofocus&&!o||_g()==f.input?setTimeout(Pg(Hd,g),20):Id(g);for(var a in je)je.hasOwnProperty(a)&&je[a](g,b[a],le);Q(g);for(var d=0;de&&(c.gutters.style.zIndex=-1,c.scroller.style.paddingRight=0),n&&(g.style.width="0px"),f||(c.scroller.draggable=!0),k&&(c.inputDiv.style.height="1px",c.inputDiv.style.position="absolute"),d&&8>e&&(c.scrollbarH.style.minHeight=c.scrollbarV.style.minWidth="18px"),a.appendChild?a.appendChild(c.wrapper):a(c.wrapper),c.viewFrom=c.viewTo=b.first,c.view=[],c.externalMeasured=null,c.viewOffset=0,c.lastSizeC=0,c.updateLineNumbers=null,c.lineNumWidth=c.lineNumInnerWidth=c.lineNumChars=null,c.prevInput="",c.alignWidgets=!1,c.pollingFast=!1,c.poll=new Eg,c.cachedCharWidth=c.cachedTextHeight=c.cachedPaddingH=null,c.inaccurateSelection=!1,c.maxLine=null,c.maxLineLength=0,c.maxLineChanged=!1,c.wheelDX=c.wheelDY=c.wheelStartX=c.wheelStartY=null,c.shift=!1,c.selForContextMenu=null}function y(a){a.doc.mode=w.getMode(a.options,a.doc.modeOption),z(a)}function z(a){a.doc.iter(function(a){a.stateAfter&&(a.stateAfter=null),a.styles&&(a.styles=null)}),a.doc.frontier=a.doc.first,Ub(a,100),a.state.modeGen++,a.curOp&&Qc(a)}function A(a){a.options.lineWrapping?(ch(a.display.wrapper,"CodeMirror-wrap"),a.display.sizer.style.minWidth=""):(bh(a.display.wrapper,"CodeMirror-wrap"),J(a)),C(a),Qc(a),lc(a),setTimeout(function(){N(a)},100)}function B(a){var b=xc(a.display),c=a.options.lineWrapping,d=c&&Math.max(5,a.display.scroller.clientWidth/yc(a.display)-3);return function(e){if(df(a.doc,e))return 0;var f=0;if(e.widgets)for(var g=0;gb.maxLineLength&&(b.maxLineLength=c,b.maxLine=a)})}function K(a){var b=Lg(a.gutters,"CodeMirror-linenumbers");-1==b&&a.lineNumbers?a.gutters=a.gutters.concat(["CodeMirror-linenumbers"]):b>-1&&!a.lineNumbers&&(a.gutters=a.gutters.slice(0),a.gutters.splice(b,1))}function L(a){return a.display.scroller.clientHeight-a.display.wrapper.clientHeightb.clientWidth;f&&b.scrollWidth<=b.clientWidth+1&&d>0&&!b.hScrollbarTakesSpace&&(f=!1);var g=e>b.clientHeight;if(g?(c.scrollbarV.style.display="block",c.scrollbarV.style.bottom=f?d+"px":"0",c.scrollbarV.firstChild.style.height=Math.max(0,e-b.clientHeight+(b.barHeight||c.scrollbarV.clientHeight))+"px"):(c.scrollbarV.style.display="",c.scrollbarV.firstChild.style.height="0"),f?(c.scrollbarH.style.display="block",c.scrollbarH.style.right=g?d+"px":"0",c.scrollbarH.firstChild.style.width=b.scrollWidth-b.clientWidth+(b.barWidth||c.scrollbarH.clientWidth)+"px"):(c.scrollbarH.style.display="",c.scrollbarH.firstChild.style.width="0"),f&&g?(c.scrollbarFiller.style.display="block",c.scrollbarFiller.style.height=c.scrollbarFiller.style.width=d+"px"):c.scrollbarFiller.style.display="",f&&a.options.coverGutterNextToScrollbar&&a.options.fixedGutter?(c.gutterFiller.style.display="block",c.gutterFiller.style.height=d+"px",c.gutterFiller.style.width=c.gutters.offsetWidth+"px"):c.gutterFiller.style.display="",!a.state.checkedOverlayScrollbar&&b.clientHeight>0){if(0===d){var h=p&&!l?"12px":"18px";c.scrollbarV.style.minWidth=c.scrollbarH.style.minHeight=h;var i=function(b){ng(b)!=c.scrollbarV&&ng(b)!=c.scrollbarH&&Lc(a,hd)(b)};pg(c.scrollbarV,"mousedown",i),pg(c.scrollbarH,"mousedown",i)}a.state.checkedOverlayScrollbar=!0}}function O(a,b,c){var d=c&&null!=c.top?Math.max(0,c.top):a.scroller.scrollTop;d=Math.floor(d-Yb(a));var e=c&&null!=c.bottom?c.bottom:d+a.wrapper.clientHeight,f=Tf(b,d),g=Tf(b,e);if(c&&c.ensure){var h=c.ensure.from.line,i=c.ensure.to.line;if(f>h)return{from:h,to:Tf(b,Uf(Of(b,h))+a.wrapper.clientHeight)};if(Math.min(i,b.lastLine())>=g)return{from:Tf(b,Uf(Of(b,i))-a.wrapper.clientHeight),to:i}}return{from:f,to:Math.max(g,f+1)}}function P(a){var b=a.display,c=b.view;if(b.alignWidgets||b.gutters.firstChild&&a.options.fixedGutter){for(var d=S(b)-b.scroller.scrollLeft+a.doc.scrollLeft,e=b.gutters.offsetWidth,f=d+"px",g=0;g=c.viewFrom&&b.visible.to<=c.viewTo&&(null==c.updateLineNumbers||c.updateLineNumbers>=c.viewTo)&&0==Wc(a))return!1;Q(a)&&(Sc(a),b.dims=_(a));var e=d.first+d.size,f=Math.max(b.visible.from-a.options.viewportMargin,d.first),g=Math.min(e,b.visible.to+a.options.viewportMargin);c.viewFromg&&c.viewTo-g<20&&(g=Math.min(e,c.viewTo)),v&&(f=bf(a.doc,f),g=cf(a.doc,g));var h=f!=c.viewFrom||g!=c.viewTo||c.lastSizeC!=b.wrapperHeight;Vc(a,f,g),c.viewOffset=Uf(Of(a.doc,c.viewFrom)),a.display.mover.style.top=c.viewOffset+"px";var i=Wc(a);if(!h&&0==i&&!b.force&&(null==c.updateLineNumbers||c.updateLineNumbers>=c.viewTo))return!1;var j=_g();return i>4&&(c.lineDiv.style.display="none"),ab(a,c.updateLineNumbers,b.dims),i>4&&(c.lineDiv.style.display=""),j&&_g()!=j&&j.offsetHeight&&j.focus(),Yg(c.cursorDiv),Yg(c.selectionDiv),h&&(c.lastSizeC=b.wrapperHeight,Ub(a,400)),c.updateLineNumbers=null,!0}function V(a,b){for(var c=b.force,d=b.viewport,e=!0;;e=!1){if(e&&a.options.lineWrapping&&b.oldScrollerWidth!=a.display.scroller.clientWidth)c=!0;else if(c=!1,d&&null!=d.top&&(d={top:Math.min(a.doc.height+Zb(a.display)-zg-a.display.scroller.clientHeight,d.top)}),b.visible=O(a.display,a.doc,d),b.visible.from>=a.display.viewFrom&&b.visible.to<=a.display.viewTo)break;if(!U(a,b))break;Z(a);var f=M(a);Qb(a),X(a,f),N(a,f)}tg(a,"update",a),(a.display.viewFrom!=b.oldViewFrom||a.display.viewTo!=b.oldViewTo)&&tg(a,"viewportChange",a,a.display.viewFrom,a.display.viewTo)}function W(a,b){var c=new T(a,b);if(U(a,c)){Z(a),V(a,c);var d=M(a);Qb(a),X(a,d),N(a,d)}}function X(a,b){a.display.sizer.style.minHeight=a.display.heightForcer.style.top=b.docHeight+"px",a.display.gutters.style.height=Math.max(b.docHeight,b.clientHeight-zg)+"px"}function Y(a,b){a.display.sizer.offsetWidth+a.display.gutters.offsetWidthe){var i=g.node.offsetTop+g.node.offsetHeight;h=i-c,c=i}else{var j=g.node.getBoundingClientRect();h=j.bottom-j.top}var k=g.line.height-h;if(2>h&&(h=xc(b)),(k>.001||-.001>k)&&(Rf(g.line,h),$(g.line),g.rest))for(var l=0;l=b&&m.lineNumber;m.changes&&(Lg(m.changes,"gutter")>-1&&(o=!1),bb(a,m,k,c)),o&&(Yg(m.lineNumber),m.lineNumber.appendChild(document.createTextNode(R(a.options,k)))),h=m.node.nextSibling}else{var n=jb(a,m,k,c);g.insertBefore(n,h)}k+=m.size}for(;h;)h=i(h)}function bb(a,b,c,d){for(var e=0;ee&&(a.node.style.zIndex=2)),a.node}function db(a){var b=a.bgClass?a.bgClass+" "+(a.line.bgClass||""):a.line.bgClass;if(b&&(b+=" CodeMirror-linebackground"),a.background)b?a.background.className=b:(a.background.parentNode.removeChild(a.background),a.background=null);else if(b){var c=cb(a);a.background=c.insertBefore(Wg("div",null,b),c.firstChild)}}function eb(a,b){var c=a.display.externalMeasured;return c&&c.line==b.line?(a.display.externalMeasured=null,b.measure=c.measure,c.built):xf(a,b)}function fb(a,b){var c=b.text.className,d=eb(a,b);b.text==b.node&&(b.node=d.pre),b.text.parentNode.replaceChild(d.pre,b.text),b.text=d.pre,d.bgClass!=b.bgClass||d.textClass!=b.textClass?(b.bgClass=d.bgClass,b.textClass=d.textClass,gb(b)):c&&(b.text.className=c)}function gb(a){db(a),a.line.wrapClass?cb(a).className=a.line.wrapClass:a.node!=a.text&&(a.node.className="");var b=a.textClass?a.textClass+" "+(a.line.textClass||""):a.line.textClass;a.text.className=b||""}function hb(a,b,c,d){b.gutter&&(b.node.removeChild(b.gutter),b.gutter=null);var e=b.line.gutterMarkers;if(a.options.lineNumbers||e){var f=cb(b),g=b.gutter=f.insertBefore(Wg("div",null,"CodeMirror-gutter-wrapper","position: absolute; left: "+(a.options.fixedGutter?d.fixedPos:-d.gutterTotalWidth)+"px"),b.text);if(!a.options.lineNumbers||e&&e["CodeMirror-linenumbers"]||(b.lineNumber=g.appendChild(Wg("div",R(a.options,c),"CodeMirror-linenumber CodeMirror-gutter-elt","left: "+d.gutterLeft["CodeMirror-linenumbers"]+"px; width: "+a.display.lineNumInnerWidth+"px"))),e)for(var h=0;h=0){var g=rb(f.from(),e.from()),h=qb(f.to(),e.to()),i=f.empty()?e.from()==e.head:f.from()==f.head;b>=d&&--b,a.splice(--d,2,new tb(i?h:g,i?g:h))}}return new sb(a,b)}function vb(a,b){return new sb([new tb(a,b||a)],0)}function wb(a,b){return Math.max(a.first,Math.min(b,a.first+a.size-1))}function xb(a,b){if(b.linec?nb(c,Of(a,c).text.length):yb(b,Of(a,b.line).text.length)}function yb(a,b){var c=a.ch;return null==c||c>b?nb(a.line,b):0>c?nb(a.line,0):a}function zb(a,b){return b>=a.first&&b=f.ch:j.to>f.ch))){if(d&&(rg(k,"beforeCursorEnter"),k.explicitlyCleared)){if(h.markedSpans){--i;continue}break}if(!k.atomic)continue;var l=k.find(0>g?-1:1);if(0==ob(l,f)&&(l.ch+=g,l.ch<0?l=l.line>a.first?xb(a,nb(l.line-1)):null:l.ch>h.text.length&&(l=l.lineb&&(b=0),b=Math.round(b),d=Math.round(d),f.appendChild(Wg("div",null,"CodeMirror-selected","position: absolute; left: "+a+"px; top: "+b+"px; width: "+(null==c?i-a:c)+"px; height: "+(d-b)+"px"))}function k(b,c,d){function m(c,d){return qc(a,nb(b,c),"div",f,d)}var k,l,f=Of(e,b),g=f.text.length;return vh(Vf(f),c||0,null==d?g:d,function(a,b,e){var n,o,p,f=m(a,"left");if(a==b)n=f,o=p=f.left;else{if(n=m(b-1,"right"),"rtl"==e){var q=f;f=n,n=q}o=f.left,p=n.right}null==c&&0==a&&(o=h),n.top-f.top>3&&(j(o,f.top,null,f.bottom),o=h,f.bottoml.bottom||n.bottom==l.bottom&&n.right>l.right)&&(l=n),h+1>o&&(o=h),j(o,n.top,p-o,n.bottom)}),{start:k,end:l}}var d=a.display,e=a.doc,f=document.createDocumentFragment(),g=$b(a.display),h=g.left,i=d.lineSpace.offsetWidth-g.right,l=b.from(),m=b.to();if(l.line==m.line)k(l.line,l.ch,m.ch);else{var n=Of(e,l.line),o=Of(e,m.line),p=_e(n)==_e(o),q=k(l.line,l.ch,p?n.text.length+1:null).end,r=k(m.line,p?0:null,m.ch).start;p&&(q.top0?b.blinker=setInterval(function(){b.cursorDiv.style.visibility=(c=!c)?"":"hidden"},a.options.cursorBlinkRate):a.options.cursorBlinkRate<0&&(b.cursorDiv.style.visibility="hidden")}}function Ub(a,b){a.doc.mode.startState&&a.doc.frontier=a.display.viewTo)){var c=+new Date+a.options.workTime,d=re(b.mode,Xb(a,b.frontier)),e=[];b.iter(b.frontier,Math.min(b.first+b.size,a.display.viewTo+500),function(f){if(b.frontier>=a.display.viewFrom){var g=f.styles,h=rf(a,f,d,!0);f.styles=h.styles;var i=f.styleClasses,j=h.classes;j?f.styleClasses=j:i&&(f.styleClasses=null);for(var k=!g||g.length!=f.styles.length||i!=j&&(!i||!j||i.bgClass!=j.bgClass||i.textClass!=j.textClass),l=0;!k&&lc?(Ub(a,a.options.workDelay),!0):void 0}),e.length&&Kc(a,function(){for(var b=0;bg;--h){if(h<=f.first)return f.first;var i=Of(f,h-1);if(i.stateAfter&&(!c||h<=f.frontier))return h;var j=Fg(i.text,null,a.options.tabSize);(null==e||d>j)&&(e=h-1,d=j)}return e}function Xb(a,b,c){var d=a.doc,e=a.display;if(!d.mode.startState)return!0;var f=Wb(a,b,c),g=f>d.first&&Of(d,f-1).stateAfter;return g=g?re(d.mode,g):se(d.mode),d.iter(f,b,function(c){tf(a,c.text,g);var h=f==b-1||0==f%5||f>=e.viewFrom&&f2&&f.push((i.bottom+j.top)/2-c.top)}}f.push(c.bottom-c.top)}}function ac(a,b,c){if(a.line==b)return{map:a.measure.map,cache:a.measure.cache};for(var d=0;dc)return{map:a.measure.maps[d],cache:a.measure.caches[d],before:!0}}function bc(a,b){b=_e(b);var c=Sf(b),d=a.display.externalMeasured=new Oc(a.doc,b,c);d.lineN=c;var e=d.built=xf(a,d);return d.text=e.pre,Zg(a.display.lineMeasure,e.pre),d}function cc(a,b,c,d){return fc(a,ec(a,b),c,d)}function dc(a,b){if(b>=a.display.viewFrom&&b=c.lineN&&bc?(i=0,j=1,k="left"):n>c?(i=c-m,j=i+1):(l==g.length-3||c==n&&g[l+3]>c)&&(j=n-m,i=j-1,c>=n&&(k="right")),null!=i){if(h=g[l+2],m==n&&f==(h.insertLeft?"left":"right")&&(k=f),"left"==f&&0==i)for(;l&&g[l-2]==g[l-3]&&g[l-1].insertLeft;)h=g[(l-=3)+2],k="left";if("right"==f&&i==n-m)for(;ll;l++){for(;i&&Vg(b.line.text.charAt(m+i));)--i;for(;n>m+j&&Vg(b.line.text.charAt(m+j));)++j;if(d&&9>e&&0==i&&j==n-m)o=h.parentNode.getBoundingClientRect();else if(d&&a.options.lineWrapping){var p=Xg(h,i,j).getClientRects();o=p.length?p["right"==f?p.length-1:0]:gc}else o=Xg(h,i,j).getBoundingClientRect()||gc;if(o.left||o.right||0==i)break;j=i,i-=1,k="right"}d&&11>e&&(o=ic(a.display.measure,o))}else{i>0&&(k=f="right");var p;o=a.options.lineWrapping&&(p=h.getClientRects()).length>1?p["right"==f?p.length-1:0]:h.getBoundingClientRect()}if(d&&9>e&&!i&&(!o||!o.left&&!o.right)){var q=h.parentNode.getClientRects()[0];o=q?{left:q.left,right:q.left+yc(a.display),top:q.top,bottom:q.bottom}:gc}for(var r=o.top-b.rect.top,s=o.bottom-b.rect.top,t=(r+s)/2,u=b.view.measure.heights,l=0;lc.from?g(a-1):g(a,d)}d=d||Of(a.doc,b.line),e||(e=ec(a,d));var i=Vf(d),j=b.ch;if(!i)return g(j);var k=Fh(i,j),l=h(j,k);return null!=Eh&&(l.other=h(j,Eh)),l}function sc(a,b){var c=0,b=xb(a.doc,b);a.options.lineWrapping||(c=yc(a.display)*b.ch);var d=Of(a.doc,b.line),e=Uf(d)+Yb(a.display);return{left:c,right:c,top:e,bottom:e+d.height}}function tc(a,b,c,d){var e=nb(a,b);return e.xRel=d,c&&(e.outside=!0),e}function uc(a,b,c){var d=a.doc;if(c+=a.display.viewOffset,0>c)return tc(d.first,0,!0,-1);var e=Tf(d,c),f=d.first+d.size-1;if(e>f)return tc(d.first+d.size-1,Of(d,f).text.length,!0,1);0>b&&(b=0);for(var g=Of(d,e);;){var h=vc(a,g,e,b,c),i=Ze(g),j=i&&i.find(0,!0);if(!i||!(h.ch>j.from.ch||h.ch==j.from.ch&&h.xRel>0))return h;e=Sf(g=j.to.line)}}function vc(a,b,c,d,e){function j(d){var e=rc(a,nb(c,d),"line",b,i);return g=!0,f>e.bottom?e.left-h:fq)return tc(c,n,r,1);for(;;){if(k?n==m||n==Hh(b,m,1):1>=n-m){for(var s=o>d||q-d>=d-o?m:n,t=d-(s==m?o:q);Vg(b.text.charAt(s));)++s;var u=tc(c,s,s==m?p:r,-1>t?-1:t>1?1:0);return u}var v=Math.ceil(l/2),w=m+v;if(k){w=m;for(var x=0;v>x;++x)w=Hh(b,w,1)}var y=j(w);y>d?(n=w,q=y,(r=g)&&(q+=1e3),l=v):(m=w,o=y,p=g,l-=v)}}function xc(a){if(null!=a.cachedTextHeight)return a.cachedTextHeight;if(null==wc){wc=Wg("pre");for(var b=0;49>b;++b)wc.appendChild(document.createTextNode("x")),wc.appendChild(Wg("br"));wc.appendChild(document.createTextNode("x"))}Zg(a.measure,wc);var c=wc.offsetHeight/50;return c>3&&(a.cachedTextHeight=c),Yg(a.measure),c||1}function yc(a){if(null!=a.cachedCharWidth)return a.cachedCharWidth;var b=Wg("span","xxxxxxxxxx"),c=Wg("pre",[b]);Zg(a.measure,c);var d=b.getBoundingClientRect(),e=(d.right-d.left)/10;return e>2&&(a.cachedCharWidth=e),e||10}function Bc(a){a.curOp={cm:a,viewChanged:!1,startHeight:a.doc.height,forceUpdate:!1,updateInput:null,typing:!1,changeObjs:null,cursorActivityHandlers:null,cursorActivityCalled:0,selectionChanged:!1,updateMaxLine:!1,scrollLeft:null,scrollTop:null,scrollToPos:null,id:++Ac},zc?zc.ops.push(a.curOp):a.curOp.ownsGroup=zc={ops:[a.curOp],delayedCallbacks:[]}}function Cc(a){var b=a.delayedCallbacks,c=0;do{for(;c=c.viewTo)||c.maxLineChanged&&b.options.lineWrapping,a.update=a.mustUpdate&&new T(b,a.mustUpdate&&{top:a.scrollTop,ensure:a.scrollToPos},a.forceUpdate)}function Gc(a){a.updatedDisplay=a.mustUpdate&&U(a.cm,a.update)}function Hc(a){var b=a.cm,c=b.display;a.updatedDisplay&&Z(b),a.barMeasure=M(b),c.maxLineChanged&&!b.options.lineWrapping&&(a.adjustWidthTo=cc(b,c.maxLine,c.maxLine.text.length).left+3,a.maxScrollLeft=Math.max(0,c.sizer.offsetLeft+a.adjustWidthTo+zg-c.scroller.clientWidth)),(a.updatedDisplay||a.selectionChanged)&&(a.newSelectionNodes=Ob(b))}function Ic(a){var b=a.cm;null!=a.adjustWidthTo&&(b.display.sizer.style.minWidth=a.adjustWidthTo+"px",a.maxScrollLeft1&&N(b),a.updatedDisplay&&V(b,a.update),null==c.wheelStartX||null==a.scrollTop&&null==a.scrollLeft&&!a.scrollToPos||(c.wheelStartX=c.wheelStartY=null),null!=a.scrollTop&&(c.scroller.scrollTop!=a.scrollTop||a.forceScroll)){var e=Math.max(0,Math.min(c.scroller.scrollHeight-c.scroller.clientHeight,a.scrollTop));c.scroller.scrollTop=c.scrollbarV.scrollTop=d.scrollTop=e}if(null!=a.scrollLeft&&(c.scroller.scrollLeft!=a.scrollLeft||a.forceScroll)){var g=Math.max(0,Math.min(c.scroller.scrollWidth-c.scroller.clientWidth,a.scrollLeft));c.scroller.scrollLeft=c.scrollbarH.scrollLeft=d.scrollLeft=g,P(b)}if(a.scrollToPos){var h=Zd(b,xb(d,a.scrollToPos.from),xb(d,a.scrollToPos.to),a.scrollToPos.margin);a.scrollToPos.isCursor&&b.state.focused&&Yd(b,h)}var i=a.maybeHiddenMarkers,j=a.maybeUnhiddenMarkers;if(i)for(var k=0;ka.barMeasure.clientWidth&&a.barMeasure.scrollWidthf;f=e){var g=new Oc(a.doc,Of(a.doc,f),f);e=f+g.size,d.push(g)}return d}function Qc(a,b,c,d){null==b&&(b=a.doc.first),null==c&&(c=a.doc.first+a.doc.size),d||(d=0);var e=a.display;if(d&&cb)&&(e.updateLineNumbers=b),a.curOp.viewChanged=!0,b>=e.viewTo)v&&bf(a.doc,b)e.viewFrom?Sc(a):(e.viewFrom+=d,e.viewTo+=d);else if(b<=e.viewFrom&&c>=e.viewTo)Sc(a);else if(b<=e.viewFrom){var f=Uc(a,c,c+d,1);f?(e.view=e.view.slice(f.index),e.viewFrom=f.lineN,e.viewTo+=d):Sc(a)}else if(c>=e.viewTo){var f=Uc(a,b,b,-1);f?(e.view=e.view.slice(0,f.index),e.viewTo=f.lineN):Sc(a)}else{var g=Uc(a,b,b,-1),h=Uc(a,c,c+d,1);g&&h?(e.view=e.view.slice(0,g.index).concat(Pc(a,g.lineN,h.lineN)).concat(e.view.slice(h.index)),e.viewTo+=d):Sc(a)}var i=e.externalMeasured;i&&(c=e.lineN&&b=d.viewTo)){var f=d.view[Tc(a,b)];if(null!=f.node){var g=f.changes||(f.changes=[]);-1==Lg(g,c)&&g.push(c)}}}function Sc(a){a.display.viewFrom=a.display.viewTo=a.doc.first,a.display.view=[],a.display.viewOffset=0}function Tc(a,b){if(b>=a.display.viewTo)return null;if(b-=a.display.viewFrom,0>b)return null;for(var c=a.display.view,d=0;db)return d}function Uc(a,b,c,d){var f,e=Tc(a,b),g=a.display.view;if(!v||c==a.doc.first+a.doc.size)return{index:e,lineN:c};for(var h=0,i=a.display.viewFrom;e>h;h++)i+=g[h].size;if(i!=b){if(d>0){if(e==g.length-1)return null;f=i+g[e].size-b,e++}else f=i-b;b+=f,c+=f}for(;bf(a.doc,c)!=c;){if(e==(0>d?0:g.length-1))return null;c+=d*g[e-(0>d?1:0)].size,e+=d}return{index:e,lineN:c}}function Vc(a,b,c){var d=a.display,e=d.view;0==e.length||b>=d.viewTo||c<=d.viewFrom?(d.view=Pc(a,b,c),d.viewFrom=b):(d.viewFrom>b?d.view=Pc(a,b,d.viewFrom).concat(d.view):d.viewFromc&&(d.view=d.view.slice(0,Tc(a,c)))),d.viewTo=c}function Wc(a){for(var b=a.display.view,c=0,d=0;d=9&&a.display.inputHasSelection===g||p&&/[\uf700-\uf7ff]/.test(g))return _c(a),!1;var h=!a.curOp;h&&Bc(a),a.display.shift=!1,8203!=g.charCodeAt(0)||f.sel!=a.display.selForContextMenu||c||(c="\u200b");for(var i=0,j=Math.min(c.length,g.length);j>i&&c.charCodeAt(i)==g.charCodeAt(i);)++i;var k=g.slice(i),l=ph(k),m=null;a.state.pasteIncoming&&f.sel.ranges.length>1&&(Zc&&Zc.join("\n")==k?m=0==f.sel.ranges.length%Zc.length&&Mg(Zc,ph):l.length==f.sel.ranges.length&&(m=Mg(l,function(a){return[a]})));for(var n=f.sel.ranges.length-1;n>=0;n--){var o=f.sel.ranges[n],q=o.from(),r=o.to();i-1){de(a,v.line,"smart");break}}else u.electricInput&&u.electricInput.test(Of(f,v.line).text.slice(0,v.ch))&&de(a,v.line,"smart")}}return be(a),a.curOp.updateInput=s,a.curOp.typing=!0,g.length>1e3||g.indexOf("\n")>-1?b.value=a.display.prevInput="":a.display.prevInput=g,h&&Dc(a),a.state.pasteIncoming=a.state.cutIncoming=!1,!0}function _c(a,b){var c,f,g=a.doc;if(a.somethingSelected()){a.display.prevInput="";var h=g.sel.primary();c=rh&&(h.to().line-h.from().line>100||(f=a.getSelection()).length>1e3);var i=c?"-":f||a.getSelection();a.display.input.value=i,a.state.focused&&Kg(a.display.input),d&&e>=9&&(a.display.inputHasSelection=i)}else b||(a.display.prevInput=a.display.input.value="",d&&e>=9&&(a.display.inputHasSelection=null));a.display.inaccurateSelection=c}function ad(a){"nocursor"==a.options.readOnly||o&&_g()==a.display.input||a.display.input.focus()}function bd(a){a.state.focused||(ad(a),Hd(a))}function cd(a){return a.options.readOnly||a.doc.cantEdit}function dd(a){function c(){a.state.focused&&setTimeout(Pg(ad,a),0)}function g(b){vg(a,b)||mg(b)}function h(c){if(a.somethingSelected())Zc=a.getSelections(),b.inaccurateSelection&&(b.prevInput="",b.inaccurateSelection=!1,b.input.value=Zc.join("\n"),Kg(b.input));else{for(var d=[],e=[],f=0;fe?pg(b.scroller,"dblclick",Lc(a,function(b){if(!vg(a,b)){var c=gd(a,b);if(c&&!od(a,b)&&!fd(a.display,b)){jg(b);var d=a.findWordAt(c);Cb(a.doc,d.anchor,d.head)}}})):pg(b.scroller,"dblclick",function(b){vg(a,b)||jg(b)}),pg(b.lineSpace,"selectstart",function(a){fd(b,a)||jg(a)}),t||pg(b.scroller,"contextmenu",function(b){Jd(a,b)}),pg(b.scroller,"scroll",function(){b.scroller.clientHeight&&(sd(a,b.scroller.scrollTop),td(a,b.scroller.scrollLeft,!0),rg(a,"scroll",a))}),pg(b.scrollbarV,"scroll",function(){b.scroller.clientHeight&&sd(a,b.scrollbarV.scrollTop)}),pg(b.scrollbarH,"scroll",function(){b.scroller.clientHeight&&td(a,b.scrollbarH.scrollLeft)}),pg(b.scroller,"mousewheel",function(b){wd(a,b)}),pg(b.scroller,"DOMMouseScroll",function(b){wd(a,b)}),pg(b.scrollbarH,"mousedown",c),pg(b.scrollbarV,"mousedown",c),pg(b.wrapper,"scroll",function(){b.wrapper.scrollTop=b.wrapper.scrollLeft=0}),pg(b.input,"keyup",function(b){Fd.call(a,b)}),pg(b.input,"input",function(){d&&e>=9&&a.display.inputHasSelection&&(a.display.inputHasSelection=null),Yc(a)}),pg(b.input,"keydown",Lc(a,Dd)),pg(b.input,"keypress",Lc(a,Gd)),pg(b.input,"focus",Pg(Hd,a)),pg(b.input,"blur",Pg(Id,a)),a.options.dragDrop&&(pg(b.scroller,"dragstart",function(b){rd(a,b)}),pg(b.scroller,"dragenter",g),pg(b.scroller,"dragover",g),pg(b.scroller,"drop",Lc(a,qd))),pg(b.scroller,"paste",function(c){fd(b,c)||(a.state.pasteIncoming=!0,ad(a),Yc(a))}),pg(b.input,"paste",function(){if(f&&!a.state.fakedLastChar&&!(new Date-a.state.lastMiddleDown<200)){var c=b.input.selectionStart,d=b.input.selectionEnd;b.input.value+="$",b.input.selectionEnd=d,b.input.selectionStart=c,a.state.fakedLastChar=!0}a.state.pasteIncoming=!0,Yc(a)}),pg(b.input,"cut",h),pg(b.input,"copy",h),k&&pg(b.sizer,"mouseup",function(){_g()==b.input&&b.input.blur(),ad(a)})}function ed(a){var b=a.display;b.cachedCharWidth=b.cachedTextHeight=b.cachedPaddingH=null,a.setSize()}function fd(a,b){for(var c=ng(b);c!=a.wrapper;c=c.parentNode)if(!c||c.ignoreEvents||c.parentNode==a.sizer&&c!=a.mover)return!0}function gd(a,b,c,d){var e=a.display;if(!c){var f=ng(b);if(f==e.scrollbarH||f==e.scrollbarV||f==e.scrollbarFiller||f==e.gutterFiller)return null}var g,h,i=e.lineSpace.getBoundingClientRect();try{g=b.clientX-i.left,h=b.clientY-i.top}catch(b){return null}var k,j=uc(a,g,h);if(d&&1==j.xRel&&(k=Of(a.doc,j.line).text).length==j.ch){var l=Fg(k,k.length,a.options.tabSize)-k.length;j=nb(j.line,Math.max(0,Math.round((g-$b(a.display).left)/yc(a.display))-l))}return j}function hd(a){if(!vg(this,a)){var b=this,c=b.display;if(c.shift=a.shiftKey,fd(c,a))return f||(c.scroller.draggable=!1,setTimeout(function(){c.scroller.draggable=!0},100)),void 0;if(!od(b,a)){var d=gd(b,a);switch(window.focus(),og(a)){case 1:d?kd(b,a,d):ng(a)==c.scroller&&jg(a);break;case 2:f&&(b.state.lastMiddleDown=+new Date),d&&Cb(b.doc,d),setTimeout(Pg(ad,b),20),jg(a);break;case 3:t&&Jd(b,a)}}}}function kd(a,b,c){setTimeout(Pg(bd,a),0);var e,d=+new Date;jd&&jd.time>d-400&&0==ob(jd.pos,c)?e="triple":id&&id.time>d-400&&0==ob(id.pos,c)?(e="double",jd={time:d,pos:c}):(e="single",id={time:d,pos:c});var f=a.doc.sel,g=p?b.metaKey:b.ctrlKey;a.options.dragDrop&&ih&&!cd(a)&&"single"==e&&f.contains(c)>-1&&f.somethingSelected()?ld(a,b,c,g):md(a,b,c,e,g)}function ld(a,b,c,g){var h=a.display,i=Lc(a,function(j){f&&(h.scroller.draggable=!1),a.state.draggingText=!1,qg(document,"mouseup",i),qg(h.scroller,"drop",i),Math.abs(b.clientX-j.clientX)+Math.abs(b.clientY-j.clientY)<10&&(jg(j),g||Cb(a.doc,c),ad(a),d&&9==e&&setTimeout(function(){document.body.focus(),ad(a)},20))});f&&(h.scroller.draggable=!0),a.state.draggingText=i,h.scroller.dragDrop&&h.scroller.dragDrop(),pg(document,"mouseup",i),pg(h.scroller,"drop",i)}function md(a,b,c,d,e){function n(b){if(0!=ob(m,b))if(m=b,"rect"==d){for(var e=[],f=a.options.tabSize,k=Fg(Of(g,c.line).text,c.ch,f),l=Fg(Of(g,b.line).text,b.ch,f),n=Math.min(k,l),o=Math.max(k,l),p=Math.min(c.line,b.line),q=Math.min(a.lastLine(),Math.max(c.line,b.line));q>=p;p++){var r=Of(g,p).text,s=Gg(r,n,f);n==o?e.push(new tb(nb(p,s),nb(p,s))):r.length>s&&e.push(new tb(nb(p,s),nb(p,Gg(r,o,f))))}e.length||e.push(new tb(c,c)),Ib(g,ub(j.ranges.slice(0,i).concat(e),i),{origin:"*mouse",scroll:!1}),a.scrollIntoView(b)}else{var t=h,u=t.anchor,v=b;if("single"!=d){if("double"==d)var w=a.findWordAt(b);else var w=new tb(nb(b.line,0),xb(g,nb(b.line+1,0)));ob(w.anchor,u)>0?(v=w.head,u=rb(t.from(),w.anchor)):(v=w.anchor,u=qb(t.to(),w.head))}var e=j.ranges.slice(0);e[i]=new tb(xb(g,u),v),Ib(g,ub(e,i),Cg)}}function q(b){var c=++p,e=gd(a,b,!0,"rect"==d);if(e)if(0!=ob(e,m)){bd(a),n(e);var h=O(f,g);(e.line>=h.to||e.lineo.bottom?20:0;i&&setTimeout(Lc(a,function(){p==c&&(f.scroller.scrollTop+=i,q(b))}),50)}}function r(b){p=1/0,jg(b),ad(a),qg(document,"mousemove",s),qg(document,"mouseup",t),g.history.lastSelOrigin=null}var f=a.display,g=a.doc;jg(b);var h,i,j=g.sel;if(e&&!b.shiftKey?(i=g.sel.contains(c),h=i>-1?g.sel.ranges[i]:new tb(c,c)):h=g.sel.primary(),b.altKey)d="rect",e||(h=new tb(c,c)),c=gd(a,b,!0,!0),i=-1;else if("double"==d){var k=a.findWordAt(c);h=a.display.shift||g.extend?Bb(g,h,k.anchor,k.head):k}else if("triple"==d){var l=new tb(nb(c.line,0),xb(g,nb(c.line+1,0)));h=a.display.shift||g.extend?Bb(g,h,l.anchor,l.head):l}else h=Bb(g,h,c);e?i>-1?Eb(g,i,h,Cg):(i=g.sel.ranges.length,Ib(g,ub(g.sel.ranges.concat([h]),i),{scroll:!1,origin:"*mouse"})):(i=0,Ib(g,new sb([h],0),Cg),j=g.sel);var m=c,o=f.wrapper.getBoundingClientRect(),p=0,s=Lc(a,function(a){og(a)?q(a):r(a)}),t=Lc(a,r);pg(document,"mousemove",s),pg(document,"mouseup",t)}function nd(a,b,c,d,e){try{var f=b.clientX,g=b.clientY}catch(b){return!1}if(f>=Math.floor(a.display.gutters.getBoundingClientRect().right))return!1;d&&jg(b);var h=a.display,i=h.lineDiv.getBoundingClientRect();if(g>i.bottom||!xg(a,c))return lg(b);g-=i.top-h.viewOffset;for(var j=0;j=f){var l=Tf(a.doc,g),m=a.options.gutters[j];return e(a,c,a,l,m,b),lg(b)}}}function od(a,b){return nd(a,b,"gutterClick",!0,tg)}function qd(a){var b=this;if(!vg(b,a)&&!fd(b.display,a)){jg(a),d&&(pd=+new Date);var c=gd(b,a,!0),e=a.dataTransfer.files;if(c&&!cd(b))if(e&&e.length&&window.FileReader&&window.File)for(var f=e.length,g=Array(f),h=0,i=function(a,d){var e=new FileReader;e.onload=Lc(b,function(){if(g[d]=e.result,++h==f){c=xb(b.doc,c);var a={from:c,to:c,text:ph(g.join("\n")),origin:"paste"};Rd(b.doc,a),Hb(b.doc,vb(c,Ld(a)))}}),e.readAsText(a)},j=0;f>j;++j)i(e[j],j);else{if(b.state.draggingText&&b.doc.sel.contains(c)>-1)return b.state.draggingText(a),setTimeout(Pg(ad,b),20),void 0;try{var g=a.dataTransfer.getData("Text");if(g){if(b.state.draggingText&&!(p?a.metaKey:a.ctrlKey))var k=b.listSelections();if(Jb(b.doc,vb(c,c)),k)for(var j=0;jh.clientWidth||e&&h.scrollHeight>h.clientHeight){if(e&&p&&f)a:for(var j=c.target,k=g.view;j!=h;j=j.parentNode)for(var l=0;lm?n=Math.max(0,n+m-50):o=Math.min(b.doc.height,o+m+50),W(b,{top:n,bottom:o})}20>ud&&(null==g.wheelStartX?(g.wheelStartX=h.scrollLeft,g.wheelStartY=h.scrollTop,g.wheelDX=d,g.wheelDY=e,setTimeout(function(){if(null!=g.wheelStartX){var a=h.scrollLeft-g.wheelStartX,b=h.scrollTop-g.wheelStartY,c=b&&g.wheelDY&&b/g.wheelDY||a&&g.wheelDX&&a/g.wheelDX;g.wheelStartX=g.wheelStartY=null,c&&(vd=(vd*ud+c)/(ud+1),++ud)}},200)):(g.wheelDX+=d,g.wheelDY+=e))}}function xd(a,b,c){if("string"==typeof b&&(b=te[b],!b))return!1;a.display.pollingFast&&$c(a)&&(a.display.pollingFast=!1);var d=a.display.shift,e=!1;try{cd(a)&&(a.state.suppressEdits=!0),c&&(a.display.shift=!1),e=b(a)!=Ag}finally{a.display.shift=d,a.state.suppressEdits=!1}return e}function yd(a){var b=a.state.keyMaps.slice(0);return a.options.extraKeys&&b.push(a.options.extraKeys),b.push(a.options.keyMap),b}function Ad(a,b){var c=ve(a.options.keyMap),d=c.auto;clearTimeout(zd),d&&!xe(b)&&(zd=setTimeout(function(){ve(a.options.keyMap)==c&&(a.options.keyMap=d.call?d.call(null,a):d,D(a))},50));var e=ye(b,!0),f=!1;if(!e)return!1;var g=yd(a);return f=b.shiftKey?we("Shift-"+e,g,function(b){return xd(a,b,!0)})||we(e,g,function(b){return("string"==typeof b?/^go[A-Z]/.test(b):b.motion)?xd(a,b):void 0}):we(e,g,function(b){return xd(a,b)}),f&&(jg(b),Tb(a),tg(a,"keyHandled",a,e,b)),f}function Bd(a,b,c){var d=we("'"+c+"'",yd(a),function(b){return xd(a,b,!0)});return d&&(jg(b),Tb(a),tg(a,"keyHandled",a,"'"+c+"'",b)),d}function Dd(a){var b=this;if(bd(b),!vg(b,a)){d&&11>e&&27==a.keyCode&&(a.returnValue=!1);var c=a.keyCode;b.display.shift=16==c||a.shiftKey;var f=Ad(b,a);i&&(Cd=f?c:null,!f&&88==c&&!rh&&(p?a.metaKey:a.ctrlKey)&&b.replaceSelection("",null,"cut")),18!=c||/\bCodeMirror-crosshair\b/.test(b.display.lineDiv.className)||Ed(b)}}function Ed(a){function c(a){18!=a.keyCode&&a.altKey||(bh(b,"CodeMirror-crosshair"),qg(document,"keyup",c),qg(document,"mouseover",c))}var b=a.display.lineDiv;ch(b,"CodeMirror-crosshair"),pg(document,"keyup",c),pg(document,"mouseover",c)}function Fd(a){16==a.keyCode&&(this.doc.sel.shift=!1),vg(this,a)}function Gd(a){var b=this;if(!(vg(b,a)||a.ctrlKey&&!a.altKey||p&&a.metaKey)){var c=a.keyCode,f=a.charCode;if(i&&c==Cd)return Cd=null,jg(a),void 0;if(!(i&&(!a.which||a.which<10)||k)||!Ad(b,a)){var g=String.fromCharCode(null==f?c:f);Bd(b,a,g)||(d&&e>=9&&(b.display.inputHasSelection=null),Yc(b))}}}function Hd(a){"nocursor"!=a.options.readOnly&&(a.state.focused||(rg(a,"focus",a),a.state.focused=!0,ch(a.display.wrapper,"CodeMirror-focused"),a.curOp||a.display.selForContextMenu==a.doc.sel||(_c(a),f&&setTimeout(Pg(_c,a,!0),0))),Xc(a),Tb(a))}function Id(a){a.state.focused&&(rg(a,"blur",a),a.state.focused=!1,bh(a.display.wrapper,"CodeMirror-focused")),clearInterval(a.display.blinker),setTimeout(function(){a.state.focused||(a.display.shift=!1)},150)}function Jd(a,b){function m(){if(null!=c.input.selectionStart){var b=a.somethingSelected(),d=c.input.value="\u200b"+(b?c.input.value:"");c.prevInput=b?"":"\u200b",c.input.selectionStart=1,c.input.selectionEnd=d.length,c.selForContextMenu=a.doc.sel}}function n(){if(c.inputDiv.style.position="relative",c.input.style.cssText=k,d&&9>e&&(c.scrollbarV.scrollTop=c.scroller.scrollTop=h),Xc(a),null!=c.input.selectionStart){(!d||d&&9>e)&&m();var b=0,f=function(){c.selForContextMenu==a.doc.sel&&0==c.input.selectionStart?Lc(a,te.selectAll)(a):b++<10?c.detectingSelectAll=setTimeout(f,500):_c(a)};c.detectingSelectAll=setTimeout(f,200)}}if(!vg(a,b,"contextmenu")){var c=a.display;if(!fd(c,b)&&!Kd(a,b)){var g=gd(a,b),h=c.scroller.scrollTop;if(g&&!i){var j=a.options.resetSelectionOnContextMenu;j&&-1==a.doc.sel.contains(g)&&Lc(a,Ib)(a.doc,vb(g),Bg);var k=c.input.style.cssText;if(c.inputDiv.style.position="absolute",c.input.style.cssText="position: fixed; width: 30px; height: 30px; top: "+(b.clientY-5)+"px; left: "+(b.clientX-5)+"px; z-index: 1000; background: "+(d?"rgba(255, 255, 255, .05)":"transparent")+"; outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);",f)var l=window.scrollY;if(ad(a),f&&window.scrollTo(null,l),_c(a),a.somethingSelected()||(c.input.value=c.prevInput=" "),c.selForContextMenu=a.doc.sel,clearTimeout(c.detectingSelectAll),d&&e>=9&&m(),t){mg(b);var o=function(){qg(window,"mouseup",o),setTimeout(n,20)};pg(window,"mouseup",o)}else setTimeout(n,50)}}}}function Kd(a,b){return xg(a,"gutterContextMenu")?nd(a,b,"gutterContextMenu",!1,rg):!1}function Md(a,b){if(ob(a,b.from)<0)return a;if(ob(a,b.to)<=0)return Ld(b);var c=a.line+b.text.length-(b.to.line-b.from.line)-1,d=a.ch;return a.line==b.to.line&&(d+=Ld(b).ch-b.to.ch),nb(c,d)}function Nd(a,b){for(var c=[],d=0;d=0;--e)Sd(a,{from:d[e].from,to:d[e].to,text:e?[""]:b.text});else Sd(a,b)}}function Sd(a,b){if(1!=b.text.length||""!=b.text[0]||0!=ob(b.from,b.to)){var c=Nd(a,b);$f(a,b,c,a.cm?a.cm.curOp.id:0/0),Vd(a,b,c,Oe(a,b));var d=[];Mf(a,function(a,c){c||-1!=Lg(d,a.history)||(ig(a.history,b),d.push(a.history)),Vd(a,b,null,Oe(a,b))})}}function Td(a,b,c){if(!a.cm||!a.cm.state.suppressEdits){for(var e,d=a.history,f=a.sel,g="undo"==b?d.done:d.undone,h="undo"==b?d.undone:d.done,i=0;i=0;--i){var l=e.changes[i];if(l.origin=b,k&&!Qd(a,l,!1))return g.length=0,void 0;j.push(Xf(a,l));var m=i?Nd(a,l):Jg(g);Vd(a,l,m,Qe(a,l)),!i&&a.cm&&a.cm.scrollIntoView({from:l.from,to:Ld(l)});var n=[];Mf(a,function(a,b){b||-1!=Lg(n,a.history)||(ig(a.history,l),n.push(a.history)),Vd(a,l,null,Qe(a,l))})}}}}function Ud(a,b){if(0!=b&&(a.first+=b,a.sel=new sb(Mg(a.sel.ranges,function(a){return new tb(nb(a.anchor.line+b,a.anchor.ch),nb(a.head.line+b,a.head.ch))}),a.sel.primIndex),a.cm)){Qc(a.cm,a.first,a.first-b,b);for(var c=a.cm.display,d=c.viewFrom;da.lastLine())){if(b.from.linef&&(b={from:b.from,to:nb(f,Of(a,f).text.length),text:[b.text[0]],origin:b.origin}),b.removed=Pf(a,b.from,b.to),c||(c=Nd(a,b)),a.cm?Wd(a.cm,b,d):Ff(a,b,d),Jb(a,c,Bg)}}function Wd(a,b,c){var d=a.doc,e=a.display,f=b.from,g=b.to,h=!1,i=f.line;a.options.lineWrapping||(i=Sf(_e(Of(d,f.line))),d.iter(i,g.line+1,function(a){return a==e.maxLine?(h=!0,!0):void 0})),d.sel.contains(b.from,b.to)>-1&&wg(a),Ff(d,b,c,B(a)),a.options.lineWrapping||(d.iter(i,f.line+b.text.length,function(a){var b=I(a);b>e.maxLineLength&&(e.maxLine=a,e.maxLineLength=b,e.maxLineChanged=!0,h=!1)}),h&&(a.curOp.updateMaxLine=!0)),d.frontier=Math.min(d.frontier,f.line),Ub(a,400);var j=b.text.length-(g.line-f.line)-1;f.line!=g.line||1!=b.text.length||Ef(a.doc,b)?Qc(a,f.line,g.line+1,j):Rc(a,f.line,"text");var k=xg(a,"changes"),l=xg(a,"change");if(l||k){var m={from:f,to:g,text:b.text,removed:b.removed,origin:b.origin};l&&tg(a,"change",a,m),k&&(a.curOp.changeObjs||(a.curOp.changeObjs=[])).push(m)}a.display.selForContextMenu=null}function Xd(a,b,c,d,e){if(d||(d=c),ob(d,c)<0){var f=d;d=c,c=f}"string"==typeof b&&(b=ph(b)),Rd(a,{from:c,to:d,text:b,origin:e})}function Yd(a,b){var c=a.display,d=c.sizer.getBoundingClientRect(),e=null;if(b.top+d.top<0?e=!0:b.bottom+d.top>(window.innerHeight||document.documentElement.clientHeight)&&(e=!1),null!=e&&!m){var f=Wg("div","\u200b",null,"position: absolute; top: "+(b.top-c.viewOffset-Yb(a.display))+"px; height: "+(b.bottom-b.top+zg)+"px; left: "+b.left+"px; width: 2px;");a.display.lineSpace.appendChild(f),f.scrollIntoView(e),a.display.lineSpace.removeChild(f)}}function Zd(a,b,c,d){for(null==d&&(d=0);;){var e=!1,f=rc(a,b),g=c&&c!=b?rc(a,c):f,h=_d(a,Math.min(f.left,g.left),Math.min(f.top,g.top)-d,Math.max(f.left,g.left),Math.max(f.bottom,g.bottom)+d),i=a.doc.scrollTop,j=a.doc.scrollLeft;if(null!=h.scrollTop&&(sd(a,h.scrollTop),Math.abs(a.doc.scrollTop-i)>1&&(e=!0)),null!=h.scrollLeft&&(td(a,h.scrollLeft),Math.abs(a.doc.scrollLeft-j)>1&&(e=!0)),!e)return f}}function $d(a,b,c,d,e){var f=_d(a,b,c,d,e);null!=f.scrollTop&&sd(a,f.scrollTop),null!=f.scrollLeft&&td(a,f.scrollLeft)}function _d(a,b,c,d,e){var f=a.display,g=xc(a.display);0>c&&(c=0);var h=a.curOp&&null!=a.curOp.scrollTop?a.curOp.scrollTop:f.scroller.scrollTop,i=f.scroller.clientHeight-zg,j={};e-c>i&&(e=c+i);var k=a.doc.height+Zb(f),l=g>c,m=e>k-g;if(h>c)j.scrollTop=l?0:c;else if(e>h+i){var n=Math.min(c,(m?k:e)-i);n!=h&&(j.scrollTop=n)}var o=a.curOp&&null!=a.curOp.scrollLeft?a.curOp.scrollLeft:f.scroller.scrollLeft,p=f.scroller.clientWidth-zg-f.gutters.offsetWidth,q=d-b>p;return q&&(d=c+i),10>b?j.scrollLeft=0:o>b?j.scrollLeft=Math.max(0,b-(q?0:10)):d>p+o-3&&(j.scrollLeft=d+(q?0:10)-p),j}function ae(a,b,c){(null!=b||null!=c)&&ce(a),null!=b&&(a.curOp.scrollLeft=(null==a.curOp.scrollLeft?a.doc.scrollLeft:a.curOp.scrollLeft)+b),null!=c&&(a.curOp.scrollTop=(null==a.curOp.scrollTop?a.doc.scrollTop:a.curOp.scrollTop)+c)}function be(a){ce(a);var b=a.getCursor(),c=b,d=b;a.options.lineWrapping||(c=b.ch?nb(b.line,b.ch-1):b,d=nb(b.line,b.ch+1)),a.curOp.scrollToPos={from:c,to:d,margin:a.options.cursorScrollMargin,isCursor:!0}}function ce(a){var b=a.curOp.scrollToPos;if(b){a.curOp.scrollToPos=null;var c=sc(a,b.from),d=sc(a,b.to),e=_d(a,Math.min(c.left,d.left),Math.min(c.top,d.top)-b.margin,Math.max(c.right,d.right),Math.max(c.bottom,d.bottom)+b.margin);a.scrollTo(e.scrollLeft,e.scrollTop)}}function de(a,b,c,d){var f,e=a.doc;null==c&&(c="add"),"smart"==c&&(e.mode.indent?f=Xb(a,b):c="prev");var g=a.options.tabSize,h=Of(e,b),i=Fg(h.text,null,g);h.stateAfter&&(h.stateAfter=null);var k,j=h.text.match(/^\s*/)[0];if(d||/\S/.test(h.text)){if("smart"==c&&(k=e.mode.indent(f,h.text.slice(j.length),h.text),k==Ag||k>150)){if(!d)return;c="prev"}}else k=0,c="not";"prev"==c?k=b>e.first?Fg(Of(e,b-1).text,null,g):0:"add"==c?k=i+a.options.indentUnit:"subtract"==c?k=i-a.options.indentUnit:"number"==typeof c&&(k=i+c),k=Math.max(0,k);var l="",m=0;if(a.options.indentWithTabs)for(var n=Math.floor(k/g);n;--n)m+=g,l+=" ";if(k>m&&(l+=Ig(k-m)),l!=j)Xd(e,l,nb(b,0),nb(b,j.length),"+input");else for(var n=0;n=0;b--)Xd(a.doc,"",d[b].from,d[b].to,"+delete");be(a)})}function ge(a,b,c,d,e){function k(){var b=f+c;return b=a.first+a.size?j=!1:(f=b,i=Of(a,b))}function l(a){var b=(e?Hh:Ih)(i,g,c,!0);if(null==b){if(a||!k())return j=!1;g=e?(0>c?zh:yh)(i):0>c?i.text.length:0}else g=b;return!0}var f=b.line,g=b.ch,h=c,i=Of(a,f),j=!0;if("char"==d)l();else if("column"==d)l(!0);else if("word"==d||"group"==d)for(var m=null,n="group"==d,o=a.cm&&a.cm.getHelper(b,"wordChars"),p=!0;!(0>c)||l(!p);p=!1){var q=i.text.charAt(g)||"\n",r=Sg(q,o)?"w":n&&"\n"==q?"n":!n||/\s/.test(q)?null:"p";if(!n||p||r||(r="s"),m&&m!=r){0>c&&(c=1,l());break}if(r&&(m=r),c>0&&!l(!p))break}var s=Nb(a,nb(f,g),h,!0);return j||(s.hitSide=!0),s}function he(a,b,c,d){var g,e=a.doc,f=b.left;if("page"==d){var h=Math.min(a.display.wrapper.clientHeight,window.innerHeight||document.documentElement.clientHeight);g=b.top+c*(h-(0>c?1.5:.5)*xc(a.display))}else"line"==d&&(g=c>0?b.bottom+3:b.top-3);for(;;){var i=uc(a,f,g);if(!i.outside)break;if(0>c?0>=g:g>=e.height){i.hitSide=!0;break}g+=5*c}return i}function ke(a,b,c,d){w.defaults[a]=b,c&&(je[a]=d?function(a,b,d){d!=le&&c(a,b,d)}:c)}function ve(a){return"string"==typeof a?ue[a]:a}function Ce(a,b,c,d,e){if(d&&d.shared)return Ee(a,b,c,d,e);if(a.cm&&!a.cm.curOp)return Lc(a.cm,Ce)(a,b,c,d,e);var f=new Ae(a,e),g=ob(b,c);if(d&&Og(d,f,!1),g>0||0==g&&f.clearWhenEmpty!==!1)return f;if(f.replacedWith&&(f.collapsed=!0,f.widgetNode=Wg("span",[f.replacedWith],"CodeMirror-widget"),d.handleMouseEvents||(f.widgetNode.ignoreEvents=!0),d.insertLeft&&(f.widgetNode.insertLeft=!0)),f.collapsed){if($e(a,b.line,b,c,f)||b.line!=c.line&&$e(a,c.line,b,c,f))throw new Error("Inserting collapsed marker partially overlapping an existing one");v=!0}f.addToHistory&&$f(a,{from:b,to:c,origin:"markText"},a.sel,0/0);var j,h=b.line,i=a.cm;if(a.iter(h,c.line+1,function(a){i&&f.collapsed&&!i.options.lineWrapping&&_e(a)==i.display.maxLine&&(j=!0),f.collapsed&&h!=b.line&&Rf(a,0),Le(a,new Ie(f,h==b.line?b.ch:null,h==c.line?c.ch:null)),++h}),f.collapsed&&a.iter(b.line,c.line+1,function(b){df(a,b)&&Rf(b,0)}),f.clearOnEnter&&pg(f,"beforeCursorEnter",function(){f.clear()
-}),f.readOnly&&(u=!0,(a.history.done.length||a.history.undone.length)&&a.clearHistory()),f.collapsed&&(f.id=++Be,f.atomic=!0),i){if(j&&(i.curOp.updateMaxLine=!0),f.collapsed)Qc(i,b.line,c.line+1);else if(f.className||f.title||f.startStyle||f.endStyle)for(var k=b.line;k<=c.line;k++)Rc(i,k,"text");f.atomic&&Lb(i.doc),tg(i,"markerAdded",i,f)}return f}function Ee(a,b,c,d,e){d=Og(d),d.shared=!1;var f=[Ce(a,b,c,d,e)],g=f[0],h=d.widgetNode;return Mf(a,function(a){h&&(d.widgetNode=h.cloneNode(!0)),f.push(Ce(a,xb(a,b),xb(a,c),d,e));for(var i=0;i=b:f.to>b);(e||(e=[])).push(new Ie(g,f.from,i?null:f.to))}}return e}function Ne(a,b,c){if(a)for(var e,d=0;d=b:f.to>b);if(h||f.from==b&&"bookmark"==g.type&&(!c||f.marker.insertLeft)){var i=null==f.from||(g.inclusiveLeft?f.from<=b:f.from0&&h)for(var l=0;ll;++l)o.push(q);o.push(i)}return o}function Pe(a){for(var b=0;b0)){var k=[i,1],l=ob(j.from,h.from),m=ob(j.to,h.to);(0>l||!g.inclusiveLeft&&!l)&&k.push({from:j.from,to:h.from}),(m>0||!g.inclusiveRight&&!m)&&k.push({from:h.to,to:j.to}),e.splice.apply(e,k),i+=k.length-1}}return e}function Se(a){var b=a.markedSpans;if(b){for(var c=0;c=0&&0>=l||0>=k&&l>=0)&&(0>=k&&(ob(j.to,c)>0||i.marker.inclusiveRight&&e.inclusiveLeft)||k>=0&&(ob(j.from,d)<0||i.marker.inclusiveLeft&&e.inclusiveRight)))return!0}}}function _e(a){for(var b;b=Ye(a);)a=b.find(-1,!0).line;return a}function af(a){for(var b,c;b=Ze(a);)a=b.find(1,!0).line,(c||(c=[])).push(a);return c}function bf(a,b){var c=Of(a,b),d=_e(c);return c==d?b:Sf(d)}function cf(a,b){if(b>a.lastLine())return b;var d,c=Of(a,b);if(!df(a,c))return b;for(;d=Ze(c);)c=d.find(1,!0).line;return Sf(c)+1}function df(a,b){var c=v&&b.markedSpans;if(c)for(var d,e=0;ed;d++){var e=a.token(b,c);if(b.pos>b.start)return e}throw new Error("Mode "+a.name+" failed to advance stream.")}function qf(a,b,c,d,e,f,g){var h=c.flattenSpans;null==h&&(h=a.options.flattenSpans);var l,i=0,j=null,k=new ze(b,a.options.tabSize);for(""==b&&nf(of(c,d),f);!k.eol();){if(k.pos>a.options.maxHighlightLength?(h=!1,g&&tf(a,b,d,k.pos),k.pos=b.length,l=null):l=nf(pf(c,k,d),f),a.options.addModeClass){var m=w.innerMode(c,d).mode.name;m&&(l="m-"+(l?m+" "+l:m))}h&&j==l||(ij;){var d=e[i];d>a&&e.splice(i,1,a,e[i+1],d),i+=2,j=Math.min(a,d)}if(b)if(h.opaque)e.splice(c,i-c,a,"cm-overlay "+b),i=c+2;else for(;i>c;c+=2){var f=e[c+1];e[c+1]=(f?f+" ":"")+"cm-overlay "+b}},f)}return{styles:e,classes:f.bgClass||f.textClass?f:null}}function sf(a,b){if(!b.styles||b.styles[0]!=a.state.modeGen){var c=rf(a,b,b.stateAfter=Xb(a,Sf(b)));b.styles=c.styles,c.classes?b.styleClasses=c.classes:b.styleClasses&&(b.styleClasses=null)}return b.styles}function tf(a,b,c,d){var e=a.doc.mode,f=new ze(b,a.options.tabSize);for(f.start=f.pos=d||0,""==b&&of(e,c);!f.eol()&&f.pos<=a.options.maxHighlightLength;)pf(e,f,c),f.start=f.pos}function wf(a,b){if(!a||/^\s*$/.test(a))return null;var c=b.addModeClass?vf:uf;return c[a]||(c[a]=a.replace(/\S+/g,"cm-$&"))}function xf(a,b){var c=Wg("span",null,null,f?"padding-right: .1px":null),e={pre:Wg("pre",[c]),content:c,col:0,pos:0,cm:a};b.measure={};for(var g=0;g<=(b.rest?b.rest.length:0);g++){var i,h=g?b.rest[g-1]:b.line;e.pos=0,e.addToken=zf,(d||f)&&a.getOption("lineWrapping")&&(e.addToken=Af(e.addToken)),oh(a.display.measure)&&(i=Vf(h))&&(e.addToken=Bf(e.addToken,i)),e.map=[],Df(h,e,sf(a,h)),h.styleClasses&&(h.styleClasses.bgClass&&(e.bgClass=dh(h.styleClasses.bgClass,e.bgClass||"")),h.styleClasses.textClass&&(e.textClass=dh(h.styleClasses.textClass,e.textClass||""))),0==e.map.length&&e.map.push(0,0,e.content.appendChild(mh(a.display.measure))),0==g?(b.measure.map=e.map,b.measure.cache={}):((b.measure.maps||(b.measure.maps=[])).push(e.map),(b.measure.caches||(b.measure.caches=[])).push({}))}return rg(a,"renderLine",a,b.line,e.pre),e.pre.className&&(e.textClass=dh(e.pre.className,e.textClass||"")),e}function yf(a){var b=Wg("span","\u2022","cm-invalidchar");return b.title="\\u"+a.charCodeAt(0).toString(16),b}function zf(a,b,c,f,g,h){if(b){var i=a.cm.options.specialChars,j=!1;if(i.test(b))for(var k=document.createDocumentFragment(),l=0;;){i.lastIndex=l;var m=i.exec(b),n=m?m.index-l:b.length-l;if(n){var o=document.createTextNode(b.slice(l,l+n));d&&9>e?k.appendChild(Wg("span",[o])):k.appendChild(o),a.map.push(a.pos,a.pos+n,o),a.col+=n,a.pos+=n}if(!m)break;if(l+=n+1," "==m[0]){var p=a.cm.options.tabSize,q=p-a.col%p,o=k.appendChild(Wg("span",Ig(q),"cm-tab"));a.col+=q}else{var o=a.cm.options.specialCharPlaceholder(m[0]);d&&9>e?k.appendChild(Wg("span",[o])):k.appendChild(o),a.col+=1}a.map.push(a.pos,a.pos+1,o),a.pos++}else{a.col+=b.length;var k=document.createTextNode(b);a.map.push(a.pos,a.pos+b.length,k),d&&9>e&&(j=!0),a.pos+=b.length}if(c||f||g||j){var r=c||"";f&&(r+=f),g&&(r+=g);var s=Wg("span",[k],r);return h&&(s.title=h),a.content.appendChild(s)}a.content.appendChild(k)}}function Af(a){function b(a){for(var b=" ",c=0;ci&&l.from<=i)break}if(l.to>=j)return a(c,d,e,f,g,h);a(c,d.slice(0,l.to-i),e,f,null,h),f=null,d=d.slice(l.to-i),i=l.to}}}function Cf(a,b,c,d){var e=!d&&c.widgetNode;e&&(a.map.push(a.pos,a.pos+b,e),a.content.appendChild(e)),a.pos+=b}function Df(a,b,c){var d=a.markedSpans,e=a.text,f=0;if(d)for(var k,m,n,o,p,q,h=e.length,i=0,g=1,j="",l=0;;){if(l==i){m=n=o=p="",q=null,l=1/0;for(var r=[],s=0;si)?(null!=t.to&&l>t.to&&(l=t.to,n=""),u.className&&(m+=" "+u.className),u.startStyle&&t.from==i&&(o+=" "+u.startStyle),u.endStyle&&t.to==l&&(n+=" "+u.endStyle),u.title&&!p&&(p=u.title),u.collapsed&&(!q||We(q.marker,u)<0)&&(q=t)):t.from>i&&l>t.from&&(l=t.from),"bookmark"==u.type&&t.from==i&&u.widgetNode&&r.push(u)}if(q&&(q.from||0)==i&&(Cf(b,(null==q.to?h+1:q.to)-i,q.marker,null==q.from),null==q.to))return;if(!q&&r.length)for(var s=0;s=h)break;for(var v=Math.min(h,l);;){if(j){var w=i+j.length;if(!q){var x=w>v?j.slice(0,v-i):j;b.addToken(b,x,k?k+m:m,o,i+x.length==l?n:"",p)}if(w>=v){j=j.slice(v-i),i=v;break}i=w,o=""}j=e.slice(f,f=c[g++]),k=wf(c[g++],b.cm.options)}}else for(var g=1;g1&&a.remove(g.line+1,n-1),a.insert(g.line+1,p)}tg(a,"change",a,b)}function Gf(a){this.lines=a,this.parent=null;for(var b=0,c=0;bb||b>=a.size)throw new Error("There is no line "+(b+a.first)+" in the document.");for(var c=a;!c.lines;)for(var d=0;;++d){var e=c.children[d],f=e.chunkSize();if(f>b){c=e;break}b-=f}return c.lines[b]}function Pf(a,b,c){var d=[],e=b.line;return a.iter(b.line,c.line+1,function(a){var f=a.text;e==c.line&&(f=f.slice(0,c.ch)),e==b.line&&(f=f.slice(b.ch)),d.push(f),++e}),d}function Qf(a,b,c){var d=[];return a.iter(b,c,function(a){d.push(a.text)}),d}function Rf(a,b){var c=b-a.height;if(c)for(var d=a;d;d=d.parent)d.height+=c}function Sf(a){if(null==a.parent)return null;for(var b=a.parent,c=Lg(b.lines,a),d=b.parent;d;b=d,d=d.parent)for(var e=0;d.children[e]!=b;++e)c+=d.children[e].chunkSize();return c+b.first}function Tf(a,b){var c=a.first;a:do{for(var d=0;db){a=e;continue a}b-=f,c+=e.chunkSize()}return c}while(!a.lines);for(var d=0;db)break;b-=h}return c+d}function Uf(a){a=_e(a);for(var b=0,c=a.parent,d=0;d1&&!a.done[a.done.length-2].ranges?(a.done.pop(),Jg(a.done)):void 0}function $f(a,b,c,d){var e=a.history;e.undone.length=0;var g,f=+new Date;if((e.lastOp==d||e.lastOrigin==b.origin&&b.origin&&("+"==b.origin.charAt(0)&&a.cm&&e.lastModTime>f-a.cm.options.historyEventDelay||"*"==b.origin.charAt(0)))&&(g=Zf(e,e.lastOp==d))){var h=Jg(g.changes);0==ob(b.from,b.to)&&0==ob(b.from,h.to)?h.to=Ld(b):g.changes.push(Xf(a,b))}else{var i=Jg(e.done);for(i&&i.ranges||bg(a.sel,e.done),g={changes:[Xf(a,b)],generation:e.generation},e.done.push(g);e.done.length>e.undoDepth;)e.done.shift(),e.done[0].ranges||e.done.shift()}e.done.push(c),e.generation=++e.maxGeneration,e.lastModTime=e.lastSelTime=f,e.lastOp=e.lastSelOp=d,e.lastOrigin=e.lastSelOrigin=b.origin,h||rg(a,"historyAdded")}function _f(a,b,c,d){var e=b.charAt(0);return"*"==e||"+"==e&&c.ranges.length==d.ranges.length&&c.somethingSelected()==d.somethingSelected()&&new Date-a.history.lastSelTime<=(a.cm?a.cm.options.historyEventDelay:500)}function ag(a,b,c,d){var e=a.history,f=d&&d.origin;c==e.lastSelOp||f&&e.lastSelOrigin==f&&(e.lastModTime==e.lastSelTime&&e.lastOrigin==f||_f(a,f,Jg(e.done),b))?e.done[e.done.length-1]=b:bg(b,e.done),e.lastSelTime=+new Date,e.lastSelOrigin=f,e.lastSelOp=c,d&&d.clearRedo!==!1&&Yf(e.undone)}function bg(a,b){var c=Jg(b);c&&c.ranges&&c.equals(a)||b.push(a)}function cg(a,b,c,d){var e=b["spans_"+a.id],f=0;a.iter(Math.max(a.first,c),Math.min(a.first+a.size,d),function(c){c.markedSpans&&((e||(e=b["spans_"+a.id]={}))[f]=c.markedSpans),++f})}function dg(a){if(!a)return null;for(var c,b=0;b-1&&(Jg(h)[l]=j[l],delete j[l])}}}return e}function gg(a,b,c,d){c0}function yg(a){a.prototype.on=function(a,b){pg(this,a,b)},a.prototype.off=function(a,b){qg(this,a,b)}}function Eg(){this.id=null}function Gg(a,b,c){for(var d=0,e=0;;){var f=a.indexOf(" ",d);-1==f&&(f=a.length);var g=f-d;if(f==a.length||e+g>=b)return d+Math.min(g,b-e);if(e+=f-d,e+=c-e%c,d=f+1,e>=b)return d}}function Ig(a){for(;Hg.length<=a;)Hg.push(Jg(Hg)+" ");return Hg[a]}function Jg(a){return a[a.length-1]}function Lg(a,b){for(var c=0;c-1&&Rg(a)?!0:b.test(a):Rg(a)}function Tg(a){for(var b in a)if(a.hasOwnProperty(b)&&a[b])return!1;return!0}function Vg(a){return a.charCodeAt(0)>=768&&Ug.test(a)}function Wg(a,b,c,d){var e=document.createElement(a);if(c&&(e.className=c),d&&(e.style.cssText=d),"string"==typeof b)e.appendChild(document.createTextNode(b));else if(b)for(var f=0;f0;--b)a.removeChild(a.firstChild);return a}function Zg(a,b){return Yg(a).appendChild(b)}function $g(a,b){if(a.contains)return a.contains(b);for(;b=b.parentNode;)if(b==a)return!0}function _g(){return document.activeElement}function ah(a){return new RegExp("\\b"+a+"\\b\\s*")}function bh(a,b){var c=ah(b);c.test(a.className)&&(a.className=a.className.replace(c,""))}function ch(a,b){ah(b).test(a.className)||(a.className+=" "+b)}function dh(a,b){for(var c=a.split(" "),d=0;d2&&!(d&&8>e))}return lh?Wg("span","\u200b"):Wg("span","\xa0",null,"display: inline-block; width: 1px; margin-right: -1px")}function oh(a){if(null!=nh)return nh;var b=Zg(a,document.createTextNode("A\u062eA")),c=Xg(b,0,1).getBoundingClientRect();if(!c||c.left==c.right)return!1;var d=Xg(b,1,2).getBoundingClientRect();return nh=d.right-c.right<3}function th(a){if(null!=sh)return sh;var b=Zg(a,Wg("span","x")),c=b.getBoundingClientRect(),d=Xg(b,0,1).getBoundingClientRect();return sh=Math.abs(c.left-d.left)>1}function vh(a,b,c,d){if(!a)return d(b,c,"ltr");for(var e=!1,f=0;fb||b==c&&g.to==b)&&(d(Math.max(g.from,b),Math.min(g.to,c),1==g.level?"rtl":"ltr"),e=!0)}e||d(b,c,"ltr")}function wh(a){return a.level%2?a.to:a.from}function xh(a){return a.level%2?a.from:a.to}function yh(a){var b=Vf(a);return b?wh(b[0]):0}function zh(a){var b=Vf(a);return b?xh(Jg(b)):a.text.length}function Ah(a,b){var c=Of(a.doc,b),d=_e(c);d!=c&&(b=Sf(d));var e=Vf(d),f=e?e[0].level%2?zh(d):yh(d):0;return nb(b,f)}function Bh(a,b){for(var c,d=Of(a.doc,b);c=Ze(d);)d=c.find(1,!0).line,b=null;var e=Vf(d),f=e?e[0].level%2?yh(d):zh(d):d.text.length;return nb(null==b?Sf(d):b,f)}function Ch(a,b){var c=Ah(a,b.line),d=Of(a.doc,c.line),e=Vf(d);if(!e||0==e[0].level){var f=Math.max(0,d.text.search(/\S/)),g=b.line==c.line&&b.ch<=f&&b.ch;return nb(c.line,g?0:f)}return c}function Dh(a,b,c){var d=a[0].level;return b==d?!0:c==d?!1:c>b}function Fh(a,b){Eh=null;for(var d,c=0;cb)return c;if(e.from==b||e.to==b){if(null!=d)return Dh(a,e.level,a[d].level)?(e.from!=e.to&&(Eh=d),c):(e.from!=e.to&&(Eh=c),d);d=c}}return d}function Gh(a,b,c,d){if(!d)return b+c;do b+=c;while(b>0&&Vg(a.text.charAt(b)));return b}function Hh(a,b,c,d){var e=Vf(a);if(!e)return Ih(a,b,c,d);for(var f=Fh(e,b),g=e[f],h=Gh(a,b,g.level%2?-c:c,d);;){if(h>g.from&&h0==g.level%2?g.to:g.from);if(g=e[f+=c],!g)return null;h=c>0==g.level%2?Gh(a,g.to,-1,d):Gh(a,g.from,1,d)}}function Ih(a,b,c,d){var e=b+c;if(d)for(;e>0&&Vg(a.text.charAt(e));)e+=c;return 0>e||e>a.text.length?null:e}var a=/gecko\/\d/i.test(navigator.userAgent),b=/MSIE \d/.test(navigator.userAgent),c=/Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent),d=b||c,e=d&&(b?document.documentMode||6:c[1]),f=/WebKit\//.test(navigator.userAgent),g=f&&/Qt\/\d+\.\d+/.test(navigator.userAgent),h=/Chrome\//.test(navigator.userAgent),i=/Opera\//.test(navigator.userAgent),j=/Apple Computer/.test(navigator.vendor),k=/KHTML\//.test(navigator.userAgent),l=/Mac OS X 1\d\D([8-9]|\d\d)\D/.test(navigator.userAgent),m=/PhantomJS/.test(navigator.userAgent),n=/AppleWebKit/.test(navigator.userAgent)&&/Mobile\/\w+/.test(navigator.userAgent),o=n||/Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(navigator.userAgent),p=n||/Mac/.test(navigator.platform),q=/win/i.test(navigator.platform),r=i&&navigator.userAgent.match(/Version\/(\d*\.\d*)/);r&&(r=Number(r[1])),r&&r>=15&&(i=!1,f=!0);var s=p&&(g||i&&(null==r||12.11>r)),t=a||d&&e>=9,u=!1,v=!1,nb=w.Pos=function(a,b){return this instanceof nb?(this.line=a,this.ch=b,void 0):new nb(a,b)},ob=w.cmpPos=function(a,b){return a.line-b.line||a.ch-b.ch};sb.prototype={primary:function(){return this.ranges[this.primIndex]},equals:function(a){if(a==this)return!0;if(a.primIndex!=this.primIndex||a.ranges.length!=this.ranges.length)return!1;for(var b=0;b=0&&ob(a,d.to())<=0)return c}return-1}},tb.prototype={from:function(){return rb(this.anchor,this.head)},to:function(){return qb(this.anchor,this.head)},empty:function(){return this.head.line==this.anchor.line&&this.head.ch==this.anchor.ch}};var wc,id,jd,gc={left:0,right:0,top:0,bottom:0},zc=null,Ac=0,Zc=null,pd=0,ud=0,vd=null;d?vd=-.53:a?vd=15:h?vd=-.7:j&&(vd=-1/3);var zd,Cd=null,Ld=w.changeEnd=function(a){return a.text?nb(a.from.line+a.text.length-1,Jg(a.text).length+(1==a.text.length?a.from.ch:0)):a.to};w.prototype={constructor:w,focus:function(){window.focus(),ad(this),Yc(this)},setOption:function(a,b){var c=this.options,d=c[a];(c[a]!=b||"mode"==a)&&(c[a]=b,je.hasOwnProperty(a)&&Lc(this,je[a])(this,b,d))},getOption:function(a){return this.options[a]},getDoc:function(){return this.doc},addKeyMap:function(a,b){this.state.keyMaps[b?"push":"unshift"](a)},removeKeyMap:function(a){for(var b=this.state.keyMaps,c=0;cc&&(de(this,e.head.line,a,!0),c=e.head.line,d==this.doc.sel.primIndex&&be(this));else{var f=e.from(),g=e.to(),h=Math.max(c,f.line);c=Math.min(this.lastLine(),g.line-(g.ch?0:1))+1;for(var i=h;c>i;++i)de(this,i,a);var j=this.doc.sel.ranges;0==f.ch&&b.length==j.length&&j[d].from().ch>0&&Eb(this.doc,d,new tb(f,j[d].to()),Bg)}}}),getTokenAt:function(a,b){var c=this.doc;a=xb(c,a);for(var d=Xb(this,a.line,b),e=this.doc.mode,f=Of(c,a.line),g=new ze(f.text,this.options.tabSize);g.pos>1;if((g?b[2*g-1]:0)>=e)d=g;else{if(!(b[2*g+1]h?f:0==h?null:f.slice(0,h-1)},getModeAt:function(a){var b=this.doc.mode;return b.innerMode?w.innerMode(b,this.getTokenAt(a).state).mode:b},getHelper:function(a,b){return this.getHelpers(a,b)[0]},getHelpers:function(a,b){var c=[];if(!qe.hasOwnProperty(b))return qe;var d=qe[b],e=this.getModeAt(a);if("string"==typeof e[b])d[e[b]]&&c.push(d[e[b]]);else if(e[b])for(var f=0;fd&&(a=d,c=!0);var e=Of(this.doc,a);return oc(this,e,{top:0,left:0},b||"page").top+(c?this.doc.height-Uf(e):0)},defaultTextHeight:function(){return xc(this.display)},defaultCharWidth:function(){return yc(this.display)},setGutterMarker:Mc(function(a,b,c){return ee(this.doc,a,"gutter",function(a){var d=a.gutterMarkers||(a.gutterMarkers={});return d[b]=c,!c&&Tg(d)&&(a.gutterMarkers=null),!0})}),clearGutter:Mc(function(a){var b=this,c=b.doc,d=c.first;c.iter(function(c){c.gutterMarkers&&c.gutterMarkers[a]&&(c.gutterMarkers[a]=null,Rc(b,d,"gutter"),Tg(c.gutterMarkers)&&(c.gutterMarkers=null)),++d})}),addLineWidget:Mc(function(a,b,c){return jf(this,a,b,c)}),removeLineWidget:function(a){a.clear()},lineInfo:function(a){if("number"==typeof a){if(!zb(this.doc,a))return null;var b=a;if(a=Of(this.doc,a),!a)return null}else{var b=Sf(a);if(null==b)return null}return{line:b,handle:a,text:a.text,gutterMarkers:a.gutterMarkers,textClass:a.textClass,bgClass:a.bgClass,wrapClass:a.wrapClass,widgets:a.widgets}},getViewport:function(){return{from:this.display.viewFrom,to:this.display.viewTo}},addWidget:function(a,b,c,d,e){var f=this.display;a=rc(this,xb(this.doc,a));var g=a.bottom,h=a.left;if(b.style.position="absolute",f.sizer.appendChild(b),"over"==d)g=a.top;else if("above"==d||"near"==d){var i=Math.max(f.wrapper.clientHeight,this.doc.height),j=Math.max(f.sizer.clientWidth,f.lineSpace.clientWidth);("above"==d||a.bottom+b.offsetHeight>i)&&a.top>b.offsetHeight?g=a.top-b.offsetHeight:a.bottom+b.offsetHeight<=i&&(g=a.bottom),h+b.offsetWidth>j&&(h=j-b.offsetWidth)}b.style.top=g+"px",b.style.left=b.style.right="","right"==e?(h=f.sizer.clientWidth-b.offsetWidth,b.style.right="0px"):("left"==e?h=0:"middle"==e&&(h=(f.sizer.clientWidth-b.offsetWidth)/2),b.style.left=h+"px"),c&&$d(this,h,g,h+b.offsetWidth,g+b.offsetHeight)},triggerOnKeyDown:Mc(Dd),triggerOnKeyPress:Mc(Gd),triggerOnKeyUp:Fd,execCommand:function(a){return te.hasOwnProperty(a)?te[a](this):void 0},findPosH:function(a,b,c,d){var e=1;0>b&&(e=-1,b=-b);for(var f=0,g=xb(this.doc,a);b>f&&(g=ge(this.doc,g,e,c,d),!g.hitSide);++f);return g
-},moveH:Mc(function(a,b){var c=this;c.extendSelectionsBy(function(d){return c.display.shift||c.doc.extend||d.empty()?ge(c.doc,d.head,a,b,c.options.rtlMoveVisually):0>a?d.from():d.to()},Dg)}),deleteH:Mc(function(a,b){var c=this.doc.sel,d=this.doc;c.somethingSelected()?d.replaceSelection("",null,"+delete"):fe(this,function(c){var e=ge(d,c.head,a,b,!1);return 0>a?{from:e,to:c.head}:{from:c.head,to:e}})}),findPosV:function(a,b,c,d){var e=1,f=d;0>b&&(e=-1,b=-b);for(var g=0,h=xb(this.doc,a);b>g;++g){var i=rc(this,h,"div");if(null==f?f=i.left:i.left=f,h=he(this,i,e,c),h.hitSide)break}return h},moveV:Mc(function(a,b){var c=this,d=this.doc,e=[],f=!c.display.shift&&!d.extend&&d.sel.somethingSelected();if(d.extendSelectionsBy(function(g){if(f)return 0>a?g.from():g.to();var h=rc(c,g.head,"div");null!=g.goalColumn&&(h.left=g.goalColumn),e.push(h.left);var i=he(c,h,a,b);return"page"==b&&g==d.sel.primary()&&ae(c,null,qc(c,i,"div").top-h.top),i},Dg),e.length)for(var g=0;g0&&h(c.charAt(d-1));)--d;for(;e.5)&&C(this),rg(this,"refresh",this)}),swapDoc:Mc(function(a){var b=this.doc;return b.cm=null,Nf(this,a),lc(this),_c(this),this.scrollTo(a.scrollLeft,a.scrollTop),this.curOp.forceScroll=!0,tg(this,"swapDoc",this,b),b}),getInputField:function(){return this.display.input},getWrapperElement:function(){return this.display.wrapper},getScrollerElement:function(){return this.display.scroller},getGutterElement:function(){return this.display.gutters}},yg(w);var ie=w.defaults={},je=w.optionHandlers={},le=w.Init={toString:function(){return"CodeMirror.Init"}};ke("value","",function(a,b){a.setValue(b)},!0),ke("mode",null,function(a,b){a.doc.modeOption=b,y(a)},!0),ke("indentUnit",2,y,!0),ke("indentWithTabs",!1),ke("smartIndent",!0),ke("tabSize",4,function(a){z(a),lc(a),Qc(a)},!0),ke("specialChars",/[\t\u0000-\u0019\u00ad\u200b-\u200f\u2028\u2029\ufeff]/g,function(a,b){a.options.specialChars=new RegExp(b.source+(b.test(" ")?"":"| "),"g"),a.refresh()},!0),ke("specialCharPlaceholder",yf,function(a){a.refresh()},!0),ke("electricChars",!0),ke("rtlMoveVisually",!q),ke("wholeLineUpdateBefore",!0),ke("theme","default",function(a){E(a),F(a)},!0),ke("keyMap","default",D),ke("extraKeys",null),ke("lineWrapping",!1,A,!0),ke("gutters",[],function(a){K(a.options),F(a)},!0),ke("fixedGutter",!0,function(a,b){a.display.gutters.style.left=b?S(a.display)+"px":"0",a.refresh()},!0),ke("coverGutterNextToScrollbar",!1,N,!0),ke("lineNumbers",!1,function(a){K(a.options),F(a)},!0),ke("firstLineNumber",1,F,!0),ke("lineNumberFormatter",function(a){return a},F,!0),ke("showCursorWhenSelecting",!1,Qb,!0),ke("resetSelectionOnContextMenu",!0),ke("readOnly",!1,function(a,b){"nocursor"==b?(Id(a),a.display.input.blur(),a.display.disabled=!0):(a.display.disabled=!1,b||_c(a))}),ke("disableInput",!1,function(a,b){b||_c(a)},!0),ke("dragDrop",!0),ke("cursorBlinkRate",530),ke("cursorScrollMargin",0),ke("cursorHeight",1,Qb,!0),ke("singleCursorHeightPerLine",!0,Qb,!0),ke("workTime",100),ke("workDelay",100),ke("flattenSpans",!0,z,!0),ke("addModeClass",!1,z,!0),ke("pollInterval",100),ke("undoDepth",200,function(a,b){a.doc.history.undoDepth=b}),ke("historyEventDelay",1250),ke("viewportMargin",10,function(a){a.refresh()},!0),ke("maxHighlightLength",1e4,z,!0),ke("moveInputWithCursor",!0,function(a,b){b||(a.display.inputDiv.style.top=a.display.inputDiv.style.left=0)}),ke("tabindex",null,function(a,b){a.display.input.tabIndex=b||""}),ke("autofocus",null);var me=w.modes={},ne=w.mimeModes={};w.defineMode=function(a,b){if(w.defaults.mode||"null"==a||(w.defaults.mode=a),arguments.length>2){b.dependencies=[];for(var c=2;c0)e=new nb(e.line,e.ch+1),a.replaceRange(f.charAt(e.ch-1)+f.charAt(e.ch-2),nb(e.line,e.ch-2),e,"+transpose");else if(e.line>a.doc.first){var g=Of(a.doc,e.line-1).text;g&&a.replaceRange(f.charAt(0)+"\n"+g.charAt(g.length-1),nb(e.line-1,g.length-1),nb(e.line,1),"+transpose")}c.push(new tb(e,e))}a.setSelections(c)})},newlineAndIndent:function(a){Kc(a,function(){for(var b=a.listSelections().length,c=0;b>c;c++){var d=a.listSelections()[c];a.replaceRange("\n",d.anchor,d.head,"+input"),a.indentLine(d.from().line+1,null,!0),be(a)}})},toggleOverwrite:function(a){a.toggleOverwrite()}},ue=w.keyMap={};ue.basic={Left:"goCharLeft",Right:"goCharRight",Up:"goLineUp",Down:"goLineDown",End:"goLineEnd",Home:"goLineStartSmart",PageUp:"goPageUp",PageDown:"goPageDown",Delete:"delCharAfter",Backspace:"delCharBefore","Shift-Backspace":"delCharBefore",Tab:"defaultTab","Shift-Tab":"indentAuto",Enter:"newlineAndIndent",Insert:"toggleOverwrite",Esc:"singleSelection"},ue.pcDefault={"Ctrl-A":"selectAll","Ctrl-D":"deleteLine","Ctrl-Z":"undo","Shift-Ctrl-Z":"redo","Ctrl-Y":"redo","Ctrl-Home":"goDocStart","Ctrl-Up":"goDocStart","Ctrl-End":"goDocEnd","Ctrl-Down":"goDocEnd","Ctrl-Left":"goGroupLeft","Ctrl-Right":"goGroupRight","Alt-Left":"goLineStart","Alt-Right":"goLineEnd","Ctrl-Backspace":"delGroupBefore","Ctrl-Delete":"delGroupAfter","Ctrl-S":"save","Ctrl-F":"find","Ctrl-G":"findNext","Shift-Ctrl-G":"findPrev","Shift-Ctrl-F":"replace","Shift-Ctrl-R":"replaceAll","Ctrl-[":"indentLess","Ctrl-]":"indentMore","Ctrl-U":"undoSelection","Shift-Ctrl-U":"redoSelection","Alt-U":"redoSelection",fallthrough:"basic"},ue.macDefault={"Cmd-A":"selectAll","Cmd-D":"deleteLine","Cmd-Z":"undo","Shift-Cmd-Z":"redo","Cmd-Y":"redo","Cmd-Home":"goDocStart","Cmd-Up":"goDocStart","Cmd-End":"goDocEnd","Cmd-Down":"goDocEnd","Alt-Left":"goGroupLeft","Alt-Right":"goGroupRight","Cmd-Left":"goLineLeft","Cmd-Right":"goLineRight","Alt-Backspace":"delGroupBefore","Ctrl-Alt-Backspace":"delGroupAfter","Alt-Delete":"delGroupAfter","Cmd-S":"save","Cmd-F":"find","Cmd-G":"findNext","Shift-Cmd-G":"findPrev","Cmd-Alt-F":"replace","Shift-Cmd-Alt-F":"replaceAll","Cmd-[":"indentLess","Cmd-]":"indentMore","Cmd-Backspace":"delWrappedLineLeft","Cmd-Delete":"delWrappedLineRight","Cmd-U":"undoSelection","Shift-Cmd-U":"redoSelection",fallthrough:["basic","emacsy"]},ue.emacsy={"Ctrl-F":"goCharRight","Ctrl-B":"goCharLeft","Ctrl-P":"goLineUp","Ctrl-N":"goLineDown","Alt-F":"goWordRight","Alt-B":"goWordLeft","Ctrl-A":"goLineStart","Ctrl-E":"goLineEnd","Ctrl-V":"goPageDown","Shift-Ctrl-V":"goPageUp","Ctrl-D":"delCharAfter","Ctrl-H":"delCharBefore","Alt-D":"delWordAfter","Alt-Backspace":"delWordBefore","Ctrl-K":"killLine","Ctrl-T":"transposeChars"},ue["default"]=p?ue.macDefault:ue.pcDefault;var we=w.lookupKey=function(a,b,c){function d(b){b=ve(b);var e=b[a];if(e===!1)return"stop";if(null!=e&&c(e))return!0;if(b.nofallthrough)return"stop";var f=b.fallthrough;if(null==f)return!1;if("[object Array]"!=Object.prototype.toString.call(f))return d(f);for(var g=0;g=this.string.length},sol:function(){return this.pos==this.lineStart},peek:function(){return this.string.charAt(this.pos)||void 0},next:function(){return this.posb},eatSpace:function(){for(var a=this.pos;/[\s\u00a0]/.test(this.string.charAt(this.pos));)++this.pos;return this.pos>a},skipToEnd:function(){this.pos=this.string.length},skipTo:function(a){var b=this.string.indexOf(a,this.pos);return b>-1?(this.pos=b,!0):void 0},backUp:function(a){this.pos-=a},column:function(){return this.lastColumnPos0?null:(f&&b!==!1&&(this.pos+=f[0].length),f)}var d=function(a){return c?a.toLowerCase():a},e=this.string.substr(this.pos,a.length);return d(e)==d(a)?(b!==!1&&(this.pos+=a.length),!0):void 0},current:function(){return this.string.slice(this.start,this.pos)},hideFirstChars:function(a,b){this.lineStart+=a;try{return b()}finally{this.lineStart-=a}}};var Ae=w.TextMarker=function(a,b){this.lines=[],this.type=b,this.doc=a};yg(Ae),Ae.prototype.clear=function(){if(!this.explicitlyCleared){var a=this.doc.cm,b=a&&!a.curOp;if(b&&Bc(a),xg(this,"clear")){var c=this.find();c&&tg(this,"clear",c.from,c.to)}for(var d=null,e=null,f=0;fa.display.maxLineLength&&(a.display.maxLine=i,a.display.maxLineLength=j,a.display.maxLineChanged=!0)}null!=d&&a&&this.collapsed&&Qc(a,d,e+1),this.lines.length=0,this.explicitlyCleared=!0,this.atomic&&this.doc.cantEdit&&(this.doc.cantEdit=!1,a&&Lb(a.doc)),a&&tg(a,"markerCleared",a,this),b&&Dc(a),this.parent&&this.parent.clear()}},Ae.prototype.find=function(a,b){null==a&&"bookmark"==this.type&&(a=1);for(var c,d,e=0;ec;++c){var e=this.lines[c];this.height-=e.height,mf(e),tg(e,"delete")}this.lines.splice(a,b)},collapse:function(a){a.push.apply(a,this.lines)},insertInner:function(a,b,c){this.height+=c,this.lines=this.lines.slice(0,a).concat(b).concat(this.lines.slice(a));for(var d=0;da;++a)if(c(this.lines[a]))return!0}},Hf.prototype={chunkSize:function(){return this.size},removeInner:function(a,b){this.size-=b;for(var c=0;ca){var f=Math.min(b,e-a),g=d.height;if(d.removeInner(a,f),this.height-=g-d.height,e==f&&(this.children.splice(c--,1),d.parent=null),0==(b-=f))break;a=0}else a-=e}if(this.size-b<25&&(this.children.length>1||!(this.children[0]instanceof Gf))){var h=[];this.collapse(h),this.children=[new Gf(h)],this.children[0].parent=this}},collapse:function(a){for(var b=0;b=a){if(e.insertInner(a,b,c),e.lines&&e.lines.length>50){for(;e.lines.length>50;){var g=e.lines.splice(e.lines.length-25,25),h=new Gf(g);e.height-=h.height,this.children.splice(d+1,0,h),h.parent=this}this.maybeSpill()}break}a-=f}},maybeSpill:function(){if(!(this.children.length<=10)){var a=this;do{var b=a.children.splice(a.children.length-5,5),c=new Hf(b);if(a.parent){a.size-=c.size,a.height-=c.height;var e=Lg(a.parent.children,a);a.parent.children.splice(e+1,0,c)}else{var d=new Hf(a.children);d.parent=a,a.children=[d,c],a=d}c.parent=a.parent}while(a.children.length>10);a.parent.maybeSpill()}},iterN:function(a,b,c){for(var d=0;da){var g=Math.min(b,f-a);if(e.iterN(a,g,c))return!0;if(0==(b-=g))break;a=0}else a-=f}}};var If=0,Jf=w.Doc=function(a,b,c){if(!(this instanceof Jf))return new Jf(a,b,c);null==c&&(c=0),Hf.call(this,[new Gf([new kf("",null)])]),this.first=c,this.scrollTop=this.scrollLeft=0,this.cantEdit=!1,this.cleanGeneration=1,this.frontier=c;var d=nb(c,0);this.sel=vb(d),this.history=new Wf(null),this.id=++If,this.modeOption=b,"string"==typeof a&&(a=ph(a)),Ff(this,{from:d,to:d,text:a}),Ib(this,vb(d),Bg)};Jf.prototype=Ng(Hf.prototype,{constructor:Jf,iter:function(a,b,c){c?this.iterN(a-this.first,b-a,c):this.iterN(this.first,this.first+this.size,a)},insert:function(a,b){for(var c=0,d=0;d=0;f--)Rd(this,d[f]);h?Hb(this,h):this.cm&&be(this.cm)}),undo:Nc(function(){Td(this,"undo")}),redo:Nc(function(){Td(this,"redo")}),undoSelection:Nc(function(){Td(this,"undo",!0)}),redoSelection:Nc(function(){Td(this,"redo",!0)}),setExtending:function(a){this.extend=a},getExtending:function(){return this.extend},historySize:function(){for(var a=this.history,b=0,c=0,d=0;d=a.ch)&&b.push(e.marker.parent||e.marker)}return b},findMarks:function(a,b,c){a=xb(this,a),b=xb(this,b);var d=[],e=a.line;return this.iter(a.line,b.line+1,function(f){var g=f.markedSpans;if(g)for(var h=0;hi.to||null==i.from&&e!=a.line||e==b.line&&i.from>b.ch||c&&!c(i.marker)||d.push(i.marker.parent||i.marker)}++e}),d},getAllMarks:function(){var a=[];return this.iter(function(b){var c=b.markedSpans;if(c)for(var d=0;da?(b=a,!0):(a-=e,++c,void 0)}),xb(this,nb(c,b))},indexFromPos:function(a){a=xb(this,a);var b=a.ch;return a.lineb&&(b=a.from),null!=a.to&&a.toh||h>=b)return g+(b-f);g+=h-f,g+=c-g%c,f=h+1}},Hg=[""],Kg=function(a){a.select()};n?Kg=function(a){a.selectionStart=0,a.selectionEnd=a.value.length}:d&&(Kg=function(a){try{a.select()}catch(b){}}),[].indexOf&&(Lg=function(a,b){return a.indexOf(b)}),[].map&&(Mg=function(a,b){return a.map(b)});var Xg,Qg=/[\u00df\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/,Rg=w.isWordChar=function(a){return/\w/.test(a)||a>"\x80"&&(a.toUpperCase()!=a.toLowerCase()||Qg.test(a))},Ug=/[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065e\u0670\u06d6-\u06dc\u06de-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0900-\u0902\u093c\u0941-\u0948\u094d\u0951-\u0955\u0962\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1a17\u1a18\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1dc0-\u1de6\u1dfd-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua825\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe5\uabe8\uabed\udc00-\udfff\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]/;
-Xg=document.createRange?function(a,b,c){var d=document.createRange();return d.setEnd(a,c),d.setStart(a,b),d}:function(a,b,c){var d=document.body.createTextRange();return d.moveToElementText(a.parentNode),d.collapse(!0),d.moveEnd("character",c),d.moveStart("character",b),d},d&&11>e&&(_g=function(){try{return document.activeElement}catch(a){return document.body}});var jh,lh,nh,fh=!1,ih=function(){if(d&&9>e)return!1;var a=Wg("div");return"draggable"in a||"dragDrop"in a}(),ph=w.splitLines=3!="\n\nb".split(/\n/).length?function(a){for(var b=0,c=[],d=a.length;d>=b;){var e=a.indexOf("\n",b);-1==e&&(e=a.length);var f=a.slice(b,"\r"==a.charAt(e-1)?e-1:e),g=f.indexOf("\r");-1!=g?(c.push(f.slice(0,g)),b+=g+1):(c.push(f),b=e+1)}return c}:function(a){return a.split(/\r\n?|\n/)},qh=window.getSelection?function(a){try{return a.selectionStart!=a.selectionEnd}catch(b){return!1}}:function(a){try{var b=a.ownerDocument.selection.createRange()}catch(c){}return b&&b.parentElement()==a?0!=b.compareEndPoints("StartToEnd",b):!1},rh=function(){var a=Wg("div");return"oncopy"in a?!0:(a.setAttribute("oncopy","return;"),"function"==typeof a.oncopy)}(),sh=null,uh={3:"Enter",8:"Backspace",9:"Tab",13:"Enter",16:"Shift",17:"Ctrl",18:"Alt",19:"Pause",20:"CapsLock",27:"Esc",32:"Space",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"Left",38:"Up",39:"Right",40:"Down",44:"PrintScrn",45:"Insert",46:"Delete",59:";",61:"=",91:"Mod",92:"Mod",93:"Mod",107:"=",109:"-",127:"Delete",173:"-",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'",63232:"Up",63233:"Down",63234:"Left",63235:"Right",63272:"Delete",63273:"Home",63275:"End",63276:"PageUp",63277:"PageDown",63302:"Insert"};w.keyNames=uh,function(){for(var a=0;10>a;a++)uh[a+48]=uh[a+96]=String(a);for(var a=65;90>=a;a++)uh[a]=String.fromCharCode(a);for(var a=1;12>=a;a++)uh[a+111]=uh[a+63235]="F"+a}();var Eh,Jh=function(){function c(c){return 247>=c?a.charAt(c):c>=1424&&1524>=c?"R":c>=1536&&1773>=c?b.charAt(c-1536):c>=1774&&2220>=c?"r":c>=8192&&8203>=c?"w":8204==c?"b":"L"}function j(a,b,c){this.level=a,this.from=b,this.to=c}var a="bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN",b="rrrrrrrrrrrr,rNNmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmrrrrrrrnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmNmmmm",d=/[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/,e=/[stwN]/,f=/[LRr]/,g=/[Lb1n]/,h=/[1n]/,i="L";return function(a){if(!d.test(a))return!1;for(var m,b=a.length,k=[],l=0;b>l;++l)k.push(m=c(a.charCodeAt(l)));for(var l=0,n=i;b>l;++l){var m=k[l];"m"==m?k[l]=n:n=m}for(var l=0,o=i;b>l;++l){var m=k[l];"1"==m&&"r"==o?k[l]="n":f.test(m)&&(o=m,"r"==m&&(k[l]="R"))}for(var l=1,n=k[0];b-1>l;++l){var m=k[l];"+"==m&&"1"==n&&"1"==k[l+1]?k[l]="1":","!=m||n!=k[l+1]||"1"!=n&&"n"!=n||(k[l]=n),n=m}for(var l=0;b>l;++l){var m=k[l];if(","==m)k[l]="N";else if("%"==m){for(var p=l+1;b>p&&"%"==k[p];++p);for(var q=l&&"!"==k[l-1]||b>p&&"1"==k[p]?"1":"N",r=l;p>r;++r)k[r]=q;l=p-1}}for(var l=0,o=i;b>l;++l){var m=k[l];"L"==o&&"1"==m?k[l]="L":f.test(m)&&(o=m)}for(var l=0;b>l;++l)if(e.test(k[l])){for(var p=l+1;b>p&&e.test(k[p]);++p);for(var s="L"==(l?k[l-1]:i),t="L"==(b>p?k[p]:i),q=s||t?"L":"R",r=l;p>r;++r)k[r]=q;l=p-1}for(var v,u=[],l=0;b>l;)if(g.test(k[l])){var w=l;for(++l;b>l&&g.test(k[l]);++l);u.push(new j(0,w,l))}else{var x=l,y=u.length;for(++l;b>l&&"L"!=k[l];++l);for(var r=x;l>r;)if(h.test(k[r])){r>x&&u.splice(y,0,new j(1,x,r));var z=r;for(++r;l>r&&h.test(k[r]);++r);u.splice(y,0,new j(2,z,r)),x=r}else++r;l>x&&u.splice(y,0,new j(1,x,l))}return 1==u[0].level&&(v=a.match(/^\s+/))&&(u[0].from=v[0].length,u.unshift(new j(0,0,v[0].length))),1==Jg(u).level&&(v=a.match(/\s+$/))&&(Jg(u).to-=v[0].length,u.push(new j(0,b-v[0].length,b))),u[0].level!=Jg(u).level&&u.push(new j(u[0].level,b,b)),u}}();return w.version="4.6.0",w});
\ No newline at end of file
+!function(a){if("object"==typeof exports&&"object"==typeof module)module.exports=a();else{if("function"==typeof define&&define.amd)return define([],a);(this||window).CodeMirror=a()}}(function(){"use strict";function x(a,b){if(!(this instanceof x))return new x(a,b);this.options=b=b?mg(b):{},mg(Dd,b,!1),K(b);var c=b.value;"string"==typeof c&&(c=new df(c,b.mode,null,b.lineSeparator)),this.doc=c;var d=new x.inputStyles[b.inputStyle](this),e=this.display=new y(a,c,d);e.wrapper.CodeMirror=this,G(this),E(this),b.lineWrapping&&(this.display.wrapper.className+=" CodeMirror-wrap"),b.autofocus&&!p&&e.input.focus(),O(this),this.state={keyMaps:[],overlays:[],modeGen:0,overwrite:!1,delayingBlurEvent:!1,focused:!1,suppressEdits:!1,pasteIncoming:!1,cutIncoming:!1,selectingText:!1,draggingText:!1,highlight:new bg,keySeq:null,specialChars:null};var i=this;f&&11>g&&setTimeout(function(){i.display.input.reset(!0)},20),sc(this),Gg(),Yb(this),this.curOp.forceUpdate=!0,hf(this,c),b.autofocus&&!p||i.hasFocus()?setTimeout(ng(ad,this),20):bd(this);for(var j in Ed)Ed.hasOwnProperty(j)&&Ed[j](this,b[j],Gd);T(this),b.finishInit&&b.finishInit(this);for(var k=0;kg&&(e.gutters.style.zIndex=-1,e.scroller.style.paddingRight=0),h||c&&p||(e.scroller.draggable=!0),a&&(a.appendChild?a.appendChild(e.wrapper):a(e.wrapper)),e.viewFrom=e.viewTo=b.first,e.reportedViewFrom=e.reportedViewTo=b.first,e.view=[],e.renderedView=null,e.externalMeasured=null,e.viewOffset=0,e.lastWrapHeight=e.lastWrapWidth=0,e.updateLineNumbers=null,e.nativeBarWidth=e.barHeight=e.barWidth=0,e.scrollbarsClipped=!1,e.lineNumWidth=e.lineNumInnerWidth=e.lineNumChars=null,e.alignWidgets=!1,e.cachedCharWidth=e.cachedTextHeight=e.cachedPaddingH=null,e.maxLine=null,e.maxLineLength=0,e.maxLineChanged=!1,e.wheelDX=e.wheelDY=e.wheelStartX=e.wheelStartY=null,e.shift=!1,e.selForContextMenu=null,e.activeTouch=null,d.init(e)}function z(a){a.doc.mode=x.getMode(a.options,a.doc.modeOption),A(a)}function A(a){a.doc.iter(function(a){a.stateAfter&&(a.stateAfter=null),a.styles&&(a.styles=null)}),a.doc.frontier=a.doc.first,lb(a,100),a.state.modeGen++,a.curOp&&lc(a)}function B(a){a.options.lineWrapping?(Cg(a.display.wrapper,"CodeMirror-wrap"),a.display.sizer.style.minWidth="",a.display.sizerWidth=null):(Bg(a.display.wrapper,"CodeMirror-wrap"),J(a)),D(a),lc(a),Ib(a),setTimeout(function(){P(a)},100)}function C(a){var b=Ub(a.display),c=a.options.lineWrapping,d=c&&Math.max(5,a.display.scroller.clientWidth/Vb(a.display)-3);return function(e){if(ze(a.doc,e))return 0;var f=0;if(e.widgets)for(var g=0;gb.maxLineLength&&(b.maxLineLength=c,b.maxLine=a)})}function K(a){var b=ig(a.gutters,"CodeMirror-linenumbers");-1==b&&a.lineNumbers?a.gutters=a.gutters.concat(["CodeMirror-linenumbers"]):b>-1&&!a.lineNumbers&&(a.gutters=a.gutters.slice(0),a.gutters.splice(b,1))}function L(a){var b=a.display,c=b.gutters.offsetWidth,d=Math.round(a.doc.height+qb(a.display));return{clientHeight:b.scroller.clientHeight,viewHeight:b.wrapper.clientHeight,scrollWidth:b.scroller.scrollWidth,clientWidth:b.scroller.clientWidth,viewWidth:b.wrapper.clientWidth,barLeft:a.options.fixedGutter?c:0,docHeight:d,scrollHeight:d+sb(a)+b.barHeight,nativeBarWidth:b.nativeBarWidth,gutterWidth:c}}function M(a,b,c){this.cm=c;var d=this.vert=ug("div",[ug("div",null,null,"min-width: 1px")],"CodeMirror-vscrollbar"),e=this.horiz=ug("div",[ug("div",null,null,"height: 100%; min-height: 1px")],"CodeMirror-hscrollbar");a(d),a(e),Mf(d,"scroll",function(){d.clientHeight&&b(d.scrollTop,"vertical")}),Mf(e,"scroll",function(){e.clientWidth&&b(e.scrollLeft,"horizontal")}),this.checkedZeroWidth=!1,f&&8>g&&(this.horiz.style.minHeight=this.vert.style.minWidth="18px")}function N(){}function O(a){a.display.scrollbars&&(a.display.scrollbars.clear(),a.display.scrollbars.addClass&&Bg(a.display.wrapper,a.display.scrollbars.addClass)),a.display.scrollbars=new x.scrollbarModel[a.options.scrollbarStyle](function(b){a.display.wrapper.insertBefore(b,a.display.scrollbarFiller),Mf(b,"mousedown",function(){a.state.focused&&setTimeout(function(){a.display.input.focus()},0)}),b.setAttribute("cm-not-content","true")},function(b,c){"horizontal"==c?Lc(a,b):Kc(a,b)},a),a.display.scrollbars.addClass&&Cg(a.display.wrapper,a.display.scrollbars.addClass)}function P(a,b){b||(b=L(a));var c=a.display.barWidth,d=a.display.barHeight;Q(a,b);for(var e=0;4>e&&c!=a.display.barWidth||d!=a.display.barHeight;e++)c!=a.display.barWidth&&a.options.lineWrapping&&aa(a),Q(a,L(a)),c=a.display.barWidth,d=a.display.barHeight}function Q(a,b){var c=a.display,d=c.scrollbars.update(b);c.sizer.style.paddingRight=(c.barWidth=d.right)+"px",c.sizer.style.paddingBottom=(c.barHeight=d.bottom)+"px",d.right&&d.bottom?(c.scrollbarFiller.style.display="block",c.scrollbarFiller.style.height=d.bottom+"px",c.scrollbarFiller.style.width=d.right+"px"):c.scrollbarFiller.style.display="",d.bottom&&a.options.coverGutterNextToScrollbar&&a.options.fixedGutter?(c.gutterFiller.style.display="block",c.gutterFiller.style.height=d.bottom+"px",c.gutterFiller.style.width=b.gutterWidth+"px"):c.gutterFiller.style.display=""}function R(a,b,c){var d=c&&null!=c.top?Math.max(0,c.top):a.scroller.scrollTop;d=Math.floor(d-pb(a));var e=c&&null!=c.bottom?c.bottom:d+a.wrapper.clientHeight,f=of(b,d),g=of(b,e);if(c&&c.ensure){var h=c.ensure.from.line,i=c.ensure.to.line;f>h?(f=h,g=of(b,pf(jf(b,h))+a.wrapper.clientHeight)):Math.min(i,b.lastLine())>=g&&(f=of(b,pf(jf(b,i))-a.wrapper.clientHeight),g=i)}return{from:f,to:Math.max(g,f+1)}}function S(a){var b=a.display,c=b.view;if(b.alignWidgets||b.gutters.firstChild&&a.options.fixedGutter){for(var d=V(b)-b.scroller.scrollLeft+a.doc.scrollLeft,e=b.gutters.offsetWidth,f=d+"px",g=0;g=c.viewFrom&&b.visible.to<=c.viewTo&&(null==c.updateLineNumbers||c.updateLineNumbers>=c.viewTo)&&c.renderedView==c.view&&0==rc(a))return!1;T(a)&&(nc(a),b.dims=ca(a));var e=d.first+d.size,f=Math.max(b.visible.from-a.options.viewportMargin,d.first),g=Math.min(e,b.visible.to+a.options.viewportMargin);c.viewFromg&&c.viewTo-g<20&&(g=Math.min(e,c.viewTo)),w&&(f=xe(a.doc,f),g=ye(a.doc,g));var h=f!=c.viewFrom||g!=c.viewTo||c.lastWrapHeight!=b.wrapperHeight||c.lastWrapWidth!=b.wrapperWidth;qc(a,f,g),c.viewOffset=pf(jf(a.doc,c.viewFrom)),a.display.mover.style.top=c.viewOffset+"px";var i=rc(a);if(!h&&0==i&&!b.force&&c.renderedView==c.view&&(null==c.updateLineNumbers||c.updateLineNumbers>=c.viewTo))return!1;var j=zg();return i>4&&(c.lineDiv.style.display="none"),da(a,c.updateLineNumbers,b.dims),i>4&&(c.lineDiv.style.display=""),c.renderedView=c.view,j&&zg()!=j&&j.offsetHeight&&j.focus(),wg(c.cursorDiv),wg(c.selectionDiv),c.gutters.style.height=c.sizer.style.minHeight=0,h&&(c.lastWrapHeight=b.wrapperHeight,c.lastWrapWidth=b.wrapperWidth,lb(a,400)),c.updateLineNumbers=null,!0}function Z(a,b){for(var c=b.viewport,d=!0;(d&&a.options.lineWrapping&&b.oldDisplayWidth!=tb(a)||(c&&null!=c.top&&(c={top:Math.min(a.doc.height+qb(a.display)-ub(a),c.top)}),b.visible=R(a.display,a.doc,c),!(b.visible.from>=a.display.viewFrom&&b.visible.to<=a.display.viewTo)))&&Y(a,b);d=!1){aa(a);var e=L(a);gb(a),_(a,e),P(a,e)}b.signal(a,"update",a),(a.display.viewFrom!=a.display.reportedViewFrom||a.display.viewTo!=a.display.reportedViewTo)&&(b.signal(a,"viewportChange",a,a.display.viewFrom,a.display.viewTo),a.display.reportedViewFrom=a.display.viewFrom,a.display.reportedViewTo=a.display.viewTo)}function $(a,b){var c=new W(a,b);if(Y(a,c)){aa(a),Z(a,c);var d=L(a);gb(a),_(a,d),P(a,d),c.finish()}}function _(a,b){a.display.sizer.style.minHeight=b.docHeight+"px";var c=b.docHeight+a.display.barHeight;a.display.heightForcer.style.top=c+"px",a.display.gutters.style.height=Math.max(c+sb(a),b.clientHeight)+"px"}function aa(a){for(var b=a.display,c=b.lineDiv.offsetTop,d=0;dg){var i=e.node.offsetTop+e.node.offsetHeight;h=i-c,c=i}else{var j=e.node.getBoundingClientRect();h=j.bottom-j.top}var k=e.line.height-h;if(2>h&&(h=Ub(b)),(k>.001||-.001>k)&&(mf(e.line,h),ba(e.line),e.rest))for(var l=0;l=b&&m.lineNumber;m.changes&&(ig(m.changes,"gutter")>-1&&(o=!1),ea(a,m,k,c)),o&&(wg(m.lineNumber),m.lineNumber.appendChild(document.createTextNode(U(a.options,k)))),g=m.node.nextSibling}else{var n=ma(a,m,k,c);f.insertBefore(n,g)}k+=m.size}for(;g;)g=i(g)}function ea(a,b,c,d){for(var e=0;eg&&(a.node.style.zIndex=2)),a.node}function ga(a){var b=a.bgClass?a.bgClass+" "+(a.line.bgClass||""):a.line.bgClass;if(b&&(b+=" CodeMirror-linebackground"),a.background)b?a.background.className=b:(a.background.parentNode.removeChild(a.background),a.background=null);else if(b){var c=fa(a);a.background=c.insertBefore(ug("div",null,b),c.firstChild)}}function ha(a,b){var c=a.display.externalMeasured;return c&&c.line==b.line?(a.display.externalMeasured=null,b.measure=c.measure,c.built):Te(a,b)}function ia(a,b){var c=b.text.className,d=ha(a,b);b.text==b.node&&(b.node=d.pre),b.text.parentNode.replaceChild(d.pre,b.text),b.text=d.pre,d.bgClass!=b.bgClass||d.textClass!=b.textClass?(b.bgClass=d.bgClass,b.textClass=d.textClass,ja(b)):c&&(b.text.className=c)}function ja(a){ga(a),a.line.wrapClass?fa(a).className=a.line.wrapClass:a.node!=a.text&&(a.node.className="");var b=a.textClass?a.textClass+" "+(a.line.textClass||""):a.line.textClass;a.text.className=b||""}function ka(a,b,c,d){if(b.gutter&&(b.node.removeChild(b.gutter),b.gutter=null),b.gutterBackground&&(b.node.removeChild(b.gutterBackground),b.gutterBackground=null),b.line.gutterClass){var e=fa(b);b.gutterBackground=ug("div",null,"CodeMirror-gutter-background "+b.line.gutterClass,"left: "+(a.options.fixedGutter?d.fixedPos:-d.gutterTotalWidth)+"px; width: "+d.gutterTotalWidth+"px"),e.insertBefore(b.gutterBackground,b.text)}var f=b.line.gutterMarkers;if(a.options.lineNumbers||f){var e=fa(b),g=b.gutter=ug("div",null,"CodeMirror-gutter-wrapper","left: "+(a.options.fixedGutter?d.fixedPos:-d.gutterTotalWidth)+"px");if(a.display.input.setUneditable(g),e.insertBefore(g,b.text),b.line.gutterClass&&(g.className+=" "+b.line.gutterClass),!a.options.lineNumbers||f&&f["CodeMirror-linenumbers"]||(b.lineNumber=g.appendChild(ug("div",U(a.options,c),"CodeMirror-linenumber CodeMirror-gutter-elt","left: "+d.gutterLeft["CodeMirror-linenumbers"]+"px; width: "+a.display.lineNumInnerWidth+"px"))),f)for(var h=0;h1)if(wa&&wa.join("\n")==b){if(d.ranges.length%wa.length==0){i=[];for(var j=0;j=0;j--){var k=d.ranges[j],l=k.from(),m=k.to();k.empty()&&(c&&c>0?l=qa(l.line,l.ch-c):a.state.overwrite&&!g&&(m=qa(m.line,Math.min(jf(f,m.line).text.length,m.ch+gg(h).length))));var n=a.curOp.updateInput,o={from:l,to:m,text:i?i[j%i.length]:h,origin:e||(g?"paste":a.state.cutIncoming?"cut":"+input")};kd(a.doc,o),Sf(a,"inputRead",a,o)}b&&!g&&za(a,b),wd(a),a.curOp.updateInput=n,a.curOp.typing=!0,a.state.pasteIncoming=a.state.cutIncoming=!1}function ya(a,b){var c=a.clipboardData&&a.clipboardData.getData("text/plain");return c?(a.preventDefault(),b.isReadOnly()||b.options.disableInput||fc(b,function(){xa(b,c,0,null,"paste")}),!0):void 0}function za(a,b){if(a.options.electricChars&&a.options.smartIndent)for(var c=a.doc.sel,d=c.ranges.length-1;d>=0;d--){var e=c.ranges[d];if(!(e.head.ch>100||d&&c.ranges[d-1].head.line==e.head.line)){var f=a.getModeAt(e.head),g=!1;if(f.electricChars){for(var h=0;h-1){g=yd(a,e.head.line,"smart");break}}else f.electricInput&&f.electricInput.test(jf(a.doc,e.head.line).text.slice(0,e.head.ch))&&(g=yd(a,e.head.line,"smart"));g&&Sf(a,"electricInput",a,e.head.line)}}}function Aa(a){for(var b=[],c=[],d=0;de?i.map:j[e],g=0;ge?a.line:a.rest[e]),l=f[g]+d;return(0>d||h!=b)&&(l=f[g+(d?1:0)]),qa(k,l)}}}var d=a.text.firstChild,e=!1;if(!b||!yg(d,b))return Ga(qa(nf(a.line),0),!0);if(b==d&&(e=!0,b=d.childNodes[c],c=0,!b)){var f=a.rest?gg(a.rest):a.line;return Ga(qa(nf(f),f.text.length),e)}var g=3==b.nodeType?b:null,h=b;for(g||1!=b.childNodes.length||3!=b.firstChild.nodeType||(g=b.firstChild,c&&(c=g.nodeValue.length));h.parentNode!=d;)h=h.parentNode;var i=a.measure,j=i.maps,l=k(g,h,c);if(l)return Ga(l,e);for(var m=h.nextSibling,n=g?g.nodeValue.length-c:0;m;m=m.nextSibling){if(l=k(m,m.firstChild,0))return Ga(qa(l.line,l.ch-n),e);n+=m.textContent.length}for(var o=h.previousSibling,n=c;o;o=o.previousSibling){if(l=k(o,o.firstChild,-1))return Ga(qa(l.line,l.ch+n),e);n+=m.textContent.length}}function Ja(a,b,c,d,e){function i(a){return function(b){return b.id==a}}function j(b){if(1==b.nodeType){var c=b.getAttribute("cm-text");if(null!=c)return""==c&&(c=b.textContent.replace(/\u200b/g,"")),void(f+=c);var l,k=b.getAttribute("cm-marker");if(k){var m=a.findMarks(qa(d,0),qa(e+1,0),i(+k));return void(m.length&&(l=m[0].find())&&(f+=kf(a.doc,l.from,l.to).join(h)))}if("false"==b.getAttribute("contenteditable"))return;for(var n=0;n=0){var g=ua(f.from(),e.from()),h=ta(f.to(),e.to()),i=f.empty()?e.from()==e.head:f.from()==f.head;b>=d&&--b,a.splice(--d,2,new La(i?h:g,i?g:h))}}return new Ka(a,b)}function Na(a,b){return new Ka([new La(a,b||a)],0)}function Oa(a,b){return Math.max(a.first,Math.min(b,a.first+a.size-1))}function Pa(a,b){if(b.linec?qa(c,jf(a,c).text.length):Qa(b,jf(a,b.line).text.length)}function Qa(a,b){var c=a.ch;return null==c||c>b?qa(a.line,b):0>c?qa(a.line,0):a}function Ra(a,b){return b>=a.first&&b=b.ch:h.to>b.ch))){if(e&&(Qf(i,"beforeCursorEnter"),i.explicitlyCleared)){if(f.markedSpans){--g;continue}break}if(!i.atomic)continue;if(c){var k,j=i.find(0>d?1:-1);if((0>d?i.inclusiveRight:i.inclusiveLeft)&&(j=fb(a,j,-d,f)),j&&j.line==b.line&&(k=ra(j,c))&&(0>d?0>k:k>0))return db(a,j,b,d,e)}var l=i.find(0>d?-1:1);return(0>d?i.inclusiveLeft:i.inclusiveRight)&&(l=fb(a,l,d,f)),l?db(a,l,b,d,e):null}}return b}function eb(a,b,c,d,e){var f=d||1,g=db(a,b,c,f,e)||!e&&db(a,b,c,f,!0)||db(a,b,c,-f,e)||!e&&db(a,b,c,-f,!0);return g?g:(a.cantEdit=!0,qa(a.first,0))}function fb(a,b,c,d){return 0>c&&0==b.ch?b.line>a.first?Pa(a,qa(b.line-1)):null:c>0&&b.ch==(d||jf(a,b.line)).text.length?b.lineb&&(b=0),b=Math.round(b),d=Math.round(d),f.appendChild(ug("div",null,"CodeMirror-selected","position: absolute; left: "+a+"px; top: "+b+"px; width: "+(null==c?i-a:c)+"px; height: "+(d-b)+"px"))}function k(b,c,d){function m(c,d){return Nb(a,qa(b,c),"div",f,d)}var k,l,f=jf(e,b),g=f.text.length;return Tg(qf(f),c||0,null==d?g:d,function(a,b,e){var n,o,p,f=m(a,"left");if(a==b)n=f,o=p=f.left;else{if(n=m(b-1,"right"),"rtl"==e){var q=f;f=n,n=q}o=f.left,p=n.right}null==c&&0==a&&(o=h),n.top-f.top>3&&(j(o,f.top,null,f.bottom),o=h,f.bottoml.bottom||n.bottom==l.bottom&&n.right>l.right)&&(l=n),h+1>o&&(o=h),j(o,n.top,p-o,n.bottom)}),{start:k,end:l}}var d=a.display,e=a.doc,f=document.createDocumentFragment(),g=rb(a.display),h=g.left,i=Math.max(d.sizerWidth,tb(a)-d.sizer.offsetLeft)-g.right,l=b.from(),m=b.to();if(l.line==m.line)k(l.line,l.ch,m.ch);else{var n=jf(e,l.line),o=jf(e,m.line),p=ve(n)==ve(o),q=k(l.line,l.ch,p?n.text.length+1:null).end,r=k(m.line,p?0:null,m.ch).start;p&&(q.top0?b.blinker=setInterval(function(){b.cursorDiv.style.visibility=(c=!c)?"":"hidden"},a.options.cursorBlinkRate):a.options.cursorBlinkRate<0&&(b.cursorDiv.style.visibility="hidden")}}function lb(a,b){a.doc.mode.startState&&a.doc.frontier=a.display.viewTo)){var c=+new Date+a.options.workTime,d=Md(b.mode,ob(a,b.frontier)),e=[];b.iter(b.frontier,Math.min(b.first+b.size,a.display.viewTo+500),function(f){if(b.frontier>=a.display.viewFrom){var g=f.styles,h=f.text.length>a.options.maxHighlightLength,i=Ne(a,f,h?Md(b.mode,d):d,!0);f.styles=i.styles;var j=f.styleClasses,k=i.classes;k?f.styleClasses=k:j&&(f.styleClasses=null);for(var l=!g||g.length!=f.styles.length||j!=k&&(!j||!k||j.bgClass!=k.bgClass||j.textClass!=k.textClass),m=0;!l&&mc?(lb(a,a.options.workDelay),!0):void 0}),e.length&&fc(a,function(){for(var b=0;bg;--h){if(h<=f.first)return f.first;var i=jf(f,h-1);if(i.stateAfter&&(!c||h<=f.frontier))return h;var j=cg(i.text,null,a.options.tabSize);(null==e||d>j)&&(e=h-1,d=j)}return e}function ob(a,b,c){var d=a.doc,e=a.display;if(!d.mode.startState)return!0;var f=nb(a,b,c),g=f>d.first&&jf(d,f-1).stateAfter;return g=g?Md(d.mode,g):Nd(d.mode),d.iter(f,b,function(c){Pe(a,c.text,g);var h=f==b-1||f%5==0||f>=e.viewFrom&&f2&&f.push((i.bottom+j.top)/2-c.top)}}f.push(c.bottom-c.top)}}function wb(a,b,c){if(a.line==b)return{map:a.measure.map,cache:a.measure.cache};for(var d=0;dc)return{map:a.measure.maps[d],cache:a.measure.caches[d],before:!0}}function xb(a,b){b=ve(b);var c=nf(b),d=a.display.externalMeasured=new jc(a.doc,b,c);d.lineN=c;var e=d.built=Te(a,d);return d.text=e.pre,xg(a.display.lineMeasure,e.pre),d}function yb(a,b,c,d){return Bb(a,Ab(a,b),c,d)}function zb(a,b){if(b>=a.display.viewFrom&&b=c.lineN&&bb?(e=0,f=1,g="left"):j>b?(e=b-i,f=e+1):(h==a.length-3||b==j&&a[h+3]>b)&&(f=j-i,e=f-1,b>=j&&(g="right")),null!=e){if(d=a[h+2],i==j&&c==(d.insertLeft?"left":"right")&&(g=c),"left"==c&&0==e)for(;h&&a[h-2]==a[h-3]&&a[h-1].insertLeft;)d=a[(h-=3)+2],
+g="left";if("right"==c&&e==j-i)for(;hm;m++){for(;i&&tg(b.line.text.charAt(e.coverStart+i));)--i;for(;e.coverStart+jg&&0==i&&j==e.coverEnd-e.coverStart)l=h.parentNode.getBoundingClientRect();else if(f&&a.options.lineWrapping){var n=vg(h,i,j).getClientRects();l=n.length?n["right"==d?n.length-1:0]:Cb}else l=vg(h,i,j).getBoundingClientRect()||Cb;if(l.left||l.right||0==i)break;j=i,i-=1,k="right"}f&&11>g&&(l=Fb(a.display.measure,l))}else{i>0&&(k=d="right");var n;l=a.options.lineWrapping&&(n=h.getClientRects()).length>1?n["right"==d?n.length-1:0]:h.getBoundingClientRect()}if(f&&9>g&&!i&&(!l||!l.left&&!l.right)){var o=h.parentNode.getClientRects()[0];l=o?{left:o.left,right:o.left+Vb(a.display),top:o.top,bottom:o.bottom}:Cb}for(var p=l.top-b.rect.top,q=l.bottom-b.rect.top,r=(p+q)/2,s=b.view.measure.heights,m=0;mc.from?g(a-1):g(a,d)}d=d||jf(a.doc,b.line),e||(e=Ab(a,d));var i=qf(d),j=b.ch;if(!i)return g(j);var k=bh(i,j),l=h(j,k);return null!=ah&&(l.other=h(j,ah)),l}function Pb(a,b){var c=0,b=Pa(a.doc,b);a.options.lineWrapping||(c=Vb(a.display)*b.ch);var d=jf(a.doc,b.line),e=pf(d)+pb(a.display);return{left:c,right:c,top:e,bottom:e+d.height}}function Qb(a,b,c,d){var e=qa(a,b);return e.xRel=d,c&&(e.outside=!0),e}function Rb(a,b,c){var d=a.doc;if(c+=a.display.viewOffset,0>c)return Qb(d.first,0,!0,-1);var e=of(d,c),f=d.first+d.size-1;if(e>f)return Qb(d.first+d.size-1,jf(d,f).text.length,!0,1);0>b&&(b=0);for(var g=jf(d,e);;){var h=Sb(a,g,e,b,c),i=te(g),j=i&&i.find(0,!0);if(!i||!(h.ch>j.from.ch||h.ch==j.from.ch&&h.xRel>0))return h;e=nf(g=j.to.line)}}function Sb(a,b,c,d,e){function j(d){var e=Ob(a,qa(c,d),"line",b,i);return g=!0,f>e.bottom?e.left-h:fq)return Qb(c,n,r,1);for(;;){if(k?n==m||n==dh(b,m,1):1>=n-m){for(var s=o>d||q-d>=d-o?m:n,t=d-(s==m?o:q);tg(b.text.charAt(s));)++s;var u=Qb(c,s,s==m?p:r,-1>t?-1:t>1?1:0);return u}var v=Math.ceil(l/2),w=m+v;if(k){w=m;for(var x=0;v>x;++x)w=dh(b,w,1)}var y=j(w);y>d?(n=w,q=y,(r=g)&&(q+=1e3),l=v):(m=w,o=y,p=g,l-=v)}}function Ub(a){if(null!=a.cachedTextHeight)return a.cachedTextHeight;if(null==Tb){Tb=ug("pre");for(var b=0;49>b;++b)Tb.appendChild(document.createTextNode("x")),Tb.appendChild(ug("br"));Tb.appendChild(document.createTextNode("x"))}xg(a.measure,Tb);var c=Tb.offsetHeight/50;return c>3&&(a.cachedTextHeight=c),wg(a.measure),c||1}function Vb(a){if(null!=a.cachedCharWidth)return a.cachedCharWidth;var b=ug("span","xxxxxxxxxx"),c=ug("pre",[b]);xg(a.measure,c);var d=b.getBoundingClientRect(),e=(d.right-d.left)/10;return e>2&&(a.cachedCharWidth=e),e||10}function Yb(a){a.curOp={cm:a,viewChanged:!1,startHeight:a.doc.height,forceUpdate:!1,updateInput:null,typing:!1,changeObjs:null,cursorActivityHandlers:null,cursorActivityCalled:0,selectionChanged:!1,updateMaxLine:!1,scrollLeft:null,scrollTop:null,scrollToPos:null,focus:!1,id:++Xb},Wb?Wb.ops.push(a.curOp):a.curOp.ownsGroup=Wb={ops:[a.curOp],delayedCallbacks:[]}}function Zb(a){var b=a.delayedCallbacks,c=0;do{for(;c=c.viewTo)||c.maxLineChanged&&b.options.lineWrapping,a.update=a.mustUpdate&&new W(b,a.mustUpdate&&{top:a.scrollTop,ensure:a.scrollToPos},a.forceUpdate)}function bc(a){a.updatedDisplay=a.mustUpdate&&Y(a.cm,a.update)}function cc(a){var b=a.cm,c=b.display;a.updatedDisplay&&aa(b),a.barMeasure=L(b),c.maxLineChanged&&!b.options.lineWrapping&&(a.adjustWidthTo=yb(b,c.maxLine,c.maxLine.text.length).left+3,b.display.sizerWidth=a.adjustWidthTo,a.barMeasure.scrollWidth=Math.max(c.scroller.clientWidth,c.sizer.offsetLeft+a.adjustWidthTo+sb(b)+b.display.barWidth),a.maxScrollLeft=Math.max(0,c.sizer.offsetLeft+a.adjustWidthTo-tb(b))),(a.updatedDisplay||a.selectionChanged)&&(a.preparedSelection=c.input.prepareSelection())}function dc(a){var b=a.cm;null!=a.adjustWidthTo&&(b.display.sizer.style.minWidth=a.adjustWidthTo+"px",a.maxScrollLeftf;f=e){var g=new jc(a.doc,jf(a.doc,f),f);e=f+g.size,d.push(g)}return d}function lc(a,b,c,d){null==b&&(b=a.doc.first),null==c&&(c=a.doc.first+a.doc.size),d||(d=0);var e=a.display;if(d&&cb)&&(e.updateLineNumbers=b),a.curOp.viewChanged=!0,b>=e.viewTo)w&&xe(a.doc,b)e.viewFrom?nc(a):(e.viewFrom+=d,e.viewTo+=d);else if(b<=e.viewFrom&&c>=e.viewTo)nc(a);else if(b<=e.viewFrom){var f=pc(a,c,c+d,1);f?(e.view=e.view.slice(f.index),e.viewFrom=f.lineN,e.viewTo+=d):nc(a)}else if(c>=e.viewTo){var f=pc(a,b,b,-1);f?(e.view=e.view.slice(0,f.index),e.viewTo=f.lineN):nc(a)}else{var g=pc(a,b,b,-1),h=pc(a,c,c+d,1);g&&h?(e.view=e.view.slice(0,g.index).concat(kc(a,g.lineN,h.lineN)).concat(e.view.slice(h.index)),e.viewTo+=d):nc(a)}var i=e.externalMeasured;i&&(c=e.lineN&&b=d.viewTo)){var f=d.view[oc(a,b)];if(null!=f.node){var g=f.changes||(f.changes=[]);-1==ig(g,c)&&g.push(c)}}}function nc(a){a.display.viewFrom=a.display.viewTo=a.doc.first,a.display.view=[],a.display.viewOffset=0}function oc(a,b){if(b>=a.display.viewTo)return null;if(b-=a.display.viewFrom,0>b)return null;for(var c=a.display.view,d=0;db)return d}function pc(a,b,c,d){var f,e=oc(a,b),g=a.display.view;if(!w||c==a.doc.first+a.doc.size)return{index:e,lineN:c};for(var h=0,i=a.display.viewFrom;e>h;h++)i+=g[h].size;if(i!=b){if(d>0){if(e==g.length-1)return null;f=i+g[e].size-b,e++}else f=i-b;b+=f,c+=f}for(;xe(a.doc,c)!=c;){if(e==(0>d?0:g.length-1))return null;c+=d*g[e-(0>d?1:0)].size,e+=d}return{index:e,lineN:c}}function qc(a,b,c){var d=a.display,e=d.view;0==e.length||b>=d.viewTo||c<=d.viewFrom?(d.view=kc(a,b,c),d.viewFrom=b):(d.viewFrom>b?d.view=kc(a,b,d.viewFrom).concat(d.view):d.viewFromc&&(d.view=d.view.slice(0,oc(a,c)))),d.viewTo=c}function rc(a){for(var b=a.display.view,c=0,d=0;d400}var b=a.display;Mf(b.scroller,"mousedown",gc(a,xc)),f&&11>g?Mf(b.scroller,"dblclick",gc(a,function(b){if(!Uf(a,b)){var c=wc(a,b);if(c&&!Ec(a,b)&&!vc(a.display,b)){Gf(b);var d=a.findWordAt(c);Ua(a.doc,d.anchor,d.head)}}})):Mf(b.scroller,"dblclick",function(b){Uf(a,b)||Gf(b)}),u||Mf(b.scroller,"contextmenu",function(b){cd(a,b)});var c,d={end:0};Mf(b.scroller,"touchstart",function(e){if(!Uf(a,e)&&!h(e)){clearTimeout(c);var f=+new Date;b.activeTouch={start:f,moved:!1,prev:f-d.end<=300?d:null},1==e.touches.length&&(b.activeTouch.left=e.touches[0].pageX,b.activeTouch.top=e.touches[0].pageY)}}),Mf(b.scroller,"touchmove",function(){b.activeTouch&&(b.activeTouch.moved=!0)}),Mf(b.scroller,"touchend",function(c){var d=b.activeTouch;if(d&&!vc(b,c)&&null!=d.left&&!d.moved&&new Date-d.start<300){var g,f=a.coordsChar(b.activeTouch,"page");g=!d.prev||i(d,d.prev)?new La(f,f):!d.prev.prev||i(d,d.prev.prev)?a.findWordAt(f):new La(qa(f.line,0),Pa(a.doc,qa(f.line+1,0))),a.setSelection(g.anchor,g.head),a.focus(),Gf(c)}e()}),Mf(b.scroller,"touchcancel",e),Mf(b.scroller,"scroll",function(){b.scroller.clientHeight&&(Kc(a,b.scroller.scrollTop),Lc(a,b.scroller.scrollLeft,!0),Qf(a,"scroll",a))}),Mf(b.scroller,"mousewheel",function(b){Pc(a,b)}),Mf(b.scroller,"DOMMouseScroll",function(b){Pc(a,b)}),Mf(b.wrapper,"scroll",function(){b.wrapper.scrollTop=b.wrapper.scrollLeft=0}),b.dragFunctions={enter:function(b){Uf(a,b)||Jf(b)},over:function(b){Uf(a,b)||(Ic(a,b),Jf(b))},start:function(b){Hc(a,b)},drop:gc(a,Gc),leave:function(){Jc(a)}};var j=b.input.getField();Mf(j,"keyup",function(b){Zc.call(a,b)}),Mf(j,"keydown",gc(a,Xc)),Mf(j,"keypress",gc(a,$c)),Mf(j,"focus",ng(ad,a)),Mf(j,"blur",ng(bd,a))}function tc(a,b,c){var d=c&&c!=x.Init;if(!b!=!d){var e=a.display.dragFunctions,f=b?Mf:Pf;f(a.display.scroller,"dragstart",e.start),f(a.display.scroller,"dragenter",e.enter),f(a.display.scroller,"dragover",e.over),f(a.display.scroller,"dragleave",e.leave),f(a.display.scroller,"drop",e.drop)}}function uc(a){var b=a.display;(b.lastWrapHeight!=b.wrapper.clientHeight||b.lastWrapWidth!=b.wrapper.clientWidth)&&(b.cachedCharWidth=b.cachedTextHeight=b.cachedPaddingH=null,b.scrollbarsClipped=!1,a.setSize())}function vc(a,b){for(var c=Kf(b);c!=a.wrapper;c=c.parentNode)if(!c||1==c.nodeType&&"true"==c.getAttribute("cm-ignore-events")||c.parentNode==a.sizer&&c!=a.mover)return!0}function wc(a,b,c,d){var e=a.display;if(!c&&"true"==Kf(b).getAttribute("cm-not-content"))return null;var f,g,h=e.lineSpace.getBoundingClientRect();try{f=b.clientX-h.left,g=b.clientY-h.top}catch(b){return null}var j,i=Rb(a,f,g);if(d&&1==i.xRel&&(j=jf(a.doc,i.line).text).length==i.ch){var k=cg(j,j.length,a.options.tabSize)-j.length;i=qa(i.line,Math.max(0,Math.round((f-rb(a.display).left)/Vb(a.display))-k))}return i}function xc(a){var b=this,c=b.display;if(!(Uf(b,a)||c.activeTouch&&c.input.supportsTouch())){if(c.shift=a.shiftKey,vc(c,a))return void(h||(c.scroller.draggable=!1,setTimeout(function(){c.scroller.draggable=!0},100)));if(!Ec(b,a)){var d=wc(b,a);switch(window.focus(),Lf(a)){case 1:b.state.selectingText?b.state.selectingText(a):d?Ac(b,a,d):Kf(a)==c.scroller&&Gf(a);break;case 2:h&&(b.state.lastMiddleDown=+new Date),d&&Ua(b.doc,d),setTimeout(function(){c.input.focus()},20),Gf(a);break;case 3:u?cd(b,a):_c(b)}}}}function Ac(a,b,c){f?setTimeout(ng(va,a),0):a.curOp.focus=zg();var e,d=+new Date;zc&&zc.time>d-400&&0==ra(zc.pos,c)?e="triple":yc&&yc.time>d-400&&0==ra(yc.pos,c)?(e="double",zc={time:d,pos:c}):(e="single",yc={time:d,pos:c});var i,g=a.doc.sel,h=q?b.metaKey:b.ctrlKey;a.options.dragDrop&&Ig&&!a.isReadOnly()&&"single"==e&&(i=g.contains(c))>-1&&(ra((i=g.ranges[i]).from(),c)<0||c.xRel>0)&&(ra(i.to(),c)>0||c.xRel<0)?Bc(a,b,c,h):Cc(a,b,c,e,h)}function Bc(a,b,c,d){var e=a.display,i=+new Date,j=gc(a,function(k){h&&(e.scroller.draggable=!1),a.state.draggingText=!1,Pf(document,"mouseup",j),Pf(e.scroller,"drop",j),Math.abs(b.clientX-k.clientX)+Math.abs(b.clientY-k.clientY)<10&&(Gf(k),!d&&+new Date-200=p;p++){var r=jf(g,p).text,s=dg(r,m,f);m==o?e.push(new La(qa(p,s),qa(p,s))):r.length>s&&e.push(new La(qa(p,s),qa(p,dg(r,o,f))))}e.length||e.push(new La(c,c)),$a(g,Ma(j.ranges.slice(0,i).concat(e),i),{origin:"*mouse",scroll:!1}),a.scrollIntoView(b)}else{var t=h,u=t.anchor,v=b;if("single"!=d){if("double"==d)var w=a.findWordAt(b);else var w=new La(qa(b.line,0),Pa(g,qa(b.line+1,0)));ra(w.anchor,u)>0?(v=w.head,u=ua(t.from(),w.anchor)):(v=w.anchor,u=ta(t.to(),w.head))}var e=j.ranges.slice(0);e[i]=new La(Pa(g,u),v),$a(g,Ma(e,i),_f)}}function r(b){var c=++q,e=wc(a,b,!0,"rect"==d);if(e)if(0!=ra(e,n)){a.curOp.focus=zg(),o(e);var h=R(f,g);(e.line>=h.to||e.linep.bottom?20:0;i&&setTimeout(gc(a,function(){q==c&&(f.scroller.scrollTop+=i,r(b))}),50)}}function s(b){a.state.selectingText=!1,q=1/0,Gf(b),f.input.focus(),Pf(document,"mousemove",t),Pf(document,"mouseup",u),g.history.lastSelOrigin=null}var f=a.display,g=a.doc;Gf(b);var h,i,j=g.sel,k=j.ranges;if(e&&!b.shiftKey?(i=g.sel.contains(c),h=i>-1?k[i]:new La(c,c)):(h=g.sel.primary(),i=g.sel.primIndex),b.altKey)d="rect",e||(h=new La(c,c)),c=wc(a,b,!0,!0),i=-1;else if("double"==d){var l=a.findWordAt(c);h=a.display.shift||g.extend?Ta(g,h,l.anchor,l.head):l}else if("triple"==d){var m=new La(qa(c.line,0),Pa(g,qa(c.line+1,0)));h=a.display.shift||g.extend?Ta(g,h,m.anchor,m.head):m}else h=Ta(g,h,c);e?-1==i?(i=k.length,$a(g,Ma(k.concat([h]),i),{scroll:!1,origin:"*mouse"})):k.length>1&&k[i].empty()&&"single"==d&&!b.shiftKey?($a(g,Ma(k.slice(0,i).concat(k.slice(i+1)),0),{scroll:!1,origin:"*mouse"}),j=g.sel):Wa(g,i,h,_f):(i=0,$a(g,new Ka([h],0),_f),j=g.sel);var n=c,p=f.wrapper.getBoundingClientRect(),q=0,t=gc(a,function(a){Lf(a)?r(a):s(a)}),u=gc(a,s);a.state.selectingText=u,Mf(document,"mousemove",t),Mf(document,"mouseup",u)}function Dc(a,b,c,d){try{var e=b.clientX,f=b.clientY}catch(b){return!1}if(e>=Math.floor(a.display.gutters.getBoundingClientRect().right))return!1;d&&Gf(b);var g=a.display,h=g.lineDiv.getBoundingClientRect();if(f>h.bottom||!Wf(a,c))return If(b);f-=h.top-g.viewOffset;for(var i=0;i=e){var k=of(a.doc,f),l=a.options.gutters[i];return Qf(a,c,a,k,l,b),If(b)}}}function Ec(a,b){return Dc(a,b,"gutterClick",!0)}function Gc(a){var b=this;if(Jc(b),!Uf(b,a)&&!vc(b.display,a)){Gf(a),f&&(Fc=+new Date);var c=wc(b,a,!0),d=a.dataTransfer.files;if(c&&!b.isReadOnly())if(d&&d.length&&window.FileReader&&window.File)for(var e=d.length,g=Array(e),h=0,i=function(a,d){if(!b.options.allowDropFileTypes||-1!=ig(b.options.allowDropFileTypes,a.type)){var f=new FileReader;f.onload=gc(b,function(){var a=f.result;if(/[\x00-\x08\x0e-\x1f]{2}/.test(a)&&(a=""),g[d]=a,++h==e){c=Pa(b.doc,c);var i={from:c,to:c,text:b.doc.splitLines(g.join(b.doc.lineSeparator())),origin:"paste"};kd(b.doc,i),Za(b.doc,Na(c,ed(i)))}}),f.readAsText(a)}},j=0;e>j;++j)i(d[j],j);else{if(b.state.draggingText&&b.doc.sel.contains(c)>-1)return b.state.draggingText(a),void setTimeout(function(){b.display.input.focus()},20);try{var g=a.dataTransfer.getData("Text");if(g){if(b.state.draggingText&&!(q?a.altKey:a.ctrlKey))var k=b.listSelections();if(_a(b.doc,Na(c,c)),k)for(var j=0;ji.clientWidth,l=i.scrollHeight>i.clientHeight;if(e&&j||f&&l){if(f&&q&&h)a:for(var m=b.target,n=g.view;m!=i;m=m.parentNode)for(var o=0;op?r=Math.max(0,r+p-50):s=Math.min(a.doc.height,s+p+50),$(a,{top:r,bottom:s})}20>Mc&&(null==g.wheelStartX?(g.wheelStartX=i.scrollLeft,g.wheelStartY=i.scrollTop,g.wheelDX=e,g.wheelDY=f,setTimeout(function(){if(null!=g.wheelStartX){var a=i.scrollLeft-g.wheelStartX,b=i.scrollTop-g.wheelStartY,c=b&&g.wheelDY&&b/g.wheelDY||a&&g.wheelDX&&a/g.wheelDX;g.wheelStartX=g.wheelStartY=null,c&&(Nc=(Nc*Mc+c)/(Mc+1),++Mc)}},200)):(g.wheelDX+=e,g.wheelDY+=f))}}function Qc(a,b,c){if("string"==typeof b&&(b=Od[b],!b))return!1;a.display.input.ensurePolled();var d=a.display.shift,e=!1;try{a.isReadOnly()&&(a.state.suppressEdits=!0),c&&(a.display.shift=!1),e=b(a)!=Zf}finally{a.display.shift=d,a.state.suppressEdits=!1}return e}function Rc(a,b,c){for(var d=0;dg&&27==a.keyCode&&(a.returnValue=!1);var c=a.keyCode;b.display.shift=16==c||a.shiftKey;var d=Uc(b,a);k&&(Wc=d?c:null,!d&&88==c&&!Pg&&(q?a.metaKey:a.ctrlKey)&&b.replaceSelection("",null,"cut")),18!=c||/\bCodeMirror-crosshair\b/.test(b.display.lineDiv.className)||Yc(b)}}function Yc(a){function c(a){18!=a.keyCode&&a.altKey||(Bg(b,"CodeMirror-crosshair"),Pf(document,"keyup",c),Pf(document,"mouseover",c))}var b=a.display.lineDiv;Cg(b,"CodeMirror-crosshair"),Mf(document,"keyup",c),Mf(document,"mouseover",c)}function Zc(a){16==a.keyCode&&(this.doc.sel.shift=!1),Uf(this,a)}function $c(a){var b=this;if(!(vc(b.display,a)||Uf(b,a)||a.ctrlKey&&!a.altKey||q&&a.metaKey)){var c=a.keyCode,d=a.charCode;if(k&&c==Wc)return Wc=null,void Gf(a);if(!k||a.which&&!(a.which<10)||!Uc(b,a)){var e=String.fromCharCode(null==d?c:d);Vc(b,a,e)||b.display.input.onKeyPress(a)}}}function _c(a){a.state.delayingBlurEvent=!0,setTimeout(function(){a.state.delayingBlurEvent&&(a.state.delayingBlurEvent=!1,bd(a))},100)}function ad(a){a.state.delayingBlurEvent&&(a.state.delayingBlurEvent=!1),"nocursor"!=a.options.readOnly&&(a.state.focused||(Qf(a,"focus",a),a.state.focused=!0,Cg(a.display.wrapper,"CodeMirror-focused"),a.curOp||a.display.selForContextMenu==a.doc.sel||(a.display.input.reset(),h&&setTimeout(function(){a.display.input.reset(!0)},20)),a.display.input.receivedFocus()),kb(a))}function bd(a){a.state.delayingBlurEvent||(a.state.focused&&(Qf(a,"blur",a),a.state.focused=!1,Bg(a.display.wrapper,"CodeMirror-focused")),clearInterval(a.display.blinker),setTimeout(function(){a.state.focused||(a.display.shift=!1)},150))}function cd(a,b){vc(a.display,b)||dd(a,b)||Uf(a,b,"contextmenu")||a.display.input.onContextMenu(b)}function dd(a,b){return Wf(a,"gutterContextMenu")?Dc(a,b,"gutterContextMenu",!1):!1}function fd(a,b){if(ra(a,b.from)<0)return a;if(ra(a,b.to)<=0)return ed(b);var c=a.line+b.text.length-(b.to.line-b.from.line)-1,d=a.ch;return a.line==b.to.line&&(d+=ed(b).ch-b.to.ch),qa(c,d)}function gd(a,b){for(var c=[],d=0;d=0;--e)ld(a,{from:d[e].from,to:d[e].to,text:e?[""]:b.text});else ld(a,b)}}function ld(a,b){if(1!=b.text.length||""!=b.text[0]||0!=ra(b.from,b.to)){var c=gd(a,b);vf(a,b,c,a.cm?a.cm.curOp.id:NaN),od(a,b,c,ie(a,b));var d=[];gf(a,function(a,c){c||-1!=ig(d,a.history)||(Ff(a.history,b),d.push(a.history)),od(a,b,null,ie(a,b))})}}function md(a,b,c){if(!a.cm||!a.cm.state.suppressEdits){for(var e,d=a.history,f=a.sel,g="undo"==b?d.done:d.undone,h="undo"==b?d.undone:d.done,i=0;i=0;--i){var l=e.changes[i];if(l.origin=b,k&&!jd(a,l,!1))return void(g.length=0);j.push(sf(a,l));var m=i?gd(a,l):gg(g);od(a,l,m,ke(a,l)),!i&&a.cm&&a.cm.scrollIntoView({from:l.from,to:ed(l)});var n=[];gf(a,function(a,b){b||-1!=ig(n,a.history)||(Ff(a.history,l),n.push(a.history)),od(a,l,null,ke(a,l))})}}}}function nd(a,b){if(0!=b&&(a.first+=b,a.sel=new Ka(jg(a.sel.ranges,function(a){return new La(qa(a.anchor.line+b,a.anchor.ch),qa(a.head.line+b,a.head.ch))}),a.sel.primIndex),a.cm)){lc(a.cm,a.first,a.first-b,b);for(var c=a.cm.display,d=c.viewFrom;da.lastLine())){if(b.from.linef&&(b={from:b.from,to:qa(f,jf(a,f).text.length),text:[b.text[0]],origin:b.origin}),b.removed=kf(a,b.from,b.to),c||(c=gd(a,b)),a.cm?pd(a.cm,b,d):_e(a,b,d),_a(a,c,$f)}}function pd(a,b,c){var d=a.doc,e=a.display,f=b.from,g=b.to,h=!1,i=f.line;a.options.lineWrapping||(i=nf(ve(jf(d,f.line))),d.iter(i,g.line+1,function(a){return a==e.maxLine?(h=!0,!0):void 0})),d.sel.contains(b.from,b.to)>-1&&Vf(a),_e(d,b,c,C(a)),a.options.lineWrapping||(d.iter(i,f.line+b.text.length,function(a){var b=I(a);b>e.maxLineLength&&(e.maxLine=a,e.maxLineLength=b,e.maxLineChanged=!0,h=!1)}),h&&(a.curOp.updateMaxLine=!0)),d.frontier=Math.min(d.frontier,f.line),lb(a,400);var j=b.text.length-(g.line-f.line)-1;b.full?lc(a):f.line!=g.line||1!=b.text.length||$e(a.doc,b)?lc(a,f.line,g.line+1,j):mc(a,f.line,"text");var k=Wf(a,"changes"),l=Wf(a,"change");if(l||k){var m={from:f,to:g,text:b.text,removed:b.removed,origin:b.origin};l&&Sf(a,"change",a,m),k&&(a.curOp.changeObjs||(a.curOp.changeObjs=[])).push(m)}a.display.selForContextMenu=null}function qd(a,b,c,d,e){if(d||(d=c),ra(d,c)<0){var f=d;d=c,c=f}"string"==typeof b&&(b=a.splitLines(b)),kd(a,{from:c,to:d,text:b,origin:e})}function rd(a,b){if(!Uf(a,"scrollCursorIntoView")){var c=a.display,d=c.sizer.getBoundingClientRect(),e=null;if(b.top+d.top<0?e=!0:b.bottom+d.top>(window.innerHeight||document.documentElement.clientHeight)&&(e=!1),null!=e&&!n){var f=ug("div","\u200b",null,"position: absolute; top: "+(b.top-c.viewOffset-pb(a.display))+"px; height: "+(b.bottom-b.top+sb(a)+c.barHeight)+"px; left: "+b.left+"px; width: 2px;");a.display.lineSpace.appendChild(f),f.scrollIntoView(e),a.display.lineSpace.removeChild(f)}}}function sd(a,b,c,d){null==d&&(d=0);for(var e=0;5>e;e++){var f=!1,g=Ob(a,b),h=c&&c!=b?Ob(a,c):g,i=ud(a,Math.min(g.left,h.left),Math.min(g.top,h.top)-d,Math.max(g.left,h.left),Math.max(g.bottom,h.bottom)+d),j=a.doc.scrollTop,k=a.doc.scrollLeft;if(null!=i.scrollTop&&(Kc(a,i.scrollTop),Math.abs(a.doc.scrollTop-j)>1&&(f=!0)),null!=i.scrollLeft&&(Lc(a,i.scrollLeft),Math.abs(a.doc.scrollLeft-k)>1&&(f=!0)),!f)break}return g}function td(a,b,c,d,e){var f=ud(a,b,c,d,e);null!=f.scrollTop&&Kc(a,f.scrollTop),null!=f.scrollLeft&&Lc(a,f.scrollLeft)}function ud(a,b,c,d,e){var f=a.display,g=Ub(a.display);0>c&&(c=0);var h=a.curOp&&null!=a.curOp.scrollTop?a.curOp.scrollTop:f.scroller.scrollTop,i=ub(a),j={};e-c>i&&(e=c+i);var k=a.doc.height+qb(f),l=g>c,m=e>k-g;if(h>c)j.scrollTop=l?0:c;else if(e>h+i){var n=Math.min(c,(m?k:e)-i);n!=h&&(j.scrollTop=n)}var o=a.curOp&&null!=a.curOp.scrollLeft?a.curOp.scrollLeft:f.scroller.scrollLeft,p=tb(a)-(a.options.fixedGutter?f.gutters.offsetWidth:0),q=d-b>p;return q&&(d=b+p),10>b?j.scrollLeft=0:o>b?j.scrollLeft=Math.max(0,b-(q?0:10)):d>p+o-3&&(j.scrollLeft=d+(q?0:10)-p),j}function vd(a,b,c){(null!=b||null!=c)&&xd(a),null!=b&&(a.curOp.scrollLeft=(null==a.curOp.scrollLeft?a.doc.scrollLeft:a.curOp.scrollLeft)+b),null!=c&&(a.curOp.scrollTop=(null==a.curOp.scrollTop?a.doc.scrollTop:a.curOp.scrollTop)+c)}function wd(a){xd(a);var b=a.getCursor(),c=b,d=b;a.options.lineWrapping||(c=b.ch?qa(b.line,b.ch-1):b,d=qa(b.line,b.ch+1)),a.curOp.scrollToPos={from:c,to:d,margin:a.options.cursorScrollMargin,isCursor:!0}}function xd(a){var b=a.curOp.scrollToPos;if(b){a.curOp.scrollToPos=null;var c=Pb(a,b.from),d=Pb(a,b.to),e=ud(a,Math.min(c.left,d.left),Math.min(c.top,d.top)-b.margin,Math.max(c.right,d.right),Math.max(c.bottom,d.bottom)+b.margin);
+a.scrollTo(e.scrollLeft,e.scrollTop)}}function yd(a,b,c,d){var f,e=a.doc;null==c&&(c="add"),"smart"==c&&(e.mode.indent?f=ob(a,b):c="prev");var g=a.options.tabSize,h=jf(e,b),i=cg(h.text,null,g);h.stateAfter&&(h.stateAfter=null);var k,j=h.text.match(/^\s*/)[0];if(d||/\S/.test(h.text)){if("smart"==c&&(k=e.mode.indent(f,h.text.slice(j.length),h.text),k==Zf||k>150)){if(!d)return;c="prev"}}else k=0,c="not";"prev"==c?k=b>e.first?cg(jf(e,b-1).text,null,g):0:"add"==c?k=i+a.options.indentUnit:"subtract"==c?k=i-a.options.indentUnit:"number"==typeof c&&(k=i+c),k=Math.max(0,k);var l="",m=0;if(a.options.indentWithTabs)for(var n=Math.floor(k/g);n;--n)m+=g,l+=" ";if(k>m&&(l+=fg(k-m)),l!=j)return qd(e,l,qa(b,0),qa(b,j.length),"+input"),h.stateAfter=null,!0;for(var n=0;n=0;b--)qd(a.doc,"",d[b].from,d[b].to,"+delete");wd(a)})}function Bd(a,b,c,d,e){function j(){var b=f+c;return b=a.first+a.size?!1:(f=b,i=jf(a,b))}function k(a){var b=(e?dh:eh)(i,g,c,!0);if(null==b){if(a||!j())return!1;g=e?(0>c?Xg:Wg)(i):0>c?i.text.length:0}else g=b;return!0}var f=b.line,g=b.ch,h=c,i=jf(a,f);if("char"==d)k();else if("column"==d)k(!0);else if("word"==d||"group"==d)for(var l=null,m="group"==d,n=a.cm&&a.cm.getHelper(b,"wordChars"),o=!0;!(0>c)||k(!o);o=!1){var p=i.text.charAt(g)||"\n",q=qg(p,n)?"w":m&&"\n"==p?"n":!m||/\s/.test(p)?null:"p";if(!m||o||q||(q="s"),l&&l!=q){0>c&&(c=1,k());break}if(q&&(l=q),c>0&&!k(!o))break}var r=eb(a,qa(f,g),b,h,!0);return ra(b,r)||(r.hitSide=!0),r}function Cd(a,b,c,d){var g,e=a.doc,f=b.left;if("page"==d){var h=Math.min(a.display.wrapper.clientHeight,window.innerHeight||document.documentElement.clientHeight);g=b.top+c*(h-(0>c?1.5:.5)*Ub(a.display))}else"line"==d&&(g=c>0?b.bottom+3:b.top-3);for(;;){var i=Rb(a,f,g);if(!i.outside)break;if(0>c?0>=g:g>=e.height){i.hitSide=!0;break}g+=5*c}return i}function Fd(a,b,c,d){x.defaults[a]=b,c&&(Ed[a]=d?function(a,b,d){d!=Gd&&c(a,b,d)}:c)}function Qd(a){for(var c,d,e,f,b=a.split(/-(?!$)/),a=b[b.length-1],g=0;g0||0==g&&f.clearWhenEmpty!==!1)return f;if(f.replacedWith&&(f.collapsed=!0,f.widgetNode=ug("span",[f.replacedWith],"CodeMirror-widget"),d.handleMouseEvents||f.widgetNode.setAttribute("cm-ignore-events","true"),d.insertLeft&&(f.widgetNode.insertLeft=!0)),f.collapsed){if(ue(a,b.line,b,c,f)||b.line!=c.line&&ue(a,c.line,b,c,f))throw new Error("Inserting collapsed marker partially overlapping an existing one");w=!0}f.addToHistory&&vf(a,{from:b,to:c,origin:"markText"},a.sel,NaN);var j,h=b.line,i=a.cm;if(a.iter(h,c.line+1,function(a){i&&f.collapsed&&!i.options.lineWrapping&&ve(a)==i.display.maxLine&&(j=!0),f.collapsed&&h!=b.line&&mf(a,0),fe(a,new ce(f,h==b.line?b.ch:null,h==c.line?c.ch:null)),++h}),f.collapsed&&a.iter(b.line,c.line+1,function(b){ze(a,b)&&mf(b,0)}),f.clearOnEnter&&Mf(f,"beforeCursorEnter",function(){f.clear()}),f.readOnly&&(v=!0,(a.history.done.length||a.history.undone.length)&&a.clearHistory()),f.collapsed&&(f.id=++Wd,f.atomic=!0),i){if(j&&(i.curOp.updateMaxLine=!0),f.collapsed)lc(i,b.line,c.line+1);else if(f.className||f.title||f.startStyle||f.endStyle||f.css)for(var k=b.line;k<=c.line;k++)mc(i,k,"text");f.atomic&&bb(i.doc),Sf(i,"markerAdded",i,f)}return f}function $d(a,b,c,d,e){d=mg(d),d.shared=!1;var f=[Yd(a,b,c,d,e)],g=f[0],h=d.widgetNode;return gf(a,function(a){h&&(d.widgetNode=h.cloneNode(!0)),f.push(Yd(a,Pa(a,b),Pa(a,c),d,e));for(var i=0;i=b:f.to>b);(e||(e=[])).push(new ce(g,f.from,i?null:f.to))}}return e}function he(a,b,c){if(a)for(var e,d=0;d=b:f.to>b);if(h||f.from==b&&"bookmark"==g.type&&(!c||f.marker.insertLeft)){var i=null==f.from||(g.inclusiveLeft?f.from<=b:f.from0&&h)for(var l=0;ll;++l)o.push(q);o.push(i)}return o}function je(a){for(var b=0;b0)){var k=[i,1],l=ra(j.from,h.from),m=ra(j.to,h.to);(0>l||!g.inclusiveLeft&&!l)&&k.push({from:j.from,to:h.from}),(m>0||!g.inclusiveRight&&!m)&&k.push({from:h.to,to:j.to}),e.splice.apply(e,k),i+=k.length-1}}return e}function me(a){var b=a.markedSpans;if(b){for(var c=0;c=0&&0>=l||0>=k&&l>=0)&&(0>=k&&(ra(j.to,c)>0||i.marker.inclusiveRight&&e.inclusiveLeft)||k>=0&&(ra(j.from,d)<0||i.marker.inclusiveLeft&&e.inclusiveRight)))return!0}}}function ve(a){for(var b;b=se(a);)a=b.find(-1,!0).line;return a}function we(a){for(var b,c;b=te(a);)a=b.find(1,!0).line,(c||(c=[])).push(a);return c}function xe(a,b){var c=jf(a,b),d=ve(c);return c==d?b:nf(d)}function ye(a,b){if(b>a.lastLine())return b;var d,c=jf(a,b);if(!ze(a,c))return b;for(;d=te(c);)c=d.find(1,!0).line;return nf(c)+1}function ze(a,b){var c=w&&b.markedSpans;if(c)for(var d,e=0;ee;e++){d&&(d[0]=x.innerMode(a,c).mode);var f=a.token(b,c);if(b.pos>b.start)return f}throw new Error("Mode "+a.name+" failed to advance stream.")}function Le(a,b,c,d){function e(a){return{start:k.start,end:k.pos,string:k.current(),type:h||null,state:a?Md(f.mode,j):j}}var h,f=a.doc,g=f.mode;b=Pa(f,b);var l,i=jf(f,b.line),j=ob(a,b.line,c),k=new Vd(i.text,a.options.tabSize);for(d&&(l=[]);(d||k.posa.options.maxHighlightLength?(h=!1,g&&Pe(a,b,d,k.pos),k.pos=b.length,l=null):l=Ie(Ke(c,k,d,m),f),m){var n=m[0].name;n&&(l="m-"+(l?n+" "+l:n))}if(!h||j!=l){for(;ij;){var d=e[i];d>a&&e.splice(i,1,a,e[i+1],d),i+=2,j=Math.min(a,d)}if(b)if(h.opaque)e.splice(c,i-c,a,"cm-overlay "+b),i=c+2;else for(;i>c;c+=2){var f=e[c+1];e[c+1]=(f?f+" ":"")+"cm-overlay "+b}},f)}return{styles:e,classes:f.bgClass||f.textClass?f:null}}function Oe(a,b,c){if(!b.styles||b.styles[0]!=a.state.modeGen){var d=ob(a,nf(b)),e=Ne(a,b,b.text.length>a.options.maxHighlightLength?Md(a.doc.mode,d):d);b.stateAfter=d,b.styles=e.styles,e.classes?b.styleClasses=e.classes:b.styleClasses&&(b.styleClasses=null),c===a.doc.frontier&&a.doc.frontier++}return b.styles}function Pe(a,b,c,d){var e=a.doc.mode,f=new Vd(b,a.options.tabSize);for(f.start=f.pos=d||0,""==b&&Je(e,c);!f.eol();)Ke(e,f,c),f.start=f.pos}function Se(a,b){if(!a||/^\s*$/.test(a))return null;var c=b.addModeClass?Re:Qe;return c[a]||(c[a]=a.replace(/\S+/g,"cm-$&"))}function Te(a,b){var c=ug("span",null,null,h?"padding-right: .1px":null),d={pre:ug("pre",[c],"CodeMirror-line"),content:c,col:0,pos:0,cm:a,splitSpaces:(f||h)&&a.getOption("lineWrapping")};b.measure={};for(var e=0;e<=(b.rest?b.rest.length:0);e++){var i,g=e?b.rest[e-1]:b.line;d.pos=0,d.addToken=Ve,Mg(a.display.measure)&&(i=qf(g))&&(d.addToken=Xe(d.addToken,i)),d.map=[];var j=b!=a.display.externalMeasured&&nf(g);Ze(g,d,Oe(a,g,j)),g.styleClasses&&(g.styleClasses.bgClass&&(d.bgClass=Dg(g.styleClasses.bgClass,d.bgClass||"")),g.styleClasses.textClass&&(d.textClass=Dg(g.styleClasses.textClass,d.textClass||""))),0==d.map.length&&d.map.push(0,0,d.content.appendChild(Kg(a.display.measure))),0==e?(b.measure.map=d.map,b.measure.cache={}):((b.measure.maps||(b.measure.maps=[])).push(d.map),(b.measure.caches||(b.measure.caches=[])).push({}))}return h&&/\bcm-tab\b/.test(d.content.lastChild.className)&&(d.content.className="cm-tab-wrap-hack"),Qf(a,"renderLine",a,b.line,d.pre),d.pre.className&&(d.textClass=Dg(d.pre.className,d.textClass||"")),d}function Ue(a){var b=ug("span","\u2022","cm-invalidchar");return b.title="\\u"+a.charCodeAt(0).toString(16),b.setAttribute("aria-label",b.title),b}function Ve(a,b,c,d,e,h,i){if(b){var j=a.splitSpaces?b.replace(/ {3,}/g,We):b,k=a.cm.state.specialChars,l=!1;if(k.test(b))for(var m=document.createDocumentFragment(),n=0;;){k.lastIndex=n;var o=k.exec(b),p=o?o.index-n:b.length-n;if(p){var q=document.createTextNode(j.slice(n,n+p));f&&9>g?m.appendChild(ug("span",[q])):m.appendChild(q),a.map.push(a.pos,a.pos+p,q),a.col+=p,a.pos+=p}if(!o)break;if(n+=p+1," "==o[0]){var r=a.cm.options.tabSize,s=r-a.col%r,q=m.appendChild(ug("span",fg(s),"cm-tab"));q.setAttribute("role","presentation"),q.setAttribute("cm-text"," "),a.col+=s}else if("\r"==o[0]||"\n"==o[0]){var q=m.appendChild(ug("span","\r"==o[0]?"\u240d":"\u2424","cm-invalidchar"));q.setAttribute("cm-text",o[0]),a.col+=1}else{var q=a.cm.options.specialCharPlaceholder(o[0]);q.setAttribute("cm-text",o[0]),f&&9>g?m.appendChild(ug("span",[q])):m.appendChild(q),a.col+=1}a.map.push(a.pos,a.pos+1,q),a.pos++}else{a.col+=b.length;var m=document.createTextNode(j);a.map.push(a.pos,a.pos+b.length,m),f&&9>g&&(l=!0),a.pos+=b.length}if(c||d||e||l||i){var t=c||"";d&&(t+=d),e&&(t+=e);var u=ug("span",[m],t,i);return h&&(u.title=h),a.content.appendChild(u)}a.content.appendChild(m)}}function We(a){for(var b=" ",c=0;cj&&m.from<=j)break}if(m.to>=k)return a(c,d,e,f,g,h,i);a(c,d.slice(0,m.to-j),e,f,null,h,i),f=null,d=d.slice(m.to-j),j=m.to}}}function Ye(a,b,c,d){var e=!d&&c.widgetNode;e&&a.map.push(a.pos,a.pos+b,e),!d&&a.cm.display.input.needsContentAttribute&&(e||(e=a.content.appendChild(document.createElement("span"))),e.setAttribute("cm-marker",c.id)),e&&(a.cm.display.input.setUneditable(e),a.content.appendChild(e)),a.pos+=b}function Ze(a,b,c){var d=a.markedSpans,e=a.text,f=0;if(d)for(var k,l,n,o,p,q,r,h=e.length,i=0,g=1,j="",m=0;;){if(m==i){n=o=p=q=l="",r=null,m=1/0;for(var t,s=[],u=0;ui||w.collapsed&&v.to==i&&v.from==i)?(null!=v.to&&v.to!=i&&m>v.to&&(m=v.to,o=""),w.className&&(n+=" "+w.className),w.css&&(l=(l?l+";":"")+w.css),w.startStyle&&v.from==i&&(p+=" "+w.startStyle),w.endStyle&&v.to==m&&(t||(t=[])).push(w.endStyle,v.to),w.title&&!q&&(q=w.title),w.collapsed&&(!r||qe(r.marker,w)<0)&&(r=v)):v.from>i&&m>v.from&&(m=v.from)}if(t)for(var u=0;u=h)break;for(var x=Math.min(h,m);;){if(j){var y=i+j.length;if(!r){var z=y>x?j.slice(0,x-i):j;b.addToken(b,z,k?k+n:n,p,i+z.length==m?o:"",q,l)}if(y>=x){j=j.slice(x-i),i=x;break}i=y,p=""}j=e.slice(f,f=c[g++]),k=Se(c[g++],b.cm.options)}}else for(var g=1;gc;++c)f.push(new Fe(j[c],e(c),d));return f}var h=b.from,i=b.to,j=b.text,k=jf(a,h.line),l=jf(a,i.line),m=gg(j),n=e(j.length-1),o=i.line-h.line;if(b.full)a.insert(0,g(0,j.length)),a.remove(j.length,a.size-j.length);else if($e(a,b)){var p=g(0,j.length-1);f(l,l.text,n),o&&a.remove(h.line,o),p.length&&a.insert(h.line,p)}else if(k==l)if(1==j.length)f(k,k.text.slice(0,h.ch)+m+k.text.slice(i.ch),n);else{var p=g(1,j.length-1);p.push(new Fe(m+k.text.slice(i.ch),n,d)),f(k,k.text.slice(0,h.ch)+j[0],e(0)),a.insert(h.line+1,p)}else if(1==j.length)f(k,k.text.slice(0,h.ch)+j[0]+l.text.slice(i.ch),e(0)),a.remove(h.line+1,o);else{f(k,k.text.slice(0,h.ch)+j[0],e(0)),f(l,m+l.text.slice(i.ch),n);var p=g(1,j.length-1);o>1&&a.remove(h.line+1,o-1),a.insert(h.line+1,p)}Sf(a,"change",a,b)}function af(a){this.lines=a,this.parent=null;for(var b=0,c=0;bb||b>=a.size)throw new Error("There is no line "+(b+a.first)+" in the document.");for(var c=a;!c.lines;)for(var d=0;;++d){var e=c.children[d],f=e.chunkSize();if(f>b){c=e;break}b-=f}return c.lines[b]}function kf(a,b,c){var d=[],e=b.line;return a.iter(b.line,c.line+1,function(a){var f=a.text;e==c.line&&(f=f.slice(0,c.ch)),e==b.line&&(f=f.slice(b.ch)),d.push(f),++e}),d}function lf(a,b,c){var d=[];return a.iter(b,c,function(a){d.push(a.text)}),d}function mf(a,b){var c=b-a.height;if(c)for(var d=a;d;d=d.parent)d.height+=c}function nf(a){if(null==a.parent)return null;for(var b=a.parent,c=ig(b.lines,a),d=b.parent;d;b=d,d=d.parent)for(var e=0;d.children[e]!=b;++e)c+=d.children[e].chunkSize();return c+b.first}function of(a,b){var c=a.first;a:do{for(var d=0;db){a=e;continue a}b-=f,c+=e.chunkSize()}return c}while(!a.lines);for(var d=0;db)break;b-=h}return c+d}function pf(a){a=ve(a);for(var b=0,c=a.parent,d=0;d1&&!a.done[a.done.length-2].ranges?(a.done.pop(),gg(a.done)):void 0}function vf(a,b,c,d){var e=a.history;e.undone.length=0;var g,f=+new Date;if((e.lastOp==d||e.lastOrigin==b.origin&&b.origin&&("+"==b.origin.charAt(0)&&a.cm&&e.lastModTime>f-a.cm.options.historyEventDelay||"*"==b.origin.charAt(0)))&&(g=uf(e,e.lastOp==d))){var h=gg(g.changes);0==ra(b.from,b.to)&&0==ra(b.from,h.to)?h.to=ed(b):g.changes.push(sf(a,b))}else{var i=gg(e.done);for(i&&i.ranges||yf(a.sel,e.done),g={changes:[sf(a,b)],generation:e.generation},e.done.push(g);e.done.length>e.undoDepth;)e.done.shift(),e.done[0].ranges||e.done.shift()}e.done.push(c),e.generation=++e.maxGeneration,e.lastModTime=e.lastSelTime=f,e.lastOp=e.lastSelOp=d,e.lastOrigin=e.lastSelOrigin=b.origin,h||Qf(a,"historyAdded")}function wf(a,b,c,d){var e=b.charAt(0);return"*"==e||"+"==e&&c.ranges.length==d.ranges.length&&c.somethingSelected()==d.somethingSelected()&&new Date-a.history.lastSelTime<=(a.cm?a.cm.options.historyEventDelay:500)}function xf(a,b,c,d){var e=a.history,f=d&&d.origin;c==e.lastSelOp||f&&e.lastSelOrigin==f&&(e.lastModTime==e.lastSelTime&&e.lastOrigin==f||wf(a,f,gg(e.done),b))?e.done[e.done.length-1]=b:yf(b,e.done),e.lastSelTime=+new Date,e.lastSelOrigin=f,e.lastSelOp=c,d&&d.clearRedo!==!1&&tf(e.undone)}function yf(a,b){var c=gg(b);c&&c.ranges&&c.equals(a)||b.push(a)}function zf(a,b,c,d){var e=b["spans_"+a.id],f=0;a.iter(Math.max(a.first,c),Math.min(a.first+a.size,d),function(c){c.markedSpans&&((e||(e=b["spans_"+a.id]={}))[f]=c.markedSpans),++f})}function Af(a){if(!a)return null;for(var c,b=0;b-1&&(gg(h)[l]=j[l],delete j[l])}}}return e}function Df(a,b,c,d){c0?d.slice():Nf:d||Nf}function Sf(a,b){function f(a){return function(){a.apply(null,d)}}var c=Of(a,b,!1);if(c.length){var e,d=Array.prototype.slice.call(arguments,2);Wb?e=Wb.delayedCallbacks:Rf?e=Rf:(e=Rf=[],setTimeout(Tf,0));for(var g=0;g0}function Xf(a){a.prototype.on=function(a,b){Mf(this,a,b)},a.prototype.off=function(a,b){Pf(this,a,b)}}function bg(){this.id=null}function fg(a){for(;eg.length<=a;)eg.push(gg(eg)+" ");return eg[a]}function gg(a){return a[a.length-1]}function ig(a,b){for(var c=0;c-1&&pg(a)?!0:b.test(a):pg(a)}function rg(a){for(var b in a)if(a.hasOwnProperty(b)&&a[b])return!1;return!0}function tg(a){return a.charCodeAt(0)>=768&&sg.test(a)}function ug(a,b,c,d){var e=document.createElement(a);if(c&&(e.className=c),d&&(e.style.cssText=d),"string"==typeof b)e.appendChild(document.createTextNode(b));else if(b)for(var f=0;f0;--b)a.removeChild(a.firstChild);return a}function xg(a,b){return wg(a).appendChild(b)}function zg(){for(var a=document.activeElement;a&&a.root&&a.root.activeElement;)a=a.root.activeElement;return a}function Ag(a){return new RegExp("(^|\\s)"+a+"(?:$|\\s)\\s*")}function Dg(a,b){for(var c=a.split(" "),d=0;d2&&!(f&&8>g))}var c=Jg?ug("span","\u200b"):ug("span","\xa0",null,"display: inline-block; width: 1px; margin-right: -1px");return c.setAttribute("cm-text",""),c}function Mg(a){if(null!=Lg)return Lg;var b=xg(a,document.createTextNode("A\u062eA")),c=vg(b,0,1).getBoundingClientRect();if(!c||c.left==c.right)return!1;var d=vg(b,1,2).getBoundingClientRect();return Lg=d.right-c.right<3}function Rg(a){if(null!=Qg)return Qg;var b=xg(a,ug("span","x")),c=b.getBoundingClientRect(),d=vg(b,0,1).getBoundingClientRect();return Qg=Math.abs(c.left-d.left)>1}function Tg(a,b,c,d){if(!a)return d(b,c,"ltr");for(var e=!1,f=0;fb||b==c&&g.to==b)&&(d(Math.max(g.from,b),Math.min(g.to,c),1==g.level?"rtl":"ltr"),e=!0)}e||d(b,c,"ltr")}function Ug(a){return a.level%2?a.to:a.from}function Vg(a){return a.level%2?a.from:a.to}function Wg(a){var b=qf(a);return b?Ug(b[0]):0}function Xg(a){var b=qf(a);return b?Vg(gg(b)):a.text.length}function Yg(a,b){var c=jf(a.doc,b),d=ve(c);d!=c&&(b=nf(d));var e=qf(d),f=e?e[0].level%2?Xg(d):Wg(d):0;return qa(b,f)}function Zg(a,b){for(var c,d=jf(a.doc,b);c=te(d);)d=c.find(1,!0).line,b=null;var e=qf(d),f=e?e[0].level%2?Wg(d):Xg(d):d.text.length;return qa(null==b?nf(d):b,f)}function $g(a,b){var c=Yg(a,b.line),d=jf(a.doc,c.line),e=qf(d);if(!e||0==e[0].level){var f=Math.max(0,d.text.search(/\S/)),g=b.line==c.line&&b.ch<=f&&b.ch;return qa(c.line,g?0:f)}return c}function _g(a,b,c){var d=a[0].level;return b==d?!0:c==d?!1:c>b}function bh(a,b){ah=null;for(var d,c=0;cb)return c;if(e.from==b||e.to==b){if(null!=d)return _g(a,e.level,a[d].level)?(e.from!=e.to&&(ah=d),c):(e.from!=e.to&&(ah=c),d);d=c}}return d}function ch(a,b,c,d){if(!d)return b+c;do b+=c;while(b>0&&tg(a.text.charAt(b)));return b}function dh(a,b,c,d){var e=qf(a);if(!e)return eh(a,b,c,d);for(var f=bh(e,b),g=e[f],h=ch(a,b,g.level%2?-c:c,d);;){if(h>g.from&&h0==g.level%2?g.to:g.from);if(g=e[f+=c],!g)return null;h=c>0==g.level%2?ch(a,g.to,-1,d):ch(a,g.from,1,d)}}function eh(a,b,c,d){var e=b+c;if(d)for(;e>0&&tg(a.text.charAt(e));)e+=c;return 0>e||e>a.text.length?null:e}var a=navigator.userAgent,b=navigator.platform,c=/gecko\/\d/i.test(a),d=/MSIE \d/.test(a),e=/Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(a),f=d||e,g=f&&(d?document.documentMode||6:e[1]),h=/WebKit\//.test(a),i=h&&/Qt\/\d+\.\d+/.test(a),j=/Chrome\//.test(a),k=/Opera\//.test(a),l=/Apple Computer/.test(navigator.vendor),m=/Mac OS X 1\d\D([8-9]|\d\d)\D/.test(a),n=/PhantomJS/.test(a),o=/AppleWebKit/.test(a)&&/Mobile\/\w+/.test(a),p=o||/Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(a),q=o||/Mac/.test(b),r=/win/i.test(b),s=k&&a.match(/Version\/(\d*\.\d*)/);s&&(s=Number(s[1])),s&&s>=15&&(k=!1,h=!0);var t=q&&(i||k&&(null==s||12.11>s)),u=c||f&&g>=9,v=!1,w=!1;M.prototype=mg({update:function(a){var b=a.scrollWidth>a.clientWidth+1,c=a.scrollHeight>a.clientHeight+1,d=a.nativeBarWidth;if(c){this.vert.style.display="block",this.vert.style.bottom=b?d+"px":"0";var e=a.viewHeight-(b?d:0);this.vert.firstChild.style.height=Math.max(0,a.scrollHeight-a.clientHeight+e)+"px"}else this.vert.style.display="",this.vert.firstChild.style.height="0";if(b){this.horiz.style.display="block",this.horiz.style.right=c?d+"px":"0",this.horiz.style.left=a.barLeft+"px";var f=a.viewWidth-a.barLeft-(c?d:0);this.horiz.firstChild.style.width=a.scrollWidth-a.clientWidth+f+"px"}else this.horiz.style.display="",this.horiz.firstChild.style.width="0";return!this.checkedZeroWidth&&a.clientHeight>0&&(0==d&&this.zeroWidthHack(),this.checkedZeroWidth=!0),{right:c?d:0,bottom:b?d:0}},setScrollLeft:function(a){this.horiz.scrollLeft!=a&&(this.horiz.scrollLeft=a),this.disableHoriz&&this.enableZeroWidthBar(this.horiz,this.disableHoriz)},setScrollTop:function(a){this.vert.scrollTop!=a&&(this.vert.scrollTop=a),this.disableVert&&this.enableZeroWidthBar(this.vert,this.disableVert)},zeroWidthHack:function(){var a=q&&!m?"12px":"18px";this.horiz.style.height=this.vert.style.width=a,this.horiz.style.pointerEvents=this.vert.style.pointerEvents="none",this.disableHoriz=new bg,this.disableVert=new bg},enableZeroWidthBar:function(a,b){function c(){var d=a.getBoundingClientRect(),e=document.elementFromPoint(d.left+1,d.bottom-1);e!=a?a.style.pointerEvents="none":b.set(1e3,c)}a.style.pointerEvents="auto",b.set(1e3,c)},clear:function(){var a=this.horiz.parentNode;a.removeChild(this.horiz),a.removeChild(this.vert)}},M.prototype),N.prototype=mg({update:function(){return{bottom:0,right:0}},setScrollLeft:function(){},setScrollTop:function(){},clear:function(){}},N.prototype),x.scrollbarModel={"native":M,"null":N},W.prototype.signal=function(a,b){Wf(a,b)&&this.events.push(arguments)},W.prototype.finish=function(){for(var a=0;a=9&&b.hasSelection&&(b.hasSelection=null),b.poll()}),Mf(e,"paste",function(a){Uf(c,a)||ya(a,c)||(c.state.pasteIncoming=!0,b.fastPoll())}),Mf(e,"cut",h),Mf(e,"copy",h),Mf(a.scroller,"paste",function(d){vc(a,d)||Uf(c,d)||(c.state.pasteIncoming=!0,b.focus())}),Mf(a.lineSpace,"selectstart",function(b){vc(a,b)||Gf(b)}),Mf(e,"compositionstart",function(){var a=c.getCursor("from");b.composing&&b.composing.range.clear(),b.composing={start:a,range:c.markText(a,c.getCursor("to"),{className:"CodeMirror-composing"})}}),Mf(e,"compositionend",function(){b.composing&&(b.poll(),b.composing.range.clear(),b.composing=null)})},prepareSelection:function(){var a=this.cm,b=a.display,c=a.doc,d=hb(a);if(a.options.moveInputWithCursor){var e=Ob(a,c.sel.primary().head,"div"),f=b.wrapper.getBoundingClientRect(),g=b.lineDiv.getBoundingClientRect();d.teTop=Math.max(0,Math.min(b.wrapper.clientHeight-10,e.top+g.top-f.top)),d.teLeft=Math.max(0,Math.min(b.wrapper.clientWidth-10,e.left+g.left-f.left))}return d},showSelection:function(a){var b=this.cm,c=b.display;xg(c.cursorDiv,a.cursors),xg(c.selectionDiv,a.selection),null!=a.teTop&&(this.wrapper.style.top=a.teTop+"px",this.wrapper.style.left=a.teLeft+"px")},reset:function(a){if(!this.contextMenuPending){var b,c,d=this.cm,e=d.doc;if(d.somethingSelected()){this.prevInput="";var h=e.sel.primary();b=Pg&&(h.to().line-h.from().line>100||(c=d.getSelection()).length>1e3);var i=b?"-":c||d.getSelection();this.textarea.value=i,d.state.focused&&hg(this.textarea),f&&g>=9&&(this.hasSelection=i)}else a||(this.prevInput=this.textarea.value="",f&&g>=9&&(this.hasSelection=null));this.inaccurateSelection=b}},getField:function(){return this.textarea},supportsTouch:function(){return!1},focus:function(){if("nocursor"!=this.cm.options.readOnly&&(!p||zg()!=this.textarea))try{this.textarea.focus()}catch(a){}},blur:function(){this.textarea.blur()},resetPosition:function(){this.wrapper.style.top=this.wrapper.style.left=0},receivedFocus:function(){this.slowPoll()},slowPoll:function(){var a=this;a.pollingFast||a.polling.set(this.cm.options.pollInterval,function(){a.poll(),a.cm.state.focused&&a.slowPoll()})},fastPoll:function(){function c(){var d=b.poll();d||a?(b.pollingFast=!1,b.slowPoll()):(a=!0,b.polling.set(60,c))}var a=!1,b=this;b.pollingFast=!0,b.polling.set(20,c)},poll:function(){var a=this.cm,b=this.textarea,c=this.prevInput;if(this.contextMenuPending||!a.state.focused||Og(b)&&!c&&!this.composing||a.isReadOnly()||a.options.disableInput||a.state.keySeq)return!1;var d=b.value;if(d==c&&!a.somethingSelected())return!1;if(f&&g>=9&&this.hasSelection===d||q&&/[\uf700-\uf7ff]/.test(d))return a.display.input.reset(),!1;if(a.doc.sel==a.display.selForContextMenu){var e=d.charCodeAt(0);if(8203!=e||c||(c="\u200b"),8666==e)return this.reset(),this.cm.execCommand("undo")}for(var h=0,i=Math.min(c.length,d.length);i>h&&c.charCodeAt(h)==d.charCodeAt(h);)++h;var j=this;return fc(a,function(){xa(a,d.slice(h),c.length-h,null,j.composing?"*compose":null),d.length>1e3||d.indexOf("\n")>-1?b.value=j.prevInput="":j.prevInput=d,j.composing&&(j.composing.range.clear(),j.composing.range=a.markText(j.composing.start,a.getCursor("to"),{className:"CodeMirror-composing"}))}),!0},ensurePolled:function(){this.pollingFast&&this.poll()&&(this.pollingFast=!1)},onKeyPress:function(){f&&g>=9&&(this.hasSelection=null),this.fastPoll()},onContextMenu:function(a){function o(){if(null!=e.selectionStart){var a=c.somethingSelected(),f="\u200b"+(a?e.value:"");e.value="\u21da",e.value=f,b.prevInput=a?"":"\u200b",e.selectionStart=1,e.selectionEnd=f.length,d.selForContextMenu=c.doc.sel}}function p(){if(b.contextMenuPending=!1,b.wrapper.style.position="relative",e.style.cssText=m,f&&9>g&&d.scrollbars.setScrollTop(d.scroller.scrollTop=j),null!=e.selectionStart){(!f||f&&9>g)&&o();var a=0,h=function(){d.selForContextMenu==c.doc.sel&&0==e.selectionStart&&e.selectionEnd>0&&"\u200b"==b.prevInput?gc(c,Od.selectAll)(c):a++<10?d.detectingSelectAll=setTimeout(h,500):d.input.reset()};d.detectingSelectAll=setTimeout(h,200)}}var b=this,c=b.cm,d=c.display,e=b.textarea,i=wc(c,a),j=d.scroller.scrollTop;if(i&&!k){var l=c.options.resetSelectionOnContextMenu;l&&-1==c.doc.sel.contains(i)&&gc(c,$a)(c.doc,Na(i),$f);var m=e.style.cssText;if(b.wrapper.style.position="absolute",e.style.cssText="position: fixed; width: 30px; height: 30px; top: "+(a.clientY-5)+"px; left: "+(a.clientX-5)+"px; z-index: 1000; background: "+(f?"rgba(255, 255, 255, .05)":"transparent")+"; outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);",h)var n=window.scrollY;if(d.input.focus(),h&&window.scrollTo(null,n),d.input.reset(),c.somethingSelected()||(e.value=b.prevInput=" "),b.contextMenuPending=!0,d.selForContextMenu=c.doc.sel,clearTimeout(d.detectingSelectAll),f&&g>=9&&o(),u){Jf(a);var q=function(){Pf(window,"mouseup",q),setTimeout(p,20)};Mf(window,"mouseup",q)}else setTimeout(p,50)}},readOnlyChanged:function(a){a||this.reset()},setUneditable:kg,needsContentAttribute:!1},Ca.prototype),Ea.prototype=mg({init:function(a){function e(a){if(!Uf(c,a)){if(c.somethingSelected())wa=c.getSelections(),"cut"==a.type&&c.replaceSelection("",null,"cut");else{if(!c.options.lineWiseCopyCut)return;var b=Aa(c);wa=b.text,"cut"==a.type&&c.operation(function(){c.setSelections(b.ranges,0,$f),c.replaceSelection("",null,"cut")})}if(a.clipboardData&&!o)a.preventDefault(),a.clipboardData.clearData(),a.clipboardData.setData("text/plain",wa.join("\n"));else{var d=Da(),e=d.firstChild;c.display.lineSpace.insertBefore(d,c.display.lineSpace.firstChild),e.value=wa.join("\n");var f=document.activeElement;hg(e),setTimeout(function(){c.display.lineSpace.removeChild(d),f.focus()},50)}}}var b=this,c=b.cm,d=b.div=a.lineDiv;Ba(d),Mf(d,"paste",function(a){Uf(c,a)||ya(a,c)}),Mf(d,"compositionstart",function(a){var d=a.data;if(b.composing={sel:c.doc.sel,data:d,startData:d},d){var e=c.doc.sel.primary(),f=c.getLine(e.head.line),g=f.indexOf(d,Math.max(0,e.head.ch-d.length));g>-1&&g<=e.head.ch&&(b.composing.sel=Na(qa(e.head.line,g),qa(e.head.line,g+d.length)))}}),Mf(d,"compositionupdate",function(a){b.composing.data=a.data}),Mf(d,"compositionend",function(a){var c=b.composing;c&&(a.data==c.startData||/\u200b/.test(a.data)||(c.data=a.data),setTimeout(function(){c.handled||b.applyComposition(c),b.composing==c&&(b.composing=null)},50))}),Mf(d,"touchstart",function(){b.forceCompositionEnd()}),Mf(d,"input",function(){b.composing||(c.isReadOnly()||!b.pollContent())&&fc(b.cm,function(){lc(c)})}),Mf(d,"copy",e),Mf(d,"cut",e)},prepareSelection:function(){var a=hb(this.cm,!1);return a.focus=this.cm.state.focused,a},showSelection:function(a){a&&this.cm.display.view.length&&(a.focus&&this.showPrimarySelection(),this.showMultipleSelections(a))},showPrimarySelection:function(){var a=window.getSelection(),b=this.cm.doc.sel.primary(),d=Ha(this.cm,a.anchorNode,a.anchorOffset),e=Ha(this.cm,a.focusNode,a.focusOffset);if(!d||d.bad||!e||e.bad||0!=ra(ua(d,e),b.from())||0!=ra(ta(d,e),b.to())){var f=Fa(this.cm,b.from()),g=Fa(this.cm,b.to());if(f||g){var h=this.cm.display.view,i=a.rangeCount&&a.getRangeAt(0);if(f){if(!g){var j=h[h.length-1].measure,k=j.maps?j.maps[j.maps.length-1]:j.map;g={node:k[k.length-1],offset:k[k.length-2]-k[k.length-3]}}}else f={node:h[0].measure.map[2],offset:0};try{var l=vg(f.node,f.offset,g.offset,g.node)}catch(m){}l&&(!c&&this.cm.state.focused?(a.collapse(f.node,f.offset),l.collapsed||a.addRange(l)):(a.removeAllRanges(),a.addRange(l)),i&&null==a.anchorNode?a.addRange(i):c&&this.startGracePeriod()),this.rememberSelection()}}},startGracePeriod:function(){var a=this;clearTimeout(this.gracePeriod),this.gracePeriod=setTimeout(function(){a.gracePeriod=!1,a.selectionChanged()&&a.cm.operation(function(){a.cm.curOp.selectionChanged=!0})},20)},showMultipleSelections:function(a){xg(this.cm.display.cursorDiv,a.cursors),xg(this.cm.display.selectionDiv,a.selection)},rememberSelection:function(){var a=window.getSelection();this.lastAnchorNode=a.anchorNode,this.lastAnchorOffset=a.anchorOffset,this.lastFocusNode=a.focusNode,this.lastFocusOffset=a.focusOffset},selectionInEditor:function(){var a=window.getSelection();if(!a.rangeCount)return!1;var b=a.getRangeAt(0).commonAncestorContainer;return yg(this.div,b)},focus:function(){"nocursor"!=this.cm.options.readOnly&&this.div.focus()},blur:function(){this.div.blur()},getField:function(){return this.div},supportsTouch:function(){return!0},receivedFocus:function(){function b(){a.cm.state.focused&&(a.pollSelection(),a.polling.set(a.cm.options.pollInterval,b))}var a=this;this.selectionInEditor()?this.pollSelection():fc(this.cm,function(){a.cm.curOp.selectionChanged=!0}),this.polling.set(this.cm.options.pollInterval,b)},selectionChanged:function(){var a=window.getSelection();return a.anchorNode!=this.lastAnchorNode||a.anchorOffset!=this.lastAnchorOffset||a.focusNode!=this.lastFocusNode||a.focusOffset!=this.lastFocusOffset},pollSelection:function(){if(!this.composing&&!this.gracePeriod&&this.selectionChanged()){var a=window.getSelection(),b=this.cm;this.rememberSelection();var c=Ha(b,a.anchorNode,a.anchorOffset),d=Ha(b,a.focusNode,a.focusOffset);c&&d&&fc(b,function(){$a(b.doc,Na(c,d),$f),(c.bad||d.bad)&&(b.curOp.selectionChanged=!0)})}},pollContent:function(){var a=this.cm,b=a.display,c=a.doc.sel.primary(),d=c.from(),e=c.to();if(d.lineb.viewTo-1)return!1;var f;if(d.line==b.viewFrom||0==(f=oc(a,d.line)))var g=nf(b.view[0].line),h=b.view[0].node;else var g=nf(b.view[f].line),h=b.view[f-1].node.nextSibling;var i=oc(a,e.line);if(i==b.view.length-1)var j=b.viewTo-1,k=b.lineDiv.lastChild;else var j=nf(b.view[i+1].line)-1,k=b.view[i+1].node.previousSibling;for(var l=a.doc.splitLines(Ja(a,h,k,g,j)),m=kf(a.doc,qa(g,0),qa(j,jf(a.doc,j).text.length));l.length>1&&m.length>1;)if(gg(l)==gg(m))l.pop(),m.pop(),j--;else{if(l[0]!=m[0])break;l.shift(),m.shift(),g++}for(var n=0,o=0,p=l[0],q=m[0],r=Math.min(p.length,q.length);r>n&&p.charCodeAt(n)==q.charCodeAt(n);)++n;for(var s=gg(l),t=gg(m),u=Math.min(s.length-(1==l.length?n:0),t.length-(1==m.length?n:0));u>o&&s.charCodeAt(s.length-o-1)==t.charCodeAt(t.length-o-1);)++o;l[l.length-1]=s.slice(0,s.length-o),l[0]=l[0].slice(n);var v=qa(g,n),w=qa(j,m.length?gg(m).length-o:0);return l.length>1||l[0]||ra(v,w)?(qd(a.doc,l,v,w,"+input"),!0):void 0},ensurePolled:function(){this.forceCompositionEnd()},reset:function(){this.forceCompositionEnd()},forceCompositionEnd:function(){this.composing&&!this.composing.handled&&(this.applyComposition(this.composing),this.composing.handled=!0,this.div.blur(),this.div.focus())},applyComposition:function(a){this.cm.isReadOnly()?gc(this.cm,lc)(this.cm):a.data&&a.data!=a.startData&&gc(this.cm,xa)(this.cm,a.data,0,a.sel)},setUneditable:function(a){a.contentEditable="false"},onKeyPress:function(a){a.preventDefault(),this.cm.isReadOnly()||gc(this.cm,xa)(this.cm,String.fromCharCode(null==a.charCode?a.keyCode:a.charCode),0)},readOnlyChanged:function(a){this.div.contentEditable=String("nocursor"!=a)},onContextMenu:kg,resetPosition:kg,needsContentAttribute:!0},Ea.prototype),x.inputStyles={textarea:Ca,contenteditable:Ea},Ka.prototype={primary:function(){return this.ranges[this.primIndex]},equals:function(a){if(a==this)return!0;if(a.primIndex!=this.primIndex||a.ranges.length!=this.ranges.length)return!1;for(var b=0;b=0&&ra(a,d.to())<=0)return c}return-1}},La.prototype={from:function(){return ua(this.anchor,this.head)},to:function(){return ta(this.anchor,this.head)},empty:function(){return this.head.line==this.anchor.line&&this.head.ch==this.anchor.ch}};var Tb,yc,zc,Cb={left:0,right:0,top:0,bottom:0},Wb=null,Xb=0,Fc=0,Mc=0,Nc=null;f?Nc=-.53:c?Nc=15:j?Nc=-.7:l&&(Nc=-1/3);var Oc=function(a){var b=a.wheelDeltaX,c=a.wheelDeltaY;return null==b&&a.detail&&a.axis==a.HORIZONTAL_AXIS&&(b=a.detail),null==c&&a.detail&&a.axis==a.VERTICAL_AXIS?c=a.detail:null==c&&(c=a.wheelDelta),{x:b,y:c}};x.wheelEventPixels=function(a){var b=Oc(a);return b.x*=Nc,b.y*=Nc,b};var Sc=new bg,Wc=null,ed=x.changeEnd=function(a){return a.text?qa(a.from.line+a.text.length-1,gg(a.text).length+(1==a.text.length?a.from.ch:0)):a.to};x.prototype={constructor:x,focus:function(){window.focus(),this.display.input.focus()},setOption:function(a,b){var c=this.options,d=c[a];(c[a]!=b||"mode"==a)&&(c[a]=b,Ed.hasOwnProperty(a)&&gc(this,Ed[a])(this,b,d))},getOption:function(a){return this.options[a]},getDoc:function(){return this.doc},addKeyMap:function(a,b){this.state.keyMaps[b?"push":"unshift"](Ud(a))},removeKeyMap:function(a){for(var b=this.state.keyMaps,c=0;cc&&(yd(this,e.head.line,a,!0),c=e.head.line,d==this.doc.sel.primIndex&&wd(this));else{var f=e.from(),g=e.to(),h=Math.max(c,f.line);c=Math.min(this.lastLine(),g.line-(g.ch?0:1))+1;for(var i=h;c>i;++i)yd(this,i,a);var j=this.doc.sel.ranges;0==f.ch&&b.length==j.length&&j[d].from().ch>0&&Wa(this.doc,d,new La(f,j[d].to()),$f)}}}),getTokenAt:function(a,b){return Le(this,a,b)},getLineTokens:function(a,b){return Le(this,qa(a),b,!0)},getTokenTypeAt:function(a){a=Pa(this.doc,a);var f,b=Oe(this,jf(this.doc,a.line)),c=0,d=(b.length-1)/2,e=a.ch;if(0==e)f=b[2];else for(;;){var g=c+d>>1;if((g?b[2*g-1]:0)>=e)d=g;else{if(!(b[2*g+1]h?f:0==h?null:f.slice(0,h-1)},getModeAt:function(a){var b=this.doc.mode;return b.innerMode?x.innerMode(b,this.getTokenAt(a).state).mode:b},getHelper:function(a,b){return this.getHelpers(a,b)[0]},getHelpers:function(a,b){var c=[];if(!Ld.hasOwnProperty(b))return c;var d=Ld[b],e=this.getModeAt(a);if("string"==typeof e[b])d[e[b]]&&c.push(d[e[b]]);else if(e[b])for(var f=0;fe&&(a=e,c=!0),d=jf(this.doc,a)}else d=a;return Lb(this,d,{top:0,left:0},b||"page").top+(c?this.doc.height-pf(d):0)},defaultTextHeight:function(){return Ub(this.display)},defaultCharWidth:function(){return Vb(this.display)},setGutterMarker:hc(function(a,b,c){return zd(this.doc,a,"gutter",function(a){var d=a.gutterMarkers||(a.gutterMarkers={});return d[b]=c,!c&&rg(d)&&(a.gutterMarkers=null),!0})}),clearGutter:hc(function(a){var b=this,c=b.doc,d=c.first;c.iter(function(c){c.gutterMarkers&&c.gutterMarkers[a]&&(c.gutterMarkers[a]=null,mc(b,d,"gutter"),rg(c.gutterMarkers)&&(c.gutterMarkers=null)),++d})}),lineInfo:function(a){if("number"==typeof a){if(!Ra(this.doc,a))return null;var b=a;if(a=jf(this.doc,a),!a)return null}else{var b=nf(a);if(null==b)return null}return{line:b,handle:a,text:a.text,gutterMarkers:a.gutterMarkers,textClass:a.textClass,bgClass:a.bgClass,wrapClass:a.wrapClass,widgets:a.widgets}},getViewport:function(){return{from:this.display.viewFrom,to:this.display.viewTo}},addWidget:function(a,b,c,d,e){var f=this.display;a=Ob(this,Pa(this.doc,a));var g=a.bottom,h=a.left;if(b.style.position="absolute",b.setAttribute("cm-ignore-events","true"),this.display.input.setUneditable(b),f.sizer.appendChild(b),"over"==d)g=a.top;else if("above"==d||"near"==d){var i=Math.max(f.wrapper.clientHeight,this.doc.height),j=Math.max(f.sizer.clientWidth,f.lineSpace.clientWidth);("above"==d||a.bottom+b.offsetHeight>i)&&a.top>b.offsetHeight?g=a.top-b.offsetHeight:a.bottom+b.offsetHeight<=i&&(g=a.bottom),h+b.offsetWidth>j&&(h=j-b.offsetWidth)}b.style.top=g+"px",b.style.left=b.style.right="","right"==e?(h=f.sizer.clientWidth-b.offsetWidth,b.style.right="0px"):("left"==e?h=0:"middle"==e&&(h=(f.sizer.clientWidth-b.offsetWidth)/2),b.style.left=h+"px"),c&&td(this,h,g,h+b.offsetWidth,g+b.offsetHeight)},triggerOnKeyDown:hc(Xc),triggerOnKeyPress:hc($c),triggerOnKeyUp:Zc,execCommand:function(a){return Od.hasOwnProperty(a)?Od[a].call(null,this):void 0},triggerElectric:hc(function(a){za(this,a)}),findPosH:function(a,b,c,d){var e=1;0>b&&(e=-1,b=-b);for(var f=0,g=Pa(this.doc,a);b>f&&(g=Bd(this.doc,g,e,c,d),!g.hitSide);++f);return g},moveH:hc(function(a,b){var c=this;c.extendSelectionsBy(function(d){return c.display.shift||c.doc.extend||d.empty()?Bd(c.doc,d.head,a,b,c.options.rtlMoveVisually):0>a?d.from():d.to()},ag)}),deleteH:hc(function(a,b){var c=this.doc.sel,d=this.doc;c.somethingSelected()?d.replaceSelection("",null,"+delete"):Ad(this,function(c){var e=Bd(d,c.head,a,b,!1);return 0>a?{from:e,to:c.head}:{from:c.head,to:e}})}),findPosV:function(a,b,c,d){var e=1,f=d;0>b&&(e=-1,b=-b);for(var g=0,h=Pa(this.doc,a);b>g;++g){var i=Ob(this,h,"div");if(null==f?f=i.left:i.left=f,h=Cd(this,i,e,c),h.hitSide)break}return h},moveV:hc(function(a,b){var c=this,d=this.doc,e=[],f=!c.display.shift&&!d.extend&&d.sel.somethingSelected();if(d.extendSelectionsBy(function(g){if(f)return 0>a?g.from():g.to();var h=Ob(c,g.head,"div");null!=g.goalColumn&&(h.left=g.goalColumn),e.push(h.left);var i=Cd(c,h,a,b);return"page"==b&&g==d.sel.primary()&&vd(c,null,Nb(c,i,"div").top-h.top),i},ag),e.length)for(var g=0;g0&&h(c.charAt(d-1));)--d;for(;e.5)&&D(this),Qf(this,"refresh",this)}),swapDoc:hc(function(a){var b=this.doc;return b.cm=null,hf(this,a),Ib(this),this.display.input.reset(),this.scrollTo(a.scrollLeft,a.scrollTop),this.curOp.forceScroll=!0,Sf(this,"swapDoc",this,b),b}),getInputField:function(){return this.display.input.getField()},getWrapperElement:function(){return this.display.wrapper},getScrollerElement:function(){return this.display.scroller},getGutterElement:function(){return this.display.gutters}},Xf(x);var Dd=x.defaults={},Ed=x.optionHandlers={},Gd=x.Init={toString:function(){return"CodeMirror.Init"}};Fd("value","",function(a,b){a.setValue(b)},!0),Fd("mode",null,function(a,b){a.doc.modeOption=b,z(a)},!0),Fd("indentUnit",2,z,!0),Fd("indentWithTabs",!1),Fd("smartIndent",!0),Fd("tabSize",4,function(a){A(a),Ib(a),lc(a)},!0),Fd("lineSeparator",null,function(a,b){if(a.doc.lineSep=b,b){var c=[],d=a.doc.first;a.doc.iter(function(a){for(var e=0;;){var f=a.text.indexOf(b,e);if(-1==f)break;e=f+b.length,c.push(qa(d,f))}d++});for(var e=c.length-1;e>=0;e--)qd(a.doc,b,c[e],qa(c[e].line,c[e].ch+b.length))}}),Fd("specialChars",/[\t\u0000-\u0019\u00ad\u200b-\u200f\u2028\u2029\ufeff]/g,function(a,b,c){a.state.specialChars=new RegExp(b.source+(b.test(" ")?"":"| "),"g"),c!=x.Init&&a.refresh()}),Fd("specialCharPlaceholder",Ue,function(a){a.refresh()},!0),Fd("electricChars",!0),Fd("inputStyle",p?"contenteditable":"textarea",function(){throw new Error("inputStyle can not (yet) be changed in a running editor")},!0),Fd("rtlMoveVisually",!r),Fd("wholeLineUpdateBefore",!0),Fd("theme","default",function(a){E(a),F(a)},!0),Fd("keyMap","default",function(a,b,c){var d=Ud(b),e=c!=x.Init&&Ud(c);e&&e.detach&&e.detach(a,d),d.attach&&d.attach(a,e||null)}),Fd("extraKeys",null),Fd("lineWrapping",!1,B,!0),Fd("gutters",[],function(a){K(a.options),F(a)},!0),Fd("fixedGutter",!0,function(a,b){a.display.gutters.style.left=b?V(a.display)+"px":"0",a.refresh()},!0),Fd("coverGutterNextToScrollbar",!1,function(a){P(a)},!0),Fd("scrollbarStyle","native",function(a){O(a),P(a),a.display.scrollbars.setScrollTop(a.doc.scrollTop),a.display.scrollbars.setScrollLeft(a.doc.scrollLeft)},!0),Fd("lineNumbers",!1,function(a){K(a.options),F(a)},!0),Fd("firstLineNumber",1,F,!0),Fd("lineNumberFormatter",function(a){return a},F,!0),Fd("showCursorWhenSelecting",!1,gb,!0),Fd("resetSelectionOnContextMenu",!0),Fd("lineWiseCopyCut",!0),Fd("readOnly",!1,function(a,b){"nocursor"==b?(bd(a),a.display.input.blur(),a.display.disabled=!0):a.display.disabled=!1,a.display.input.readOnlyChanged(b)}),Fd("disableInput",!1,function(a,b){b||a.display.input.reset()},!0),Fd("dragDrop",!0,tc),Fd("allowDropFileTypes",null),Fd("cursorBlinkRate",530),Fd("cursorScrollMargin",0),Fd("cursorHeight",1,gb,!0),Fd("singleCursorHeightPerLine",!0,gb,!0),Fd("workTime",100),Fd("workDelay",100),Fd("flattenSpans",!0,A,!0),Fd("addModeClass",!1,A,!0),Fd("pollInterval",100),Fd("undoDepth",200,function(a,b){a.doc.history.undoDepth=b}),Fd("historyEventDelay",1250),Fd("viewportMargin",10,function(a){a.refresh()},!0),Fd("maxHighlightLength",1e4,A,!0),Fd("moveInputWithCursor",!0,function(a,b){b||a.display.input.resetPosition()}),Fd("tabindex",null,function(a,b){a.display.input.getField().tabIndex=b||""}),Fd("autofocus",null);var Hd=x.modes={},Id=x.mimeModes={};x.defineMode=function(a,b){x.defaults.mode||"null"==a||(x.defaults.mode=a),arguments.length>2&&(b.dependencies=Array.prototype.slice.call(arguments,2)),Hd[a]=b},x.defineMIME=function(a,b){Id[a]=b},x.resolveMode=function(a){if("string"==typeof a&&Id.hasOwnProperty(a))a=Id[a];else if(a&&"string"==typeof a.name&&Id.hasOwnProperty(a.name)){var b=Id[a.name];"string"==typeof b&&(b={name:b}),a=lg(b,a),a.name=b.name}else if("string"==typeof a&&/^[\w\-]+\/[\w\-]+\+xml$/.test(a))return x.resolveMode("application/xml");return"string"==typeof a?{name:a}:a||{name:"null"}},x.getMode=function(a,b){var b=x.resolveMode(b),c=Hd[b.name];if(!c)return x.getMode(a,"text/plain");var d=c(a,b);if(Jd.hasOwnProperty(b.name)){var e=Jd[b.name];for(var f in e)e.hasOwnProperty(f)&&(d.hasOwnProperty(f)&&(d["_"+f]=d[f]),d[f]=e[f])}if(d.name=b.name,b.helperType&&(d.helperType=b.helperType),b.modeProps)for(var f in b.modeProps)d[f]=b.modeProps[f];return d},x.defineMode("null",function(){return{token:function(a){a.skipToEnd()}}}),x.defineMIME("text/plain","null");var Jd=x.modeExtensions={};x.extendMode=function(a,b){var c=Jd.hasOwnProperty(a)?Jd[a]:Jd[a]={};mg(b,c)},x.defineExtension=function(a,b){x.prototype[a]=b},x.defineDocExtension=function(a,b){df.prototype[a]=b},x.defineOption=Fd;var Kd=[];x.defineInitHook=function(a){Kd.push(a)};var Ld=x.helpers={};x.registerHelper=function(a,b,c){Ld.hasOwnProperty(a)||(Ld[a]=x[a]={_global:[]}),Ld[a][b]=c},x.registerGlobalHelper=function(a,b,c,d){x.registerHelper(a,b,d),Ld[a]._global.push({pred:c,val:d})};var Md=x.copyState=function(a,b){if(b===!0)return b;if(a.copyState)return a.copyState(b);var c={};for(var d in b){var e=b[d];e instanceof Array&&(e=e.concat([])),c[d]=e}return c},Nd=x.startState=function(a,b,c){return a.startState?a.startState(b,c):!0};x.innerMode=function(a,b){for(;a.innerMode;){var c=a.innerMode(b);if(!c||c.mode==a)break;b=c.state,a=c.mode}return c||{mode:a,state:b}};var Od=x.commands={selectAll:function(a){a.setSelection(qa(a.firstLine(),0),qa(a.lastLine()),$f)},singleSelection:function(a){a.setSelection(a.getCursor("anchor"),a.getCursor("head"),$f)},killLine:function(a){Ad(a,function(b){if(b.empty()){var c=jf(a.doc,b.head.line).text.length;return b.head.ch==c&&b.head.line0)e=new qa(e.line,e.ch+1),a.replaceRange(f.charAt(e.ch-1)+f.charAt(e.ch-2),qa(e.line,e.ch-2),e,"+transpose");else if(e.line>a.doc.first){var g=jf(a.doc,e.line-1).text;g&&a.replaceRange(f.charAt(0)+a.doc.lineSeparator()+g.charAt(g.length-1),qa(e.line-1,g.length-1),qa(e.line,1),"+transpose")}c.push(new La(e,e))}a.setSelections(c)})},newlineAndIndent:function(a){fc(a,function(){for(var b=a.listSelections().length,c=0;b>c;c++){var d=a.listSelections()[c];a.replaceRange(a.doc.lineSeparator(),d.anchor,d.head,"+input"),a.indentLine(d.from().line+1,null,!0)}wd(a)})},toggleOverwrite:function(a){a.toggleOverwrite()}},Pd=x.keyMap={};Pd.basic={Left:"goCharLeft",Right:"goCharRight",Up:"goLineUp",Down:"goLineDown",End:"goLineEnd",Home:"goLineStartSmart",PageUp:"goPageUp",PageDown:"goPageDown",Delete:"delCharAfter",Backspace:"delCharBefore","Shift-Backspace":"delCharBefore",Tab:"defaultTab","Shift-Tab":"indentAuto",Enter:"newlineAndIndent",Insert:"toggleOverwrite",Esc:"singleSelection"},Pd.pcDefault={"Ctrl-A":"selectAll","Ctrl-D":"deleteLine","Ctrl-Z":"undo","Shift-Ctrl-Z":"redo","Ctrl-Y":"redo","Ctrl-Home":"goDocStart","Ctrl-End":"goDocEnd","Ctrl-Up":"goLineUp","Ctrl-Down":"goLineDown","Ctrl-Left":"goGroupLeft","Ctrl-Right":"goGroupRight","Alt-Left":"goLineStart","Alt-Right":"goLineEnd","Ctrl-Backspace":"delGroupBefore","Ctrl-Delete":"delGroupAfter","Ctrl-S":"save","Ctrl-F":"find",
+"Ctrl-G":"findNext","Shift-Ctrl-G":"findPrev","Shift-Ctrl-F":"replace","Shift-Ctrl-R":"replaceAll","Ctrl-[":"indentLess","Ctrl-]":"indentMore","Ctrl-U":"undoSelection","Shift-Ctrl-U":"redoSelection","Alt-U":"redoSelection",fallthrough:"basic"},Pd.emacsy={"Ctrl-F":"goCharRight","Ctrl-B":"goCharLeft","Ctrl-P":"goLineUp","Ctrl-N":"goLineDown","Alt-F":"goWordRight","Alt-B":"goWordLeft","Ctrl-A":"goLineStart","Ctrl-E":"goLineEnd","Ctrl-V":"goPageDown","Shift-Ctrl-V":"goPageUp","Ctrl-D":"delCharAfter","Ctrl-H":"delCharBefore","Alt-D":"delWordAfter","Alt-Backspace":"delWordBefore","Ctrl-K":"killLine","Ctrl-T":"transposeChars"},Pd.macDefault={"Cmd-A":"selectAll","Cmd-D":"deleteLine","Cmd-Z":"undo","Shift-Cmd-Z":"redo","Cmd-Y":"redo","Cmd-Home":"goDocStart","Cmd-Up":"goDocStart","Cmd-End":"goDocEnd","Cmd-Down":"goDocEnd","Alt-Left":"goGroupLeft","Alt-Right":"goGroupRight","Cmd-Left":"goLineLeft","Cmd-Right":"goLineRight","Alt-Backspace":"delGroupBefore","Ctrl-Alt-Backspace":"delGroupAfter","Alt-Delete":"delGroupAfter","Cmd-S":"save","Cmd-F":"find","Cmd-G":"findNext","Shift-Cmd-G":"findPrev","Cmd-Alt-F":"replace","Shift-Cmd-Alt-F":"replaceAll","Cmd-[":"indentLess","Cmd-]":"indentMore","Cmd-Backspace":"delWrappedLineLeft","Cmd-Delete":"delWrappedLineRight","Cmd-U":"undoSelection","Shift-Cmd-U":"redoSelection","Ctrl-Up":"goDocStart","Ctrl-Down":"goDocEnd",fallthrough:["basic","emacsy"]},Pd["default"]=q?Pd.macDefault:Pd.pcDefault,x.normalizeKeyMap=function(a){var b={};for(var c in a)if(a.hasOwnProperty(c)){var d=a[c];if(/^(name|fallthrough|(de|at)tach)$/.test(c))continue;if("..."==d){delete a[c];continue}for(var e=jg(c.split(" "),Qd),f=0;f=this.string.length},sol:function(){return this.pos==this.lineStart},peek:function(){return this.string.charAt(this.pos)||void 0},next:function(){return this.posb},eatSpace:function(){for(var a=this.pos;/[\s\u00a0]/.test(this.string.charAt(this.pos));)++this.pos;return this.pos>a},skipToEnd:function(){this.pos=this.string.length},skipTo:function(a){var b=this.string.indexOf(a,this.pos);return b>-1?(this.pos=b,!0):void 0},backUp:function(a){this.pos-=a},column:function(){return this.lastColumnPos0?null:(f&&b!==!1&&(this.pos+=f[0].length),f)}var d=function(a){return c?a.toLowerCase():a},e=this.string.substr(this.pos,a.length);return d(e)==d(a)?(b!==!1&&(this.pos+=a.length),!0):void 0},current:function(){return this.string.slice(this.start,this.pos)},hideFirstChars:function(a,b){this.lineStart+=a;try{return b()}finally{this.lineStart-=a}}};var Wd=0,Xd=x.TextMarker=function(a,b){this.lines=[],this.type=b,this.doc=a,this.id=++Wd};Xf(Xd),Xd.prototype.clear=function(){if(!this.explicitlyCleared){var a=this.doc.cm,b=a&&!a.curOp;if(b&&Yb(a),Wf(this,"clear")){var c=this.find();c&&Sf(this,"clear",c.from,c.to)}for(var d=null,e=null,f=0;fa.display.maxLineLength&&(a.display.maxLine=i,a.display.maxLineLength=j,a.display.maxLineChanged=!0)}null!=d&&a&&this.collapsed&&lc(a,d,e+1),this.lines.length=0,this.explicitlyCleared=!0,this.atomic&&this.doc.cantEdit&&(this.doc.cantEdit=!1,a&&bb(a.doc)),a&&Sf(a,"markerCleared",a,this),b&&$b(a),this.parent&&this.parent.clear()}},Xd.prototype.find=function(a,b){null==a&&"bookmark"==this.type&&(a=1);for(var c,d,e=0;ec;++c){var e=this.lines[c];this.height-=e.height,He(e),Sf(e,"delete")}this.lines.splice(a,b)},collapse:function(a){a.push.apply(a,this.lines)},insertInner:function(a,b,c){this.height+=c,this.lines=this.lines.slice(0,a).concat(b).concat(this.lines.slice(a));for(var d=0;da;++a)if(c(this.lines[a]))return!0}},bf.prototype={chunkSize:function(){return this.size},removeInner:function(a,b){this.size-=b;for(var c=0;ca){var f=Math.min(b,e-a),g=d.height;if(d.removeInner(a,f),this.height-=g-d.height,e==f&&(this.children.splice(c--,1),d.parent=null),0==(b-=f))break;a=0}else a-=e}if(this.size-b<25&&(this.children.length>1||!(this.children[0]instanceof af))){var h=[];this.collapse(h),this.children=[new af(h)],this.children[0].parent=this}},collapse:function(a){for(var b=0;b=a){if(e.insertInner(a,b,c),e.lines&&e.lines.length>50){for(;e.lines.length>50;){var g=e.lines.splice(e.lines.length-25,25),h=new af(g);e.height-=h.height,this.children.splice(d+1,0,h),h.parent=this}this.maybeSpill()}break}a-=f}},maybeSpill:function(){if(!(this.children.length<=10)){var a=this;do{var b=a.children.splice(a.children.length-5,5),c=new bf(b);if(a.parent){a.size-=c.size,a.height-=c.height;var e=ig(a.parent.children,a);a.parent.children.splice(e+1,0,c)}else{var d=new bf(a.children);d.parent=a,a.children=[d,c],a=d}c.parent=a.parent}while(a.children.length>10);a.parent.maybeSpill()}},iterN:function(a,b,c){for(var d=0;da){var g=Math.min(b,f-a);if(e.iterN(a,g,c))return!0;if(0==(b-=g))break;a=0}else a-=f}}};var cf=0,df=x.Doc=function(a,b,c,d){if(!(this instanceof df))return new df(a,b,c,d);null==c&&(c=0),bf.call(this,[new af([new Fe("",null)])]),this.first=c,this.scrollTop=this.scrollLeft=0,this.cantEdit=!1,this.cleanGeneration=1,this.frontier=c;var e=qa(c,0);this.sel=Na(e),this.history=new rf(null),this.id=++cf,this.modeOption=b,this.lineSep=d,this.extend=!1,"string"==typeof a&&(a=this.splitLines(a)),_e(this,{from:e,to:e,text:a}),$a(this,Na(e),$f)};df.prototype=lg(bf.prototype,{constructor:df,iter:function(a,b,c){c?this.iterN(a-this.first,b-a,c):this.iterN(this.first,this.first+this.size,a)},insert:function(a,b){for(var c=0,d=0;d=0;f--)kd(this,d[f]);h?Za(this,h):this.cm&&wd(this.cm)}),undo:ic(function(){md(this,"undo")}),redo:ic(function(){md(this,"redo")}),undoSelection:ic(function(){md(this,"undo",!0)}),redoSelection:ic(function(){md(this,"redo",!0)}),setExtending:function(a){this.extend=a},getExtending:function(){return this.extend},historySize:function(){for(var a=this.history,b=0,c=0,d=0;d=a.ch)&&b.push(e.marker.parent||e.marker)}return b},findMarks:function(a,b,c){a=Pa(this,a),b=Pa(this,b);var d=[],e=a.line;return this.iter(a.line,b.line+1,function(f){var g=f.markedSpans;if(g)for(var h=0;hi.to||null==i.from&&e!=a.line||e==b.line&&i.from>b.ch||c&&!c(i.marker)||d.push(i.marker.parent||i.marker)}++e}),d},getAllMarks:function(){var a=[];return this.iter(function(b){var c=b.markedSpans;if(c)for(var d=0;da?(b=a,!0):(a-=e,void++c)}),Pa(this,qa(c,b))},indexFromPos:function(a){a=Pa(this,a);var b=a.ch;return a.lineb&&(b=a.from),null!=a.to&&a.toh||h>=b)return g+(b-f);g+=h-f,g+=c-g%c,f=h+1}},dg=x.findColumn=function(a,b,c){for(var d=0,e=0;;){var f=a.indexOf(" ",d);-1==f&&(f=a.length);var g=f-d;if(f==a.length||e+g>=b)return d+Math.min(g,b-e);if(e+=f-d,e+=c-e%c,d=f+1,e>=b)return d}},eg=[""],hg=function(a){a.select()};o?hg=function(a){a.selectionStart=0,a.selectionEnd=a.value.length}:f&&(hg=function(a){try{a.select()}catch(b){}});var vg,og=/[\u00df\u0587\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/,pg=x.isWordChar=function(a){return/\w/.test(a)||a>"\x80"&&(a.toUpperCase()!=a.toLowerCase()||og.test(a))},sg=/[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065e\u0670\u06d6-\u06dc\u06de-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0900-\u0902\u093c\u0941-\u0948\u094d\u0951-\u0955\u0962\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1a17\u1a18\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1dc0-\u1de6\u1dfd-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua825\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe5\uabe8\uabed\udc00-\udfff\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]/;vg=document.createRange?function(a,b,c,d){var e=document.createRange();return e.setEnd(d||a,c),e.setStart(a,b),e}:function(a,b,c){var d=document.body.createTextRange();try{d.moveToElementText(a.parentNode)}catch(e){return d}return d.collapse(!0),d.moveEnd("character",c),d.moveStart("character",b),d};var yg=x.contains=function(a,b){if(3==b.nodeType&&(b=b.parentNode),a.contains)return a.contains(b);do if(11==b.nodeType&&(b=b.host),b==a)return!0;while(b=b.parentNode)};f&&11>g&&(zg=function(){try{return document.activeElement}catch(a){return document.body}});var Jg,Lg,Bg=x.rmClass=function(a,b){var c=a.className,d=Ag(b).exec(c);if(d){var e=c.slice(d.index+d[0].length);a.className=c.slice(0,d.index)+(e?d[1]+e:"")}},Cg=x.addClass=function(a,b){var c=a.className;Ag(b).test(c)||(a.className+=(c?" ":"")+b)},Fg=!1,Ig=function(){if(f&&9>g)return!1;var a=ug("div");return"draggable"in a||"dragDrop"in a}(),Ng=x.splitLines=3!="\n\nb".split(/\n/).length?function(a){for(var b=0,c=[],d=a.length;d>=b;){var e=a.indexOf("\n",b);-1==e&&(e=a.length);var f=a.slice(b,"\r"==a.charAt(e-1)?e-1:e),g=f.indexOf("\r");-1!=g?(c.push(f.slice(0,g)),b+=g+1):(c.push(f),b=e+1)}return c}:function(a){return a.split(/\r\n?|\n/)},Og=window.getSelection?function(a){try{return a.selectionStart!=a.selectionEnd}catch(b){return!1}}:function(a){try{var b=a.ownerDocument.selection.createRange()}catch(c){}return b&&b.parentElement()==a?0!=b.compareEndPoints("StartToEnd",b):!1},Pg=function(){var a=ug("div");return"oncopy"in a?!0:(a.setAttribute("oncopy","return;"),"function"==typeof a.oncopy)}(),Qg=null,Sg=x.keyNames={3:"Enter",8:"Backspace",9:"Tab",13:"Enter",16:"Shift",17:"Ctrl",18:"Alt",19:"Pause",20:"CapsLock",27:"Esc",32:"Space",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"Left",38:"Up",39:"Right",40:"Down",44:"PrintScrn",45:"Insert",46:"Delete",59:";",61:"=",91:"Mod",92:"Mod",93:"Mod",106:"*",107:"=",109:"-",110:".",111:"/",127:"Delete",173:"-",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'",63232:"Up",63233:"Down",63234:"Left",63235:"Right",63272:"Delete",63273:"Home",63275:"End",63276:"PageUp",63277:"PageDown",63302:"Insert"};!function(){for(var a=0;10>a;a++)Sg[a+48]=Sg[a+96]=String(a);for(var a=65;90>=a;a++)Sg[a]=String.fromCharCode(a);for(var a=1;12>=a;a++)Sg[a+111]=Sg[a+63235]="F"+a}();var ah,fh=function(){function c(c){return 247>=c?a.charAt(c):c>=1424&&1524>=c?"R":c>=1536&&1773>=c?b.charAt(c-1536):c>=1774&&2220>=c?"r":c>=8192&&8203>=c?"w":8204==c?"b":"L"}function j(a,b,c){this.level=a,this.from=b,this.to=c}var a="bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN",b="rrrrrrrrrrrr,rNNmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmrrrrrrrnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmNmmmm",d=/[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/,e=/[stwN]/,f=/[LRr]/,g=/[Lb1n]/,h=/[1n]/,i="L";return function(a){if(!d.test(a))return!1;for(var m,b=a.length,k=[],l=0;b>l;++l)k.push(m=c(a.charCodeAt(l)));for(var l=0,n=i;b>l;++l){var m=k[l];"m"==m?k[l]=n:n=m}for(var l=0,o=i;b>l;++l){var m=k[l];"1"==m&&"r"==o?k[l]="n":f.test(m)&&(o=m,"r"==m&&(k[l]="R"))}for(var l=1,n=k[0];b-1>l;++l){var m=k[l];"+"==m&&"1"==n&&"1"==k[l+1]?k[l]="1":","!=m||n!=k[l+1]||"1"!=n&&"n"!=n||(k[l]=n),n=m}for(var l=0;b>l;++l){var m=k[l];if(","==m)k[l]="N";else if("%"==m){for(var p=l+1;b>p&&"%"==k[p];++p);for(var q=l&&"!"==k[l-1]||b>p&&"1"==k[p]?"1":"N",r=l;p>r;++r)k[r]=q;l=p-1}}for(var l=0,o=i;b>l;++l){var m=k[l];"L"==o&&"1"==m?k[l]="L":f.test(m)&&(o=m)}for(var l=0;b>l;++l)if(e.test(k[l])){for(var p=l+1;b>p&&e.test(k[p]);++p);for(var s="L"==(l?k[l-1]:i),t="L"==(b>p?k[p]:i),q=s||t?"L":"R",r=l;p>r;++r)k[r]=q;l=p-1}for(var v,u=[],l=0;b>l;)if(g.test(k[l])){var w=l;for(++l;b>l&&g.test(k[l]);++l);u.push(new j(0,w,l))}else{var x=l,y=u.length;for(++l;b>l&&"L"!=k[l];++l);for(var r=x;l>r;)if(h.test(k[r])){r>x&&u.splice(y,0,new j(1,x,r));var z=r;for(++r;l>r&&h.test(k[r]);++r);u.splice(y,0,new j(2,z,r)),x=r}else++r;l>x&&u.splice(y,0,new j(1,x,l))}return 1==u[0].level&&(v=a.match(/^\s+/))&&(u[0].from=v[0].length,u.unshift(new j(0,0,v[0].length))),1==gg(u).level&&(v=a.match(/\s+$/))&&(gg(u).to-=v[0].length,u.push(new j(0,b-v[0].length,b))),2==u[0].level&&u.unshift(new j(1,u[0].to,u[0].to)),u[0].level!=gg(u).level&&u.push(new j(u[0].level,b,b)),u}}();return x.version="5.11.0",x});
\ No newline at end of file
diff --git a/lib/mergely.css b/lib/mergely.css
index 5053d0b..ab257f7 100644
--- a/lib/mergely.css
+++ b/lib/mergely.css
@@ -12,17 +12,19 @@
.mergely-column { border: 1px solid #ccc; }
.mergely-active { border: 1px solid #a3d1ff; }
+.mergely.a,.mergely.d,.mergely.c { color: #000; }
+
.mergely.a.rhs.start { border-top: 1px solid #a3d1ff; }
.mergely.a.lhs.start.end,
.mergely.a.rhs.end { border-bottom: 1px solid #a3d1ff; }
.mergely.a.rhs { background-color: #ddeeff; }
.mergely.a.lhs.start.end.first { border-bottom: 0; border-top: 1px solid #a3d1ff; }
-.mergely.d.lhs { background-color: #edc0c0; }
+.mergely.d.lhs { background-color: #ffe9e9; }
.mergely.d.lhs.end,
-.mergely.d.rhs.start.end { border-bottom: 1px solid #ff7f7f; }
-.mergely.d.rhs.start.end.first { border-bottom: 0; border-top: 1px solid #ff7f7f; }
-.mergely.d.lhs.start { border-top: 1px solid #ff7f7f; }
+.mergely.d.rhs.start.end { border-bottom: 1px solid #f8e8e8; }
+.mergely.d.rhs.start.end.first { border-bottom: 0; border-top: 1px solid #f8e8e8; }
+.mergely.d.lhs.start { border-top: 1px solid #f8e8e8; }
.mergely.c.lhs,
.mergely.c.rhs { background-color: #fafafa; }
@@ -32,4 +34,12 @@
.mergely.c.rhs.end { border-bottom: 1px solid #a3a3a3; }
.mergely.ch.a.rhs { background-color: #ddeeff; }
-.mergely.ch.d.lhs { background-color: #edc0c0; text-decoration: line-through; color: #888; }
+.mergely.ch.d.lhs { background-color: #ffe9e9; text-decoration: line-through; color: red !important; }
+
+.mergely.current.start { border-top: 1px solid #000 !important; }
+.mergely.current.end { border-bottom: 1px solid #000 !important; }
+.mergely.current.lhs.a.start.end,
+.mergely.current.rhs.d.start.end { border-top: 0 !important; }
+.mergely.current.CodeMirror-linenumber { color: #F9F9F9; font-weight: bold; background-color: #777; }
+.CodeMirror-linenumber { cursor: pointer; }
+.CodeMirror-code { color: #717171; }
diff --git a/lib/mergely.js b/lib/mergely.js
index 61d29bb..e6cadd7 100644
--- a/lib/mergely.js
+++ b/lib/mergely.js
@@ -496,7 +496,7 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
if (direction == 'next') {
this._current_diff = Math.min(++this._current_diff, this.changes.length - 1);
}
- else {
+ else if (direction == 'prev') {
this._current_diff = Math.max(--this._current_diff, 0);
}
this._scroll_to_change(this.changes[this._current_diff]);
@@ -727,6 +727,33 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
);
sz(true);
}
+
+ this.editor[this.id + '-lhs'].on('gutterClick', function(cm, n) {
+ return $(this.changes).filter(function (i, change) {
+ if (n >= change['lhs-line-from'] && n <= change['lhs-line-to']) {
+ this._current_diff = i;
+ return true;
+ }
+ }.bind(this));
+ // I really don't like this here - something about gutterClick does not
+ // like mutating editor here. Need to trigger the scroll to diff from
+ // a timeout.
+ setTimeout(function() { this.scrollToDiff(); }.bind(this), 10);
+ }.bind(this));
+
+ this.editor[this.id + '-rhs'].on('gutterClick', function(cm, n) {
+ $(this.changes).filter(function (i, change) {
+ if (n >= change['rhs-line-from'] && n <= change['rhs-line-to']) {
+ this._current_diff = i;
+ return true;
+ }
+ }.bind(this));
+ // I really don't like this here - something about gutterClick does not
+ // like mutating editor here. Need to trigger the scroll to diff from
+ // a timeout.
+ setTimeout(function() { this.scrollToDiff(); }.bind(this), 10);
+ }.bind(this));
+
//bind
var setv;
if (this.settings.lhs) {
@@ -744,23 +771,10 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
var self = this;
var led = self.editor[self.id+'-lhs'];
var red = self.editor[self.id+'-rhs'];
-
- var yref = led.getScrollerElement().offsetHeight * 0.5; // center between >0 and 1/2
-
// set cursors
led.setCursor(Math.max(change["lhs-line-from"],0), 0); // use led.getCursor().ch ?
red.setCursor(Math.max(change["rhs-line-from"],0), 0);
-
- // using directly CodeMirror breaks canvas alignment
- // var ly = led.charCoords({line: Math.max(change["lhs-line-from"],0), ch: 0}, "local").top;
-
- // calculate scroll offset for current change. Warning: returns relative y position so we scroll to 0 first.
- led.scrollTo(null, 0);
- red.scrollTo(null, 0);
- self._calculate_offsets(self.id+'-lhs', self.id+'-rhs', [change]);
- led.scrollTo(null, Math.max(change["lhs-y-start"]-yref, 0));
- red.scrollTo(null, Math.max(change["rhs-y-start"]-yref, 0));
- // right pane should simply follows
+ led.scrollIntoView({line: change["lhs-line-to"]});
},
_scrolling: function(editor_name) {
@@ -1123,6 +1137,7 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
var self = this;
var led = this.editor[editor_name1];
var red = this.editor[editor_name2];
+ var current_diff = this._current_diff;
var timer = new Mgly.Timer();
led.operation(function() {
@@ -1137,6 +1152,12 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
led.addLineClass(llf, 'background', 'start');
led.addLineClass(llt, 'background', 'end');
+ if (current_diff == i) {
+ if (llf != llt) {
+ led.addLineClass(llf, 'background', 'current');
+ }
+ led.addLineClass(llt, 'background', 'current');
+ }
if (llf == 0 && llt == 0 && rlf == 0) {
led.addLineClass(llf, 'background', clazz.join(' '));
led.addLineClass(llf, 'background', 'first');
@@ -1182,7 +1203,13 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
var clazz = ['mergely', 'rhs', change['op'], 'cid-' + i];
red.addLineClass(rlf, 'background', 'start');
red.addLineClass(rlt, 'background', 'end');
-
+
+ if (current_diff == i) {
+ if (rlf != rlt) {
+ red.addLineClass(rlf, 'background', 'current');
+ }
+ red.addLineClass(rlt, 'background', 'current');
+ }
if (rlf == 0 && rlt == 0 && llf == 0) {
red.addLineClass(rlf, 'background', clazz.join(' '));
red.addLineClass(rlf, 'background', 'first');
@@ -1283,6 +1310,7 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
self.chfns[self.id + '-rhs'].push(m[0].markText(m[1], m[2], m[3]));
}
});
+
this.trace('change', 'LCS markup time', timer.stop());
// merge buttons
@@ -1311,6 +1339,35 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
self._merge_change(change, side, oside);
return false;
});
+
+ // gutter markup
+ var lhsLineNumbers = $('#mergely-lhs ~ .CodeMirror').find('.CodeMirror-linenumber');
+ var rhsLineNumbers = $('#mergely-rhs ~ .CodeMirror').find('.CodeMirror-linenumber');
+ rhsLineNumbers.removeClass('mergely current');
+ lhsLineNumbers.removeClass('mergely current');
+ for (var i = 0; i < changes.length; ++i) {
+ if (current_diff == i && change.op !== 'd') {
+ var change = changes[i];
+ var j, jf = change['rhs-line-from'], jt = change['rhs-line-to'] + 1;
+ for (j = jf; j < jt; j++) {
+ var n = (j + 1).toString();
+ rhsLineNumbers
+ .filter(function(i, node) { return $(node).text() === n; })
+ .addClass('mergely current');
+ }
+ }
+ if (current_diff == i && change.op !== 'a') {
+ var change = changes[i];
+ jf = change['lhs-line-from'], jt = change['lhs-line-to'] + 1;
+ for (j = jf; j < jt; j++) {
+ var n = (j + 1).toString();
+ lhsLineNumbers
+ .filter(function(i, node) { return $(node).text() === n; })
+ .addClass('mergely current');
+ }
+ }
+ }
+
this.trace('change', 'markup buttons time', timer.stop());
},
_merge_change : function(change, side, oside) {
@@ -1424,6 +1481,10 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
var vp = this._get_viewport(editor_name1, editor_name2);
for (var i = 0; i < changes.length; ++i) {
var change = changes[i];
+ var fill = this.settings.fgcolor[change['op']];
+ if (this._current_diff==i) {
+ fill = '#000';
+ }
this.trace('draw', change);
// margin indicators
@@ -1434,14 +1495,14 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
this.trace('draw', 'marker calculated', lhs_y_start, lhs_y_end, rhs_y_start, rhs_y_end);
ctx_lhs.beginPath();
- ctx_lhs.fillStyle = this.settings.fgcolor[(this._current_diff==i?'c':'')+change['op']];
+ ctx_lhs.fillStyle = fill;
ctx_lhs.strokeStyle = '#000';
ctx_lhs.lineWidth = 0.5;
ctx_lhs.fillRect(1.5, lhs_y_start, 4.5, Math.max(lhs_y_end - lhs_y_start, 5));
ctx_lhs.strokeRect(1.5, lhs_y_start, 4.5, Math.max(lhs_y_end - lhs_y_start, 5));
ctx_rhs.beginPath();
- ctx_rhs.fillStyle = this.settings.fgcolor[(this._current_diff==i?'c':'')+change['op']];
+ ctx_rhs.fillStyle = fill;
ctx_rhs.strokeStyle = '#000';
ctx_rhs.lineWidth = 0.5;
ctx_rhs.fillRect(1.5, rhs_y_start, 4.5, Math.max(rhs_y_end - rhs_y_start, 5));
@@ -1460,7 +1521,7 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
// draw left box
ctx.beginPath();
- ctx.strokeStyle = this.settings.fgcolor[(this._current_diff==i?'c':'')+change['op']];
+ ctx.strokeStyle = fill;
ctx.lineWidth = (this._current_diff==i) ? 1.5 : 1;
var rectWidth = this.draw_lhs_width;
diff --git a/lib/mergely.min.js b/lib/mergely.min.js
index 688c958..56257ae 100755
--- a/lib/mergely.min.js
+++ b/lib/mergely.min.js
@@ -1,6 +1,7 @@
/**
- * Copyright (c) 2015 by Jamie Peabody, http://www.mergely.com
+ * Copyright (c) 2016 by Jamie Peabody, http://www.mergely.com
* All rights reserved.
- * Version: 3.3.10 2015-06-28
+ * Version: 3.4.0 2016-02-07
*/
-"use strict";!function(a,b,c,d){var e={};e.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()},e.ChangeExpression=new RegExp(/(^(?![><\-])*\d+(?:,\d+)?)([acd])(\d+(?:,\d+)?)/),e.DiffParser=function(a){for(var b=[],c=0,d=a.split(/\n/),f=0;f0&&"c"==i.op&&(f+=1),b(f,f+j.length)}if("d"!=i.op){f=c.getLines("rhs").slice(0,i["rhs-line-from"]).join(" ").length,g=i["rhs-line-to"]+1;var k=c.getLines("rhs").slice(i["rhs-line-from"],g).join(" ");"a"==i.op?k+=" ":f>0&&"c"==i.op&&(f+=1),a(f,f+k.length)}}}}),e.CodeifyText=function(a){this._max_code=0,this._diff_codes={},this.ctxs={},this.options={ignorews:!1},c.extend(this,a),this.lhs=a.lhs.split("\n"),this.rhs=a.rhs.split("\n")},c.extend(e.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;d0?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){var i;for(i=c.lhs_start;i "+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;var r,s,t,u,q={x:0,y:0};for(r=0;p>=r;++r){for(s=j-r;j+r>=s;s+=2){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(s=k-r;k+r>=s;s+=2){for(s==k+r?t=g[o+s-1]:(t=g[o+s+1]-1,s>k-r&&g[o+s-1]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=b.codes.length||a.modified[f]);)f++;for(;g=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}}),e.mergely=function(a,b){a&&this.init(a,b)},c.extend(e.mergely.prototype,{name:"mergely",init:function(a,b){this.diffView=new e.CodeMirrorDiffView(a,b),this.bind(a)},bind:function(a){this.diffView.bind(a)}}),e.CodeMirrorDiffView=function(a,b){d.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)},c.extend(e.CodeMirrorDiffView.prototype,{init:function(a,b){this.settings={autoupdate:!0,autoresize:!0,rhs_margin:"right",wrap_lines:!1,line_numbers:!0,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 d=b?16:0,e=c(a).parent().width()+d,f=0;"auto"==this.width?e=this._auto_width(e):(e=this.width,this.editor_width=e),"auto"==this.height?f=c(a).parent().height():(f=this.height,this.editor_height=f);var g=e/2-16-8,h=f,i=c(a);i.find(".mergely-column").css({width:g+"px"}),i.find(".mergely-column, .mergely-canvas, .mergely-margin, .mergely-column textarea, .CodeMirror-scroll, .cm-s-default").css({height:h+"px"}),i.find(".mergely-canvas").css({height:h+"px"}),i.find(".mergely-column textarea").css({width:g+"px"}),i.css({width:e,height:f,clear:"both"}),"none"==i.css("display")&&(0!=this.fadein?i.fadeIn(this.fadein):i.show(),this.loaded&&this.loaded()),this.resized&&this.resized()},_debug:"",resized:function(){}};var d={mode:"text/plain",readOnly:!1,lineWrapping:this.settings.wrap_lines,lineNumbers:this.settings.line_numbers,gutters:["merge","CodeMirror-linenumbers"]};this.lhs_cmsettings={},this.rhs_cmsettings={},this.element=c(a),b&&b.cmsettings&&c.extend(this.lhs_cmsettings,d,b.cmsettings,b.lhs_cmsettings),b&&b.cmsettings&&c.extend(this.rhs_cmsettings,d,b.cmsettings,b.rhs_cmsettings),this.element.bind("destroyed",c.proxy(this.teardown,this)),c.data(a,"mergely",this),this._setOptions(b)},unbind:function(){null!=this.changed_timeout&&clearTimeout(this.changed_timeout),this.editor[this.id+"-lhs"].toTextArea(),this.editor[this.id+"-rhs"].toTextArea(),c(a).off(".mergely")},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())},_setOptions:function(a){if(c.extend(this.settings,a),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?c(this.element).find(".mergely-margin").css({display:"block"}):c(this.element).find(".mergely-margin").css({display:"none"}));var d,e;this.settings.hasOwnProperty("wrap_lines")&&this.editor&&(d=this.editor[this.id+"-lhs"],e=this.editor[this.id+"-rhs"],d.setOption("lineWrapping",this.settings.wrap_lines),e.setOption("lineWrapping",this.settings.wrap_lines)),this.settings.hasOwnProperty("line_numbers")&&this.editor&&(d=this.editor[this.id+"-lhs"],e=this.editor[this.id+"-rhs"],d.setOption("lineNumbers",this.settings.line_numbers),e.setOption("lineNumbers",this.settings.line_numbers))},options:function(a){return a?(this._setOptions(a),this.settings.autoresize&&this.resize(),this.settings.autoupdate&&this.update(),void 0):this.settings},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 e.diff(a,b,this.settings);return c.normal_form()},bind:function(b){this.element.hide(),this.id=c(b).attr("id"),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 e,f;if(void 0!=c.button)e='',f='';else{var g="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;";e='<
',f='>
'}this.merge_rhs_button=c(f),this.merge_lhs_button=c(e);var h=this.settings.editor_height,i=this.settings.editor_width;this.element.append(c('')),this.element.append(c('')),this.element.append(c(''));var j=c('');this.settings.sidebar||this.element.find(".mergely-margin").css({display:"none"}),"left"==this.settings.rhs_margin&&this.element.append(j),this.element.append(c('')),"left"!=this.settings.rhs_margin&&this.element.append(j);var k="#"+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&&(k+=this.id+" .CodeMirror-scroll { height: 100%; overflow: auto; }"),k+="\n.CodeMirror { line-height: 18px; }",c('").appendTo("head");var l=c("#"+this.id+"-rhs").get(0);if(!l)return console.error("rhs textarea not defined - Mergely not initialized properly"),void 0;var m=c("#"+this.id+"-lhs").get(0);if(!l)return console.error("lhs textarea not defined - Mergely not initialized properly"),void 0;var n=this;if(this.editor=[],this.editor[this.id+"-lhs"]=d.fromTextArea(m,this.lhs_cmsettings),this.editor[this.id+"-rhs"]=d.fromTextArea(l,this.rhs_cmsettings),this.editor[this.id+"-lhs"].on("change",function(){n.settings.autoupdate&&n._changing(n.id+"-lhs",n.id+"-rhs")}),this.editor[this.id+"-lhs"].on("scroll",function(){n._scrolling(n.id+"-lhs")}),this.editor[this.id+"-rhs"].on("change",function(){n.settings.autoupdate&&n._changing(n.id+"-lhs",n.id+"-rhs")}),this.editor[this.id+"-rhs"].on("scroll",function(){n._scrolling(n.id+"-rhs")}),this.settings.autoresize){var o=null,p=function(a){n.settings.resize&&n.settings.resize(a),n.editor[n.id+"-lhs"].refresh(),n.editor[n.id+"-rhs"].refresh(),n.settings.autoupdate&&n._changing(n.id+"-lhs",n.id+"-rhs")};c(a).on("resize.mergely",function(){o&&clearTimeout(o),o=setTimeout(p,n.settings.resize_timeout)}),p(!0)}var q;this.settings.lhs&&(q=this.editor[this.id+"-lhs"].getDoc().setValue,this.settings.lhs(q.bind(this.editor[this.id+"-lhs"].getDoc()))),this.settings.rhs&&(q=this.editor[this.id+"-rhs"].getDoc().setValue,this.settings.rhs(q.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=.5*c.getScrollerElement().offsetHeight;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=c(this.editor[a].getScrollerElement());void 0==this.midway&&(this.midway=(b.height()/2+b.offset().top).toFixed(2));var d=this.editor[a].coordsChar({left:0,top:this.midway}),f=b.scrollTop(),g=b.scrollLeft();this.trace("scroll","side",a),this.trace("scroll","midway",this.midway),this.trace("scroll","midline",d),this.trace("scroll","top_to",f),this.trace("scroll","left_to",g);var h=this.id+"-lhs",i=this.id+"-rhs";for(var j in this.editor)if(this.editor.hasOwnProperty(j)&&a!=j){for(var k=a.replace(this.id+"-",""),l=j.replace(this.id+"-",""),m=0,n=null,o=!1,p=0;p=q[k+"-line-from"]&&(n=q,d.line>=n[k+"-line-to"]&&(q.hasOwnProperty(k+"-y-start")&&q.hasOwnProperty(k+"-y-end")&&q.hasOwnProperty(l+"-y-start")&&q.hasOwnProperty(l+"-y-end")?m+=q[k+"-y-end"]-q[k+"-y-start"]-(q[l+"-y-end"]-q[l+"-y-start"]):o=!0))}var r=this.editor[j].getViewport(),s=!0;if(n&&(this.trace("scroll","last change before midline",n),d.line>=r.from&&d<=r.to&&(s=!1)),this.trace("scroll","scroll",s),s||o?(this.trace("scroll","scrolling other side",f-m),this._skipscroll[j]=!0,this.editor[j].scrollTo(g,f-m)):this.trace("scroll","not scrolling other side"),this.settings.autoupdate){var t=new e.Timer;this._calculate_offsets(h,i,this.changes),this.trace("change","offsets time",t.stop()),this._markup_changes(h,i,this.changes),this.trace("change","markup time",t.stop()),this._draw_diff(h,i,this.changes),this.trace("change","draw time",t.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 e.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 b,c,d,f,g,h,i,a=this,j=function(){for(f=new e.Timer,g=0,i=c.lineCount();i>g;++g)c.removeLineClass(g,"background");for(g=0;ga.from&&b["lhs-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 d=c("#"+this.id+" .CodeMirror-measure").first(),e=d.offset().top-4;return e?(this.editor[a].scrollTo(null,b),this.draw_top_offset=.5-e,!0):!1},_calculate_offsets:function(a,b,d){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 e=c("#"+a+"-"+b+"-canvas");if(e.length||console.error("failed to find canvas","#"+a+"-"+b+"-canvas"),!e.width())return console.error("canvas width is 0"),void 0;this.draw_mid_width=c("#"+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 f=this.editor[a].charCoords({line:0}),g=this.editor[b].charCoords({line:0}),h=this._get_viewport(a,b),i=0;i=0?j["lhs-line-from"]:0,l=j["lhs-line-to"]>=0?j["lhs-line-to"]:0,m=j["rhs-line-from"]>=0?j["rhs-line-from"]:0,n=j["rhs-line-to"]>=0?j["rhs-line-to"]:0;this.editor[a].getOption("lineWrapping")||this.editor[b].getOption("lineWrapping")?(s=this.editor[a].cursorCoords({line:k,ch:0},"page"),v=this.editor[a].getLineHandle(k),o={top:s.top,bottom:s.top+v.height},t=this.editor[a].cursorCoords({line:l,ch:0},"page"),u=this.editor[a].getLineHandle(l),p={top:t.top,bottom:t.top+u.height},s=this.editor[b].cursorCoords({line:m,ch:0},"page"),w=this.editor[b].getLineHandle(m),q={top:s.top,bottom:s.top+w.height},t=this.editor[b].cursorCoords({line:n,ch:0},"page"),x=this.editor[b].getLineHandle(n),r={top:t.top,bottom:t.top+x.height}):(o={top:f.top+k*this.em_height,bottom:f.bottom+k*this.em_height+2},p={top:f.top+l*this.em_height,bottom:f.bottom+l*this.em_height+2},q={top:g.top+m*this.em_height,bottom:g.bottom+m*this.em_height+2},r={top:g.top+n*this.em_height,bottom:g.bottom+n*this.em_height+2}),"a"==j.op?m>0&&(o.top=o.bottom,o.bottom+=this.em_height,p=o):"d"==j.op&&k>0&&(q.top=q.bottom,q.bottom+=this.em_height,r=q),j["lhs-y-start"]=this.draw_top_offset+o.top,j["lhs-y-end"]="c"==j.op||"d"==j.op?this.draw_top_offset+p.bottom:this.draw_top_offset+p.top,j["rhs-y-start"]=this.draw_top_offset+q.top,j["rhs-y-end"]="c"==j.op||"a"==j.op?this.draw_top_offset+r.bottom:this.draw_top_offset+r.top,this.trace("calc","change calculated",i,j)}else delete j["lhs-y-start"],delete j["lhs-y-end"],delete j["rhs-y-start"],delete j["rhs-y-end"]}return d},_markup_changes:function(a,b,d){c(".merge-button").remove();var f=this,g=this.editor[a],h=this.editor[b],i=new e.Timer;g.operation(function(){for(var a=0;a=0?b["lhs-line-from"]:0,e=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(g.addLineClass(c,"background","start"),g.addLineClass(e,"background","end"),0==c&&0==e&&0==i)g.addLineClass(c,"background",k.join(" ")),g.addLineClass(c,"background","first");else for(var l=c;e>=l;++l)g.addLineClass(l,"background",k.join(" ")),g.addLineClass(l,"background",k.join(" "));if(!h.getOption("readOnly")){var m=f.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),g.setGutterMarker(c,"merge",m.get(0))}}});var j=this._get_viewport(a,b);this.trace("change","markup lhs-editor time",i.stop()),h.operation(function(){for(var a=0;a=0?b["lhs-line-from"]:0;b["lhs-line-to"]>=0?b["lhs-line-to"]:0;var i=b["rhs-line-from"]>=0?b["rhs-line-from"]:0,k=b["rhs-line-to"]>=0?b["rhs-line-to"]:0;if(f._is_change_in_view(j,b)){var l=["mergely","rhs",b.op,"cid-"+a];if(h.addLineClass(i,"background","start"),h.addLineClass(k,"background","end"),0==i&&0==k&&0==c)h.addLineClass(i,"background",l.join(" ")),h.addLineClass(i,"background","first");else for(var m=i;k>=m;++m)h.addLineClass(m,"background",l.join(" ")),h.addLineClass(m,"background",l.join(" "));if(!g.getOption("readOnly")){var n=f.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),h.setGutterMarker(i,"merge",n.get(0))}}}}),this.trace("change","markup rhs-editor time",i.stop());var l,m,n,o,k=[];for(l=0;this.settings.lcs&&l=0?p["lhs-line-from"]:0,r=p["lhs-line-to"]>=0?p["lhs-line-to"]:0,s=p["rhs-line-from"]>=0?p["rhs-line-from"]:0,t=p["rhs-line-to"]>=0?p["rhs-line-to"]:0;if(this._is_change_in_view(j,p))if("d"==p.op){var u=q,v=r,w=g.lineInfo(v);w&&k.push([g,{line:u,ch:0},{line:v,ch:w.text.length},{className:"mergely ch d lhs"}])}else if("c"==p.op)for(m=q,n=s,o=0;m>=0&&r>=m||n>=0&&t>=n;++m,++n){var x,y;if(n+o>t)x=g.getLine(m),k.push([g,{line:m,ch:0},{line:m,ch:x.length},{className:"mergely ch d lhs"}]);else if(m+o>r)y=h.getLine(n),k.push([h,{line:n,ch:0},{line:n,ch:y.length},{className:"mergely ch a rhs"}]);else{x=g.getLine(m),y=h.getLine(n);var z=new e.LCS(x,y);z.diff(function(a,b){k.push([h,{line:n,ch:a},{line:n,ch:b},{className:"mergely ch a rhs"}])},function(a,b){k.push([g,{line:m,ch:a},{line:m,ch:b},{className:"mergely ch d lhs"}])})}}}this.trace("change","LCS marktext time",i.stop()),g.operation(function(){for(var a=0;a=i;--h)g[c].setCursor({line:h,ch:-1}),g[c].execCommand("deleteLine");else if("lhs"==b)if("a"==a.op)for(i=parseInt(a[c+"-line-from"],10),j=parseInt(a[c+"-line-to"],10),h=j;h>=i;--h)g[c].setCursor({line:h,ch:-1}),g[c].execCommand("deleteLine");else g[c].replaceRange(k,d.Pos(a[c+"-line-from"]+1,0));g.lhs.setValue(g.lhs.getValue()),g.rhs.setValue(g.rhs.getValue()),this._scroll_to_change(a)}},_draw_info:function(a,d){var e=c(this.editor[a].getScrollerElement()).height(),f=c(this.editor[a].getScrollerElement()).children(":first-child").height(),g=b.getElementById(a+"-"+d+"-canvas");if(void 0==g)throw"Failed to find: "+a+"-"+d+"-canvas";var h=c("#"+this.id+"-lhs-margin"),i=c("#"+this.id+"-rhs-margin");return{visible_page_height:e,gutter_height:f,visible_page_ratio:e/f,margin_ratio:e/f,lhs_scroller:c(this.editor[a].getScrollerElement()),rhs_scroller:c(this.editor[d].getScrollerElement()),lhs_lines:this.editor[a].lineCount(),rhs_lines:this.editor[d].lineCount(),dcanvas:g,clhs:h,crhs:i,lhs_xyoffset:c(h).offset(),rhs_xyoffset:c(i).offset()}},_draw_diff:function(a,b,d){var e=this._draw_info(a,b),f=e.clhs.get(0),g=e.crhs.get(0),h=e.dcanvas.getContext("2d"),i=f.getContext("2d"),j=g.getContext("2d");this.trace("draw","visible_page_height",e.visible_page_height),this.trace("draw","gutter_height",e.gutter_height),this.trace("draw","visible_page_ratio",e.visible_page_ratio),this.trace("draw","lhs-scroller-top",e.lhs_scroller.scrollTop()),this.trace("draw","rhs-scroller-top",e.rhs_scroller.scrollTop()),c.each(c.find("#"+this.id+" canvas"),function(){c(this).get(0).height=e.visible_page_height}),e.clhs.unbind("click"),e.crhs.unbind("click"),i.beginPath(),i.fillStyle=this.settings.bgcolor,i.strokeStyle="#888",i.fillRect(0,0,6.5,e.visible_page_height),i.strokeRect(0,0,6.5,e.visible_page_height),j.beginPath(),j.fillStyle=this.settings.bgcolor,j.strokeStyle="#888",j.fillRect(0,0,6.5,e.visible_page_height),j.strokeRect(0,0,6.5,e.visible_page_height);for(var k=this._get_viewport(a,b),l=0;l=t?h.lineTo(u+s,v):(h.arcTo(u+s,v,u+s,v+r,r),h.arcTo(u+s,v+t,u+s-r,v+t,r)),h.lineTo(u,v+t)),h.stroke(),s=this.draw_rhs_width,t=q-p-1,u=this.draw_rhs_max,v=p,h.moveTo(u,v),"Microsoft Internet Explorer"==navigator.appName?(h.lineTo(this.draw_rhs_max-this.draw_rhs_width,p),h.lineTo(this.draw_rhs_max-this.draw_rhs_width,q+1),h.lineTo(this.draw_rhs_max,q+1)):(0>=t?h.lineTo(u-s,v):(h.arcTo(u-s,v,u-s,v+r,r),h.arcTo(u-s,v+t,u-r,v+t,r)),h.lineTo(u,v+t)),h.stroke();var w=this.draw_lhs_min+this.draw_lhs_width,x=n+(o+1-n)/2,y=this.draw_rhs_max-this.draw_rhs_width,z=p+(q+1-p)/2;h.moveTo(w,x),x==z?h.lineTo(y,z):h.bezierCurveTo(w+12,x-3,y-12,z-3,y,z),h.stroke()}}i.fillStyle=this.settings.vpcolor,j.fillStyle=this.settings.vpcolor;var A=e.clhs.height()*e.visible_page_ratio,B=e.lhs_scroller.scrollTop()/e.gutter_height*e.clhs.height(),C=e.crhs.height()*e.visible_page_ratio,D=e.rhs_scroller.scrollTop()/e.gutter_height*e.crhs.height();this.trace("draw","cls.height",e.clhs.height()),this.trace("draw","lhs_scroller.scrollTop()",e.lhs_scroller.scrollTop()),this.trace("draw","gutter_height",e.gutter_height),this.trace("draw","visible_page_ratio",e.visible_page_ratio),this.trace("draw","lhs from",B,"lhs to",A),this.trace("draw","rhs from",D,"rhs to",C),i.fillRect(1.5,B,4.5,A),j.fillRect(1.5,D,4.5,C),e.clhs.click(function(a){var b=a.pageY-e.lhs_xyoffset.top-A/2,c=Math.max(0,b/f.height*e.lhs_scroller.get(0).scrollHeight);e.lhs_scroller.scrollTop(c)}),e.crhs.click(function(a){var b=a.pageY-e.rhs_xyoffset.top-C/2,c=Math.max(0,b/g.height*e.rhs_scroller.get(0).scrollHeight);e.rhs_scroller.scrollTop(c)})},trace:function(a){this.settings._debug.indexOf(a)>=0&&(arguments[0]=a+":",console.log([].slice.apply(arguments)))}}),c.pluginMaker=function(a){c.fn[a.prototype.name]=function(b){var f,d=c.makeArray(arguments),e=d.slice(1);return this.each(function(){var g=c.data(this,a.prototype.name);if(g){if("string"==typeof b)f=g[b].apply(g,e);else if(g.update)return g.update.apply(g,d)}else new a(this,b)}),void 0!=f?f:void 0}},c.pluginMaker(e.mergely)}(window,document,jQuery,CodeMirror);
\ No newline at end of file
+"use strict";!function(a,b,c,d){var e={};e.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()},e.ChangeExpression=new RegExp(/(^(?![><\-])*\d+(?:,\d+)?)([acd])(\d+(?:,\d+)?)/),e.DiffParser=function(a){for(var b=[],c=0,d=a.split(/\n/),f=0;f0&&"c"==i.op&&(f+=1),b(f,f+j.length)}if("d"!=i.op){f=c.getLines("rhs").slice(0,i["rhs-line-from"]).join(" ").length,g=i["rhs-line-to"]+1;var k=c.getLines("rhs").slice(i["rhs-line-from"],g).join(" ");"a"==i.op?k+=" ":f>0&&"c"==i.op&&(f+=1),a(f,f+k.length)}}}}),e.CodeifyText=function(a){this._max_code=0,this._diff_codes={},this.ctxs={},this.options={ignorews:!1},c.extend(this,a),this.lhs=a.lhs.split("\n"),this.rhs=a.rhs.split("\n")},c.extend(e.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){for(var d=(this._max_code,0);d0?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){var i;for(i=c.lhs_start;i "+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;var r,s,t,u,q={x:0,y:0};for(r=0;p>=r;++r){for(s=j-r;j+r>=s;s+=2){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(s=k-r;k+r>=s;s+=2){for(s==k+r?t=g[o+s-1]:(t=g[o+s+1]-1,s>k-r&&g[o+s-1]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=b.codes.length||a.modified[f]);)f++;for(;g=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}}),e.mergely=function(a,b){a&&this.init(a,b)},c.extend(e.mergely.prototype,{name:"mergely",init:function(a,b){this.diffView=new e.CodeMirrorDiffView(a,b),this.bind(a)},bind:function(a){this.diffView.bind(a)}}),e.CodeMirrorDiffView=function(a,b){d.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)},c.extend(e.CodeMirrorDiffView.prototype,{init:function(a,b){this.settings={autoupdate:!0,autoresize:!0,rhs_margin:"right",wrap_lines:!1,line_numbers:!0,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(a){},rhs:function(a){},loaded:function(){},_auto_width:function(a){return a},resize:function(b){var d=b?16:0,e=c(a).parent().width()+d,f=0;"auto"==this.width?e=this._auto_width(e):(e=this.width,this.editor_width=e),"auto"==this.height?f=c(a).parent().height():(f=this.height,this.editor_height=f);var g=e/2-16-8,h=f,i=c(a);i.find(".mergely-column").css({width:g+"px"}),i.find(".mergely-column, .mergely-canvas, .mergely-margin, .mergely-column textarea, .CodeMirror-scroll, .cm-s-default").css({height:h+"px"}),i.find(".mergely-canvas").css({height:h+"px"}),i.find(".mergely-column textarea").css({width:g+"px"}),i.css({width:e,height:f,clear:"both"}),"none"==i.css("display")&&(0!=this.fadein?i.fadeIn(this.fadein):i.show(),this.loaded&&this.loaded()),this.resized&&this.resized()},_debug:"",resized:function(){}};var d={mode:"text/plain",readOnly:!1,lineWrapping:this.settings.wrap_lines,lineNumbers:this.settings.line_numbers,gutters:["merge","CodeMirror-linenumbers"]};this.lhs_cmsettings={},this.rhs_cmsettings={},this.element=c(a),b&&b.cmsettings&&c.extend(this.lhs_cmsettings,d,b.cmsettings,b.lhs_cmsettings),b&&b.cmsettings&&c.extend(this.rhs_cmsettings,d,b.cmsettings,b.rhs_cmsettings),this.element.bind("destroyed",c.proxy(this.teardown,this)),c.data(a,"mergely",this),this._setOptions(b)},unbind:function(){null!=this.changed_timeout&&clearTimeout(this.changed_timeout),this.editor[this.id+"-lhs"].toTextArea(),this.editor[this.id+"-rhs"].toTextArea(),c(a).off(".mergely")},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&&("next"==a?this._current_diff=Math.min(++this._current_diff,this.changes.length-1):"prev"==a&&(this._current_diff=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())},_setOptions:function(a){if(c.extend(this.settings,a),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?this.element.find(".mergely-margin").css({display:"block"}):this.element.find(".mergely-margin").css({display:"none"}));var d,e;this.settings.hasOwnProperty("wrap_lines")&&this.editor&&(d=this.editor[this.id+"-lhs"],e=this.editor[this.id+"-rhs"],d.setOption("lineWrapping",this.settings.wrap_lines),e.setOption("lineWrapping",this.settings.wrap_lines)),this.settings.hasOwnProperty("line_numbers")&&this.editor&&(d=this.editor[this.id+"-lhs"],e=this.editor[this.id+"-rhs"],d.setOption("lineNumbers",this.settings.line_numbers),e.setOption("lineNumbers",this.settings.line_numbers))},options:function(a){return a?(this._setOptions(a),this.settings.autoresize&&this.resize(),this.settings.autoupdate&&this.update(),void 0):this.settings},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 e.diff(a,b,this.settings);return c.normal_form()},bind:function(b){this.element.hide(),this.id=c(b).attr("id"),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 e,f;if(void 0!=c.button)e='',f='';else{var g="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;";e='<
',f='>
'}this.merge_rhs_button=c(f),this.merge_lhs_button=c(e);var h=this.settings.editor_height,i=this.settings.editor_width;this.element.append(c('')),this.element.append(c('')),this.element.append(c(''));var j=c('');this.settings.sidebar||this.element.find(".mergely-margin").css({display:"none"}),"left"==this.settings.rhs_margin&&this.element.append(j),this.element.append(c('')),"left"!=this.settings.rhs_margin&&this.element.append(j);var k="#"+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&&(k+=this.id+" .CodeMirror-scroll { height: 100%; overflow: auto; }"),k+="\n.CodeMirror { line-height: 18px; }",c('").appendTo("head");var l=this.element.find("#"+this.id+"-rhs").get(0);if(!l)return void console.error("rhs textarea not defined - Mergely not initialized properly");var m=this.element.find("#"+this.id+"-lhs").get(0);if(!l)return void console.error("lhs textarea not defined - Mergely not initialized properly");var n=this;if(this.editor=[],this.editor[this.id+"-lhs"]=d.fromTextArea(m,this.lhs_cmsettings),this.editor[this.id+"-rhs"]=d.fromTextArea(l,this.rhs_cmsettings),this.editor[this.id+"-lhs"].on("change",function(){n.settings.autoupdate&&n._changing(n.id+"-lhs",n.id+"-rhs")}),this.editor[this.id+"-lhs"].on("scroll",function(){n._scrolling(n.id+"-lhs")}),this.editor[this.id+"-rhs"].on("change",function(){n.settings.autoupdate&&n._changing(n.id+"-lhs",n.id+"-rhs")}),this.editor[this.id+"-rhs"].on("scroll",function(){n._scrolling(n.id+"-rhs")}),this.settings.autoresize){var o=null,p=function(a){n.settings.resize&&n.settings.resize(a),n.editor[n.id+"-lhs"].refresh(),n.editor[n.id+"-rhs"].refresh(),n.settings.autoupdate&&n._changing(n.id+"-lhs",n.id+"-rhs")};c(a).on("resize.mergely",function(){o&&clearTimeout(o),o=setTimeout(p,n.settings.resize_timeout)}),p(!0)}this.editor[this.id+"-lhs"].on("gutterClick",function(a,b){return $(this.changes).filter(function(a,c){return b>=c["lhs-line-from"]&&b<=c["lhs-line-to"]?(this._current_diff=a,!0):void 0}.bind(this))}.bind(this)),this.editor[this.id+"-rhs"].on("gutterClick",function(a,b){$(this.changes).filter(function(a,c){return b>=c["rhs-line-from"]&&b<=c["rhs-line-to"]?(this._current_diff=a,!0):void 0}.bind(this)),setTimeout(function(){this.scrollToDiff()}.bind(this),10)}.bind(this));var q;this.settings.lhs&&(q=this.editor[this.id+"-lhs"].getDoc().setValue,this.settings.lhs(q.bind(this.editor[this.id+"-lhs"].getDoc()))),this.settings.rhs&&(q=this.editor[this.id+"-rhs"].getDoc().setValue,this.settings.rhs(q.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"];c.setCursor(Math.max(a["lhs-line-from"],0),0),d.setCursor(Math.max(a["rhs-line-from"],0),0),c.scrollIntoView({line:a["lhs-line-to"]})}},_scrolling:function(a){if(this._skipscroll[a]===!0)return void(this._skipscroll[a]=!1);var b=c(this.editor[a].getScrollerElement());void 0==this.midway&&(this.midway=(b.height()/2+b.offset().top).toFixed(2));var d=this.editor[a].coordsChar({left:0,top:this.midway}),f=b.scrollTop(),g=b.scrollLeft();this.trace("scroll","side",a),this.trace("scroll","midway",this.midway),this.trace("scroll","midline",d),this.trace("scroll","top_to",f),this.trace("scroll","left_to",g);var h=this.id+"-lhs",i=this.id+"-rhs";for(var j in this.editor)if(this.editor.hasOwnProperty(j)&&a!=j){for(var k=a.replace(this.id+"-",""),l=j.replace(this.id+"-",""),m=0,n=null,o=!1,p=0;p=q[k+"-line-from"]&&(n=q,d.line>=n[k+"-line-to"]&&(q.hasOwnProperty(k+"-y-start")&&q.hasOwnProperty(k+"-y-end")&&q.hasOwnProperty(l+"-y-start")&&q.hasOwnProperty(l+"-y-end")?m+=q[k+"-y-end"]-q[k+"-y-start"]-(q[l+"-y-end"]-q[l+"-y-start"]):o=!0))}var r=this.editor[j].getViewport(),s=!0;if(n&&(this.trace("scroll","last change before midline",n),d.line>=r.from&&d<=r.to&&(s=!1)),this.trace("scroll","scroll",s),s||o?(this.trace("scroll","scrolling other side",f-m),this._skipscroll[j]=!0,this.editor[j].scrollTo(g,f-m)):this.trace("scroll","not scrolling other side"),this.settings.autoupdate){var t=new e.Timer;this._calculate_offsets(h,i,this.changes),this.trace("change","offsets time",t.stop()),this._markup_changes(h,i,this.changes),this.trace("change","markup time",t.stop()),this._draw_diff(h,i,this.changes),this.trace("change","draw time",t.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 e.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 b,c,d,f,g,h,i,a=this,j=function(){for(f=new e.Timer,g=0,i=c.lineCount();i>g;++g)c.removeLineClass(g,"background");for(g=0;ga.from&&b["lhs-line-to"]>a.to||b["rhs-line-from"]a.from&&b["rhs-line-to"]>a.to)?!1:!0},_set_top_offset:function(a){var b=this.editor[a].getScrollInfo().top;this.editor[a].scrollTo(null,0);var c=this.element.find(".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,d){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 e=c("#"+a+"-"+b+"-canvas");if(e.length||console.error("failed to find canvas","#"+a+"-"+b+"-canvas"),!e.width())return void console.error("canvas width is 0");this.draw_mid_width=c("#"+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 f=this.editor[a].charCoords({line:0}),g=this.editor[b].charCoords({line:0}),h=this._get_viewport(a,b),i=0;i=0?j["lhs-line-from"]:0,l=j["lhs-line-to"]>=0?j["lhs-line-to"]:0,m=j["rhs-line-from"]>=0?j["rhs-line-from"]:0,n=j["rhs-line-to"]>=0?j["rhs-line-to"]:0;this.editor[a].getOption("lineWrapping")||this.editor[b].getOption("lineWrapping")?(s=this.editor[a].cursorCoords({line:k,ch:0},"page"),v=this.editor[a].getLineHandle(k),o={top:s.top,bottom:s.top+v.height},t=this.editor[a].cursorCoords({line:l,ch:0},"page"),u=this.editor[a].getLineHandle(l),p={top:t.top,bottom:t.top+u.height},s=this.editor[b].cursorCoords({line:m,ch:0},"page"),w=this.editor[b].getLineHandle(m),q={top:s.top,bottom:s.top+w.height},t=this.editor[b].cursorCoords({line:n,ch:0},"page"),x=this.editor[b].getLineHandle(n),r={top:t.top,bottom:t.top+x.height}):(o={top:f.top+k*this.em_height,bottom:f.bottom+k*this.em_height+2},p={top:f.top+l*this.em_height,bottom:f.bottom+l*this.em_height+2},q={top:g.top+m*this.em_height,bottom:g.bottom+m*this.em_height+2},r={top:g.top+n*this.em_height,bottom:g.bottom+n*this.em_height+2}),"a"==j.op?m>0&&(o.top=o.bottom,o.bottom+=this.em_height,p=o):"d"==j.op&&k>0&&(q.top=q.bottom,q.bottom+=this.em_height,r=q),j["lhs-y-start"]=this.draw_top_offset+o.top,"c"==j.op||"d"==j.op?j["lhs-y-end"]=this.draw_top_offset+p.bottom:j["lhs-y-end"]=this.draw_top_offset+p.top,j["rhs-y-start"]=this.draw_top_offset+q.top,"c"==j.op||"a"==j.op?j["rhs-y-end"]=this.draw_top_offset+r.bottom:j["rhs-y-end"]=this.draw_top_offset+r.top,this.trace("calc","change calculated",i,j)}else delete j["lhs-y-start"],delete j["lhs-y-end"],delete j["rhs-y-start"],delete j["rhs-y-end"]}return d},_markup_changes:function(a,b,d){c(".merge-button").remove();var f=this,g=this.editor[a],h=this.editor[b],i=this._current_diff,j=new e.Timer;g.operation(function(){for(var a=0;a=0?b["lhs-line-from"]:0,e=b["lhs-line-to"]>=0?b["lhs-line-to"]:0,j=b["rhs-line-from"]>=0?b["rhs-line-from"]:0,l=(b["rhs-line-to"]>=0?b["rhs-line-to"]:0,["mergely","lhs",b.op,"cid-"+a]);if(g.addLineClass(c,"background","start"),g.addLineClass(e,"background","end"),i==a&&(c!=e&&g.addLineClass(c,"background","current"),g.addLineClass(e,"background","current")),0==c&&0==e&&0==j)g.addLineClass(c,"background",l.join(" ")),g.addLineClass(c,"background","first");else for(var m=c;e>=m;++m)g.addLineClass(m,"background",l.join(" ")),g.addLineClass(m,"background",l.join(" "));if(!h.getOption("readOnly")){var n=f.merge_rhs_button.clone();n.button&&n.button({icons:{primary:"ui-icon-triangle-1-e"},text:!1}),n.addClass("merge-button"),n.attr("id","merge-rhs-"+a),g.setGutterMarker(c,"merge",n.get(0))}}});var k=this._get_viewport(a,b);this.trace("change","markup lhs-editor time",j.stop()),h.operation(function(){for(var a=0;a=0?b["lhs-line-from"]:0,j=(b["lhs-line-to"]>=0?b["lhs-line-to"]:0,b["rhs-line-from"]>=0?b["rhs-line-from"]:0),l=b["rhs-line-to"]>=0?b["rhs-line-to"]:0;if(f._is_change_in_view(k,b)){var m=["mergely","rhs",b.op,"cid-"+a];if(h.addLineClass(j,"background","start"),h.addLineClass(l,"background","end"),i==a&&(j!=l&&h.addLineClass(j,"background","current"),h.addLineClass(l,"background","current")),0==j&&0==l&&0==c)h.addLineClass(j,"background",m.join(" ")),h.addLineClass(j,"background","first");else for(var n=j;l>=n;++n)h.addLineClass(n,"background",m.join(" ")),h.addLineClass(n,"background",m.join(" "));if(!g.getOption("readOnly")){var o=f.merge_lhs_button.clone();o.button&&o.button({icons:{primary:"ui-icon-triangle-1-w"},text:!1}),o.addClass("merge-button"),o.attr("id","merge-lhs-"+a),h.setGutterMarker(j,"merge",o.get(0))}}}}),this.trace("change","markup rhs-editor time",j.stop());var m,n,o,p,l=[];for(m=0;this.settings.lcs&&m=0?q["lhs-line-from"]:0,s=q["lhs-line-to"]>=0?q["lhs-line-to"]:0,t=q["rhs-line-from"]>=0?q["rhs-line-from"]:0,u=q["rhs-line-to"]>=0?q["rhs-line-to"]:0;if(this._is_change_in_view(k,q))if("d"==q.op){var v=r,w=s,x=g.lineInfo(w);x&&l.push([g,{line:v,ch:0},{line:w,ch:x.text.length},{className:"mergely ch d lhs"}])}else if("c"==q.op)for(n=r,o=t,p=0;n>=0&&s>=n||o>=0&&u>=o;++n,++o){var y,z;if(o+p>u)y=g.getLine(n),l.push([g,{line:n,ch:0},{line:n,ch:y.length},{className:"mergely ch d lhs"}]);else if(n+p>s)z=h.getLine(o),l.push([h,{line:o,ch:0},{line:o,ch:z.length},{className:"mergely ch a rhs"}]);else{y=g.getLine(n),z=h.getLine(o);var A=new e.LCS(y,z);A.diff(function(a,b){l.push([h,{line:o,ch:a},{line:o,ch:b},{className:"mergely ch a rhs"}])},function(a,b){l.push([g,{line:n,ch:a},{line:n,ch:b},{className:"mergely ch d lhs"}])})}}}this.trace("change","LCS marktext time",j.stop()),g.operation(function(){for(var a=0;an;n++){var G=(n+1).toString();D.filter(function(a,b){return $(b).text()===G}).addClass("mergely current")}}if(i==m&&"a"!==q.op){var q=d[m];for(E=q["lhs-line-from"],F=q["lhs-line-to"]+1,n=E;F>n;n++){var G=(n+1).toString();C.filter(function(a,b){return $(b).text()===G}).addClass("mergely current")}}}this.trace("change","markup buttons time",j.stop())},_merge_change:function(a,b,c){if(a){var h,i,j,e=this.editor[this.id+"-lhs"],f=this.editor[this.id+"-rhs"],g={lhs:e,rhs:f},k=g[b].getRange(d.Pos(a[b+"-line-from"],0),d.Pos(a[b+"-line-to"]+1,0));if("c"==a.op)g[c].replaceRange(k,d.Pos(a[c+"-line-from"],0),d.Pos(a[c+"-line-to"]+1,0));else if("rhs"==b)if("a"==a.op)g[c].replaceRange(k,d.Pos(a[c+"-line-from"]+1,0),d.Pos(a[c+"-line-to"]+1,0));else for(i=parseInt(a[c+"-line-from"],10),j=parseInt(a[c+"-line-to"],10),h=j;h>=i;--h)g[c].setCursor({line:h,ch:-1}),g[c].execCommand("deleteLine");else if("lhs"==b)if("a"==a.op)for(i=parseInt(a[c+"-line-from"],10),j=parseInt(a[c+"-line-to"],10),h=j;h>=i;--h)g[c].setCursor({line:h,ch:-1}),g[c].execCommand("deleteLine");else g[c].replaceRange(k,d.Pos(a[c+"-line-from"]+1,0));g.lhs.setValue(g.lhs.getValue()),g.rhs.setValue(g.rhs.getValue()),this._scroll_to_change(a)}},_draw_info:function(a,d){var e=c(this.editor[a].getScrollerElement()).height(),f=c(this.editor[a].getScrollerElement()).children(":first-child").height(),g=b.getElementById(a+"-"+d+"-canvas");if(void 0==g)throw"Failed to find: "+a+"-"+d+"-canvas";var h=this.element.find("#"+this.id+"-lhs-margin"),i=this.element.find("#"+this.id+"-rhs-margin");return{visible_page_height:e,gutter_height:f,visible_page_ratio:e/f,margin_ratio:e/f,lhs_scroller:c(this.editor[a].getScrollerElement()),rhs_scroller:c(this.editor[d].getScrollerElement()),lhs_lines:this.editor[a].lineCount(),rhs_lines:this.editor[d].lineCount(),dcanvas:g,clhs:h,crhs:i,lhs_xyoffset:c(h).offset(),rhs_xyoffset:c(i).offset()}},_draw_diff:function(a,b,d){var e=this._draw_info(a,b),f=e.clhs.get(0),g=e.crhs.get(0),h=e.dcanvas.getContext("2d"),i=f.getContext("2d"),j=g.getContext("2d");this.trace("draw","visible_page_height",e.visible_page_height),this.trace("draw","gutter_height",e.gutter_height),this.trace("draw","visible_page_ratio",e.visible_page_ratio),this.trace("draw","lhs-scroller-top",e.lhs_scroller.scrollTop()),this.trace("draw","rhs-scroller-top",e.rhs_scroller.scrollTop()),c.each(this.element.find("canvas"),function(){c(this).get(0).height=e.visible_page_height}),e.clhs.unbind("click"),e.crhs.unbind("click"),i.beginPath(),i.fillStyle=this.settings.bgcolor,i.strokeStyle="#888",i.fillRect(0,0,6.5,e.visible_page_height),i.strokeRect(0,0,6.5,e.visible_page_height),j.beginPath(),j.fillStyle=this.settings.bgcolor,j.strokeStyle="#888",j.fillRect(0,0,6.5,e.visible_page_height),j.strokeRect(0,0,6.5,e.visible_page_height);for(var k=this._get_viewport(a,b),l=0;l=u?h.lineTo(v+t,w):(h.arcTo(v+t,w,v+t,w+s,s),h.arcTo(v+t,w+u,v+t-s,w+u,s)),h.lineTo(v,w+u)),h.stroke(),t=this.draw_rhs_width,u=r-q-1,v=this.draw_rhs_max,w=q,h.moveTo(v,w),"Microsoft Internet Explorer"==navigator.appName?(h.lineTo(this.draw_rhs_max-this.draw_rhs_width,q),h.lineTo(this.draw_rhs_max-this.draw_rhs_width,r+1),h.lineTo(this.draw_rhs_max,r+1)):(0>=u?h.lineTo(v-t,w):(h.arcTo(v-t,w,v-t,w+s,s),h.arcTo(v-t,w+u,v-s,w+u,s)),h.lineTo(v,w+u)),h.stroke();var x=this.draw_lhs_min+this.draw_lhs_width,y=o+(p+1-o)/2,z=this.draw_rhs_max-this.draw_rhs_width,A=q+(r+1-q)/2;h.moveTo(x,y),y==A?h.lineTo(z,A):h.bezierCurveTo(x+12,y-3,z-12,A-3,z,A),h.stroke()}}i.fillStyle=this.settings.vpcolor,j.fillStyle=this.settings.vpcolor;var B=e.clhs.height()*e.visible_page_ratio,C=e.lhs_scroller.scrollTop()/e.gutter_height*e.clhs.height(),D=e.crhs.height()*e.visible_page_ratio,E=e.rhs_scroller.scrollTop()/e.gutter_height*e.crhs.height();this.trace("draw","cls.height",e.clhs.height()),this.trace("draw","lhs_scroller.scrollTop()",e.lhs_scroller.scrollTop()),
+this.trace("draw","gutter_height",e.gutter_height),this.trace("draw","visible_page_ratio",e.visible_page_ratio),this.trace("draw","lhs from",C,"lhs to",B),this.trace("draw","rhs from",E,"rhs to",D),i.fillRect(1.5,C,4.5,B),j.fillRect(1.5,E,4.5,D),e.clhs.click(function(a){var b=a.pageY-e.lhs_xyoffset.top-B/2,c=Math.max(0,b/f.height*e.lhs_scroller.get(0).scrollHeight);e.lhs_scroller.scrollTop(c)}),e.crhs.click(function(a){var b=a.pageY-e.rhs_xyoffset.top-D/2,c=Math.max(0,b/g.height*e.rhs_scroller.get(0).scrollHeight);e.rhs_scroller.scrollTop(c)})},trace:function(a){this.settings._debug.indexOf(a)>=0&&(arguments[0]=a+":",console.log([].slice.apply(arguments)))}}),c.pluginMaker=function(a){c.fn[a.prototype.name]=function(b){var f,d=c.makeArray(arguments),e=d.slice(1);return this.each(function(){var g=c.data(this,a.prototype.name);if(g){if("string"==typeof b)f=g[b].apply(g,e);else if(g.update)return g.update.apply(g,d)}else{new a(this,b)}}),void 0!=f?f:void 0}},c.pluginMaker(e.mergely)}(window,document,jQuery,CodeMirror);
\ No newline at end of file