本文概述
差异工具用于比较两个文本文件之间的文本差异。如果你是开发人员(如果不是, 那么你是如何来到这里的?), 你可能已经在NetBeans和Sublime等著名的IDE中看到了这种工具。在本文中, 我们将展示如何为著名的Java ACE编辑器实现一个非常有用且易于使用的diff工具实现。
要求
要为ACE编辑器实现差异/合并控件, 我们将依赖于@benkeen编写的Ace-diff插件。该插件是Ace Editor的包装器, 提供了2个面板的差异和合并工具, 可直观显示两个文档中的差异, 并允许你将更改从一个复制到另一个。它建立在google-diff-match-patch库的顶部。
为了在你的项目中实现此工具, 请在Github中项目的/ dist文件夹中获得ace-diff.js或ace-diff.min.js文件的副本。以及Github中项目的/ libs文件夹中的diff_match_patch.js文件。然后继续在文档中添加一个脚本标签, 其中包括所需的插件(在ACE编辑器之后):
<!-- Add ace editor from the CDN or a local copy -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.5/ace.js" type="text/javascript" charset="utf-8"></script>
<!-- Add the diff plugin -->
<script src="ace-diff.js"></script>
<!-- Add the diff_match_patch plugin -->
<script src="diff_match_patch.js"></script>
如果需要更多信息, 请访问Github中的ace-diff官方存储库。此后, 你将可以在文档中实例化AceDiff类。但是, 要可视化编辑器, 你还没有准备好!继续添加一些CSS以正确可视化编辑器。
注意:根据你要在控件中找到控件的位置, 你需要更改一些属性。你可以按照需要的方式更改类的名称, 但不要忘记在Javascript中使用classes属性初始化时也要更改它们。
通过将.css文件链接到文档或在样式标签中添加以下CSS:
#flex-container {
display: flex;
display: -webkit-flex;
flex-direction: row;
position: absolute;
bottom: 0;
width: 100%;
top: 0px !important;
left: 0px;
/* these 3 lines are to prevents an unsightly scrolling bounce affect on Safari */
height: 100%;
width: 100%;
overflow: auto;
}
#flex-container>div {
flex-grow: 1;
-webkit-flex-grow: 1;
position: relative;
}
#flex-container>div#acediff-gutter {
flex: 0 0 60px;
-webkit-flex: 0 0 60px;
border-left: 1px solid #999999;
border-right: 1px solid #999999;
background-color: #efefef;
overflow: hidden;
}
#acediff-gutter svg {
background-color: #efefef;
}
.acediff-class {
position: absolute !important;
top: 0;
bottom: 0;
width: 100%;
}
.acediff-diff {
background-color: #d8f2ff;
border-top: 1px solid #a2d7f2;
border-bottom: 1px solid #a2d7f2;
position: absolute;
z-index: 4;
}
.acediff-diff.targetOnly {
height: 0px !important;
border-top: 1px solid #a2d7f2;
border-bottom: 0px;
position: absolute;
}
.acediff-connector {
fill: #d8f2ff;
stroke: #a2d7f2;
}
.acediff-copy-left {
float: right;
}
.acediff-copy-right, .acediff-copy-left {
position: relative;
}
.acediff-copy-right div {
color: #000000;
text-shadow: 1px 1px #ffffff;
position: absolute;
margin: 2px 3px;
cursor: pointer;
}
.acediff-copy-right div:hover {
color: #004ea0;
}
.acediff-copy-left div {
color: #000000;
text-shadow: 1px 1px #ffffff;
position: absolute;
right: 0px;
margin: 2px 3px;
cursor: pointer;
}
.acediff-copy-left div:hover {
color: #c98100;
}
你就可以开始了。
实现
diff控件需要具有以下标记:
<div id="flex-container">
<div>
<div class="acediff-class" id="editor-left"></div>
</div>
<div id="acediff-gutter"></div>
<div>
<div class="acediff-class" id="editor-right"></div>
</div>
</div>
你可以使用以下JS进行初始化:
<script>
var aceDiffer = new AceDiff({
left:{
id:"editor-left"
}, right:{
id:"editor-right"
}
});
</script>
请注意, 插件提供了以下所有选项, 你可以根据需要更改这些选项来操作该工具:
{
mode: null, theme: null, diffGranularity: 'broad', showDiffs: true, showConnectors: true, maxDiffs: 5000, left: {
id: 'acediff-left-editor', content: null, mode: null, theme: null, editable: true, copyLinkEnabled: true
}, right: {
id: 'acediff-right-editor', content: null, mode: null, theme: null, editable: true, copyLinkEnabled: true
}, classes: {
gutterID: 'acediff-gutter', diff: 'acediff-diff', connector: 'acediff-connector', newCodeConnectorLink: 'acediff-new-code-connector-copy', newCodeConnectorLinkContent: '→', deletedCodeConnectorLink: 'acediff-deleted-code-connector-copy', deletedCodeConnectorLinkContent: '←', copyRightContainer: 'acediff-copy-right', copyLeftContainer: 'acediff-copy-left'
}
}
此外, 你仍然可以使用有用的API来访问ACE编辑器的常规属性:
- aceInstance.getEditors():此方法返回一个具有左右属性的对象。每个文件都包含对原始Ace编辑器的引用, 以防你需要对它们进行任何操作。
- aceInstance.setOptions():这使你可以动态设置前面提到的许多选项。请注意, 在编辑器构造期间使用的某些内容(例如, 类)不能被覆盖。
- aceInstance.getNumDiffs():返回当前显示的差异数。
- aceInstance.diff():更新差异。永远都不需要这样做, 因为AceDiff会自动识别关键事件, 例如对编辑器的更改和窗口大小的调整。
- aceInstance.destroy():销毁AceDiff实例, 销毁两个编辑器并清除装订线。
如你所见, 使用AceDiff确实很容易且实用。请参阅以下典型用法示例:
含开始内容
你可以设置以纯HTML开头的diff控件, 即:
<div id="flex-container">
<div>
<div class="acediff-class" id="editor-left">{
propertyA: 12, propertyB: 123, propertyC: 321, }</div>
</div>
<div id="acediff-gutter"></div>
<div>
<div class="acediff-class" id="editor-right">{
propertyA: 12, propertyZ: 123, propertyC: 321, }</div>
</div>
</div>
<script>
var aceDiffer = new AceDiff({
left:{
id:"editor-left"
}, right:{
id:"editor-right"
}
});
</script>
动态内容
如果要以二维方式(使用jQuery或Angular)启动diff控件, 则可能需要(或想要)以动态方式将内容添加到编辑器中, 要实现此目的, 请使用aceDiffer实例的getEditors方法检索ACE编辑器实例并使用setValue方法对其进行动态更改。
<div id="flex-container">
<div>
<div class="acediff-class" id="editor-left"></div>
</div>
<div id="acediff-gutter"></div>
<div>
<div class="acediff-class" id="editor-right"></div>
</div>
</div>
<script>
var aceDiffer = new AceDiff({
// Add a mode
mode:"ace/mode/javascript", left:{
id:"editor-left"
}, right:{
id:"editor-right"
}
});
var editors = aceDiffer.getEditors();
var leftString = "var a = {\n propertyA: 12, \n propertyB: 123, \n propertyC: 321, \n}";
var rightString = "var a = {\n propertyA: 12, \n propertyZ: 123, \n propertyC: 321, \n}";
// Set Value to the editors
editors.left.setValue(leftString, 1);
editors.right.setValue(rightString, 1);
// Optional to prevent CTRL-Z and remove original content as the content was dinamically added
editors.left.getSession().setUndoManager(new ace.UndoManager());
editors.right.getSession().setUndoManager(new ace.UndoManager());
</script>
编码愉快!
评论前必须登录!
注册