Merge pull request #52 from rtfpessoa/pbu88-use_nunjucks_templates

Use nunjucks templates
This commit is contained in:
Rodrigo Fernandes 2016-02-21 16:42:56 +00:00
commit 208a98b88d
27 changed files with 3470 additions and 216 deletions

View file

@ -19,3 +19,5 @@ Nuno Teixeira, [@nmatpt](https://github.com/nmatpt)
Mikko Rantanen, [@Rantanen](https://github.com/Rantanen)
Wolfgang Illmeyer, [@escitalopram](https://github.com/escitalopram)
Jameskmonger, [@Jameskmonger](https://github.com/Jameskmonger)

View file

@ -1,6 +1,6 @@
{
"name": "diff2html",
"version": "1.3.2",
"version": "2.0.0-beta1",
"homepage": "http://rtfpessoa.github.io/diff2html/",
"description": "Fast Diff to colorized HTML",
"keywords": [
@ -28,6 +28,7 @@
"url": "git://github.com/rtfpessoa/diff2html.git"
},
"main": [
"./dist/diff2html-templates.js",
"./dist/diff2html.js",
"./dist/diff2html-ui.js",
"./dist/diff2html.css"

View file

@ -2,6 +2,7 @@ test:
override:
- nvm install 0.12 && npm test
- nvm install 4 && npm test
- nvm install 5 && npm test
post:
- npm install
- istanbul cover ./node_modules/mocha/bin/_mocha --report lcovonly -- -R spec

171
dist/diff2html-templates.js vendored Normal file
View file

@ -0,0 +1,171 @@
(function() {(window.nunjucksPrecompiled = window.nunjucksPrecompiled || {})["line-by-line/column-line-number.html"] = (function() {
function root(env, context, frame, runtime, cb) {
var lineno = null;
var colno = null;
var output = "";
try {
var parentTemplate = null;
output += "<tr>\n <td class=\"d2h-code-linenumber ";
output += runtime.suppressValue(runtime.memberLookup((runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "diffParser")),"LINE_TYPE")),"INFO"), env.opts.autoescape);
output += "\"></td>\n <td class=\"";
output += runtime.suppressValue(runtime.memberLookup((runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "diffParser")),"LINE_TYPE")),"INFO"), env.opts.autoescape);
output += "\">\n <div class=\"d2h-code-line ";
output += runtime.suppressValue(runtime.memberLookup((runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "diffParser")),"LINE_TYPE")),"INFO"), env.opts.autoescape);
output += "\"> ";
output += runtime.suppressValue((lineno = 3, colno = 73, runtime.callWrap(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "utils")),"escape"), "utils[\"escape\"]", context, [runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "block")),"header")])), env.opts.autoescape);
output += " </div>\n </td>\n</tr>\n";
if(parentTemplate) {
parentTemplate.rootRenderFunc(env, context, frame, runtime, cb);
} else {
cb(null, output);
}
;
} catch (e) {
cb(runtime.handleError(e, lineno, colno));
}
}
return {
root: root
};
})();
})();
(function() {(window.nunjucksPrecompiled = window.nunjucksPrecompiled || {})["line-by-line/empty-diff.html"] = (function() {
function root(env, context, frame, runtime, cb) {
var lineno = null;
var colno = null;
var output = "";
try {
var parentTemplate = null;
output += "<tr>\n <td class=\"";
output += runtime.suppressValue(runtime.memberLookup((runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "diffParser")),"LINE_TYPE")),"INFO"), env.opts.autoescape);
output += "\">\n <div class=\"d2h-code-line ";
output += runtime.suppressValue(runtime.memberLookup((runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "diffParser")),"LINE_TYPE")),"INFO"), env.opts.autoescape);
output += "\">\n File without changes\n </div>\n </td>\n</tr>\n";
if(parentTemplate) {
parentTemplate.rootRenderFunc(env, context, frame, runtime, cb);
} else {
cb(null, output);
}
;
} catch (e) {
cb(runtime.handleError(e, lineno, colno));
}
}
return {
root: root
};
})();
})();
(function() {(window.nunjucksPrecompiled = window.nunjucksPrecompiled || {})["line-by-line/file-diff.html"] = (function() {
function root(env, context, frame, runtime, cb) {
var lineno = null;
var colno = null;
var output = "";
try {
var parentTemplate = null;
output += "<div id=\"";
output += runtime.suppressValue((lineno = 0, colno = 32, runtime.callWrap(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "printerUtils")),"getHtmlId"), "printerUtils[\"getHtmlId\"]", context, [runtime.contextOrFrameLookup(context, frame, "file")])), env.opts.autoescape);
output += "\" class=\"d2h-file-wrapper\" data-lang=\"";
output += runtime.suppressValue(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "file")),"language"), env.opts.autoescape);
output += "\">\n <div class=\"d2h-file-header\">\n <div class=\"d2h-file-stats\">\n <span class=\"d2h-lines-added\">\n <span>+";
output += runtime.suppressValue(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "file")),"addedLines"), env.opts.autoescape);
output += "</span>\n </span>\n <span class=\"d2h-lines-deleted\">\n <span>-";
output += runtime.suppressValue(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "file")),"deletedLines"), env.opts.autoescape);
output += "</span>\n </span>\n </div>\n <div class=\"d2h-file-name\">&nbsp;";
output += runtime.suppressValue((lineno = 10, colno = 62, runtime.callWrap(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "printerUtils")),"getDiffName"), "printerUtils[\"getDiffNam\"]", context, [runtime.contextOrFrameLookup(context, frame, "file")])), env.opts.autoescape);
output += "</div>\n </div>\n <div class=\"d2h-file-diff\">\n <div class=\"d2h-code-wrapper\">\n <table class=\"d2h-diff-table\">\n <tbody class=\"d2h-diff-tbody\">\n ";
output += runtime.suppressValue(env.getFilter("safe").call(context, runtime.contextOrFrameLookup(context, frame, "diffs")), env.opts.autoescape);
output += "\n </tbody>\n </table>\n </div>\n </div>\n</div>\n";
if(parentTemplate) {
parentTemplate.rootRenderFunc(env, context, frame, runtime, cb);
} else {
cb(null, output);
}
;
} catch (e) {
cb(runtime.handleError(e, lineno, colno));
}
}
return {
root: root
};
})();
})();
(function() {(window.nunjucksPrecompiled = window.nunjucksPrecompiled || {})["line-by-line/line.html"] = (function() {
function root(env, context, frame, runtime, cb) {
var lineno = null;
var colno = null;
var output = "";
try {
var parentTemplate = null;
output += "<tr>\n <td class=\"d2h-code-linenumber ";
output += runtime.suppressValue(runtime.contextOrFrameLookup(context, frame, "type"), env.opts.autoescape);
output += "\">\n <div class=\"line-num1\">";
output += runtime.suppressValue(env.getFilter("safe").call(context, (lineno = 2, colno = 46, runtime.callWrap(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "utils")),"valueOrEmpty"), "utils[\"valueOrEmp\"]", context, [runtime.contextOrFrameLookup(context, frame, "oldNumber")]))), env.opts.autoescape);
output += "</div>\n <div class=\"line-num2\">";
output += runtime.suppressValue(env.getFilter("safe").call(context, (lineno = 3, colno = 46, runtime.callWrap(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "utils")),"valueOrEmpty"), "utils[\"valueOrEmp\"]", context, [runtime.contextOrFrameLookup(context, frame, "newNumber")]))), env.opts.autoescape);
output += "</div>\n </td>\n <td class=\"";
output += runtime.suppressValue(runtime.contextOrFrameLookup(context, frame, "type"), env.opts.autoescape);
output += "\">\n <div class=\"d2h-code-line ";
output += runtime.suppressValue(runtime.contextOrFrameLookup(context, frame, "type"), env.opts.autoescape);
output += "\">\n";
if(runtime.contextOrFrameLookup(context, frame, "prefix")) {
output += "\n <span class=\"d2h-code-line-prefix\">";
output += runtime.suppressValue(env.getFilter("safe").call(context, (lineno = 8, colno = 83, runtime.callWrap(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "utils")),"convertWhiteSpaceToNonBreakingSpace"), "utils[\"convertWhi\"]", context, [runtime.contextOrFrameLookup(context, frame, "prefix")]))), env.opts.autoescape);
output += "</span>\n";
;
}
output += "\n";
if(runtime.contextOrFrameLookup(context, frame, "content")) {
output += "\n <span class=\"d2h-code-line-ctn\">";
output += runtime.suppressValue(env.getFilter("safe").call(context, (lineno = 11, colno = 80, runtime.callWrap(runtime.memberLookup((runtime.contextOrFrameLookup(context, frame, "utils")),"convertWhiteSpaceToNonBreakingSpace"), "utils[\"convertWhi\"]", context, [runtime.contextOrFrameLookup(context, frame, "content")]))), env.opts.autoescape);
output += "</span>\n";
;
}
output += "\n </div>\n </td>\n</tr>\n";
if(parentTemplate) {
parentTemplate.rootRenderFunc(env, context, frame, runtime, cb);
} else {
cb(null, output);
}
;
} catch (e) {
cb(runtime.handleError(e, lineno, colno));
}
}
return {
root: root
};
})();
})();
(function() {(window.nunjucksPrecompiled = window.nunjucksPrecompiled || {})["line-by-line/wrapper.html"] = (function() {
function root(env, context, frame, runtime, cb) {
var lineno = null;
var colno = null;
var output = "";
try {
var parentTemplate = null;
output += "<div class=\"d2h-wrapper\">\n ";
output += runtime.suppressValue(runtime.contextOrFrameLookup(context, frame, "content"), env.opts.autoescape);
output += "\n</div>\n";
if(parentTemplate) {
parentTemplate.rootRenderFunc(env, context, frame, runtime, cb);
} else {
cb(null, output);
}
;
} catch (e) {
cb(runtime.handleError(e, lineno, colno));
}
}
return {
root: root
};
})();
})();

