首页 > Web开发 > 详细

[JS 工具] 格式化显示 mailman 上的 diff 文本

时间:2018-01-14 22:22:55      阅读:416      评论:0      收藏:0      [点我收藏+]

公司使用 mailman 来显示 patch,mailman 显示的改动只有一堆黑白文字,难以辨认。有时候还把 patch 当成文件再 git add 一遍后再生成一个新的 patch,这时候对于原来 patch 的代码改动来说,整个 patch 都是新增代码,就更加难以看出改动在哪,给 review patch 带来不必要的不便。

 

有天我想可不可以做成跟 github 一样,至少增删有不同的颜色标记出来。但是又接触不到 mailman 的server,不能改动它的代码。

 

受启发于 Chrome 插件的 JS 文件注入启发,做了这样一个标签式的插件。只要把链接拖动到浏览器书签栏上生成标签,点击标签就可以生效。

 

技术分享图片

 

 

我觉得这样的方式至少有如下几个优点:

1. 免安装,服务器简单,又不需要修改到原网页代码

2. 脚本无缝迭代版本,如果是不兼容的迭代,大不了重新生成个链接让用户拖动就可以了

3. 是否插入脚本过程可控,对于不需要转化的网页,不加载脚本就是了

 

<a class="bookmark-link" onclick="handleClick(); return false;" href="javascript: void((function() {var element = document.createElement(‘script‘);element.charset = ‘utf-8‘,element.setAttribute(‘src‘, ‘http://127.0.0.1:5120/pretty.js‘);document.body.appendChild(element);})())"><span>Pretty-Patch</span></a>

标签代码

 

function handleClick() {
        alert("Drag me to the Bookmarks Bar");
        return false;
    }

如果用户点击链接而不是拖动,就提示他/她

 

javascript: void ((function () {
    var element = document.createElement(‘script‘);
    element.charset = ‘utf-8‘;
    element.setAttribute(‘src‘, ‘http://127.0.0.1:5120/pretty.js‘);
    document.body.appendChild(element); }
)())

拖动链接到浏览器书签栏上形成是书签的链接执行了以上代码。javascript: void() 就是执行一段不需要返回值的表达式,这里是一个自执行的匿名函数。在这个匿名函数里创建了 script 标签,并将 src 属性设置到脚本所在的位置,这样就在当前网页插入了我们的脚本。

 

我在 pretty.js 里放入了 jquery 的代码,还有一个最重要的开源库 “diff2html” 的 js 代码,将它的 css 文件内容复制出来当成字符串存到 prettyStyle 变量。

 

var extralStyle = ‘.d2h-file-wrapper{margin-top:30px; margin-bottom:30px;} body{margin:30px} .copyright{width:100%; text-align:center; margin-top:10px; font-size:0.9em; color:gray;}‘

prettyStyle += extralStyle;

自定义的 css 内容附加到 prettyStyle 变量上

 

接下来所有自己的 js 代码都放到了一个自执行的匿名函数 (function() { ....... })() 防止污染全局变量。虽然也没啥必要,因为这个注入的 js 文件破坏性地更改了页面,但是是一种习惯吧。

 


var diffOption = {inputFormat: ‘diff‘, showFiles: true, matching: ‘lines‘};
 
if($("#defeng-is-a-nice-person").length !== 0) {
        top.document.location.reload();
        return;
    }

这个 id 是注入的 js 文件设置的,这里判断了是否有这个 id,如果有,说明页面以及被格式化了,那么用户再点击一次标签,就重载页面,让用户看到原始页面

 

var data = $("pre").text();
if(data === undefined)
    return;
data = data.replace(/\r\n/g, "\n").trim();
data = removeFooter(data);

获得 patch 内容

 

if(data.indexOf("\n+diff --git") === -1 && data.indexOf("\n+@@ -") === -1) {
        prettyPatch(data);
    }
    else {
        $("body").empty();
        var splitStr = "\ndiff --git ";
        var filesArr = [];

        var headEnd = data.indexOf(splitStr);
        if(headEnd === -1)
            return;
        data = data.slice(headEnd);

        var each = data.split(splitStr);
        each.shift();
        if(each.length === 0)
            return;
        var len = each.length;
        splitStr = splitStr.slice(1);
        for(var i=0; i<len; i++) {
            each[i] = splitStr + each[i] + "\n";
        }

        prettyPatchPlus(each);
    }

因为有如下好几种情况:

  • patch 是用 diff 生成的
  • patch 是用 git format-patch 生成的
  • patch 被当作文件又被 git add 后生成新 patch,且还包含 diff 的patch 或者 git format-patch 的 patch

对于前两种情况,直接用 prettyPatch 函数生成结果就可以了

对于内容里包含有 patch 的情况,用 "\ndiff --git " 作为分隔符将每个文件分割出来后用 prettyPatchPlus 函数生成结果

 

function removeFooter(str) {
        return str.trim().replace(/.*?--\s*\n\s*\d+(.\d+)+$/, "");
    }

这个函数用来移除最后面的 git 版本号

 

function prettyPatch(str) {
        var diff2htmlUi = new Diff2HtmlUI({diff: str});
        diff2htmlUi.draw(‘body‘, diffOption);
    }

只要将 diff 文本直接交给 diff2html 库,就可以生成结果用来替换 body 内容

 

function prettyPatchPlus(each) {
    var len = each.length;
    var found = false;
    for(var i=0; i<len; i++) {
        var oneFile = each[i];
        var lines = oneFile.split("\n");
        var lineLen = lines.length;
        if(oneFile.indexOf("\n++++ ") !== -1) {
            var rmHeader = -1;
            for(var i=0; i<lineLen; i++) {
                var line = lines[i];
                if(line.slice(0, 3) === "+++" && line.slice(-6) === ".patch") {
                    rmHeader = i + 1;
                    continue;
                }
                if(rmHeader === -1) {
                    continue;
                }
                if(line.slice(0, 1) === "+") {
                    lines[i] = line.slice(1);
                }
            }
            oneFile = lines.slice(rmHeader).join("\n");
            oneFile = removeFooter(oneFile);
        }
        var id = "path-plus-list-" + i;
        $("<div id=‘" + id +"‘></div>").appendTo("body");
        var diff2htmlList = new Diff2HtmlUI({diff: oneFile});
        diff2htmlList.draw(‘#‘ + id, diffOption);
    }
}

prettyPatchPlus函数通过判断是否有 "\n++++ " 来判断一个文件是 diff 文本还是 patch,如果是 patch,将每一行最前面的 + 号移除。

将生成的结果替换到 body 下的 div 标签

 

$("<style>" + prettyStyle + "</style>").appendTo("head");

附加 diff2html 的 css 样式和自定义样式

 

$("body").attr("id", "defeng-is-a-nice-person");

标记这页面是经过脚本转化的

 

var publish = "2017";
    var current = (new Date()).getFullYear();
    var copyright = "copyright ©2017" + (current == publish? "": "-" + current) + " DNI-XM";
    copyright += "\tdefeng.liu@deltaww.com";
    $("<hr/><div class=‘copyright‘><span>" + copyright + "</span><div>").appendTo("body");

附加 copyright

 

[JS 工具] 格式化显示 mailman 上的 diff 文本

原文:https://www.cnblogs.com/liqingjht/p/8284330.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!