1
dist/diff2html-templates.min.js vendored Normal file

File diff suppressed because one or more lines are too long

19
dist/diff2html-ui.js vendored
View file

@ -114,8 +114,6 @@
var languages = that._getLanguages($target);
console.log(languages);
// pass the languages to the highlightjs plugin
hljs.configure({languages: languages});
@ -146,18 +144,13 @@
return line.language;
});
} else {
console.log($target.find(".d2h-file-wrapper"));
$target.find(".d2h-file-wrapper").map(function(i, file) {
allFileLanguages.push($(file).data("lang"));
});
}
// remove duplicated languages
var distinctLanguages = allFileLanguages.filter(function(v, i) {
return allFileLanguages.indexOf(v) === i;
});
return distinctLanguages;
// return only distinct languages
return this._distinct(allFileLanguages);
};
Diff2HtmlUI.prototype._getHashTag = function() {
@ -165,13 +158,19 @@
var hashTagIndex = docUrl.indexOf('#');
var hashTag = null;
if (hashTagIndex != -1) {
if (hashTagIndex !== -1) {
hashTag = docUrl.substr(hashTagIndex + 1);
}
return hashTag;
};
Diff2HtmlUI.prototype._distinct = function(collection) {
return collection.filter(function(v, i) {
return collection.indexOf(v) === i;
});
};
module.exports.Diff2HtmlUI = Diff2HtmlUI;
// Expose diff2html in the browser

View file

@ -1 +1 @@
!function(modules){function __webpack_require__(moduleId){if(installedModules[moduleId])return installedModules[moduleId].exports;var module=installedModules[moduleId]={exports:{},id:moduleId,loaded:!1};return modules[moduleId].call(module.exports,module,module.exports,__webpack_require__),module.loaded=!0,module.exports}var installedModules={};return __webpack_require__.m=modules,__webpack_require__.c=installedModules,__webpack_require__.p="",__webpack_require__(0)}([function(module,exports){(function(global){!function(){function Diff2HtmlUI(config){var cfg=config||{};cfg.diff?diffJson=Diff2Html.getJsonFromDiff(cfg.diff):cfg.json&&(diffJson=cfg.json)}var diffJson=null,defaultTarget="body";Diff2HtmlUI.prototype.draw=function(targetId,config){var cfg=config||{},$target=this._getTarget(targetId);$target.html(Diff2Html.getPrettyHtml(diffJson,cfg))},Diff2HtmlUI.prototype.fileListCloseable=function(targetId,startVisible){function show(){$showBtn.hide(),$hideBtn.show(),$fileList.show()}function hide(){$hideBtn.hide(),$showBtn.show(),$fileList.hide()}var $target=this._getTarget(targetId),hashTag=this._getHashTag(),$showBtn=$target.find(".d2h-show"),$hideBtn=$target.find(".d2h-hide"),$fileList=$target.find(".d2h-file-list");"files-summary-show"===hashTag?show():"files-summary-hide"===hashTag?hide():startVisible?show():hide(),$showBtn.click(show),$hideBtn.click(hide)},Diff2HtmlUI.prototype.highlightCode=function(targetId){var that=this,$target=that._getTarget(targetId),languages=that._getLanguages($target);console.log(languages),hljs.configure({languages:languages});var $codeLines=$target.find(".d2h-code-line-ctn");$codeLines.map(function(i,line){hljs.highlightBlock(line)})},Diff2HtmlUI.prototype._getTarget=function(targetId){var $target;return $target=$(targetId?targetId:defaultTarget)},Diff2HtmlUI.prototype._getLanguages=function($target){var allFileLanguages=[];diffJson?allFileLanguages=diffJson.map(function(line){return line.language}):(console.log($target.find(".d2h-file-wrapper")),$target.find(".d2h-file-wrapper").map(function(i,file){allFileLanguages.push($(file).data("lang"))}));var distinctLanguages=allFileLanguages.filter(function(v,i){return allFileLanguages.indexOf(v)===i});return distinctLanguages},Diff2HtmlUI.prototype._getHashTag=function(){var docUrl=document.URL,hashTagIndex=docUrl.indexOf("#"),hashTag=null;return-1!=hashTagIndex&&(hashTag=docUrl.substr(hashTagIndex+1)),hashTag},module.exports.Diff2HtmlUI=Diff2HtmlUI,global.Diff2HtmlUI=Diff2HtmlUI}()}).call(exports,function(){return this}())}]);
!function(modules){function __webpack_require__(moduleId){if(installedModules[moduleId])return installedModules[moduleId].exports;var module=installedModules[moduleId]={exports:{},id:moduleId,loaded:!1};return modules[moduleId].call(module.exports,module,module.exports,__webpack_require__),module.loaded=!0,module.exports}var installedModules={};return __webpack_require__.m=modules,__webpack_require__.c=installedModules,__webpack_require__.p="",__webpack_require__(0)}([function(module,exports){(function(global){!function(){function Diff2HtmlUI(config){var cfg=config||{};cfg.diff?diffJson=Diff2Html.getJsonFromDiff(cfg.diff):cfg.json&&(diffJson=cfg.json)}var diffJson=null,defaultTarget="body";Diff2HtmlUI.prototype.draw=function(targetId,config){var cfg=config||{},$target=this._getTarget(targetId);$target.html(Diff2Html.getPrettyHtml(diffJson,cfg))},Diff2HtmlUI.prototype.fileListCloseable=function(targetId,startVisible){function show(){$showBtn.hide(),$hideBtn.show(),$fileList.show()}function hide(){$hideBtn.hide(),$showBtn.show(),$fileList.hide()}var $target=this._getTarget(targetId),hashTag=this._getHashTag(),$showBtn=$target.find(".d2h-show"),$hideBtn=$target.find(".d2h-hide"),$fileList=$target.find(".d2h-file-list");"files-summary-show"===hashTag?show():"files-summary-hide"===hashTag?hide():startVisible?show():hide(),$showBtn.click(show),$hideBtn.click(hide)},Diff2HtmlUI.prototype.highlightCode=function(targetId){var that=this,$target=that._getTarget(targetId),languages=that._getLanguages($target);hljs.configure({languages:languages});var $codeLines=$target.find(".d2h-code-line-ctn");$codeLines.map(function(i,line){hljs.highlightBlock(line)})},Diff2HtmlUI.prototype._getTarget=function(targetId){var $target;return $target=$(targetId?targetId:defaultTarget)},Diff2HtmlUI.prototype._getLanguages=function($target){var allFileLanguages=[];return diffJson?allFileLanguages=diffJson.map(function(line){return line.language}):$target.find(".d2h-file-wrapper").map(function(i,file){allFileLanguages.push($(file).data("lang"))}),this._distinct(allFileLanguages)},Diff2HtmlUI.prototype._getHashTag=function(){var docUrl=document.URL,hashTagIndex=docUrl.indexOf("#"),hashTag=null;return-1!==hashTagIndex&&(hashTag=docUrl.substr(hashTagIndex+1)),hashTag},Diff2HtmlUI.prototype._distinct=function(collection){return collection.filter(function(v,i){return collection.indexOf(v)===i})},module.exports.Diff2HtmlUI=Diff2HtmlUI,global.Diff2HtmlUI=Diff2HtmlUI}()}).call(exports,function(){return this}())}]);

9
dist/diff2html.css vendored
View file

@ -69,11 +69,14 @@
border-collapse: collapse;
font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
font-size: 12px;
height: 18px;
line-height: 18px;
width: 100%;
}
.d2h-diff-tbody > tr > td > div {
height: 16px;
line-height: 16px;
}
.d2h-files-diff {
width: 100%;
}
@ -93,9 +96,9 @@
.d2h-code-line {
display: block;
white-space: pre;
padding: 0 10px;
height: 18px;
white-space: nowrap;
line-height: 18px;
margin-left: 80px;
/* Override HighlightJS */

3070
dist/diff2html.js vendored

File diff suppressed because it is too large Load diff

View file

@ -1 +1 @@
.d2h-code-line-prefix,.line-num1{float:left}.d2h-wrapper{display:block;margin:0 auto;text-align:left;width:100%}.d2h-file-wrapper{border:1px solid #ddd;border-radius:3px;margin-bottom:1em}.d2h-file-header{padding:5px 10px;border-bottom:1px solid #d8d8d8;background-color:#f7f7f7;font:13px Helvetica,arial,freesans,clean,sans-serif,"Segoe UI Emoji","Segoe UI Symbol"}.d2h-file-stats{display:inline;font-size:12px;text-align:center;max-width:15%}.d2h-lines-added{text-align:right}.d2h-lines-added>*{background-color:#ceffce;border:1px solid #b4e2b4;color:#399839;border-radius:5px 0 0 5px;padding:2px}.d2h-lines-deleted{text-align:left}.d2h-lines-deleted>*{background-color:#f7c8c8;border:1px solid #e9aeae;color:#c33;border-radius:0 5px 5px 0;padding:2px}.d2h-file-name{display:inline;line-height:33px;max-width:80%;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.d2h-file-diff,.d2h-file-side-diff{overflow-x:scroll;overflow-y:hidden}.d2h-diff-table{border-collapse:collapse;font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:12px;height:18px;line-height:18px;width:100%}.d2h-files-diff{width:100%}.d2h-file-side-diff{display:inline-block;width:50%;margin-right:-4px}.d2h-code-line,.d2h-code-side-line{white-space:pre;padding:0 10px;height:18px;line-height:18px;color:inherit;overflow-x:inherit;background:0 0;display:block}.d2h-code-line{margin-left:80px}.d2h-code-side-line{margin-left:50px}.d2h-code-line del,.d2h-code-side-line del{display:inline-block;margin-top:-1px;text-decoration:none;background-color:#ffb6ba;border-radius:.2em}.d2h-code-line ins,.d2h-code-side-line ins{display:inline-block;margin-top:-1px;text-decoration:none;background-color:#97f295;border-radius:.2em}.d2h-code-line-ctn,.d2h-code-line-prefix{background:0 0;padding:0}.d2h-code-linenumber,.d2h-code-side-linenumber{position:absolute;height:18px;line-height:18px;background-color:#fff;text-align:right;color:rgba(0,0,0,.3);cursor:pointer}.line-num1,.line-num2{width:32px;padding-left:3px;box-sizing:border-box;overflow:hidden;text-overflow:ellipsis}.line-num2{float:right}.d2h-code-linenumber{box-sizing:border-box;width:82px;padding-left:2px;padding-right:2px;border:solid #eee;border-width:0 1px}.d2h-code-side-linenumber{box-sizing:border-box;width:52px;padding-left:10px;padding-right:10px;border:solid #eee;border-width:0 1px;overflow:hidden;text-overflow:ellipsis}.d2h-del{background-color:#fee8e9;border-color:#e9aeae}.d2h-ins{background-color:#dfd;border-color:#b4e2b4}.d2h-info{background-color:#f8fafd;color:rgba(0,0,0,.3);border-color:#d5e4f2}.d2h-file-list-wrapper{margin-bottom:10px;padding:0 10px}.d2h-file-list-wrapper a{text-decoration:none;color:#3572b0}.d2h-file-list-wrapper a:visited{color:#3572b0}.d2h-file-list-header{font-weight:700;float:left}.d2h-file-list-line{text-align:left;font:13px Helvetica,arial,freesans,clean,sans-serif,"Segoe UI Emoji","Segoe UI Symbol"}.d2h-file-list-line .d2h-file-name{line-height:21px}.d2h-file-list{display:block}.d2h-clear{display:block;clear:both}.d2h-del.d2h-change,.d2h-ins.d2h-change{background-color:#ffc}del.d2h-change,ins.d2h-change{background-color:#fad771}.d2h-file-diff .d2h-del.d2h-change{background-color:#fae1af}.d2h-file-diff .d2h-ins.d2h-change{background-color:#ded}.d2h-file-switch{display:none;float:left;font-size:10px;cursor:pointer;margin-top:3px}
.d2h-code-line-prefix,.line-num1{float:left}.d2h-wrapper{display:block;margin:0 auto;text-align:left;width:100%}.d2h-file-wrapper{border:1px solid #ddd;border-radius:3px;margin-bottom:1em}.d2h-file-header{padding:5px 10px;border-bottom:1px solid #d8d8d8;background-color:#f7f7f7;font:13px Helvetica,arial,freesans,clean,sans-serif,"Segoe UI Emoji","Segoe UI Symbol"}.d2h-file-stats{display:inline;font-size:12px;text-align:center;max-width:15%}.d2h-lines-added{text-align:right}.d2h-lines-added>*{background-color:#ceffce;border:1px solid #b4e2b4;color:#399839;border-radius:5px 0 0 5px;padding:2px}.d2h-lines-deleted{text-align:left}.d2h-lines-deleted>*{background-color:#f7c8c8;border:1px solid #e9aeae;color:#c33;border-radius:0 5px 5px 0;padding:2px}.d2h-file-name{display:inline;line-height:33px;max-width:80%;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.d2h-file-diff,.d2h-file-side-diff{overflow-x:scroll;overflow-y:hidden}.d2h-diff-table{border-collapse:collapse;font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:12px;width:100%}.d2h-diff-tbody>tr>td>div{height:16px;line-height:16px}.d2h-files-diff{width:100%}.d2h-file-side-diff{display:inline-block;width:50%;margin-right:-4px}.d2h-code-line,.d2h-code-side-line{padding:0 10px;height:18px;line-height:18px;color:inherit;overflow-x:inherit;background:0 0;display:block}.d2h-code-line{white-space:nowrap;margin-left:80px}.d2h-code-side-line{white-space:pre;margin-left:50px}.d2h-code-line del,.d2h-code-side-line del{display:inline-block;margin-top:-1px;text-decoration:none;background-color:#ffb6ba;border-radius:.2em}.d2h-code-line ins,.d2h-code-side-line ins{display:inline-block;margin-top:-1px;text-decoration:none;background-color:#97f295;border-radius:.2em}.d2h-code-line-ctn,.d2h-code-line-prefix{background:0 0;padding:0}.d2h-code-linenumber,.d2h-code-side-linenumber{position:absolute;height:18px;line-height:18px;background-color:#fff;text-align:right;color:rgba(0,0,0,.3);cursor:pointer}.line-num1,.line-num2{width:32px;padding-left:3px;box-sizing:border-box;overflow:hidden;text-overflow:ellipsis}.line-num2{float:right}.d2h-code-linenumber{box-sizing:border-box;width:82px;padding-left:2px;padding-right:2px;border:solid #eee;border-width:0 1px}.d2h-code-side-linenumber{box-sizing:border-box;width:52px;padding-left:10px;padding-right:10px;border:solid #eee;border-width:0 1px;overflow:hidden;text-overflow:ellipsis}.d2h-del{background-color:#fee8e9;border-color:#e9aeae}.d2h-ins{background-color:#dfd;border-color:#b4e2b4}.d2h-info{background-color:#f8fafd;color:rgba(0,0,0,.3);border-color:#d5e4f2}.d2h-file-list-wrapper{margin-bottom:10px;padding:0 10px}.d2h-file-list-wrapper a{text-decoration:none;color:#3572b0}.d2h-file-list-wrapper a:visited{color:#3572b0}.d2h-file-list-header{font-weight:700;float:left}.d2h-file-list-line{text-align:left;font:13px Helvetica,arial,freesans,clean,sans-serif,"Segoe UI Emoji","Segoe UI Symbol"}.d2h-file-list-line .d2h-file-name{line-height:21px}.d2h-file-list{display:block}.d2h-clear{display:block;clear:both}.d2h-del.d2h-change,.d2h-ins.d2h-change{background-color:#ffc}del.d2h-change,ins.d2h-change{background-color:#fad771}.d2h-file-diff .d2h-del.d2h-change{background-color:#fae1af}.d2h-file-diff .d2h-ins.d2h-change{background-color:#ded}.d2h-file-switch{display:none;float:left;font-size:10px;cursor:pointer;margin-top:3px}

File diff suppressed because one or more lines are too long

View file

@ -1,6 +1,6 @@
{
"name": "diff2html",
"version": "1.3.2",
"version": "2.0.0-beta1",
"homepage": "http://rtfpessoa.github.io/diff2html/",
"description": "Fast Diff to colorized HTML",
"keywords": [
@ -43,14 +43,15 @@
},
"main": "./src/diff2html.js",
"dependencies": {
"diff": "^2.2.1"
"diff": "^2.2.1",
"nunjucks": "^2.3.0"
},
"devDependencies": {
"codacy-coverage": "^1.1.3",
"clean-css": "^3.4.9",
"codacy-coverage": "^1.1.3",
"fast-html-parser": "^1.0.1",
"istanbul": "^0.4.1",
"jscs": "^2.9.0",
"istanbul": "^0.4.2",
"jscs": "^2.10.1",
"mocha": "^2.4.5",
"uglifyjs": "^2.4.10",
"webpack": "^1.12.13"

View file

@ -8,6 +8,7 @@
set -e
INPUT_DIR=src
INTPUT_TEMPLATES_DIR=${INPUT_DIR}/templates
INPUT_UI_DIR=${INPUT_DIR}/ui
INPUT_JS_FILE=${INPUT_DIR}/diff2html.js
INPUT_JS_UI_FILE=${INPUT_UI_DIR}/js/diff2html-ui.js
@ -20,6 +21,8 @@ OUTPUT_JS_UI_FILE=${OUTPUT_DIR}/diff2html-ui.js
OUTPUT_MIN_JS_UI_FILE=${OUTPUT_DIR}/diff2html-ui.min.js
OUTPUT_CSS_FILE=${OUTPUT_DIR}/diff2html.css
OUTPUT_MIN_CSS_FILE=${OUTPUT_DIR}/diff2html.min.css
OUTPUT_TEMPLATES_FILE=${OUTPUT_DIR}/diff2html-templates.js
OUTPUT_MIN_TEMPLATES_FILE=${OUTPUT_DIR}/diff2html-templates.min.js
echo "Creating diff2html release ..."
@ -28,27 +31,27 @@ rm -rf ${OUTPUT_DIR}
mkdir -p ${OUTPUT_DIR}
echo "Generating js aggregation file in ${OUTPUT_JS_FILE}"
webpack ${INPUT_JS_FILE} ${OUTPUT_JS_FILE}
echo "Minifying ${OUTPUT_JS_FILE} to ${OUTPUT_MIN_JS_FILE}"
uglifyjs ${OUTPUT_JS_FILE} -c -o ${OUTPUT_MIN_JS_FILE}
echo "Generating js ui aggregation file in ${OUTPUT_JS_UI_FILE}"
webpack ${INPUT_JS_UI_FILE} ${OUTPUT_JS_UI_FILE}
echo "Minifying ${OUTPUT_JS_UI_FILE} to ${OUTPUT_MIN_JS_UI_FILE}"
uglifyjs ${OUTPUT_JS_UI_FILE} -c -o ${OUTPUT_MIN_JS_UI_FILE}
echo "Copying css file to ${OUTPUT_CSS_FILE}"
echo "Pre-compile nunjucks templates in ${INTPUT_TEMPLATES_DIR}"
nunjucks-precompile ${INTPUT_TEMPLATES_DIR} > ${OUTPUT_TEMPLATES_FILE}
echo "Minifying ${OUTPUT_TEMPLATES_FILE} to ${OUTPUT_MIN_TEMPLATES_FILE}"
uglifyjs ${OUTPUT_TEMPLATES_FILE} -c -o ${OUTPUT_MIN_TEMPLATES_FILE}
echo "Copying css file to ${OUTPUT_CSS_FILE}"
cp -f ${INPUT_CSS_FILE} ${OUTPUT_CSS_FILE}
echo "Minifying ${OUTPUT_CSS_FILE} to ${OUTPUT_MIN_CSS_FILE}"
cleancss --advanced --compatibility=ie8 -o ${OUTPUT_MIN_CSS_FILE} ${OUTPUT_CSS_FILE}
echo "diff2html release created successfully!"

View file

@ -9,15 +9,16 @@
Author: rtfpessoa
-->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.9.1/styles/github.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.1.0/styles/github.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.9.1/highlight.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.9.1/languages/scala.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.1.0/highlight.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.1.0/languages/scala.min.js"></script>
<!-- diff2html -->
<link rel="stylesheet" type="text/css" href="../dist/diff2html.min.css">
<link rel="stylesheet" type="text/css" href="../dist/diff2html.css">
<script type="text/javascript" src="../dist/diff2html-templates.js"></script>
<script type="text/javascript" src="../dist/diff2html.js"></script>
<script type="text/javascript" src="../dist/diff2html-ui.js"></script>
<!-- -->

View file

@ -12,48 +12,34 @@
var utils = require('./utils.js').Utils;
var Rematch = require('./rematch.js').Rematch;
var nunjucksUtils = require('./nunjucks-utils.js').NunjucksUtils;
var baseTemplatesPath = 'line-by-line';
function LineByLinePrinter(config) {
this.config = config;
}
LineByLinePrinter.prototype.makeFileDiffHtml = function(file, diffs) {
return '<div id="' + printerUtils.getHtmlId(file) + '" class="d2h-file-wrapper" data-lang="' + file.language + '">\n' +
' <div class="d2h-file-header">\n' +
' <div class="d2h-file-stats">\n' +
' <span class="d2h-lines-added">' +
' <span>+' + file.addedLines + '</span>\n' +
' </span>\n' +
' <span class="d2h-lines-deleted">' +
' <span>-' + file.deletedLines + '</span>\n' +
' </span>\n' +
' </div>\n' +
' <div class="d2h-file-name">' + printerUtils.getDiffName(file) + '</div>\n' +
' </div>\n' +
' <div class="d2h-file-diff">\n' +
' <div class="d2h-code-wrapper">\n' +
' <table class="d2h-diff-table">\n' +
' <tbody class="d2h-diff-tbody">\n' +
' ' + diffs +
' </tbody>\n' +
' </table>\n' +
' </div>\n' +
' </div>\n' +
' </div>\n';
return nunjucksUtils.render(baseTemplatesPath, 'file-diff.html', {'file': file, 'diffs': diffs});
};
LineByLinePrinter.prototype.makeLineByLineHtmlWrapper = function(content) {
return nunjucksUtils.render(baseTemplatesPath, 'wrapper.html', {'content': content});
};
LineByLinePrinter.prototype.generateLineByLineJsonHtml = function(diffFiles) {
var that = this;
var htmlDiffs = diffFiles.map(function(file) {
var diffs;
if (file.blocks.length) {
diffs = that._generateFileHtml(file);
} else {
diffs = that._generateEmptyDiff();
}
return that.makeFileDiffHtml(file, diffs);
});
var diffs;
if (file.blocks.length) {
diffs = that._generateFileHtml(file);
} else {
diffs = that._generateEmptyDiff();
}
return that.makeFileDiffHtml(file, diffs);
});
return '<div class="d2h-wrapper">\n' + htmlDiffs.join('\n') + '</div>\n';
return this.makeLineByLineHtmlWrapper(htmlDiffs.join('\n'));
};
var matcher = Rematch.rematch(function(a, b) {
@ -64,12 +50,7 @@
});
LineByLinePrinter.prototype.makeColumnLineNumberHtml = function(block) {
return '<tr>\n' +
' <td class="d2h-code-linenumber ' + diffParser.LINE_TYPE.INFO + '"></td>\n' +
' <td class="' + diffParser.LINE_TYPE.INFO + '">' +
' <div class="d2h-code-line ' + diffParser.LINE_TYPE.INFO + '">' + utils.escape(block.header) + '</div>' +
' </td>\n' +
'</tr>\n';
return nunjucksUtils.render(baseTemplatesPath, 'column-line-number.html', {block: block});
};
LineByLinePrinter.prototype._generateFileHtml = function(file) {
@ -115,10 +96,10 @@
var diff = printerUtils.diffHighlight(oldLine.content, newLine.content, that.config);
processedOldLines +=
that._generateLineHtml(deleteType, oldLine.oldNumber, oldLine.newNumber,
that.makeLineHtml(deleteType, oldLine.oldNumber, oldLine.newNumber,
diff.first.line, diff.first.prefix);
processedNewLines +=
that._generateLineHtml(insertType, newLine.oldNumber, newLine.newNumber,
that.makeLineHtml(insertType, newLine.oldNumber, newLine.newNumber,
diff.second.line, diff.second.prefix);
}
@ -140,9 +121,9 @@
}
if (line.type === diffParser.LINE_TYPE.CONTEXT) {
lines += that._generateLineHtml(line.type, line.oldNumber, line.newNumber, escapedLine);
lines += that.makeLineHtml(line.type, line.oldNumber, line.newNumber, escapedLine);
} else if (line.type === diffParser.LINE_TYPE.INSERTS && !oldLines.length) {
lines += that._generateLineHtml(line.type, line.oldNumber, line.newNumber, escapedLine);
lines += that.makeLineHtml(line.type, line.oldNumber, line.newNumber, escapedLine);
} else if (line.type === diffParser.LINE_TYPE.DELETES) {
oldLines.push(line);
} else if (line.type === diffParser.LINE_TYPE.INSERTS && Boolean(oldLines.length)) {
@ -165,52 +146,31 @@
for (var i = 0; i < oldLines.length; i++) {
var oldLine = oldLines[i];
var oldEscapedLine = utils.escape(oldLine.content);
lines += this._generateLineHtml(oldLine.type, oldLine.oldNumber, oldLine.newNumber, oldEscapedLine);
lines += this.makeLineHtml(oldLine.type, oldLine.oldNumber, oldLine.newNumber, oldEscapedLine);
}
for (var j = 0; j < newLines.length; j++) {
var newLine = newLines[j];
var newEscapedLine = utils.escape(newLine.content);
lines += this._generateLineHtml(newLine.type, newLine.oldNumber, newLine.newNumber, newEscapedLine);
lines += this.makeLineHtml(newLine.type, newLine.oldNumber, newLine.newNumber, newEscapedLine);
}
return lines;
};
LineByLinePrinter.prototype.makeLineHtml = function(type, oldNumber, newNumber, htmlPrefix, htmlContent) {
return '<tr>\n' +
' <td class="d2h-code-linenumber ' + type + '">' +
' <div class="line-num1">' + utils.valueOrEmpty(oldNumber) + '</div>' +
' <div class="line-num2">' + utils.valueOrEmpty(newNumber) + '</div>' +
' </td>\n' +
' <td class="' + type + '">' +
' <div class="d2h-code-line ' + type + '">' + htmlPrefix + htmlContent + '</div>' +
' </td>\n' +
'</tr>\n';
};
LineByLinePrinter.prototype._generateLineHtml = function(type, oldNumber, newNumber, content, prefix) {
var htmlPrefix = '';
if (prefix) {
htmlPrefix = '<span class="d2h-code-line-prefix">' + prefix + '</span>';
}
var htmlContent = '';
if (content) {
htmlContent = '<span class="d2h-code-line-ctn">' + content + '</span>';
}
return this.makeLineHtml(type, oldNumber, newNumber, htmlPrefix, htmlContent);
LineByLinePrinter.prototype.makeLineHtml = function(type, oldNumber, newNumber, content, prefix) {
return nunjucksUtils.render(baseTemplatesPath, 'line.html',
{
type: type,
oldNumber: oldNumber,
newNumber: newNumber,
prefix: prefix,
content: content
});
};
LineByLinePrinter.prototype._generateEmptyDiff = function() {
return '<tr>\n' +
' <td class="' + diffParser.LINE_TYPE.INFO + '">' +
' <div class="d2h-code-line ' + diffParser.LINE_TYPE.INFO + '">' +
'File without changes' +
' </div>' +
' </td>\n' +
'</tr>\n';
return nunjucksUtils.render(baseTemplatesPath, 'empty-diff.html', {});
};
module.exports.LineByLinePrinter = LineByLinePrinter;

34
src/nunjucks-utils.js Normal file
View file

@ -0,0 +1,34 @@
/*
*
* Utils (utils.js)
* Author: rtfpessoa
*
*/
(function() {
var path = require('path');
var nunjucks = require('nunjucks');
var templatesPath = path.resolve(__dirname, 'templates');
var diffParser = require('./diff-parser.js').DiffParser;
var printerUtils = require('./printer-utils.js').PrinterUtils;
var utils = require('./utils.js').Utils;
var nunjucksEnv = nunjucks.configure(templatesPath, {"autoescape": false})
.addGlobal('printerUtils', printerUtils)
.addGlobal('utils', utils)
.addGlobal('diffParser', diffParser);
function NunjucksUtils() {
}
NunjucksUtils.prototype.render = function(namespace, view, params) {
var viewPath = path.join(namespace, view);
return nunjucksEnv.render(viewPath, params);
};
module.exports.NunjucksUtils = new NunjucksUtils();
})();

View file

@ -0,0 +1,6 @@
<tr>
<td class="d2h-code-linenumber {{ diffParser.LINE_TYPE.INFO }}"></td>
<td class="{{ diffParser.LINE_TYPE.INFO }}">
<div class="d2h-code-line {{ diffParser.LINE_TYPE.INFO }}"> {{ utils.escape(block.header) }} </div>
</td>
</tr>

View file

@ -0,0 +1,7 @@
<tr>
<td class="{{ diffParser.LINE_TYPE.INFO }}">
<div class="d2h-code-line {{ diffParser.LINE_TYPE.INFO }}">
File without changes
</div>
</td>
</tr>

View file

@ -0,0 +1,22 @@
<div id="{{ printerUtils.getHtmlId(file) }}" class="d2h-file-wrapper" data-lang="{{ file.language }}">
<div class="d2h-file-header">
<div class="d2h-file-stats">
<span class="d2h-lines-added">
<span>+{{ file.addedLines }}</span>
</span>
<span class="d2h-lines-deleted">
<span>-{{ file.deletedLines }}</span>
</span>
</div>
<div class="d2h-file-name">&nbsp;{{ printerUtils.getDiffName(file) }}</div>
</div>
<div class="d2h-file-diff">
<div class="d2h-code-wrapper">
<table class="d2h-diff-table">
<tbody class="d2h-diff-tbody">
{{ diffs | safe}}
</tbody>
</table>
</div>
</div>
</div>

View file

@ -0,0 +1,16 @@
<tr>
<td class="d2h-code-linenumber {{ type }}">
<div class="line-num1">{{ utils.valueOrEmpty(oldNumber) | safe }}</div>
<div class="line-num2">{{ utils.valueOrEmpty(newNumber) | safe }}</div>
</td>
<td class="{{ type }}">
<div class="d2h-code-line {{ type }}">
{% if prefix %}
<span class="d2h-code-line-prefix">{{ utils.convertWhiteSpaceToNonBreakingSpace(prefix) | safe }}</span>
{% endif %}
{% if content %}
<span class="d2h-code-line-ctn">{{ utils.convertWhiteSpaceToNonBreakingSpace(content) | safe }}</span>
{% endif %}
</div>
</td>
</tr>

View file

@ -0,0 +1,3 @@
<div class="d2h-wrapper">
{{ content }}
</div>

View file

@ -69,11 +69,14 @@
border-collapse: collapse;
font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
font-size: 12px;
height: 18px;
line-height: 18px;
width: 100%;
}
.d2h-diff-tbody > tr > td > div {
height: 16px;
line-height: 16px;
}
.d2h-files-diff {
width: 100%;
}
@ -93,9 +96,9 @@
.d2h-code-line {
display: block;
white-space: pre;
padding: 0 10px;
height: 18px;
white-space: nowrap;
line-height: 18px;
margin-left: 80px;
/* Override HighlightJS */

View file

@ -68,8 +68,6 @@
var languages = that._getLanguages($target);
console.log(languages);
// pass the languages to the highlightjs plugin
hljs.configure({languages: languages});
@ -100,18 +98,13 @@
return line.language;
});
} else {
console.log($target.find(".d2h-file-wrapper"));
$target.find(".d2h-file-wrapper").map(function(i, file) {
allFileLanguages.push($(file).data("lang"));
});
}
// remove duplicated languages
var distinctLanguages = allFileLanguages.filter(function(v, i) {
return allFileLanguages.indexOf(v) === i;
});
return distinctLanguages;
// return only distinct languages
return this._distinct(allFileLanguages);
};
Diff2HtmlUI.prototype._getHashTag = function() {
@ -119,13 +112,19 @@
var hashTagIndex = docUrl.indexOf('#');
var hashTag = null;
if (hashTagIndex != -1) {
if (hashTagIndex !== -1) {
hashTag = docUrl.substr(hashTagIndex + 1);
}
return hashTag;
};
Diff2HtmlUI.prototype._distinct = function(collection) {
return collection.filter(function(v, i) {
return collection.indexOf(v) === i;
});
};
module.exports.Diff2HtmlUI = Diff2HtmlUI;
// Expose diff2html in the browser

View file

@ -10,6 +10,10 @@
function Utils() {
}
Utils.prototype.convertWhiteSpaceToNonBreakingSpace = function(str) {
return str.slice(0).replace(/ /g, '&nbsp;');
};
Utils.prototype.escape = function(str) {
return str.slice(0)
.replace(/&/g, '&amp;')

View file

@ -1,4 +1,5 @@
var assert = require('assert');
var Utils = require('../src/utils.js').Utils;
var LineByLinePrinter = require('../src/line-by-line-printer.js').LineByLinePrinter;
@ -9,32 +10,34 @@ describe('LineByLinePrinter', function() {
var lineByLinePrinter = new LineByLinePrinter({});
var fileHtml = lineByLinePrinter._generateEmptyDiff();
var expected = '<tr>\n' +
' <td class="d2h-info">' +
' <div class="d2h-code-line d2h-info">' +
'File without changes' +
' </div>' +
' <td class="d2h-info">\n' +
' <div class="d2h-code-line d2h-info">\n' +
' File without changes\n' +
' </div>\n' +
' </td>\n' +
'</tr>\n';
assert.equal(expected, fileHtml);
});
});
describe('_generateLineHtml', function() {
describe('makeLineHtml', function() {
it('should work for insertions', function() {
var diffParser = require('../src/diff-parser.js').DiffParser;
var lineByLinePrinter = new LineByLinePrinter({});
var fileHtml = lineByLinePrinter._generateLineHtml(
var fileHtml = lineByLinePrinter.makeLineHtml(
diffParser.LINE_TYPE.INSERTS, '', 30, '+', 'test');
fileHtml = fileHtml.replace(/\n\n+/g, '\n');
var expected = '<tr>\n' +
' <td class="d2h-code-linenumber d2h-ins">' +
' <div class="line-num1"></div>' +
' <div class="line-num2">30</div>' +
' <td class="d2h-code-linenumber d2h-ins">\n' +
' <div class="line-num1"></div>\n' +
' <div class="line-num2">30</div>\n' +
' </td>\n' +
' <td class="d2h-ins">' +
' <div class="d2h-code-line d2h-ins">' +
'<span class="d2h-code-line-prefix">test</span>' +
'<span class="d2h-code-line-ctn">+</span></div>' +
' <td class="d2h-ins">\n' +
' <div class="d2h-code-line d2h-ins">\n' +
' <span class="d2h-code-line-prefix">test</span>\n' +
' <span class="d2h-code-line-ctn">+</span>\n' +
' </div>\n' +
' </td>\n' +
'</tr>\n';
@ -44,17 +47,85 @@ describe('LineByLinePrinter', function() {
var diffParser = require('../src/diff-parser.js').DiffParser;
var lineByLinePrinter = new LineByLinePrinter({});
var fileHtml = lineByLinePrinter._generateLineHtml(
var fileHtml = lineByLinePrinter.makeLineHtml(
diffParser.LINE_TYPE.DELETES, 30, '', '-', 'test');
fileHtml = fileHtml.replace(/\n\n+/g, '\n');
var expected = '<tr>\n' +
' <td class="d2h-code-linenumber d2h-del">' +
' <div class="line-num1">30</div>' +
' <div class="line-num2"></div>' +
' <td class="d2h-code-linenumber d2h-del">\n' +
' <div class="line-num1">30</div>\n' +
' <div class="line-num2"></div>\n' +
' </td>\n' +
' <td class="d2h-del">' +
' <div class="d2h-code-line d2h-del">' +
'<span class="d2h-code-line-prefix">test</span>' +
'<span class="d2h-code-line-ctn">-</span></div>' +
' <td class="d2h-del">\n' +
' <div class="d2h-code-line d2h-del">\n' +
' <span class="d2h-code-line-prefix">test</span>\n' +
' <span class="d2h-code-line-ctn">-</span>\n' +
' </div>\n' +
' </td>\n' +
'</tr>\n';
assert.equal(expected, fileHtml);
});
it('should convert indents into non breakin spaces (2 white spaces)', function() {
var diffParser = require('../src/diff-parser.js').DiffParser;
var lineByLinePrinter = new LineByLinePrinter({});
var fileHtml = lineByLinePrinter.makeLineHtml(
diffParser.LINE_TYPE.INSERTS, '', 30, '+', ' test');
fileHtml = fileHtml.replace(/\n\n+/g, '\n');
var expected = '<tr>\n' +
' <td class="d2h-code-linenumber d2h-ins">\n' +
' <div class="line-num1"></div>\n' +
' <div class="line-num2">30</div>\n' +
' </td>\n' +
' <td class="d2h-ins">\n' +
' <div class="d2h-code-line d2h-ins">\n' +
' <span class="d2h-code-line-prefix">&nbsp;&nbsp;test</span>\n' +
' <span class="d2h-code-line-ctn">+</span>\n' +
' </div>\n' +
' </td>\n' +
'</tr>\n';
assert.equal(expected, fileHtml);
});
it('should convert indents into non breakin spaces (4 white spaces)', function() {
var diffParser = require('../src/diff-parser.js').DiffParser;
var lineByLinePrinter = new LineByLinePrinter({});
var fileHtml = lineByLinePrinter.makeLineHtml(
diffParser.LINE_TYPE.INSERTS, '', 30, '+', ' test');
fileHtml = fileHtml.replace(/\n\n+/g, '\n');
var expected = '<tr>\n' +
' <td class="d2h-code-linenumber d2h-ins">\n' +
' <div class="line-num1"></div>\n' +
' <div class="line-num2">30</div>\n' +
' </td>\n' +
' <td class="d2h-ins">\n' +
' <div class="d2h-code-line d2h-ins">\n' +
' <span class="d2h-code-line-prefix">&nbsp;&nbsp;&nbsp;&nbsp;test</span>\n' +
' <span class="d2h-code-line-ctn">+</span>\n' +
' </div>\n' +
' </td>\n' +
'</tr>\n';
assert.equal(expected, fileHtml);
});
it('should convert indents into non breakin spaces (one tab)', function() {
var diffParser = require('../src/diff-parser.js').DiffParser;
var lineByLinePrinter = new LineByLinePrinter({});
var fileHtml = lineByLinePrinter.makeLineHtml(
diffParser.LINE_TYPE.INSERTS, '', 30, '+', Utils.escape('\ttest'));
fileHtml = fileHtml.replace(/\n\n+/g, '\n');
var expected = '<tr>\n' +
' <td class="d2h-code-linenumber d2h-ins">\n' +
' <div class="line-num1"></div>\n' +
' <div class="line-num2">30</div>\n' +
' </td>\n' +
' <td class="d2h-ins">\n' +
' <div class="d2h-code-line d2h-ins">\n' +
' <span class="d2h-code-line-prefix">&nbsp;&nbsp;&nbsp;&nbsp;test</span>\n' +
' <span class="d2h-code-line-ctn">+</span>\n' +
' </div>\n' +
' </td>\n' +
'</tr>\n';

View file

@ -22,4 +22,18 @@ describe('Utils', function() {
assert.equal(expected, result);
});
});
describe('convertWhiteSpaceToNonBreakingSpace', function() {
it('should escape 1 whitespaces with &nbsp;', function() {
var result = Utils.convertWhiteSpaceToNonBreakingSpace(' ');
assert.equal('&nbsp;', result);
});
it('should escape 2 whitespaces with &nbsp;', function() {
var result = Utils.convertWhiteSpaceToNonBreakingSpace(' ');
assert.equal('&nbsp;&nbsp;', result);
});
it('should escape 4 whitespaces with &nbsp;', function() {
var result = Utils.convertWhiteSpaceToNonBreakingSpace(' ');
assert.equal('&nbsp;&nbsp;&nbsp;&nbsp;', result);
});
});
});

View file

@ -5,6 +5,16 @@ module.exports = {
plugins: [
new webpack.NormalModuleReplacementPlugin(
/(nunjucks)$/,
'nunjucks/index'
),
new webpack.NormalModuleReplacementPlugin(
/(precompile|nodes|lexer|parser|transformer|compiler|loaders)$/,
'node-libs-browser/mock/empty'
),
new webpack.DefinePlugin({
'process.env': {
IS_BROWSER: true