refactor: Initial migration to typescript
This commit is contained in:
parent
5fe55be6f3
commit
a8b9b2b49a
63 changed files with 5197 additions and 11130 deletions
|
|
@ -29,14 +29,14 @@ jobs:
|
||||||
key: dependency-cache-{{ checksum "yarn.lock" }}
|
key: dependency-cache-{{ checksum "yarn.lock" }}
|
||||||
paths:
|
paths:
|
||||||
- ./node_modules
|
- ./node_modules
|
||||||
- run: yarn run test
|
|
||||||
- run: yarn run lint
|
- run: yarn run lint
|
||||||
|
- run: yarn run coverage
|
||||||
- run: yarn run codacy
|
- run: yarn run codacy
|
||||||
- persist_to_workspace:
|
- persist_to_workspace:
|
||||||
root: ~/diff2html
|
root: ~/diff2html
|
||||||
paths:
|
paths:
|
||||||
- docs
|
- docs
|
||||||
- dist
|
- build
|
||||||
|
|
||||||
build-node_4:
|
build-node_4:
|
||||||
<<: *common-build
|
<<: *common-build
|
||||||
|
|
@ -80,11 +80,6 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- attach_workspace:
|
- attach_workspace:
|
||||||
at: .
|
at: .
|
||||||
- run:
|
|
||||||
name: Prepare website sources
|
|
||||||
command: |
|
|
||||||
rm -f docs/assets
|
|
||||||
mv dist docs/assets
|
|
||||||
- run:
|
- run:
|
||||||
name: Deploy
|
name: Deploy
|
||||||
working_directory: ~/diff2html/docs
|
working_directory: ~/diff2html/docs
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,6 @@
|
||||||
# Skip coverage and build folders
|
# Skip build results
|
||||||
coverage/**
|
coverage/**
|
||||||
dist/**
|
build/**
|
||||||
|
|
||||||
# Ignore symlink to build folder
|
|
||||||
docs/**
|
docs/**
|
||||||
|
node_modules/**
|
||||||
# Ignore HTML templates generated code
|
src/diff2html-templates.js
|
||||||
src/**
|
|
||||||
!src/*.js
|
|
||||||
!src/ui/js/*.js
|
|
||||||
|
|
|
||||||
330
.eslintrc.json
330
.eslintrc.json
|
|
@ -1,10 +1,12 @@
|
||||||
{
|
{
|
||||||
|
"parser": "@typescript-eslint/parser",
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
"ecmaVersion": 6,
|
"ecmaVersion": 2018,
|
||||||
|
"sourceType": "module",
|
||||||
"ecmaFeatures": {
|
"ecmaFeatures": {
|
||||||
|
"experimentalObjectRestSpread": true,
|
||||||
"jsx": true
|
"jsx": true
|
||||||
},
|
}
|
||||||
"sourceType": "module"
|
|
||||||
},
|
},
|
||||||
"env": {
|
"env": {
|
||||||
"es6": true,
|
"es6": true,
|
||||||
|
|
@ -19,325 +21,17 @@
|
||||||
"worker": true,
|
"worker": true,
|
||||||
"qunit": true
|
"qunit": true
|
||||||
},
|
},
|
||||||
"plugins": [
|
"plugins": ["standard", "node", "import", "promise", "@typescript-eslint", "jest"],
|
||||||
"standard",
|
|
||||||
"promise"
|
|
||||||
],
|
|
||||||
"globals": {
|
"globals": {
|
||||||
"document": false,
|
"document": false,
|
||||||
"navigator": false,
|
"navigator": false,
|
||||||
"window": false
|
"window": false
|
||||||
},
|
},
|
||||||
"rules": {
|
"extends": [
|
||||||
"accessor-pairs": 2,
|
"plugin:@typescript-eslint/recommended",
|
||||||
"arrow-spacing": [
|
"plugin:jest/recommended",
|
||||||
2,
|
"plugin:promise/recommended",
|
||||||
{
|
"standard",
|
||||||
"before": true,
|
"plugin:prettier/recommended"
|
||||||
"after": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"block-spacing": [
|
|
||||||
2,
|
|
||||||
"always"
|
|
||||||
],
|
|
||||||
"brace-style": [
|
|
||||||
2,
|
|
||||||
"1tbs",
|
|
||||||
{
|
|
||||||
"allowSingleLine": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"camelcase": [
|
|
||||||
2,
|
|
||||||
{
|
|
||||||
"properties": "never"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"comma-dangle": [
|
|
||||||
2,
|
|
||||||
"never"
|
|
||||||
],
|
|
||||||
"comma-spacing": [
|
|
||||||
2,
|
|
||||||
{
|
|
||||||
"before": false,
|
|
||||||
"after": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"comma-style": [
|
|
||||||
2,
|
|
||||||
"last"
|
|
||||||
],
|
|
||||||
"constructor-super": 2,
|
|
||||||
"curly": [
|
|
||||||
2,
|
|
||||||
"multi-line"
|
|
||||||
],
|
|
||||||
"dot-location": [
|
|
||||||
2,
|
|
||||||
"property"
|
|
||||||
],
|
|
||||||
"eol-last": 2,
|
|
||||||
"eqeqeq": [
|
|
||||||
2,
|
|
||||||
"allow-null"
|
|
||||||
],
|
|
||||||
"generator-star-spacing": [
|
|
||||||
2,
|
|
||||||
{
|
|
||||||
"before": true,
|
|
||||||
"after": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"handle-callback-err": [
|
|
||||||
2,
|
|
||||||
"^(err|error)$"
|
|
||||||
],
|
|
||||||
"indent": [
|
|
||||||
2,
|
|
||||||
2,
|
|
||||||
{
|
|
||||||
"SwitchCase": 1
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"jsx-quotes": [
|
|
||||||
2,
|
|
||||||
"prefer-single"
|
|
||||||
],
|
|
||||||
"key-spacing": [
|
|
||||||
2,
|
|
||||||
{
|
|
||||||
"beforeColon": false,
|
|
||||||
"afterColon": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"keyword-spacing": [
|
|
||||||
2,
|
|
||||||
{
|
|
||||||
"before": true,
|
|
||||||
"after": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"new-cap": [
|
|
||||||
2,
|
|
||||||
{
|
|
||||||
"newIsCap": true,
|
|
||||||
"capIsNew": false
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"new-parens": 2,
|
|
||||||
"no-array-constructor": 2,
|
|
||||||
"no-caller": 2,
|
|
||||||
"no-class-assign": 2,
|
|
||||||
"no-cond-assign": 2,
|
|
||||||
"no-const-assign": 2,
|
|
||||||
"no-control-regex": 2,
|
|
||||||
"no-debugger": 2,
|
|
||||||
"no-delete-var": 2,
|
|
||||||
"no-dupe-args": 2,
|
|
||||||
"no-dupe-class-members": 2,
|
|
||||||
"no-dupe-keys": 2,
|
|
||||||
"no-duplicate-case": 2,
|
|
||||||
"no-duplicate-imports": 2,
|
|
||||||
"no-empty-character-class": 2,
|
|
||||||
"no-empty-pattern": 2,
|
|
||||||
"no-eval": 2,
|
|
||||||
"no-ex-assign": 2,
|
|
||||||
"no-extend-native": 2,
|
|
||||||
"no-extra-bind": 2,
|
|
||||||
"no-extra-boolean-cast": 2,
|
|
||||||
"no-extra-parens": [
|
|
||||||
2,
|
|
||||||
"functions"
|
|
||||||
],
|
|
||||||
"no-fallthrough": 2,
|
|
||||||
"no-floating-decimal": 2,
|
|
||||||
"no-func-assign": 2,
|
|
||||||
"no-implied-eval": 2,
|
|
||||||
"no-inner-declarations": [
|
|
||||||
2,
|
|
||||||
"functions"
|
|
||||||
],
|
|
||||||
"no-invalid-regexp": 2,
|
|
||||||
"no-irregular-whitespace": 2,
|
|
||||||
"no-iterator": 2,
|
|
||||||
"no-label-var": 2,
|
|
||||||
"no-labels": [
|
|
||||||
2,
|
|
||||||
{
|
|
||||||
"allowLoop": false,
|
|
||||||
"allowSwitch": false
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"no-lone-blocks": 2,
|
|
||||||
"no-mixed-spaces-and-tabs": 2,
|
|
||||||
"no-multi-spaces": 2,
|
|
||||||
"no-multi-str": 2,
|
|
||||||
"no-multiple-empty-lines": [
|
|
||||||
2,
|
|
||||||
{
|
|
||||||
"max": 1
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"no-native-reassign": 2,
|
|
||||||
"no-negated-in-lhs": 2,
|
|
||||||
"no-new": 2,
|
|
||||||
"no-new-func": 2,
|
|
||||||
"no-new-object": 2,
|
|
||||||
"no-new-require": 2,
|
|
||||||
"no-new-symbol": 2,
|
|
||||||
"no-new-wrappers": 2,
|
|
||||||
"no-obj-calls": 2,
|
|
||||||
"no-octal": 2,
|
|
||||||
"no-octal-escape": 2,
|
|
||||||
"no-path-concat": 2,
|
|
||||||
"no-proto": 2,
|
|
||||||
"no-redeclare": 2,
|
|
||||||
"no-regex-spaces": 2,
|
|
||||||
"no-return-assign": [
|
|
||||||
2,
|
|
||||||
"except-parens"
|
|
||||||
],
|
|
||||||
"no-self-assign": 2,
|
|
||||||
"no-self-compare": 2,
|
|
||||||
"no-sequences": 2,
|
|
||||||
"no-shadow-restricted-names": 2,
|
|
||||||
"no-spaced-func": 2,
|
|
||||||
"no-sparse-arrays": 2,
|
|
||||||
"no-this-before-super": 2,
|
|
||||||
"no-throw-literal": 2,
|
|
||||||
"no-trailing-spaces": 2,
|
|
||||||
"no-undef": 2,
|
|
||||||
"no-undef-init": 2,
|
|
||||||
"no-unexpected-multiline": 2,
|
|
||||||
"no-unmodified-loop-condition": 2,
|
|
||||||
"no-unneeded-ternary": [
|
|
||||||
2,
|
|
||||||
{
|
|
||||||
"defaultAssignment": false
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"no-unreachable": 2,
|
|
||||||
"no-unsafe-finally": 2,
|
|
||||||
"no-unused-vars": [
|
|
||||||
2,
|
|
||||||
{
|
|
||||||
"vars": "all",
|
|
||||||
"args": "none"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"no-useless-call": 2,
|
|
||||||
"no-useless-computed-key": 2,
|
|
||||||
"no-useless-constructor": 2,
|
|
||||||
"no-useless-escape": 2,
|
|
||||||
"no-whitespace-before-property": 2,
|
|
||||||
"no-with": 2,
|
|
||||||
"one-var": [
|
|
||||||
2,
|
|
||||||
{
|
|
||||||
"initialized": "never"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"operator-linebreak": [
|
|
||||||
2,
|
|
||||||
"after",
|
|
||||||
{
|
|
||||||
"overrides": {
|
|
||||||
"?": "before",
|
|
||||||
":": "before"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"padded-blocks": [
|
|
||||||
2,
|
|
||||||
"never"
|
|
||||||
],
|
|
||||||
"quotes": [
|
|
||||||
2,
|
|
||||||
"single",
|
|
||||||
"avoid-escape"
|
|
||||||
],
|
|
||||||
"semi": [
|
|
||||||
2,
|
|
||||||
"always"
|
|
||||||
],
|
|
||||||
"semi-spacing": [
|
|
||||||
2,
|
|
||||||
{
|
|
||||||
"before": false,
|
|
||||||
"after": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"space-before-blocks": [
|
|
||||||
2,
|
|
||||||
"always"
|
|
||||||
],
|
|
||||||
"space-before-function-paren": [
|
|
||||||
2,
|
|
||||||
"never"
|
|
||||||
],
|
|
||||||
"space-in-parens": [
|
|
||||||
2,
|
|
||||||
"never"
|
|
||||||
],
|
|
||||||
"space-infix-ops": 2,
|
|
||||||
"space-unary-ops": [
|
|
||||||
2,
|
|
||||||
{
|
|
||||||
"words": true,
|
|
||||||
"nonwords": false
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"spaced-comment": [
|
|
||||||
2,
|
|
||||||
"always",
|
|
||||||
{
|
|
||||||
"markers": [
|
|
||||||
"global",
|
|
||||||
"globals",
|
|
||||||
"eslint",
|
|
||||||
"eslint-disable",
|
|
||||||
"*package",
|
|
||||||
"!",
|
|
||||||
","
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
|
||||||
"template-curly-spacing": [
|
|
||||||
2,
|
|
||||||
"never"
|
|
||||||
],
|
|
||||||
"use-isnan": 2,
|
|
||||||
"valid-typeof": 2,
|
|
||||||
"wrap-iife": [
|
|
||||||
2,
|
|
||||||
"any"
|
|
||||||
],
|
|
||||||
"yield-star-spacing": [
|
|
||||||
2,
|
|
||||||
"both"
|
|
||||||
],
|
|
||||||
"yoda": [
|
|
||||||
2,
|
|
||||||
"never"
|
|
||||||
],
|
|
||||||
"standard/object-curly-even-spacing": [
|
|
||||||
2,
|
|
||||||
"either"
|
|
||||||
],
|
|
||||||
"standard/array-bracket-even-spacing": [
|
|
||||||
2,
|
|
||||||
"either"
|
|
||||||
],
|
|
||||||
"standard/computed-property-even-spacing": [
|
|
||||||
2,
|
|
||||||
"even"
|
|
||||||
],
|
|
||||||
"promise/param-names": 2,
|
|
||||||
"linebreak-style": [
|
|
||||||
2,
|
|
||||||
"unix"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
5
.gitignore
vendored
5
.gitignore
vendored
|
|
@ -28,3 +28,8 @@ bower_components/
|
||||||
|
|
||||||
# Terraform
|
# Terraform
|
||||||
/terraform/.terraform
|
/terraform/.terraform
|
||||||
|
|
||||||
|
/docs/
|
||||||
|
/dist/
|
||||||
|
/build/
|
||||||
|
/src/diff2html-templates.js
|
||||||
|
|
|
||||||
366
dist/diff2html-ui.js
vendored
366
dist/diff2html-ui.js
vendored
|
|
@ -1,366 +0,0 @@
|
||||||
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
|
|
||||||
(function (global){
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
* Diff to HTML (diff2html-ui.js)
|
|
||||||
* Author: rtfpessoa
|
|
||||||
*
|
|
||||||
* Depends on: [ jQuery ]
|
|
||||||
* Optional dependencies on: [ highlight.js ]
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*global $, hljs, Diff2Html*/
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
var highlightJS = require('./highlight.js-internals.js').HighlightJS;
|
|
||||||
|
|
||||||
var diffJson = null;
|
|
||||||
var defaultTarget = 'body';
|
|
||||||
var currentSelectionColumnId = -1;
|
|
||||||
|
|
||||||
function Diff2HtmlUI(config) {
|
|
||||||
var cfg = config || {};
|
|
||||||
|
|
||||||
if (cfg.diff) {
|
|
||||||
diffJson = Diff2Html.getJsonFromDiff(cfg.diff);
|
|
||||||
} else if (cfg.json) {
|
|
||||||
diffJson = cfg.json;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._initSelection();
|
|
||||||
}
|
|
||||||
|
|
||||||
Diff2HtmlUI.prototype.draw = function(targetId, config) {
|
|
||||||
var cfg = config || {};
|
|
||||||
cfg.inputFormat = 'json';
|
|
||||||
var $target = this._getTarget(targetId);
|
|
||||||
$target.html(Diff2Html.getPrettyHtml(diffJson, cfg));
|
|
||||||
|
|
||||||
if (cfg.synchronisedScroll) {
|
|
||||||
this.synchronisedScroll($target, cfg);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Diff2HtmlUI.prototype.synchronisedScroll = function(targetId) {
|
|
||||||
var $target = this._getTarget(targetId);
|
|
||||||
$target.find('.d2h-file-side-diff').scroll(function() {
|
|
||||||
var $this = $(this);
|
|
||||||
$this.closest('.d2h-file-wrapper').find('.d2h-file-side-diff')
|
|
||||||
.scrollLeft($this.scrollLeft());
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
Diff2HtmlUI.prototype.fileListCloseable = function(targetId, startVisible) {
|
|
||||||
var $target = this._getTarget(targetId);
|
|
||||||
|
|
||||||
var hashTag = this._getHashTag();
|
|
||||||
|
|
||||||
var $showBtn = $target.find('.d2h-show');
|
|
||||||
var $hideBtn = $target.find('.d2h-hide');
|
|
||||||
var $fileList = $target.find('.d2h-file-list');
|
|
||||||
|
|
||||||
if (hashTag === 'files-summary-show') show();
|
|
||||||
else if (hashTag === 'files-summary-hide') hide();
|
|
||||||
else if (startVisible) show();
|
|
||||||
else hide();
|
|
||||||
|
|
||||||
$showBtn.click(show);
|
|
||||||
$hideBtn.click(hide);
|
|
||||||
|
|
||||||
function show() {
|
|
||||||
$showBtn.hide();
|
|
||||||
$hideBtn.show();
|
|
||||||
$fileList.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
function hide() {
|
|
||||||
$hideBtn.hide();
|
|
||||||
$showBtn.show();
|
|
||||||
$fileList.hide();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Diff2HtmlUI.prototype.highlightCode = function(targetId) {
|
|
||||||
var that = this;
|
|
||||||
|
|
||||||
var $target = that._getTarget(targetId);
|
|
||||||
|
|
||||||
// collect all the diff files and execute the highlight on their lines
|
|
||||||
var $files = $target.find('.d2h-file-wrapper');
|
|
||||||
$files.map(function(_i, file) {
|
|
||||||
var oldLinesState;
|
|
||||||
var newLinesState;
|
|
||||||
var $file = $(file);
|
|
||||||
var language = $file.data('lang');
|
|
||||||
|
|
||||||
// collect all the code lines and execute the highlight on them
|
|
||||||
var $codeLines = $file.find('.d2h-code-line-ctn');
|
|
||||||
$codeLines.map(function(_j, line) {
|
|
||||||
var $line = $(line);
|
|
||||||
var text = line.textContent;
|
|
||||||
var lineParent = line.parentNode;
|
|
||||||
|
|
||||||
var lineState;
|
|
||||||
if (lineParent.className.indexOf('d2h-del') !== -1) {
|
|
||||||
lineState = oldLinesState;
|
|
||||||
} else {
|
|
||||||
lineState = newLinesState;
|
|
||||||
}
|
|
||||||
|
|
||||||
var result = hljs.getLanguage(language) ? hljs.highlight(language, text, true, lineState) : hljs.highlightAuto(text);
|
|
||||||
|
|
||||||
if (lineParent.className.indexOf('d2h-del') !== -1) {
|
|
||||||
oldLinesState = result.top;
|
|
||||||
} else if (lineParent.className.indexOf('d2h-ins') !== -1) {
|
|
||||||
newLinesState = result.top;
|
|
||||||
} else {
|
|
||||||
oldLinesState = result.top;
|
|
||||||
newLinesState = result.top;
|
|
||||||
}
|
|
||||||
|
|
||||||
var originalStream = highlightJS.nodeStream(line);
|
|
||||||
if (originalStream.length) {
|
|
||||||
var resultNode = document.createElementNS('http://www.w3.org/1999/xhtml', 'div');
|
|
||||||
resultNode.innerHTML = result.value;
|
|
||||||
result.value = highlightJS.mergeStreams(originalStream, highlightJS.nodeStream(resultNode), text);
|
|
||||||
}
|
|
||||||
|
|
||||||
$line.addClass('hljs');
|
|
||||||
$line.addClass(result.language);
|
|
||||||
$line.html(result.value);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
Diff2HtmlUI.prototype._getTarget = function(targetId) {
|
|
||||||
var $target;
|
|
||||||
|
|
||||||
if (typeof targetId === 'object' && targetId instanceof jQuery) {
|
|
||||||
$target = targetId;
|
|
||||||
} else if (typeof targetId === 'string') {
|
|
||||||
$target = $(targetId);
|
|
||||||
} else {
|
|
||||||
console.error("Wrong target provided! Falling back to default value 'body'.");
|
|
||||||
console.log('Please provide a jQuery object or a valid DOM query string.');
|
|
||||||
$target = $(defaultTarget);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $target;
|
|
||||||
};
|
|
||||||
|
|
||||||
Diff2HtmlUI.prototype._getHashTag = function() {
|
|
||||||
var docUrl = document.URL;
|
|
||||||
var hashTagIndex = docUrl.indexOf('#');
|
|
||||||
|
|
||||||
var hashTag = null;
|
|
||||||
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;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
Diff2HtmlUI.prototype._initSelection = function() {
|
|
||||||
var body = $('body');
|
|
||||||
var that = this;
|
|
||||||
|
|
||||||
body.on('mousedown', '.d2h-diff-table', function(event) {
|
|
||||||
var target = $(event.target);
|
|
||||||
var table = target.closest('.d2h-diff-table');
|
|
||||||
|
|
||||||
if (target.closest('.d2h-code-line,.d2h-code-side-line').length) {
|
|
||||||
table.removeClass('selecting-left');
|
|
||||||
table.addClass('selecting-right');
|
|
||||||
currentSelectionColumnId = 1;
|
|
||||||
} else if (target.closest('.d2h-code-linenumber,.d2h-code-side-linenumber').length) {
|
|
||||||
table.removeClass('selecting-right');
|
|
||||||
table.addClass('selecting-left');
|
|
||||||
currentSelectionColumnId = 0;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
body.on('copy', '.d2h-diff-table', function(event) {
|
|
||||||
var clipboardData = event.originalEvent.clipboardData;
|
|
||||||
var text = that._getSelectedText();
|
|
||||||
clipboardData.setData('text', text);
|
|
||||||
event.preventDefault();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
Diff2HtmlUI.prototype._getSelectedText = function() {
|
|
||||||
var sel = window.getSelection();
|
|
||||||
var range = sel.getRangeAt(0);
|
|
||||||
var doc = range.cloneContents();
|
|
||||||
var nodes = doc.querySelectorAll('tr');
|
|
||||||
var text = '';
|
|
||||||
var idx = currentSelectionColumnId;
|
|
||||||
|
|
||||||
if (nodes.length === 0) {
|
|
||||||
text = doc.textContent;
|
|
||||||
} else {
|
|
||||||
[].forEach.call(nodes, function(tr, i) {
|
|
||||||
var td = tr.cells[tr.cells.length === 1 ? 0 : idx];
|
|
||||||
text += (i ? '\n' : '') + td.textContent.replace(/(?:\r\n|\r|\n)/g, '');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return text;
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports.Diff2HtmlUI = Diff2HtmlUI;
|
|
||||||
|
|
||||||
// Expose diff2html in the browser
|
|
||||||
global.Diff2HtmlUI = Diff2HtmlUI;
|
|
||||||
})();
|
|
||||||
|
|
||||||
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
|
||||||
},{"./highlight.js-internals.js":2}],2:[function(require,module,exports){
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
* highlight.js
|
|
||||||
* Author: isagalaev
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
function HighlightJS() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copied from Highlight.js Private API
|
|
||||||
* Will be removed when this part of the API is exposed
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Utility vars */
|
|
||||||
|
|
||||||
var ArrayProto = [];
|
|
||||||
|
|
||||||
/* Utility functions */
|
|
||||||
|
|
||||||
function escape(value) {
|
|
||||||
return value.replace(/&/gm, '&').replace(/</gm, '<').replace(/>/gm, '>');
|
|
||||||
}
|
|
||||||
|
|
||||||
function tag(node) {
|
|
||||||
return node.nodeName.toLowerCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Stream merging */
|
|
||||||
|
|
||||||
HighlightJS.prototype.nodeStream = function(node) {
|
|
||||||
var result = [];
|
|
||||||
(function _nodeStream(node, offset) {
|
|
||||||
for (var child = node.firstChild; child; child = child.nextSibling) {
|
|
||||||
if (child.nodeType === 3) {
|
|
||||||
offset += child.nodeValue.length;
|
|
||||||
} else if (child.nodeType === 1) {
|
|
||||||
result.push({
|
|
||||||
event: 'start',
|
|
||||||
offset: offset,
|
|
||||||
node: child
|
|
||||||
});
|
|
||||||
offset = _nodeStream(child, offset);
|
|
||||||
// Prevent void elements from having an end tag that would actually
|
|
||||||
// double them in the output. There are more void elements in HTML
|
|
||||||
// but we list only those realistically expected in code display.
|
|
||||||
if (!tag(child).match(/br|hr|img|input/)) {
|
|
||||||
result.push({
|
|
||||||
event: 'stop',
|
|
||||||
offset: offset,
|
|
||||||
node: child
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return offset;
|
|
||||||
})(node, 0);
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
HighlightJS.prototype.mergeStreams = function(original, highlighted, value) {
|
|
||||||
var processed = 0;
|
|
||||||
var result = '';
|
|
||||||
var nodeStack = [];
|
|
||||||
|
|
||||||
function selectStream() {
|
|
||||||
if (!original.length || !highlighted.length) {
|
|
||||||
return original.length ? original : highlighted;
|
|
||||||
}
|
|
||||||
if (original[0].offset !== highlighted[0].offset) {
|
|
||||||
return (original[0].offset < highlighted[0].offset) ? original : highlighted;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
To avoid starting the stream just before it should stop the order is
|
|
||||||
ensured that original always starts first and closes last:
|
|
||||||
if (event1 == 'start' && event2 == 'start')
|
|
||||||
return original;
|
|
||||||
if (event1 == 'start' && event2 == 'stop')
|
|
||||||
return highlighted;
|
|
||||||
if (event1 == 'stop' && event2 == 'start')
|
|
||||||
return original;
|
|
||||||
if (event1 == 'stop' && event2 == 'stop')
|
|
||||||
return highlighted;
|
|
||||||
... which is collapsed to:
|
|
||||||
*/
|
|
||||||
return highlighted[0].event === 'start' ? original : highlighted;
|
|
||||||
}
|
|
||||||
|
|
||||||
function open(node) {
|
|
||||||
function attr_str(a) {
|
|
||||||
return ' ' + a.nodeName + '="' + escape(a.value) + '"';
|
|
||||||
}
|
|
||||||
|
|
||||||
result += '<' + tag(node) + ArrayProto.map.call(node.attributes, attr_str).join('') + '>';
|
|
||||||
}
|
|
||||||
|
|
||||||
function close(node) {
|
|
||||||
result += '</' + tag(node) + '>';
|
|
||||||
}
|
|
||||||
|
|
||||||
function render(event) {
|
|
||||||
(event.event === 'start' ? open : close)(event.node);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (original.length || highlighted.length) {
|
|
||||||
var stream = selectStream();
|
|
||||||
result += escape(value.substring(processed, stream[0].offset));
|
|
||||||
processed = stream[0].offset;
|
|
||||||
if (stream === original) {
|
|
||||||
/*
|
|
||||||
On any opening or closing tag of the original markup we first close
|
|
||||||
the entire highlighted node stack, then render the original tag along
|
|
||||||
with all the following original tags at the same offset and then
|
|
||||||
reopen all the tags on the highlighted stack.
|
|
||||||
*/
|
|
||||||
nodeStack.reverse().forEach(close);
|
|
||||||
do {
|
|
||||||
render(stream.splice(0, 1)[0]);
|
|
||||||
stream = selectStream();
|
|
||||||
} while (stream === original && stream.length && stream[0].offset === processed);
|
|
||||||
nodeStack.reverse().forEach(open);
|
|
||||||
} else {
|
|
||||||
if (stream[0].event === 'start') {
|
|
||||||
nodeStack.push(stream[0].node);
|
|
||||||
} else {
|
|
||||||
nodeStack.pop();
|
|
||||||
}
|
|
||||||
render(stream.splice(0, 1)[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result + escape(value.substr(processed));
|
|
||||||
};
|
|
||||||
|
|
||||||
/* **** Highlight.js Private API **** */
|
|
||||||
|
|
||||||
module.exports.HighlightJS = new HighlightJS();
|
|
||||||
})();
|
|
||||||
|
|
||||||
},{}]},{},[1]);
|
|
||||||
1
dist/diff2html-ui.min.js
vendored
1
dist/diff2html-ui.min.js
vendored
File diff suppressed because one or more lines are too long
367
dist/diff2html.css
vendored
367
dist/diff2html.css
vendored
File diff suppressed because one or more lines are too long
71
dist/diff2html.d.ts
vendored
71
dist/diff2html.d.ts
vendored
|
|
@ -1,71 +0,0 @@
|
||||||
// Type definitions for diff2html
|
|
||||||
// Project: https://github.com/rtfpessoa/diff2html
|
|
||||||
// Definitions by: rtfpessoa <https://github.com/rtfpessoa/>
|
|
||||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
|
||||||
|
|
||||||
declare namespace Diff2Html {
|
|
||||||
|
|
||||||
export interface Options {
|
|
||||||
inputFormat?: 'diff' | 'json';
|
|
||||||
outputFormat?: 'line-by-line' | 'side-by-side';
|
|
||||||
showFiles?: boolean;
|
|
||||||
diffStyle?: 'word' | 'char';
|
|
||||||
matching?: 'lines' | 'words' | 'none';
|
|
||||||
matchWordsThreshold?: number;
|
|
||||||
matchingMaxComparisons?: number;
|
|
||||||
maxLineSizeInBlockForComparison?: number;
|
|
||||||
maxLineLengthHighlight?: number;
|
|
||||||
templates?: object;
|
|
||||||
rawTemplates?: object;
|
|
||||||
renderNothingWhenEmpty?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Line {
|
|
||||||
content: string;
|
|
||||||
type: string;
|
|
||||||
oldNumber: number;
|
|
||||||
newNumber: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Block {
|
|
||||||
oldStartLine: number;
|
|
||||||
oldStartLine2?: number;
|
|
||||||
newStartLine: number;
|
|
||||||
header: string;
|
|
||||||
lines: Line[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Result {
|
|
||||||
addedLines: number;
|
|
||||||
deletedLines: number;
|
|
||||||
isCombined: boolean;
|
|
||||||
isGitDiff: boolean;
|
|
||||||
oldName: string;
|
|
||||||
newName: string;
|
|
||||||
language: string;
|
|
||||||
blocks: Block[];
|
|
||||||
oldMode?: string;
|
|
||||||
newMode?: string;
|
|
||||||
deletedFileMode?: string;
|
|
||||||
newFileMode?: string;
|
|
||||||
isDeleted?: boolean;
|
|
||||||
isNew?: boolean;
|
|
||||||
isCopy?: boolean;
|
|
||||||
isRename?: boolean;
|
|
||||||
unchangedPercentage?: number;
|
|
||||||
changedPercentage?: number;
|
|
||||||
checksumBefore?: string;
|
|
||||||
checksumAfter?: string;
|
|
||||||
mode?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Diff2Html {
|
|
||||||
getJsonFromDiff(input: string, configuration?: Options): Result[];
|
|
||||||
getPrettyHtml(input: any, configuration?: Options): string;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
declare module "diff2html" {
|
|
||||||
var d2h: { "Diff2Html": Diff2Html.Diff2Html };
|
|
||||||
export = d2h;
|
|
||||||
}
|
|
||||||
4782
dist/diff2html.js
vendored
4782
dist/diff2html.js
vendored
File diff suppressed because it is too large
Load diff
1
dist/diff2html.min.css
vendored
1
dist/diff2html.min.css
vendored
File diff suppressed because one or more lines are too long
1
dist/diff2html.min.js
vendored
1
dist/diff2html.min.js
vendored
File diff suppressed because one or more lines are too long
|
|
@ -1 +0,0 @@
|
||||||
diff2html.xyz
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
../dist
|
|
||||||
255
docs/demo.html
255
docs/demo.html
|
|
@ -1,255 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en" class="js">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<!--[if IE]>
|
|
||||||
<meta http-equiv='X-UA-Compatible' content='IE=edge,chrome=1'/>
|
|
||||||
<![endif]-->
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
||||||
|
|
||||||
<meta name="description" content="Diff parser and pretty html generator">
|
|
||||||
<meta name="keywords" content="diff2html,git,diff,unified,pretty,html,css,javaccript">
|
|
||||||
<meta name="author" content="Rodrigo Fernandes (rtfpessoa)">
|
|
||||||
|
|
||||||
<title>diff2html</title>
|
|
||||||
|
|
||||||
<!-- search engine -->
|
|
||||||
<link rel="canonical" href="https://diff2html.xyz">
|
|
||||||
|
|
||||||
<!-- open graph -->
|
|
||||||
<meta property="og:title" content="diff2html">
|
|
||||||
<meta property="og:type" content="website">
|
|
||||||
|
|
||||||
<meta property="og:description"
|
|
||||||
content="Diff parser and pretty html generator.">
|
|
||||||
|
|
||||||
<meta property="og:url" content="https://diff2html.xyz">
|
|
||||||
<meta property="og:site_name" content="diff2html">
|
|
||||||
|
|
||||||
<!-- Bootstrap -->
|
|
||||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"
|
|
||||||
integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
|
|
||||||
|
|
||||||
<!-- Custom styles for this template -->
|
|
||||||
<link href="main.min.css" rel="stylesheet">
|
|
||||||
|
|
||||||
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.13.1/styles/github.min.css">
|
|
||||||
|
|
||||||
<!-- diff2html -->
|
|
||||||
<link rel="stylesheet" type="text/css" href="assets/diff2html.min.css">
|
|
||||||
<!-- -->
|
|
||||||
|
|
||||||
|
|
||||||
<script>
|
|
||||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
|
||||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
|
||||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
|
||||||
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
|
||||||
|
|
||||||
ga('create', 'UA-78351861-2', 'auto');
|
|
||||||
ga('send', 'pageview');
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body class="template-index template-index-min">
|
|
||||||
<div class="swag-line">
|
|
||||||
|
|
||||||
<div class="container">
|
|
||||||
<nav class="navbar navbar-default navbar-tall navbar-full" role="navigation">
|
|
||||||
<div class="navbar-header">
|
|
||||||
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#global-nav">
|
|
||||||
<span class="sr-only">Toggle navigation</span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
</button>
|
|
||||||
<a class="navbar-brand" href="index.html">diff2html</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="collapse navbar-collapse" id="global-nav">
|
|
||||||
<div class="navbar-right">
|
|
||||||
<ul class="nav navbar-nav">
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<a href="index.html#install">Getting Started</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<a href="index.html#cli">CLI</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<a href="demo.html?diff=https://github.com/rtfpessoa/diff2html/pull/106">Demo</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<a href="https://github.com/rtfpessoa/diff2html#how-to-use" target="_blank">Docs</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<a href="https://github.com/rtfpessoa/diff2html/issues/new" target="_blank">Support</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<h1>Diff Prettifier <a href="#help">
|
|
||||||
<svg height="32" class="octicon octicon-unverified" viewBox="0 0 16 16" version="1.1" width="64" aria-hidden="true">
|
|
||||||
<path
|
|
||||||
d="M15.67 7.06l-1.08-1.34c-.17-.22-.28-.48-.31-.77l-.19-1.7a1.51 1.51 0 0 0-1.33-1.33l-1.7-.19c-.3-.03-.56-.16-.78-.33L8.94.32c-.55-.44-1.33-.44-1.88 0L5.72 1.4c-.22.17-.48.28-.77.31l-1.7.19c-.7.08-1.25.63-1.33 1.33l-.19 1.7c-.03.3-.16.56-.33.78L.32 7.05c-.44.55-.44 1.33 0 1.88l1.08 1.34c.17.22.28.48.31.77l.19 1.7c.08.7.63 1.25 1.33 1.33l1.7.19c.3.03.56.16.78.33l1.34 1.08c.55.44 1.33.44 1.88 0l1.34-1.08c.22-.17.48-.28.77-.31l1.7-.19c.7-.08 1.25-.63 1.33-1.33l.19-1.7c.03-.3.16-.56.33-.78l1.08-1.34c.44-.55.44-1.33 0-1.88zM9 11.5c0 .28-.22.5-.5.5h-1c-.27 0-.5-.22-.5-.5v-1c0-.28.23-.5.5-.5h1c.28 0 .5.22.5.5v1zm1.56-4.89c-.06.17-.17.33-.3.47-.13.16-.14.19-.33.38-.16.17-.31.3-.52.45-.11.09-.2.19-.28.27-.08.08-.14.17-.19.27-.05.1-.08.19-.11.3-.03.11-.03.13-.03.25H7.13c0-.22 0-.31.03-.48.03-.19.08-.36.14-.52.06-.14.14-.28.25-.42.11-.13.23-.25.41-.38.27-.19.36-.3.48-.52.12-.22.2-.38.2-.59 0-.27-.06-.45-.2-.58-.13-.13-.31-.19-.58-.19-.09 0-.19.02-.3.05-.11.03-.17.09-.25.16-.08.07-.14.11-.2.2a.41.41 0 0 0-.09.28h-2c0-.38.13-.56.27-.83.16-.27.36-.5.61-.67.25-.17.55-.3.88-.38.33-.08.7-.13 1.09-.13.44 0 .83.05 1.17.13.34.09.63.22.88.39.23.17.41.38.55.63.13.25.19.55.19.88 0 .22 0 .42-.08.59l-.02-.01z"></path>
|
|
||||||
</svg>
|
|
||||||
</a>
|
|
||||||
</h1>
|
|
||||||
<p>GitHub, Bitbucket and GitLab commit and pull request compatible</p>
|
|
||||||
<p>Just paste the GitHub, Bitbucket or GitLab commit, pull request or merge request url
|
|
||||||
or any other git or unified compatible diff and we will render a pretty html representation of it
|
|
||||||
with code syntax highlight and line similarity matching for better code reviews.
|
|
||||||
</p>
|
|
||||||
<h2>Options:</h2>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-2 col-xs-12 col-15">
|
|
||||||
<label title="Output format of the HTML, either line by line or side by side">Output Format
|
|
||||||
<select class="options-label-value" id="diff-url-options-output-format" name="outputFormat">
|
|
||||||
<option value="line-by-line" selected>Line by Line</option>
|
|
||||||
<option value="side-by-side">Side by Side</option>
|
|
||||||
</select>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class=" col-md-2 col-xs-12 col-15">
|
|
||||||
<label title="Show the file list summary before the diff">File Summary
|
|
||||||
<input class="options-label-value" id="diff-url-options-show-files" type="checkbox" name="showFiles" checked/>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class=" col-md-2 col-xs-12 col-15">
|
|
||||||
<label title="Level of matching for the comparison algorithm">Matching Type
|
|
||||||
<select class="options-label-value" id="diff-url-options-matching" name="matching">
|
|
||||||
<option value="lines">Lines</option>
|
|
||||||
<option value="words" selected>Words</option>
|
|
||||||
<option value="none">None</option>
|
|
||||||
</select>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class=" col-md-2 col-xs-12 col-15">
|
|
||||||
<label title="Similarity threshold for the matching algorithm">Words Threshold
|
|
||||||
<input class="options-label-value" id="diff-url-options-match-words-threshold" type="number"
|
|
||||||
name="matchWordsThreshold" value="0.25" step="0.05"
|
|
||||||
min="0" max="1"/>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class=" col-md-2 col-xs-12 col-15">
|
|
||||||
<label title="Maximum number of comparison performed by the matching algorithm in a block of changes">Max
|
|
||||||
Comparisons
|
|
||||||
<input class="options-label-value" id="diff-url-options-matching-max-comparisons" type="number"
|
|
||||||
name="matchingMaxComparisons" value="2500"
|
|
||||||
step="100" min="0"/>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<br>
|
|
||||||
<div class="diff-url-wrapper">
|
|
||||||
<input id="url" class="diff-url-input" type="text" name="url" placeholder="URL"/>
|
|
||||||
<a id="url-btn" class="diff-url-btn btn btn-sm" href="#">Load</a>
|
|
||||||
</div>
|
|
||||||
<br>
|
|
||||||
<div id="url-diff-container" style="margin: 0 auto;">
|
|
||||||
</div>
|
|
||||||
<br>
|
|
||||||
<h3 id="help">Help:</h3>
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
<b>Why should I use this instead of GitHub, Bitbucket or GitLab?</b>
|
|
||||||
<p>Code Syntax Highlight</p>
|
|
||||||
<p>Line similarity match (similar lines are together)</p>
|
|
||||||
<p>Line by Line and Side by Side diffs</p>
|
|
||||||
<p>Supports any git and unified compatible diffs</p>
|
|
||||||
<p>Easy code selection</p>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<b>What urls are supported?</b>
|
|
||||||
<p>Any GitHub, Bitbucket or GitLab Commit, Pull Request or Merge Request urls.</p>
|
|
||||||
<p>Any Git or Unified Raw Diff or Patch urls.</p>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<b>Can I send a custom url for a friend, colleague or co-worker?</b>
|
|
||||||
<p>Just add a url parameter called diff to current url using as value your Commit, Pull Request, Merge Request, Diff
|
|
||||||
or Patch url.</p>
|
|
||||||
<p>ex: <a href="demo.html?diff=https://github.com/rtfpessoa/diff2html/pull/106">https://diff2html.xyz/demo.html?diff=https://github.com/rtfpessoa/diff2html/pull/106</a>
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<b>Why can't I paste a diff?</b>
|
|
||||||
<p><a href="https://diffy.org/">diffy.org</a> is an amazing tool created by <a
|
|
||||||
href="https://github.com/pbu88">pbu88</a>
|
|
||||||
to share your diffs and uses diff2html under the hood.</p>
|
|
||||||
<p>Also, diff2html cli can directly publish diffs to <a href="https://diffy.org/">diffy.org</a></p>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<br>
|
|
||||||
<h3>Thank you</h3>
|
|
||||||
<p>I want to thank <a href="https://github.com/kevinsimper">kevinsimper</a> for this great idea,
|
|
||||||
providing better diff support for existing online services.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<footer class="footer clearfix">
|
|
||||||
<p class="col-xs-10 col-xs-offset-1">
|
|
||||||
Website originally designed and built by
|
|
||||||
<a href="https://twitter.com/mdo" target="_blank">@mdo</a>,
|
|
||||||
<a href="https://twitter.com/fat" target="_blank">@fat</a>, and
|
|
||||||
<a href="https://twitter.com/dhg" target="_blank">@dhg</a>,
|
|
||||||
adapted with <span class="hero-red">❤</span> by
|
|
||||||
<a href="https://twitter.com/rtfpessoa" target="_blank">@rtfpessoa</a>.
|
|
||||||
</p>
|
|
||||||
<ul class="footer-list col-xs-10 col-xs-offset-1">
|
|
||||||
|
|
||||||
<li class="footer-list-item">
|
|
||||||
<a class="footer-list-link" href="https://github.com/rtfpessoa/diff2html#how-to-use"
|
|
||||||
target="_blank">FAQ</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li class="footer-list-item">
|
|
||||||
<a class="footer-list-link" href="https://diff2html.xyz">diff2html</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
</ul>
|
|
||||||
</footer>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- General JavaScript -->
|
|
||||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.3/jquery.min.js"></script>
|
|
||||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"
|
|
||||||
integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS"
|
|
||||||
crossorigin="anonymous"></script>
|
|
||||||
|
|
||||||
<script type="application/ld+json">
|
|
||||||
{
|
|
||||||
"@context": "http://schema.org/",
|
|
||||||
"@type": "SoftwareSourceCode",
|
|
||||||
"name": "diff2html",
|
|
||||||
"author": "Rodrigo Fernandes",
|
|
||||||
"image": "https://diff2html.xyz/img/snapshot-3.png",
|
|
||||||
"description": "Diff parser and pretty html generator.",
|
|
||||||
"codeRepository": "https://github.com/rtfpessoa/diff2html",
|
|
||||||
"programmingLanguage": "JavaScript",
|
|
||||||
"runtimePlatform": "Node >= 0.12",
|
|
||||||
"mainEntityOfPage": "https://diff2html.xyz/"
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.13.1/highlight.min.js"></script>
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.13.1/languages/scala.min.js"></script>
|
|
||||||
|
|
||||||
<!-- diff2html -->
|
|
||||||
<script type="text/javascript" src="assets/diff2html.min.js"></script>
|
|
||||||
<script type="text/javascript" src="assets/diff2html-ui.min.js"></script>
|
|
||||||
<!-- -->
|
|
||||||
|
|
||||||
<script type="text/javascript" src="demo.min.js"></script>
|
|
||||||
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
769
docs/demo.js
769
docs/demo.js
|
|
@ -1,769 +0,0 @@
|
||||||
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
|
|
||||||
(function (global, factory) {
|
|
||||||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
|
||||||
typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
|
||||||
(factory((global.WHATWGFetch = {})));
|
|
||||||
}(this, (function (exports) { 'use strict';
|
|
||||||
|
|
||||||
var support = {
|
|
||||||
searchParams: 'URLSearchParams' in self,
|
|
||||||
iterable: 'Symbol' in self && 'iterator' in Symbol,
|
|
||||||
blob:
|
|
||||||
'FileReader' in self &&
|
|
||||||
'Blob' in self &&
|
|
||||||
(function() {
|
|
||||||
try {
|
|
||||||
new Blob();
|
|
||||||
return true
|
|
||||||
} catch (e) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
})(),
|
|
||||||
formData: 'FormData' in self,
|
|
||||||
arrayBuffer: 'ArrayBuffer' in self
|
|
||||||
};
|
|
||||||
|
|
||||||
function isDataView(obj) {
|
|
||||||
return obj && DataView.prototype.isPrototypeOf(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (support.arrayBuffer) {
|
|
||||||
var viewClasses = [
|
|
||||||
'[object Int8Array]',
|
|
||||||
'[object Uint8Array]',
|
|
||||||
'[object Uint8ClampedArray]',
|
|
||||||
'[object Int16Array]',
|
|
||||||
'[object Uint16Array]',
|
|
||||||
'[object Int32Array]',
|
|
||||||
'[object Uint32Array]',
|
|
||||||
'[object Float32Array]',
|
|
||||||
'[object Float64Array]'
|
|
||||||
];
|
|
||||||
|
|
||||||
var isArrayBufferView =
|
|
||||||
ArrayBuffer.isView ||
|
|
||||||
function(obj) {
|
|
||||||
return obj && viewClasses.indexOf(Object.prototype.toString.call(obj)) > -1
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function normalizeName(name) {
|
|
||||||
if (typeof name !== 'string') {
|
|
||||||
name = String(name);
|
|
||||||
}
|
|
||||||
if (/[^a-z0-9\-#$%&'*+.^_`|~]/i.test(name)) {
|
|
||||||
throw new TypeError('Invalid character in header field name')
|
|
||||||
}
|
|
||||||
return name.toLowerCase()
|
|
||||||
}
|
|
||||||
|
|
||||||
function normalizeValue(value) {
|
|
||||||
if (typeof value !== 'string') {
|
|
||||||
value = String(value);
|
|
||||||
}
|
|
||||||
return value
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build a destructive iterator for the value list
|
|
||||||
function iteratorFor(items) {
|
|
||||||
var iterator = {
|
|
||||||
next: function() {
|
|
||||||
var value = items.shift();
|
|
||||||
return {done: value === undefined, value: value}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (support.iterable) {
|
|
||||||
iterator[Symbol.iterator] = function() {
|
|
||||||
return iterator
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return iterator
|
|
||||||
}
|
|
||||||
|
|
||||||
function Headers(headers) {
|
|
||||||
this.map = {};
|
|
||||||
|
|
||||||
if (headers instanceof Headers) {
|
|
||||||
headers.forEach(function(value, name) {
|
|
||||||
this.append(name, value);
|
|
||||||
}, this);
|
|
||||||
} else if (Array.isArray(headers)) {
|
|
||||||
headers.forEach(function(header) {
|
|
||||||
this.append(header[0], header[1]);
|
|
||||||
}, this);
|
|
||||||
} else if (headers) {
|
|
||||||
Object.getOwnPropertyNames(headers).forEach(function(name) {
|
|
||||||
this.append(name, headers[name]);
|
|
||||||
}, this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Headers.prototype.append = function(name, value) {
|
|
||||||
name = normalizeName(name);
|
|
||||||
value = normalizeValue(value);
|
|
||||||
var oldValue = this.map[name];
|
|
||||||
this.map[name] = oldValue ? oldValue + ', ' + value : value;
|
|
||||||
};
|
|
||||||
|
|
||||||
Headers.prototype['delete'] = function(name) {
|
|
||||||
delete this.map[normalizeName(name)];
|
|
||||||
};
|
|
||||||
|
|
||||||
Headers.prototype.get = function(name) {
|
|
||||||
name = normalizeName(name);
|
|
||||||
return this.has(name) ? this.map[name] : null
|
|
||||||
};
|
|
||||||
|
|
||||||
Headers.prototype.has = function(name) {
|
|
||||||
return this.map.hasOwnProperty(normalizeName(name))
|
|
||||||
};
|
|
||||||
|
|
||||||
Headers.prototype.set = function(name, value) {
|
|
||||||
this.map[normalizeName(name)] = normalizeValue(value);
|
|
||||||
};
|
|
||||||
|
|
||||||
Headers.prototype.forEach = function(callback, thisArg) {
|
|
||||||
for (var name in this.map) {
|
|
||||||
if (this.map.hasOwnProperty(name)) {
|
|
||||||
callback.call(thisArg, this.map[name], name, this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Headers.prototype.keys = function() {
|
|
||||||
var items = [];
|
|
||||||
this.forEach(function(value, name) {
|
|
||||||
items.push(name);
|
|
||||||
});
|
|
||||||
return iteratorFor(items)
|
|
||||||
};
|
|
||||||
|
|
||||||
Headers.prototype.values = function() {
|
|
||||||
var items = [];
|
|
||||||
this.forEach(function(value) {
|
|
||||||
items.push(value);
|
|
||||||
});
|
|
||||||
return iteratorFor(items)
|
|
||||||
};
|
|
||||||
|
|
||||||
Headers.prototype.entries = function() {
|
|
||||||
var items = [];
|
|
||||||
this.forEach(function(value, name) {
|
|
||||||
items.push([name, value]);
|
|
||||||
});
|
|
||||||
return iteratorFor(items)
|
|
||||||
};
|
|
||||||
|
|
||||||
if (support.iterable) {
|
|
||||||
Headers.prototype[Symbol.iterator] = Headers.prototype.entries;
|
|
||||||
}
|
|
||||||
|
|
||||||
function consumed(body) {
|
|
||||||
if (body.bodyUsed) {
|
|
||||||
return Promise.reject(new TypeError('Already read'))
|
|
||||||
}
|
|
||||||
body.bodyUsed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function fileReaderReady(reader) {
|
|
||||||
return new Promise(function(resolve, reject) {
|
|
||||||
reader.onload = function() {
|
|
||||||
resolve(reader.result);
|
|
||||||
};
|
|
||||||
reader.onerror = function() {
|
|
||||||
reject(reader.error);
|
|
||||||
};
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function readBlobAsArrayBuffer(blob) {
|
|
||||||
var reader = new FileReader();
|
|
||||||
var promise = fileReaderReady(reader);
|
|
||||||
reader.readAsArrayBuffer(blob);
|
|
||||||
return promise
|
|
||||||
}
|
|
||||||
|
|
||||||
function readBlobAsText(blob) {
|
|
||||||
var reader = new FileReader();
|
|
||||||
var promise = fileReaderReady(reader);
|
|
||||||
reader.readAsText(blob);
|
|
||||||
return promise
|
|
||||||
}
|
|
||||||
|
|
||||||
function readArrayBufferAsText(buf) {
|
|
||||||
var view = new Uint8Array(buf);
|
|
||||||
var chars = new Array(view.length);
|
|
||||||
|
|
||||||
for (var i = 0; i < view.length; i++) {
|
|
||||||
chars[i] = String.fromCharCode(view[i]);
|
|
||||||
}
|
|
||||||
return chars.join('')
|
|
||||||
}
|
|
||||||
|
|
||||||
function bufferClone(buf) {
|
|
||||||
if (buf.slice) {
|
|
||||||
return buf.slice(0)
|
|
||||||
} else {
|
|
||||||
var view = new Uint8Array(buf.byteLength);
|
|
||||||
view.set(new Uint8Array(buf));
|
|
||||||
return view.buffer
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function Body() {
|
|
||||||
this.bodyUsed = false;
|
|
||||||
|
|
||||||
this._initBody = function(body) {
|
|
||||||
this._bodyInit = body;
|
|
||||||
if (!body) {
|
|
||||||
this._bodyText = '';
|
|
||||||
} else if (typeof body === 'string') {
|
|
||||||
this._bodyText = body;
|
|
||||||
} else if (support.blob && Blob.prototype.isPrototypeOf(body)) {
|
|
||||||
this._bodyBlob = body;
|
|
||||||
} else if (support.formData && FormData.prototype.isPrototypeOf(body)) {
|
|
||||||
this._bodyFormData = body;
|
|
||||||
} else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {
|
|
||||||
this._bodyText = body.toString();
|
|
||||||
} else if (support.arrayBuffer && support.blob && isDataView(body)) {
|
|
||||||
this._bodyArrayBuffer = bufferClone(body.buffer);
|
|
||||||
// IE 10-11 can't handle a DataView body.
|
|
||||||
this._bodyInit = new Blob([this._bodyArrayBuffer]);
|
|
||||||
} else if (support.arrayBuffer && (ArrayBuffer.prototype.isPrototypeOf(body) || isArrayBufferView(body))) {
|
|
||||||
this._bodyArrayBuffer = bufferClone(body);
|
|
||||||
} else {
|
|
||||||
this._bodyText = body = Object.prototype.toString.call(body);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.headers.get('content-type')) {
|
|
||||||
if (typeof body === 'string') {
|
|
||||||
this.headers.set('content-type', 'text/plain;charset=UTF-8');
|
|
||||||
} else if (this._bodyBlob && this._bodyBlob.type) {
|
|
||||||
this.headers.set('content-type', this._bodyBlob.type);
|
|
||||||
} else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {
|
|
||||||
this.headers.set('content-type', 'application/x-www-form-urlencoded;charset=UTF-8');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (support.blob) {
|
|
||||||
this.blob = function() {
|
|
||||||
var rejected = consumed(this);
|
|
||||||
if (rejected) {
|
|
||||||
return rejected
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._bodyBlob) {
|
|
||||||
return Promise.resolve(this._bodyBlob)
|
|
||||||
} else if (this._bodyArrayBuffer) {
|
|
||||||
return Promise.resolve(new Blob([this._bodyArrayBuffer]))
|
|
||||||
} else if (this._bodyFormData) {
|
|
||||||
throw new Error('could not read FormData body as blob')
|
|
||||||
} else {
|
|
||||||
return Promise.resolve(new Blob([this._bodyText]))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this.arrayBuffer = function() {
|
|
||||||
if (this._bodyArrayBuffer) {
|
|
||||||
return consumed(this) || Promise.resolve(this._bodyArrayBuffer)
|
|
||||||
} else {
|
|
||||||
return this.blob().then(readBlobAsArrayBuffer)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
this.text = function() {
|
|
||||||
var rejected = consumed(this);
|
|
||||||
if (rejected) {
|
|
||||||
return rejected
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._bodyBlob) {
|
|
||||||
return readBlobAsText(this._bodyBlob)
|
|
||||||
} else if (this._bodyArrayBuffer) {
|
|
||||||
return Promise.resolve(readArrayBufferAsText(this._bodyArrayBuffer))
|
|
||||||
} else if (this._bodyFormData) {
|
|
||||||
throw new Error('could not read FormData body as text')
|
|
||||||
} else {
|
|
||||||
return Promise.resolve(this._bodyText)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (support.formData) {
|
|
||||||
this.formData = function() {
|
|
||||||
return this.text().then(decode)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
this.json = function() {
|
|
||||||
return this.text().then(JSON.parse)
|
|
||||||
};
|
|
||||||
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
// HTTP methods whose capitalization should be normalized
|
|
||||||
var methods = ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT'];
|
|
||||||
|
|
||||||
function normalizeMethod(method) {
|
|
||||||
var upcased = method.toUpperCase();
|
|
||||||
return methods.indexOf(upcased) > -1 ? upcased : method
|
|
||||||
}
|
|
||||||
|
|
||||||
function Request(input, options) {
|
|
||||||
options = options || {};
|
|
||||||
var body = options.body;
|
|
||||||
|
|
||||||
if (input instanceof Request) {
|
|
||||||
if (input.bodyUsed) {
|
|
||||||
throw new TypeError('Already read')
|
|
||||||
}
|
|
||||||
this.url = input.url;
|
|
||||||
this.credentials = input.credentials;
|
|
||||||
if (!options.headers) {
|
|
||||||
this.headers = new Headers(input.headers);
|
|
||||||
}
|
|
||||||
this.method = input.method;
|
|
||||||
this.mode = input.mode;
|
|
||||||
this.signal = input.signal;
|
|
||||||
if (!body && input._bodyInit != null) {
|
|
||||||
body = input._bodyInit;
|
|
||||||
input.bodyUsed = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.url = String(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.credentials = options.credentials || this.credentials || 'same-origin';
|
|
||||||
if (options.headers || !this.headers) {
|
|
||||||
this.headers = new Headers(options.headers);
|
|
||||||
}
|
|
||||||
this.method = normalizeMethod(options.method || this.method || 'GET');
|
|
||||||
this.mode = options.mode || this.mode || null;
|
|
||||||
this.signal = options.signal || this.signal;
|
|
||||||
this.referrer = null;
|
|
||||||
|
|
||||||
if ((this.method === 'GET' || this.method === 'HEAD') && body) {
|
|
||||||
throw new TypeError('Body not allowed for GET or HEAD requests')
|
|
||||||
}
|
|
||||||
this._initBody(body);
|
|
||||||
}
|
|
||||||
|
|
||||||
Request.prototype.clone = function() {
|
|
||||||
return new Request(this, {body: this._bodyInit})
|
|
||||||
};
|
|
||||||
|
|
||||||
function decode(body) {
|
|
||||||
var form = new FormData();
|
|
||||||
body
|
|
||||||
.trim()
|
|
||||||
.split('&')
|
|
||||||
.forEach(function(bytes) {
|
|
||||||
if (bytes) {
|
|
||||||
var split = bytes.split('=');
|
|
||||||
var name = split.shift().replace(/\+/g, ' ');
|
|
||||||
var value = split.join('=').replace(/\+/g, ' ');
|
|
||||||
form.append(decodeURIComponent(name), decodeURIComponent(value));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return form
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseHeaders(rawHeaders) {
|
|
||||||
var headers = new Headers();
|
|
||||||
// Replace instances of \r\n and \n followed by at least one space or horizontal tab with a space
|
|
||||||
// https://tools.ietf.org/html/rfc7230#section-3.2
|
|
||||||
var preProcessedHeaders = rawHeaders.replace(/\r?\n[\t ]+/g, ' ');
|
|
||||||
preProcessedHeaders.split(/\r?\n/).forEach(function(line) {
|
|
||||||
var parts = line.split(':');
|
|
||||||
var key = parts.shift().trim();
|
|
||||||
if (key) {
|
|
||||||
var value = parts.join(':').trim();
|
|
||||||
headers.append(key, value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return headers
|
|
||||||
}
|
|
||||||
|
|
||||||
Body.call(Request.prototype);
|
|
||||||
|
|
||||||
function Response(bodyInit, options) {
|
|
||||||
if (!options) {
|
|
||||||
options = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
this.type = 'default';
|
|
||||||
this.status = options.status === undefined ? 200 : options.status;
|
|
||||||
this.ok = this.status >= 200 && this.status < 300;
|
|
||||||
this.statusText = 'statusText' in options ? options.statusText : 'OK';
|
|
||||||
this.headers = new Headers(options.headers);
|
|
||||||
this.url = options.url || '';
|
|
||||||
this._initBody(bodyInit);
|
|
||||||
}
|
|
||||||
|
|
||||||
Body.call(Response.prototype);
|
|
||||||
|
|
||||||
Response.prototype.clone = function() {
|
|
||||||
return new Response(this._bodyInit, {
|
|
||||||
status: this.status,
|
|
||||||
statusText: this.statusText,
|
|
||||||
headers: new Headers(this.headers),
|
|
||||||
url: this.url
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
Response.error = function() {
|
|
||||||
var response = new Response(null, {status: 0, statusText: ''});
|
|
||||||
response.type = 'error';
|
|
||||||
return response
|
|
||||||
};
|
|
||||||
|
|
||||||
var redirectStatuses = [301, 302, 303, 307, 308];
|
|
||||||
|
|
||||||
Response.redirect = function(url, status) {
|
|
||||||
if (redirectStatuses.indexOf(status) === -1) {
|
|
||||||
throw new RangeError('Invalid status code')
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Response(null, {status: status, headers: {location: url}})
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.DOMException = self.DOMException;
|
|
||||||
try {
|
|
||||||
new exports.DOMException();
|
|
||||||
} catch (err) {
|
|
||||||
exports.DOMException = function(message, name) {
|
|
||||||
this.message = message;
|
|
||||||
this.name = name;
|
|
||||||
var error = Error(message);
|
|
||||||
this.stack = error.stack;
|
|
||||||
};
|
|
||||||
exports.DOMException.prototype = Object.create(Error.prototype);
|
|
||||||
exports.DOMException.prototype.constructor = exports.DOMException;
|
|
||||||
}
|
|
||||||
|
|
||||||
function fetch(input, init) {
|
|
||||||
return new Promise(function(resolve, reject) {
|
|
||||||
var request = new Request(input, init);
|
|
||||||
|
|
||||||
if (request.signal && request.signal.aborted) {
|
|
||||||
return reject(new exports.DOMException('Aborted', 'AbortError'))
|
|
||||||
}
|
|
||||||
|
|
||||||
var xhr = new XMLHttpRequest();
|
|
||||||
|
|
||||||
function abortXhr() {
|
|
||||||
xhr.abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
xhr.onload = function() {
|
|
||||||
var options = {
|
|
||||||
status: xhr.status,
|
|
||||||
statusText: xhr.statusText,
|
|
||||||
headers: parseHeaders(xhr.getAllResponseHeaders() || '')
|
|
||||||
};
|
|
||||||
options.url = 'responseURL' in xhr ? xhr.responseURL : options.headers.get('X-Request-URL');
|
|
||||||
var body = 'response' in xhr ? xhr.response : xhr.responseText;
|
|
||||||
resolve(new Response(body, options));
|
|
||||||
};
|
|
||||||
|
|
||||||
xhr.onerror = function() {
|
|
||||||
reject(new TypeError('Network request failed'));
|
|
||||||
};
|
|
||||||
|
|
||||||
xhr.ontimeout = function() {
|
|
||||||
reject(new TypeError('Network request failed'));
|
|
||||||
};
|
|
||||||
|
|
||||||
xhr.onabort = function() {
|
|
||||||
reject(new exports.DOMException('Aborted', 'AbortError'));
|
|
||||||
};
|
|
||||||
|
|
||||||
xhr.open(request.method, request.url, true);
|
|
||||||
|
|
||||||
if (request.credentials === 'include') {
|
|
||||||
xhr.withCredentials = true;
|
|
||||||
} else if (request.credentials === 'omit') {
|
|
||||||
xhr.withCredentials = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ('responseType' in xhr && support.blob) {
|
|
||||||
xhr.responseType = 'blob';
|
|
||||||
}
|
|
||||||
|
|
||||||
request.headers.forEach(function(value, name) {
|
|
||||||
xhr.setRequestHeader(name, value);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (request.signal) {
|
|
||||||
request.signal.addEventListener('abort', abortXhr);
|
|
||||||
|
|
||||||
xhr.onreadystatechange = function() {
|
|
||||||
// DONE (success or failure)
|
|
||||||
if (xhr.readyState === 4) {
|
|
||||||
request.signal.removeEventListener('abort', abortXhr);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fetch.polyfill = true;
|
|
||||||
|
|
||||||
if (!self.fetch) {
|
|
||||||
self.fetch = fetch;
|
|
||||||
self.Headers = Headers;
|
|
||||||
self.Request = Request;
|
|
||||||
self.Response = Response;
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.Headers = Headers;
|
|
||||||
exports.Request = Request;
|
|
||||||
exports.Response = Response;
|
|
||||||
exports.fetch = fetch;
|
|
||||||
|
|
||||||
Object.defineProperty(exports, '__esModule', { value: true });
|
|
||||||
|
|
||||||
})));
|
|
||||||
|
|
||||||
},{}],2:[function(require,module,exports){
|
|
||||||
/* global Diff2HtmlUI */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Example URLs:
|
|
||||||
*
|
|
||||||
* https://github.com/rtfpessoa/diff2html/commit/7d02e67f3b3386ac5d804f974d025cd7a1165839
|
|
||||||
* https://github.com/rtfpessoa/diff2html/pull/106
|
|
||||||
*
|
|
||||||
* https://gitlab.com/gitlab-org/gitlab-ce/commit/4e963fed42ad518caa7353d361a38a1250c99c41
|
|
||||||
* https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/6763
|
|
||||||
*
|
|
||||||
* https://bitbucket.org/atlassian/amps/commits/52c38116f12475f75af4a147b7a7685478b83eca
|
|
||||||
* https://bitbucket.org/atlassian/amps/pull-requests/236
|
|
||||||
*/
|
|
||||||
|
|
||||||
$(document).ready(function() {
|
|
||||||
// Improves browser compatibility
|
|
||||||
require('whatwg-fetch');
|
|
||||||
|
|
||||||
var searchParam = 'diff';
|
|
||||||
|
|
||||||
var $container = $('.container');
|
|
||||||
var $url = $('#url');
|
|
||||||
var $outputFormat = $('#diff-url-options-output-format');
|
|
||||||
var $showFiles = $('#diff-url-options-show-files');
|
|
||||||
var $matching = $('#diff-url-options-matching');
|
|
||||||
var $wordsThreshold = $('#diff-url-options-match-words-threshold');
|
|
||||||
var $matchingMaxComparisons = $('#diff-url-options-matching-max-comparisons');
|
|
||||||
|
|
||||||
if (window.location.search) {
|
|
||||||
var url = getUrlFromSearch(window.location.search);
|
|
||||||
$url.val(url);
|
|
||||||
smartDraw(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
bind();
|
|
||||||
|
|
||||||
$outputFormat
|
|
||||||
.add($showFiles)
|
|
||||||
.add($matching)
|
|
||||||
.add($wordsThreshold)
|
|
||||||
.add($matchingMaxComparisons)
|
|
||||||
.change(function(e) {
|
|
||||||
console.log('');
|
|
||||||
console.log(e);
|
|
||||||
console.log('');
|
|
||||||
smartDraw(null, true);
|
|
||||||
});
|
|
||||||
|
|
||||||
function getUrlFromSearch(search) {
|
|
||||||
try {
|
|
||||||
return search
|
|
||||||
.split('?')[1]
|
|
||||||
.split(searchParam + '=')[1]
|
|
||||||
.split('&')[0];
|
|
||||||
} catch (_ignore) {
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getParamsFromSearch(search) {
|
|
||||||
var map = {};
|
|
||||||
try {
|
|
||||||
search
|
|
||||||
.split('?')[1]
|
|
||||||
.split('&')
|
|
||||||
.map(function(e) {
|
|
||||||
var values = e.split('=');
|
|
||||||
map[values[0]] = values[1];
|
|
||||||
});
|
|
||||||
} catch (_ignore) {
|
|
||||||
}
|
|
||||||
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
function bind() {
|
|
||||||
$('#url-btn').click(function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
var url = $url.val();
|
|
||||||
smartDraw(url);
|
|
||||||
});
|
|
||||||
|
|
||||||
$url.on('paste', function(e) {
|
|
||||||
var url = e.originalEvent.clipboardData.getData('Text');
|
|
||||||
smartDraw(url);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function prepareUrl(url) {
|
|
||||||
var fetchUrl;
|
|
||||||
var headers = new Headers();
|
|
||||||
|
|
||||||
var githubCommitUrl = /^https?:\/\/(?:www\.)?github\.com\/(.*?)\/(.*?)\/commit\/(.*?)(?:\.diff)?(?:\.patch)?(?:\/.*)?$/;
|
|
||||||
var githubPrUrl = /^https?:\/\/(?:www\.)?github\.com\/(.*?)\/(.*?)\/pull\/(.*?)(?:\.diff)?(?:\.patch)?(?:\/.*)?$/;
|
|
||||||
|
|
||||||
var gitlabCommitUrl = /^https?:\/\/(?:www\.)?gitlab\.com\/(.*?)\/(.*?)\/commit\/(.*?)(?:\.diff)?(?:\.patch)?(?:\/.*)?$/;
|
|
||||||
var gitlabPrUrl = /^https?:\/\/(?:www\.)?gitlab\.com\/(.*?)\/(.*?)\/merge_requests\/(.*?)(?:\.diff)?(?:\.patch)?(?:\/.*)?$/;
|
|
||||||
|
|
||||||
var bitbucketCommitUrl = /^https?:\/\/(?:www\.)?bitbucket\.org\/(.*?)\/(.*?)\/commits\/(.*?)(?:\/raw)?(?:\/.*)?$/;
|
|
||||||
var bitbucketPrUrl = /^https?:\/\/(?:www\.)?bitbucket\.org\/(.*?)\/(.*?)\/pull-requests\/(.*?)(?:\/.*)?$/;
|
|
||||||
|
|
||||||
function gitLabUrlGen(userName, projectName, type, value) {
|
|
||||||
return 'https://crossorigin.me/https://gitlab.com/' + userName + '/' + projectName + '/' + type + '/' + value + '.diff';
|
|
||||||
}
|
|
||||||
|
|
||||||
function gitHubUrlGen(userName, projectName, type, value) {
|
|
||||||
headers.append('Accept', 'application/vnd.github.v3.diff');
|
|
||||||
return 'https://api.github.com/repos/' + userName + '/' + projectName + '/' + type + '/' + value;
|
|
||||||
}
|
|
||||||
|
|
||||||
function bitbucketUrlGen(userName, projectName, type, value) {
|
|
||||||
var baseUrl = 'https://bitbucket.org/api/2.0/repositories/';
|
|
||||||
if (type === 'pullrequests') {
|
|
||||||
return baseUrl + userName + '/' + projectName + '/pullrequests/' + value + '/diff';
|
|
||||||
}
|
|
||||||
return baseUrl + userName + '/' + projectName + '/diff/' + value;
|
|
||||||
}
|
|
||||||
|
|
||||||
var values;
|
|
||||||
if ((values = githubCommitUrl.exec(url))) {
|
|
||||||
fetchUrl = gitHubUrlGen(values[1], values[2], 'commits', values[3]);
|
|
||||||
} else if ((values = githubPrUrl.exec(url))) {
|
|
||||||
fetchUrl = gitHubUrlGen(values[1], values[2], 'pulls', values[3]);
|
|
||||||
} else if ((values = gitlabCommitUrl.exec(url))) {
|
|
||||||
fetchUrl = gitLabUrlGen(values[1], values[2], 'commit', values[3]);
|
|
||||||
} else if ((values = gitlabPrUrl.exec(url))) {
|
|
||||||
fetchUrl = gitLabUrlGen(values[1], values[2], 'merge_requests', values[3]);
|
|
||||||
} else if ((values = bitbucketCommitUrl.exec(url))) {
|
|
||||||
fetchUrl = bitbucketUrlGen(values[1], values[2], 'commit', values[3]);
|
|
||||||
} else if ((values = bitbucketPrUrl.exec(url))) {
|
|
||||||
fetchUrl = bitbucketUrlGen(values[1], values[2], 'pullrequests', values[3]);
|
|
||||||
} else {
|
|
||||||
console.info('Could not parse url, using the provided url.');
|
|
||||||
fetchUrl = 'https://crossorigin.me/' + url;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
originalUrl: url,
|
|
||||||
url: fetchUrl,
|
|
||||||
headers: headers
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function smartDraw(urlOpt, forced) {
|
|
||||||
var url = urlOpt || $url.val();
|
|
||||||
var req = prepareUrl(url);
|
|
||||||
draw(req, forced);
|
|
||||||
}
|
|
||||||
|
|
||||||
function draw(req, forced) {
|
|
||||||
if (!validateUrl(req.url)) {
|
|
||||||
console.error('Invalid url provided!');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (validateUrl(req.originalUrl)) updateUrl(req.originalUrl);
|
|
||||||
|
|
||||||
var outputFormat = $outputFormat.val();
|
|
||||||
var showFiles = $showFiles.is(':checked');
|
|
||||||
var matching = $matching.val();
|
|
||||||
var wordsThreshold = $wordsThreshold.val();
|
|
||||||
var matchingMaxComparisons = $matchingMaxComparisons.val();
|
|
||||||
|
|
||||||
fetch(req.url, {
|
|
||||||
method: 'GET',
|
|
||||||
headers: req.headers,
|
|
||||||
mode: 'cors',
|
|
||||||
cache: 'default'
|
|
||||||
})
|
|
||||||
.then(function(res) {
|
|
||||||
return res.text();
|
|
||||||
})
|
|
||||||
.then(function(data) {
|
|
||||||
var container = '#url-diff-container';
|
|
||||||
var diff2htmlUi = new Diff2HtmlUI({diff: data});
|
|
||||||
|
|
||||||
if (outputFormat === 'side-by-side') {
|
|
||||||
$container.css({'width': '100%'});
|
|
||||||
} else {
|
|
||||||
$container.css({'width': ''});
|
|
||||||
}
|
|
||||||
|
|
||||||
var params = getParamsFromSearch(window.location.search);
|
|
||||||
delete params[searchParam];
|
|
||||||
|
|
||||||
if (forced) {
|
|
||||||
params['outputFormat'] = outputFormat;
|
|
||||||
params['showFiles'] = showFiles;
|
|
||||||
params['matching'] = matching;
|
|
||||||
params['wordsThreshold'] = wordsThreshold;
|
|
||||||
params['matchingMaxComparisons'] = matchingMaxComparisons;
|
|
||||||
} else {
|
|
||||||
params['outputFormat'] = params['outputFormat'] || outputFormat;
|
|
||||||
params['showFiles'] = String(params['showFiles']) !== 'false' || (params['showFiles'] === null && showFiles);
|
|
||||||
params['matching'] = params['matching'] || matching;
|
|
||||||
params['wordsThreshold'] = params['wordsThreshold'] || wordsThreshold;
|
|
||||||
params['matchingMaxComparisons'] = params['matchingMaxComparisons'] || matchingMaxComparisons;
|
|
||||||
|
|
||||||
$outputFormat.val(params['outputFormat']);
|
|
||||||
$showFiles.prop('checked', params['showFiles']);
|
|
||||||
$matching.val(params['matching']);
|
|
||||||
$wordsThreshold.val(params['wordsThreshold']);
|
|
||||||
$matchingMaxComparisons.val(params['matchingMaxComparisons']);
|
|
||||||
}
|
|
||||||
|
|
||||||
params['synchronisedScroll'] = params['synchronisedScroll'] || true;
|
|
||||||
|
|
||||||
diff2htmlUi.draw(container, params);
|
|
||||||
diff2htmlUi.fileListCloseable(container, params['fileListCloseable'] || false);
|
|
||||||
if (params['highlight'] === undefined || params['highlight']) {
|
|
||||||
diff2htmlUi.highlightCode(container);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function validateUrl(url) {
|
|
||||||
return /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateUrl(url) {
|
|
||||||
var params = getParamsFromSearch(window.location.search);
|
|
||||||
|
|
||||||
if (params[searchParam] === url) return;
|
|
||||||
|
|
||||||
params[searchParam] = url;
|
|
||||||
|
|
||||||
var paramString = Object.keys(params).map(function(k) { return k + '=' + params[k]; }).join('&');
|
|
||||||
|
|
||||||
window.location = 'demo.html?' + paramString;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
},{"whatwg-fetch":1}]},{},[2]);
|
|
||||||
1
docs/demo.min.js
vendored
1
docs/demo.min.js
vendored
File diff suppressed because one or more lines are too long
BIN
docs/favicon.ico
BIN
docs/favicon.ico
Binary file not shown.
|
Before Width: | Height: | Size: 4.6 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 92 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 73 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 121 KiB |
433
docs/index.html
433
docs/index.html
|
|
@ -1,433 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en" class="js">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<!--[if IE]>
|
|
||||||
<meta http-equiv='X-UA-Compatible' content='IE=edge,chrome=1'/>
|
|
||||||
<![endif]-->
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
||||||
|
|
||||||
<meta name="description" content="Diff parser and pretty html generator">
|
|
||||||
<meta name="keywords" content="diff2html,git,diff,unified,pretty,html,css,javaccript">
|
|
||||||
<meta name="author" content="Rodrigo Fernandes (rtfpessoa)">
|
|
||||||
|
|
||||||
<title>diff2html</title>
|
|
||||||
|
|
||||||
<!-- search engine -->
|
|
||||||
<link rel="canonical" href="https://diff2html.xyz">
|
|
||||||
|
|
||||||
<!-- open graph -->
|
|
||||||
<meta property="og:title" content="diff2html">
|
|
||||||
<meta property="og:type" content="website">
|
|
||||||
|
|
||||||
<meta property="og:description"
|
|
||||||
content="Diff parser and pretty html generator.">
|
|
||||||
|
|
||||||
<meta property="og:url" content="https://diff2html.xyz">
|
|
||||||
<meta property="og:site_name" content="diff2html">
|
|
||||||
|
|
||||||
<!-- Bootstrap -->
|
|
||||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"
|
|
||||||
integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
|
|
||||||
|
|
||||||
<!-- Custom styles for this template -->
|
|
||||||
<link href="main.min.css" rel="stylesheet">
|
|
||||||
|
|
||||||
<script>
|
|
||||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
|
||||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
|
||||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
|
||||||
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
|
||||||
|
|
||||||
ga('create', 'UA-78351861-2', 'auto');
|
|
||||||
ga('send', 'pageview');
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body class="template-index ">
|
|
||||||
<div class="swag-line">
|
|
||||||
|
|
||||||
<div class="container">
|
|
||||||
<nav class="navbar navbar-default navbar-tall navbar-full" role="navigation">
|
|
||||||
<div class="navbar-header">
|
|
||||||
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#global-nav">
|
|
||||||
<span class="sr-only">Toggle navigation</span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
<span class="icon-bar"></span>
|
|
||||||
</button>
|
|
||||||
<a class="navbar-brand" href="index.html">diff2html</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="collapse navbar-collapse" id="global-nav">
|
|
||||||
<div class="navbar-right">
|
|
||||||
<ul class="nav navbar-nav">
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<a href="index.html#install">Getting Started</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<a href="index.html#cli">CLI</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<a href="demo.html?diff=https://github.com/rtfpessoa/diff2html/pull/106">Demo</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<a href="https://github.com/rtfpessoa/diff2html#how-to-use" target="_blank">Docs</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<a href="https://github.com/rtfpessoa/diff2html/issues/new" target="_blank">Support</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<div class="hero hero-homepage">
|
|
||||||
<span class="hero-booticon">
|
|
||||||
<span class="hero-green">diff</span><span class="hero-black">2</span><span
|
|
||||||
class="hero-red">html</span>
|
|
||||||
</span>
|
|
||||||
<h1 class="hero-header">Diff parser and pretty html generator</h1>
|
|
||||||
<h4 class="text-muted">Better diffs, unmatched reviews.</h4>
|
|
||||||
<h2><a class="btn btn-lg" href="demo.html?diff=https://github.com/rtfpessoa/diff2html/pull/106">Demo</a></h2>
|
|
||||||
|
|
||||||
<div class="screenshots screenshots-fan clearfix">
|
|
||||||
|
|
||||||
<img class="screenshot hidden-xs" src="img/snapshot-2.png">
|
|
||||||
|
|
||||||
<a class="screenshot" href="demo.html?diff=https://github.com/rtfpessoa/diff2html/pull/106">
|
|
||||||
<img src="img/snapshot-3.png">
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<a class="screenshot hidden-xs" href="demo.html?diff=https://github.com/rtfpessoa/diff2html/pull/106">
|
|
||||||
<img src="img/snapshot-1.png">
|
|
||||||
</a>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<div class="row row-padded-small row-bordered">
|
|
||||||
<div class="col-sm-8 col-sm-offset-2 text-center">
|
|
||||||
<h2 class="m-b-md">Each diff provides a comprehensive visualization of the code changes,
|
|
||||||
helping developers identify problems and better understand the changes.</h2>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row row-padded-small homepage-grid row-bordered p-t text-center">
|
|
||||||
<div class="col-sm-4">
|
|
||||||
<span class="svg-icon-large">
|
|
||||||
<svg aria-hidden="true" class="octicon octicon-diff" height="16" version="1.1"
|
|
||||||
viewBox="0 0 14 16" width="14"><path
|
|
||||||
d="M6 7h2v1H6v2h-1V8H3v-1h2V5h1v2zM3 13h5v-1H3v1z m4.5-11l3.5 3.5v9.5c0 0.55-0.45 1-1 1H1c-0.55 0-1-0.45-1-1V3c0-0.55 0.45-1 1-1h6.5z m2.5 4L7 3H1v12h9V6zM8.5 0S3 0 3 0v1h5l4 4v8h1V4.5L8.5 0z"></path></svg>
|
|
||||||
</span>
|
|
||||||
<h5><strong>Line by Line and Side by Side changes</strong></h5>
|
|
||||||
<p class="text-muted">Each diff features a line by line and side by side preview of your
|
|
||||||
changes.</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-sm-4">
|
|
||||||
<span class="svg-icon-large">
|
|
||||||
<svg aria-hidden="true" class="octicon octicon-tasklist" height="16" version="1.1"
|
|
||||||
viewBox="0 0 16 16" width="16"><path
|
|
||||||
d="M15.41 9H7.59c-0.59 0-0.59-0.41-0.59-1s0-1 0.59-1h7.81c0.59 0 0.59 0.41 0.59 1s0 1-0.59 1zM9.59 4c-0.59 0-0.59-0.41-0.59-1s0-1 0.59-1h5.81c0.59 0 0.59 0.41 0.59 1s0 1-0.59 1H9.59zM0 3.91l1.41-1.3 1.59 1.59L7.09 0l1.41 1.41-5.5 5.5L0 3.91z m7.59 8.09h7.81c0.59 0 0.59 0.41 0.59 1s0 1-0.59 1H7.59c-0.59 0-0.59-0.41-0.59-1s0-1 0.59-1z"></path></svg>
|
|
||||||
</span>
|
|
||||||
<h5><strong>Code syntax highlight</strong></h5>
|
|
||||||
<p class="text-muted">All the code changes are syntax highlighted using <a
|
|
||||||
href="https://highlightjs.org/">highlight.js</a>,
|
|
||||||
providing more readability.</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-sm-4">
|
|
||||||
<span class="svg-icon-large">
|
|
||||||
<svg aria-hidden="true" class="octicon octicon-clippy" height="16" version="1.1"
|
|
||||||
viewBox="0 0 14 16"
|
|
||||||
width="14">
|
|
||||||
<path d="M2 12h4v1H2v-1z m5-6H2v1h5v-1z m2 3V7L6 10l3 3V11h5V9H9z m-4.5-1H2v1h2.5v-1zM2 11h2.5v-1H2v1z m9 1h1v2c-0.02 0.28-0.11 0.52-0.3 0.7s-0.42 0.28-0.7 0.3H1c-0.55 0-1-0.45-1-1V3c0-0.55 0.45-1 1-1h3C4 0.89 4.89 0 6 0s2 0.89 2 2h3c0.55 0 1 0.45 1 1v5h-1V5H1v9h10V12zM2 4h8c0-0.55-0.45-1-1-1h-1c-0.55 0-1-0.45-1-1s-0.45-1-1-1-1 0.45-1 1-0.45 1-1 1h-1c-0.55 0-1 0.45-1 1z"></path>
|
|
||||||
</svg>
|
|
||||||
</span>
|
|
||||||
<h5><strong>Line similarity matching</strong></h5>
|
|
||||||
<p class="text-muted">Similar lines are paired, allowing for easier change tracking.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="install" class="row-padded-small row-centered row-bordered">
|
|
||||||
<div class="col-md-12">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-12">
|
|
||||||
<h3><strong>Install with Bower</strong></h3>
|
|
||||||
<p>You can install and manage diff2html's CSS and JS using Bower:</p>
|
|
||||||
<div class="homepage-code-example">
|
|
||||||
<p><span class="unselectable">> $ </span><span class="text-muted">bower install diff2html</span></p>
|
|
||||||
<span class="btn-clipboard" data-clipboard-text="bower install diff2html" title="Copy">Copy</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-12">
|
|
||||||
<h3><strong>Install with npm</strong></h3>
|
|
||||||
<p>You can also install diff2html using npm:</p>
|
|
||||||
<div class="homepage-code-example">
|
|
||||||
<p><span class="unselectable">> $ </span><span class="text-muted">npm install diff2html</span></p>
|
|
||||||
<span class="btn-clipboard" data-clipboard-text="npm install diff2html" title="Copy">Copy</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row row-padded-small">
|
|
||||||
<div class="col-md-12">
|
|
||||||
<a href="https://github.com/rtfpessoa/diff2html#how-to-use" target="_blank">
|
|
||||||
Find usage examples in the Docs
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="cli" class="row row-padded-small row-centered row-bordered">
|
|
||||||
<div class="col-xs-10 col-xs-offset-1 col-md-6 col-md-offset-0">
|
|
||||||
<h3><strong>With command line integration</strong></h3>
|
|
||||||
<h4 class="m-b-md">We work hard to make sure you can have your diffs in a simple and flexible
|
|
||||||
way. Go <a href="https://github.com/rtfpessoa/diff2html-cli" target="_blank">here full
|
|
||||||
documentation</a>.</h4>
|
|
||||||
</div>
|
|
||||||
<div class="col-xs-10 col-xs-offset-1 col-md-6 col-md-offset-0">
|
|
||||||
<div class="homepage-terminal-example">
|
|
||||||
<p class="m-b-md">
|
|
||||||
<span class="unselectable">> $ </span><span class="text-muted">npm install -g diff2html-cli</span><br>
|
|
||||||
<span class="unselectable">diff2html cli installed!</span>
|
|
||||||
</p>
|
|
||||||
<p class="m-b-md">
|
|
||||||
<span class="unselectable">> $ </span><span class="text-muted">diff2html</span><br>
|
|
||||||
<span class="unselectable">Previous commit changes on your browser</span>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<span class="unselectable">> $ <span class="text-muted">is that it?</span><br>
|
|
||||||
Yup, it's that simple.</span>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="users" class="row row-padded-small row-centered row-bordered">
|
|
||||||
<div class="col-md-12">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-12">
|
|
||||||
<h3><strong>Projects using diff2html</strong></h3>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row row-eq-height">
|
|
||||||
<div class="col-xs-12 col-sm-6 col-md-3 m-b-lg">
|
|
||||||
<div class="panel panel-default panel-profile m-b-0">
|
|
||||||
<div class="panel-body text-center">
|
|
||||||
<h5 class="panel-title">diff2html-cli</h5>
|
|
||||||
<p class="m-b">diff2html from your terminal to the browser.</p>
|
|
||||||
<a href="https://github.com/rtfpessoa/diff2html-cli" target="_blank"
|
|
||||||
class="btn btn-primary-outline btn-sm m-b">
|
|
||||||
<span class="icon icon-add-user"></span> View GitHub
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-xs-12 col-sm-6 col-md-3 m-b-lg">
|
|
||||||
<div class="panel panel-default panel-profile m-b-0">
|
|
||||||
<div class="panel-body text-center">
|
|
||||||
<h5 class="panel-title">Codacy</h5>
|
|
||||||
<p class="m-b">Check code style, security, duplication, complexity and coverage on every change.</p>
|
|
||||||
<a href="https://www.codacy.com" target="_blank"
|
|
||||||
class="btn btn-primary-outline btn-sm m-b">
|
|
||||||
<span class="icon icon-add-user"></span> Website
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-xs-12 col-sm-6 col-md-3 m-b-lg">
|
|
||||||
<div class="panel panel-default panel-profile m-b-0">
|
|
||||||
<div class="panel-body text-center">
|
|
||||||
<h5 class="panel-title">Ungit</h5>
|
|
||||||
<p class="m-b">The easiest way to use git. On any platform. Anywhere.</p>
|
|
||||||
<a href="https://github.com/FredrikNoren/ungit" target="_blank"
|
|
||||||
class="btn btn-primary-outline btn-sm m-b">
|
|
||||||
<span class="icon icon-add-user"></span> View GitHub
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-xs-12 col-sm-6 col-md-3 m-b-lg">
|
|
||||||
<div class="panel panel-default panel-profile m-b-0">
|
|
||||||
<div class="panel-body text-center">
|
|
||||||
<h5 class="panel-title">Diffy</h5>
|
|
||||||
<p class="m-b">Share your diffs and explain your ideas without committing.</p>
|
|
||||||
<a href="https://diffy.org/" target="_blank"
|
|
||||||
class="btn btn-primary-outline btn-sm m-b">
|
|
||||||
<span class="icon icon-add-user"></span> Website
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-xs-12 col-sm-6 col-md-3 m-b-lg">
|
|
||||||
<div class="panel panel-default panel-profile m-b-0">
|
|
||||||
<div class="panel-body text-center">
|
|
||||||
<h5 class="panel-title">diff-pane</h5>
|
|
||||||
<p class="m-b">Atom - Diff two panes.</p>
|
|
||||||
<a href="https://github.com/t-ari/diff-pane" target="_blank"
|
|
||||||
class="btn btn-primary-outline btn-sm m-b">
|
|
||||||
<span class="icon icon-add-user"></span> View GitHub
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-xs-12 col-sm-6 col-md-3 m-b-lg">
|
|
||||||
<div class="panel panel-default panel-profile m-b-0">
|
|
||||||
<div class="panel-body text-center">
|
|
||||||
<h5 class="panel-title">node-giff</h5>
|
|
||||||
<p class="m-b">Display git diff on browser.</p>
|
|
||||||
<a href="https://github.com/do7be/node-giff" target="_blank"
|
|
||||||
class="btn btn-primary-outline btn-sm m-b">
|
|
||||||
<span class="icon icon-add-user"></span> View GitHub
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-xs-12 col-sm-6 col-md-3 m-b-lg">
|
|
||||||
<div class="panel panel-default panel-profile m-b-0">
|
|
||||||
<div class="panel-body text-center">
|
|
||||||
<h5 class="panel-title">edgar-monitor</h5>
|
|
||||||
<p class="m-b">A module that processes new Edgar filings and sends out
|
|
||||||
notifications.</p>
|
|
||||||
<a href="https://github.com/buzzfeed-openlab/edgar-monitor" target="_blank"
|
|
||||||
class="btn btn-primary-outline btn-sm m-b">
|
|
||||||
<span class="icon icon-add-user"></span> View GitHub
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-xs-12 col-sm-6 col-md-3 m-b-lg">
|
|
||||||
<div class="panel panel-default panel-profile m-b-0">
|
|
||||||
<div class="panel-body text-center">
|
|
||||||
<h5 class="panel-title">node-git</h5>
|
|
||||||
<p class="m-b">Execute Git Command by Node.js.</p>
|
|
||||||
<a href="https://github.com/liangshuai/node-git" target="_blank"
|
|
||||||
class="btn btn-primary-outline btn-sm m-b">
|
|
||||||
<span class="icon icon-add-user"></span> View GitHub
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-xs-12 col-sm-6 col-md-3 m-b-lg">
|
|
||||||
<div class="panel panel-default panel-profile m-b-0">
|
|
||||||
<div class="panel-body text-center">
|
|
||||||
<h5 class="panel-title">Jenkins</h5>
|
|
||||||
<p class="m-b">Show diffs between builds</p>
|
|
||||||
<a href="https://wiki.jenkins-ci.org/display/JENKINS/Last+Changes+Plugin" target="_blank"
|
|
||||||
class="btn btn-primary-outline btn-sm m-b">
|
|
||||||
<span class="icon icon-add-user"></span> Website
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-xs-12 col-sm-6 col-md-3 m-b-lg">
|
|
||||||
<div class="panel panel-default panel-profile m-b-0">
|
|
||||||
<div class="panel-body text-center">
|
|
||||||
<h5 class="panel-title">Light Review</h5>
|
|
||||||
<p class="m-b">Code Reviews with maximum control for the leading developers</p>
|
|
||||||
<a href="http://light-review.com/" target="_blank"
|
|
||||||
class="btn btn-primary-outline btn-sm m-b">
|
|
||||||
<span class="icon icon-add-user"></span> Website
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-xs-12 col-sm-6 col-md-3 m-b-lg">
|
|
||||||
<div class="panel panel-default panel-profile m-b-0">
|
|
||||||
<div class="panel-body text-center">
|
|
||||||
<h5 class="panel-title">Simple Git</h5>
|
|
||||||
<p class="m-b">A simple package to be able to drive GIT</p>
|
|
||||||
<a href="https://github.com/mauricioszabo/simple-git" target="_blank"
|
|
||||||
class="btn btn-primary-outline btn-sm m-b">
|
|
||||||
<span class="icon icon-add-user"></span> View GitHub
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row row-padded-small text-center">
|
|
||||||
<div class="col-sm-8 col-sm-offset-2 text-center">
|
|
||||||
<h3><strong>Open Source</strong></h3>
|
|
||||||
<h4 class="m-b-md">diff2html is open source.
|
|
||||||
If you'd like to be part of the diff2html community or help us improve,
|
|
||||||
find us on <a href="https://github.com/rtfpessoa/diff2html" target="_blank">GitHub</a> and
|
|
||||||
<a href="https://gitter.im/rtfpessoa/diff2html" target="_blank">Gitter</a>. Need any help?
|
|
||||||
</h4>
|
|
||||||
<a class="btn btn-md" href="https://github.com/rtfpessoa/diff2html#how-to-use" target="_blank">
|
|
||||||
Read more in the Docs
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<footer class="footer clearfix">
|
|
||||||
<p class="col-xs-10 col-xs-offset-1">
|
|
||||||
Website originally designed and built by
|
|
||||||
<a href="https://twitter.com/mdo" target="_blank">@mdo</a>,
|
|
||||||
<a href="https://twitter.com/fat" target="_blank">@fat</a>, and
|
|
||||||
<a href="https://twitter.com/dhg" target="_blank">@dhg</a>,
|
|
||||||
adapted with <span class="hero-red">❤</span> by
|
|
||||||
<a href="https://twitter.com/rtfpessoa" target="_blank">@rtfpessoa</a>.
|
|
||||||
</p>
|
|
||||||
<ul class="footer-list col-xs-10 col-xs-offset-1">
|
|
||||||
|
|
||||||
<li class="footer-list-item">
|
|
||||||
<a class="footer-list-link" href="https://github.com/rtfpessoa/diff2html#how-to-use"
|
|
||||||
target="_blank">FAQ</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li class="footer-list-item">
|
|
||||||
<a class="footer-list-link" href="https://diff2html.xyz">diff2html</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
</ul>
|
|
||||||
</footer>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- General JavaScript -->
|
|
||||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.3/jquery.min.js"></script>
|
|
||||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"
|
|
||||||
integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS"
|
|
||||||
crossorigin="anonymous"></script>
|
|
||||||
|
|
||||||
<script type="application/ld+json">
|
|
||||||
{
|
|
||||||
"@context": "http://schema.org/",
|
|
||||||
"@type": "SoftwareSourceCode",
|
|
||||||
"name": "diff2html",
|
|
||||||
"author": "Rodrigo Fernandes",
|
|
||||||
"image": "https://diff2html.xyz/img/snapshot-3.png",
|
|
||||||
"description": "Diff parser and pretty html generator.",
|
|
||||||
"codeRepository": "https://github.com/rtfpessoa/diff2html",
|
|
||||||
"programmingLanguage": "JavaScript",
|
|
||||||
"runtimePlatform": "Node >= 0.12",
|
|
||||||
"mainEntityOfPage": "https://diff2html.xyz/"
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/1.5.10/clipboard.min.js"></script>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
new Clipboard(document.getElementsByClassName("btn-clipboard"));
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
564
docs/main.css
564
docs/main.css
File diff suppressed because one or more lines are too long
4
docs/main.min.css
vendored
4
docs/main.min.css
vendored
File diff suppressed because one or more lines are too long
|
|
@ -1 +0,0 @@
|
||||||
User-agent: *
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<urlset
|
|
||||||
xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
|
|
||||||
http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
|
|
||||||
<url>
|
|
||||||
<loc>https://diff2html.xyz/</loc>
|
|
||||||
</url>
|
|
||||||
<url>
|
|
||||||
<loc>https://diff2html.xyz/index.html</loc>
|
|
||||||
</url>
|
|
||||||
<url>
|
|
||||||
<loc>https://diff2html.xyz/demo.html</loc>
|
|
||||||
</url>
|
|
||||||
</urlset>
|
|
||||||
15
jest.config.js
Normal file
15
jest.config.js
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
module.exports = {
|
||||||
|
verbose: true,
|
||||||
|
preset: "ts-jest",
|
||||||
|
testEnvironment: "node",
|
||||||
|
coverageDirectory: "./coverage",
|
||||||
|
coverageReporters: ["lcov", "text", "html"],
|
||||||
|
coverageThreshold: {
|
||||||
|
global: {
|
||||||
|
statements: 90,
|
||||||
|
branches: 85,
|
||||||
|
functions: 90,
|
||||||
|
lines: 90
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
59
package.json
59
package.json
|
|
@ -34,22 +34,25 @@
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=4"
|
"node": ">=4"
|
||||||
},
|
},
|
||||||
"preferGlobal": true,
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"release": "./scripts/release.sh",
|
"build": "tsc",
|
||||||
"release-website": "./scripts/release-website.sh",
|
"lint": "eslint '*/**/*.{js,jsx,ts,tsx}'",
|
||||||
"templates": "./scripts/hulk.js --wrapper node --variable 'browserTemplates' ./src/templates/*.mustache > ./src/templates/diff2html-templates.js",
|
|
||||||
"style": "yarn run lint",
|
"style": "yarn run lint",
|
||||||
"lint": "eslint .",
|
"test": "jest",
|
||||||
"coverage": "istanbul cover _mocha -- -u exports -R spec ./test/**/*",
|
"coverage": "jest --collectCoverage",
|
||||||
"check-coverage": "istanbul check-coverage --statements 90 --functions 90 --branches 85 --lines 90 ./coverage/coverage.json",
|
"coverage-html": "yarn run coverage && open ./coverage/index.html",
|
||||||
"test": "yarn run coverage && yarn run check-coverage",
|
|
||||||
"codacy": "cat ./coverage/lcov.info | codacy-coverage",
|
"codacy": "cat ./coverage/lcov.info | codacy-coverage",
|
||||||
"preversion": "yarn run release && yarn run release-website && yarn run lint && yarn test",
|
"release": "yarn run release-css && yarn run release-templates && yarn run release-ts && yarn run release-browser-bundle && yarn run release-website",
|
||||||
"version": "git add -A src dist docs package.json",
|
"release-css": "./scripts/release-css.sh",
|
||||||
|
"release-templates": "./scripts/release-templates.sh",
|
||||||
|
"release-ts": "yarn run build",
|
||||||
|
"release-browser-bundle": "./scripts/release-browser-bundle.sh",
|
||||||
|
"release-website": "./scripts/release-website.sh",
|
||||||
|
"preversion": "yarn run release && yarn run lint && yarn test",
|
||||||
|
"version": "git add -A package.json",
|
||||||
"postversion": "git push && git push --tags"
|
"postversion": "git push && git push --tags"
|
||||||
},
|
},
|
||||||
"main": "./src/diff2html.js",
|
"main": "./build/commonjs-node/diff2html.js",
|
||||||
"browser": {
|
"browser": {
|
||||||
"fs": false
|
"fs": false
|
||||||
},
|
},
|
||||||
|
|
@ -60,28 +63,38 @@
|
||||||
"whatwg-fetch": "^3.0.0"
|
"whatwg-fetch": "^3.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/jest": "24.0.18",
|
||||||
|
"@types/node": "^12.7.2",
|
||||||
|
"@typescript-eslint/eslint-plugin": "2.0.0",
|
||||||
|
"@typescript-eslint/parser": "2.0.0",
|
||||||
"autoprefixer": "^9.6.0",
|
"autoprefixer": "^9.6.0",
|
||||||
"browserify": "^16.2.3",
|
"browserify": "^16.5.0",
|
||||||
"clean-css-cli": "^4.3.0",
|
"clean-css-cli": "^4.3.0",
|
||||||
"codacy-coverage": "^3.4.0",
|
"codacy-coverage": "^3.4.0",
|
||||||
"eslint": "^5.16.0",
|
"eslint": "6.2.2",
|
||||||
"eslint-plugin-promise": "^4.1.1",
|
"eslint-config-prettier": "6.1.0",
|
||||||
"eslint-plugin-standard": "^4.0.0",
|
"eslint-config-standard": "14.0.1",
|
||||||
|
"eslint-plugin-import": "2.18.2",
|
||||||
|
"eslint-plugin-jest": "22.15.2",
|
||||||
|
"eslint-plugin-node": "9.1.0",
|
||||||
|
"eslint-plugin-prettier": "3.1.0",
|
||||||
|
"eslint-plugin-promise": "^4.2.1",
|
||||||
|
"eslint-plugin-standard": "^4.0.1",
|
||||||
"fast-html-parser": "^1.0.1",
|
"fast-html-parser": "^1.0.1",
|
||||||
"istanbul": "^0.4.5",
|
"jest": "24.9.0",
|
||||||
"mkdirp": "^0.5.1",
|
"mkdirp": "^0.5.1",
|
||||||
"mocha": "5.2.0",
|
|
||||||
"nopt": "^4.0.1",
|
"nopt": "^4.0.1",
|
||||||
"postcss-cli": "^6.1.2",
|
"postcss-cli": "^6.1.3",
|
||||||
"uglify-js": "^3.6.0"
|
"prettier": "1.18.2",
|
||||||
|
"ts-jest": "24.0.2",
|
||||||
|
"typescript": "^3.6.3",
|
||||||
|
"terser": "^4.3.8"
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
"lodash": "4.17.14"
|
"lodash": "4.17.15"
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"files": [
|
"files": [
|
||||||
"src",
|
"build"
|
||||||
"dist",
|
|
||||||
"typescript"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
151
scripts/hulk.js
151
scripts/hulk.js
|
|
@ -16,61 +16,66 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// dependencies
|
// dependencies
|
||||||
var hogan = require('hogan.js');
|
const path = require("path");
|
||||||
var path = require('path');
|
const fs = require("fs");
|
||||||
var nopt = require('nopt');
|
const hogan = require("hogan.js");
|
||||||
var mkderp = require('mkdirp');
|
const nopt = require("nopt");
|
||||||
var fs = require('fs');
|
const mkderp = require("mkdirp");
|
||||||
|
|
||||||
// locals
|
// locals
|
||||||
var specials = ['/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\'];
|
const specials = ["/", ".", "*", "+", "?", "|", "(", ")", "[", "]", "{", "}", "\\"];
|
||||||
var specialsRegExp = new RegExp('(\\' + specials.join('|\\') + ')', 'g');
|
const specialsRegExp = new RegExp("(\\" + specials.join("|\\") + ")", "g");
|
||||||
var options = {
|
let options = {
|
||||||
'namespace': String,
|
namespace: String,
|
||||||
'outputdir': path,
|
outputdir: path,
|
||||||
'variable': String,
|
variable: String,
|
||||||
'wrapper': String,
|
wrapper: String,
|
||||||
'version': true,
|
version: true,
|
||||||
'help': true
|
help: true
|
||||||
};
|
};
|
||||||
var shortHand = {
|
const shortHand = {
|
||||||
'n': ['--namespace'],
|
n: ["--namespace"],
|
||||||
'o': ['--outputdir'],
|
o: ["--outputdir"],
|
||||||
'vn': ['--variable'],
|
vn: ["--variable"],
|
||||||
'w': ['--wrapper'],
|
w: ["--wrapper"],
|
||||||
'h': ['--help'],
|
h: ["--help"],
|
||||||
'v': ['--version']
|
v: ["--version"]
|
||||||
};
|
};
|
||||||
var templates;
|
let templates;
|
||||||
|
|
||||||
// options
|
// options
|
||||||
options = nopt(options, shortHand);
|
options = nopt(options, shortHand);
|
||||||
|
|
||||||
// escape special regexp characters
|
// escape special regexp characters
|
||||||
function esc(text) {
|
function esc(text) {
|
||||||
return text.replace(specialsRegExp, '\\$1');
|
return text.replace(specialsRegExp, "\\$1");
|
||||||
}
|
}
|
||||||
|
|
||||||
// cyan function for rob
|
// cyan function for rob
|
||||||
function cyan(text) {
|
function cyan(text) {
|
||||||
return '\x1B[36m' + text + '\x1B[39m';
|
return "\x1B[36m" + text + "\x1B[39m";
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for dirs and correct ext (<3 for windows)
|
// check for dirs and correct ext (<3 for windows)
|
||||||
function extractFiles(args) {
|
function extractFiles(args) {
|
||||||
var usage = '\n' +
|
const usage =
|
||||||
cyan('USAGE:') + ' hulk [--wrapper wrapper] [--outputdir outputdir] ' +
|
"\n" +
|
||||||
'[--namespace namespace] [--variable variable] FILES\n\n' +
|
cyan("USAGE:") +
|
||||||
cyan('OPTIONS:') + ' [-w, --wrapper] :: wraps the template (i.e. amd)\n' +
|
" hulk [--wrapper wrapper] [--outputdir outputdir] " +
|
||||||
' [-o, --outputdir] :: outputs the templates as individual files to a directory\n\n' +
|
"[--namespace namespace] [--variable variable] FILES\n\n" +
|
||||||
' [-n, --namespace] :: prepend string to template names\n\n' +
|
cyan("OPTIONS:") +
|
||||||
' [-vn, --variable] :: variable name for non-amd wrapper\n\n' +
|
" [-w, --wrapper] :: wraps the template (i.e. amd)\n" +
|
||||||
cyan('EXAMPLE:') + ' hulk --wrapper amd ./templates/*.mustache\n\n' +
|
" [-o, --outputdir] :: outputs the templates as individual files to a directory\n\n" +
|
||||||
cyan('NOTE:') + ' hulk supports the "*" wildcard and allows you to target specific extensions too\n';
|
" [-n, --namespace] :: prepend string to template names\n\n" +
|
||||||
var files = [];
|
" [-vn, --variable] :: variable name for non-amd wrapper\n\n" +
|
||||||
|
cyan("EXAMPLE:") +
|
||||||
|
" hulk --wrapper amd ./templates/*.mustache\n\n" +
|
||||||
|
cyan("NOTE:") +
|
||||||
|
' hulk supports the "*" wildcard and allows you to target specific extensions too\n';
|
||||||
|
let files = [];
|
||||||
|
|
||||||
if (options.version) {
|
if (options.version) {
|
||||||
console.log(require('../package.json').version);
|
console.log(require("../package.json").version);
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -81,12 +86,13 @@ function extractFiles(args) {
|
||||||
|
|
||||||
args.forEach(function(arg) {
|
args.forEach(function(arg) {
|
||||||
if (/\*/.test(arg)) {
|
if (/\*/.test(arg)) {
|
||||||
arg = arg.split('*');
|
arg = arg.split("*");
|
||||||
files = files.concat(
|
files = files.concat(
|
||||||
fs.readdirSync(arg[0] || '.')
|
fs
|
||||||
|
.readdirSync(arg[0] || ".")
|
||||||
.map(function(f) {
|
.map(function(f) {
|
||||||
var file = path.join(arg[0], f);
|
const file = path.join(arg[0], f);
|
||||||
return new RegExp(esc(arg[1]) + '$').test(f) && fs.statSync(file).isFile() && file;
|
return new RegExp(esc(arg[1]) + "$").test(f) && fs.statSync(file).isFile() && file;
|
||||||
})
|
})
|
||||||
.filter(function(f) {
|
.filter(function(f) {
|
||||||
return f;
|
return f;
|
||||||
|
|
@ -112,51 +118,65 @@ function removeByteOrderMark(text) {
|
||||||
// wrap templates
|
// wrap templates
|
||||||
function wrap(file, name, openedFile) {
|
function wrap(file, name, openedFile) {
|
||||||
switch (options.wrapper) {
|
switch (options.wrapper) {
|
||||||
case 'amd':
|
case "amd":
|
||||||
return 'define(' + (!options.outputdir ? '"' + path.join(path.dirname(file), name) + '", ' : '') +
|
return (
|
||||||
|
"define(" +
|
||||||
|
(!options.outputdir ? '"' + path.join(path.dirname(file), name) + '", ' : "") +
|
||||||
'[ "hogan.js" ], function(Hogan){ return new Hogan.Template(' +
|
'[ "hogan.js" ], function(Hogan){ return new Hogan.Template(' +
|
||||||
hogan.compile(openedFile, { asString: 1 }) +
|
hogan.compile(openedFile, { asString: 1 }) +
|
||||||
');});';
|
");});"
|
||||||
case 'node':
|
);
|
||||||
var globalObj = 'global.' + (options.variable || 'templates') + '["' + name + '"]';
|
case "node":
|
||||||
var globalStmt = globalObj + ' = new Hogan.Template(' + hogan.compile(openedFile, {asString: 1}) + ');';
|
var globalObj = "global." + (options.variable || "templates") + '["' + name + '"]';
|
||||||
|
var globalStmt = globalObj + " = new Hogan.Template(" + hogan.compile(openedFile, { asString: 1 }) + ");";
|
||||||
var nodeOutput = globalStmt;
|
var nodeOutput = globalStmt;
|
||||||
|
|
||||||
// if we have a template per file the export will expose the template directly
|
// if we have a template per file the export will expose the template directly
|
||||||
if (options.outputdir) {
|
if (options.outputdir) {
|
||||||
nodeOutput = nodeOutput + '\n' + 'module.exports = ' + globalObj + ';';
|
nodeOutput = nodeOutput + "\n" + "module.exports = " + globalObj + ";";
|
||||||
}
|
}
|
||||||
|
|
||||||
return nodeOutput;
|
return nodeOutput;
|
||||||
default:
|
default:
|
||||||
return (options.variable || 'templates') +
|
return (
|
||||||
'["' + name + '"] = new Hogan.Template(' +
|
(options.variable || "templates") +
|
||||||
|
'["' +
|
||||||
|
name +
|
||||||
|
'"] = new Hogan.Template(' +
|
||||||
hogan.compile(openedFile, { asString: 1 }) +
|
hogan.compile(openedFile, { asString: 1 }) +
|
||||||
');';
|
");"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function prepareOutput(content) {
|
function prepareOutput(content) {
|
||||||
var variableName = options.variable || 'templates';
|
const variableName = options.variable || "templates";
|
||||||
switch (options.wrapper) {
|
switch (options.wrapper) {
|
||||||
case 'amd':
|
case "amd":
|
||||||
return content;
|
return content;
|
||||||
case 'node':
|
case "node":
|
||||||
var nodeExport = '';
|
var nodeExport = "";
|
||||||
|
|
||||||
// if we have aggregated templates the export will expose the template map
|
// if we have aggregated templates the export will expose the template map
|
||||||
if (!options.outputdir) {
|
if (!options.outputdir) {
|
||||||
nodeExport = 'module.exports = global.' + variableName + ';\n';
|
nodeExport = "module.exports = global." + variableName + ";\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return '(function() {\n' +
|
return (
|
||||||
'if (!!!global.' + variableName + ') global.' + variableName + ' = {};\n' +
|
"(function() {\n" +
|
||||||
|
"if (!!!global." +
|
||||||
|
variableName +
|
||||||
|
") global." +
|
||||||
|
variableName +
|
||||||
|
" = {};\n" +
|
||||||
'var Hogan = require("hogan.js");' +
|
'var Hogan = require("hogan.js");' +
|
||||||
content + '\n' +
|
content +
|
||||||
|
"\n" +
|
||||||
nodeExport +
|
nodeExport +
|
||||||
'})();';
|
"})();"
|
||||||
|
);
|
||||||
default:
|
default:
|
||||||
return 'if (!!!' + variableName + ') var ' + variableName + ' = {};\n' + content;
|
return "if (!!!" + variableName + ") var " + variableName + " = {};\n" + content;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -167,21 +187,20 @@ if (options.outputdir) {
|
||||||
|
|
||||||
// Prepend namespace to template name
|
// Prepend namespace to template name
|
||||||
function namespace(name) {
|
function namespace(name) {
|
||||||
return (options.namespace || '') + name;
|
return (options.namespace || "") + name;
|
||||||
}
|
}
|
||||||
|
|
||||||
// write a template foreach file that matches template extension
|
// write a template foreach file that matches template extension
|
||||||
templates = extractFiles(options.argv.remain)
|
templates = extractFiles(options.argv.remain)
|
||||||
.map(function(file) {
|
.map(function(file) {
|
||||||
var openedFile = fs.readFileSync(file, 'utf-8').trim();
|
let openedFile = fs.readFileSync(file, "utf-8").trim();
|
||||||
var name;
|
let name;
|
||||||
if (!openedFile) return;
|
if (!openedFile) return;
|
||||||
name = namespace(path.basename(file).replace(/\..*$/, ''));
|
name = namespace(path.basename(file).replace(/\..*$/, ""));
|
||||||
openedFile = removeByteOrderMark(openedFile);
|
openedFile = removeByteOrderMark(openedFile);
|
||||||
openedFile = wrap(file, name, openedFile);
|
openedFile = wrap(file, name, openedFile);
|
||||||
if (!options.outputdir) return openedFile;
|
if (!options.outputdir) return openedFile;
|
||||||
fs.writeFileSync(path.join(options.outputdir, name + '.js')
|
fs.writeFileSync(path.join(options.outputdir, name + ".js"), prepareOutput(openedFile));
|
||||||
, prepareOutput(openedFile));
|
|
||||||
})
|
})
|
||||||
.filter(function(t) {
|
.filter(function(t) {
|
||||||
return t;
|
return t;
|
||||||
|
|
@ -190,4 +209,4 @@ templates = extractFiles(options.argv.remain)
|
||||||
// output templates
|
// output templates
|
||||||
if (!templates.length || options.outputdir) process.exit(0);
|
if (!templates.length || options.outputdir) process.exit(0);
|
||||||
|
|
||||||
console.log(prepareOutput(templates.join('\n')));
|
console.log(prepareOutput(templates.join("\n")));
|
||||||
|
|
|
||||||
36
scripts/release-browser-bundle.sh
Executable file
36
scripts/release-browser-bundle.sh
Executable file
|
|
@ -0,0 +1,36 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
SCRIPT_DIRECTORY="$( cd "$( dirname "$0" )" && pwd )"
|
||||||
|
|
||||||
|
INPUT_DIR=${SCRIPT_DIRECTORY}/../build/commonjs-node
|
||||||
|
INPUT_UI_DIR=${INPUT_DIR}/ui
|
||||||
|
INPUT_JS_FILE=${INPUT_DIR}/diff2html.js
|
||||||
|
INPUT_JS_UI_FILE=${INPUT_UI_DIR}/js/diff2html-ui.js
|
||||||
|
|
||||||
|
OUTPUT_DIR=${SCRIPT_DIRECTORY}/../build/browser
|
||||||
|
OUTPUT_JS_FILE=${OUTPUT_DIR}/diff2html.js
|
||||||
|
OUTPUT_MIN_JS_FILE=${OUTPUT_DIR}/diff2html.min.js
|
||||||
|
OUTPUT_JS_UI_FILE=${OUTPUT_DIR}/diff2html-ui.js
|
||||||
|
OUTPUT_MIN_JS_UI_FILE=${OUTPUT_DIR}/diff2html-ui.min.js
|
||||||
|
|
||||||
|
echo "Creating diff2html browser bundle ..."
|
||||||
|
|
||||||
|
echo "Cleaning previous versions ..."
|
||||||
|
rm -rf ${OUTPUT_DIR}
|
||||||
|
mkdir -p ${OUTPUT_DIR}
|
||||||
|
|
||||||
|
echo "Generating js aggregation file in ${OUTPUT_JS_FILE}"
|
||||||
|
browserify -e ${INPUT_JS_FILE} -o ${OUTPUT_JS_FILE}
|
||||||
|
|
||||||
|
echo "Minifying ${OUTPUT_JS_FILE} to ${OUTPUT_MIN_JS_FILE}"
|
||||||
|
terser ${OUTPUT_JS_FILE} -c -o ${OUTPUT_MIN_JS_FILE}
|
||||||
|
|
||||||
|
echo "Generating js ui aggregation file in ${OUTPUT_JS_UI_FILE}"
|
||||||
|
browserify -e ${INPUT_JS_UI_FILE} -o ${OUTPUT_JS_UI_FILE}
|
||||||
|
|
||||||
|
echo "Minifying ${OUTPUT_JS_UI_FILE} to ${OUTPUT_MIN_JS_UI_FILE}"
|
||||||
|
terser ${OUTPUT_JS_UI_FILE} -c -o ${OUTPUT_MIN_JS_UI_FILE}
|
||||||
|
|
||||||
|
echo "diff2html browser bundle created successfully!"
|
||||||
25
scripts/release-css.sh
Executable file
25
scripts/release-css.sh
Executable file
|
|
@ -0,0 +1,25 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
SCRIPT_DIRECTORY="$( cd "$( dirname "$0" )" && pwd )"
|
||||||
|
|
||||||
|
INPUT_DIR=${SCRIPT_DIRECTORY}/../src
|
||||||
|
INPUT_UI_DIR=${INPUT_DIR}/ui
|
||||||
|
INPUT_CSS_FILE=${INPUT_UI_DIR}/css/diff2html.css
|
||||||
|
|
||||||
|
OUTPUT_DIR=${SCRIPT_DIRECTORY}/../build/css
|
||||||
|
OUTPUT_CSS_FILE=${OUTPUT_DIR}/diff2html.css
|
||||||
|
OUTPUT_MIN_CSS_FILE=${OUTPUT_DIR}/diff2html.min.css
|
||||||
|
|
||||||
|
echo "Creating diff2html css ..."
|
||||||
|
|
||||||
|
echo "Cleaning previous versions ..."
|
||||||
|
rm -rf ${OUTPUT_DIR}
|
||||||
|
mkdir -p ${OUTPUT_DIR}
|
||||||
|
|
||||||
|
echo "Minifying ${OUTPUT_CSS_FILE} to ${OUTPUT_MIN_CSS_FILE}"
|
||||||
|
postcss --use autoprefixer -o ${OUTPUT_CSS_FILE} ${INPUT_CSS_FILE}
|
||||||
|
cleancss --advanced --compatibility=ie8 -o ${OUTPUT_MIN_CSS_FILE} ${OUTPUT_CSS_FILE}
|
||||||
|
|
||||||
|
echo "diff2html css created successfully!"
|
||||||
10
scripts/release-templates.sh
Executable file
10
scripts/release-templates.sh
Executable file
|
|
@ -0,0 +1,10 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
SCRIPT_DIRECTORY="$( cd "$( dirname "$0" )" && pwd )"
|
||||||
|
|
||||||
|
node ${SCRIPT_DIRECTORY}/hulk.js \
|
||||||
|
--wrapper node \
|
||||||
|
--variable 'browserTemplates' \
|
||||||
|
${SCRIPT_DIRECTORY}/../src/templates/*.mustache > ${SCRIPT_DIRECTORY}/../src/diff2html-templates.js
|
||||||
|
|
@ -1,34 +1,38 @@
|
||||||
var fs = require('fs');
|
#!/usr/bin/env node
|
||||||
|
|
||||||
var hogan = require('hogan.js');
|
const fs = require("fs");
|
||||||
|
|
||||||
var root = 'website/templates';
|
const hogan = require("hogan.js");
|
||||||
var pagesRoot = root + '/pages';
|
|
||||||
|
|
||||||
var websitePages = fs.readdirSync(root + '/pages');
|
const root = "website/templates";
|
||||||
|
const pagesRoot = root + "/pages";
|
||||||
|
|
||||||
var template = hogan.compile(readFile(root + '/template.mustache'));
|
const websitePages = fs.readdirSync(root + "/pages");
|
||||||
|
|
||||||
var options = {
|
const template = hogan.compile(readFile(root + "/template.mustache"));
|
||||||
'all': {
|
|
||||||
'demoUrl': 'demo.html?diff=https://github.com/rtfpessoa/diff2html/pull/106'
|
const options = {
|
||||||
|
all: {
|
||||||
|
demoUrl: "demo.html?diff=https://github.com/rtfpessoa/diff2html/pull/106"
|
||||||
},
|
},
|
||||||
'demo': {
|
demo: {
|
||||||
'extraClass': 'template-index-min'
|
extraClass: "template-index-min"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
websitePages.map(function(page) {
|
websitePages.map(function(page) {
|
||||||
var pagePartialTemplate = hogan.compile(readFile(pagesRoot + '/' + page + '/' + page + '.partial.mustache'));
|
const pagePartialTemplate = hogan.compile(readFile(pagesRoot + "/" + page + "/" + page + ".partial.mustache"));
|
||||||
var pageAssetsTemplate = hogan.compile(readFile(pagesRoot + '/' + page + '/' + page + '-assets.partial.mustache'));
|
const pageAssetsTemplate = hogan.compile(readFile(pagesRoot + "/" + page + "/" + page + "-assets.partial.mustache"));
|
||||||
var pageScriptsTemplate = hogan.compile(readFile(pagesRoot + '/' + page + '/' + page + '-scripts.partial.mustache'));
|
const pageScriptsTemplate = hogan.compile(
|
||||||
|
readFile(pagesRoot + "/" + page + "/" + page + "-scripts.partial.mustache")
|
||||||
|
);
|
||||||
|
|
||||||
var templateOptions = {};
|
const templateOptions = {};
|
||||||
|
|
||||||
var key;
|
let key;
|
||||||
|
|
||||||
// Allow the pages to share common options
|
// Allow the pages to share common options
|
||||||
var genericOptions = options['all'] || {};
|
const genericOptions = options.all || {};
|
||||||
for (key in genericOptions) {
|
for (key in genericOptions) {
|
||||||
if (genericOptions.hasOwnProperty(key)) {
|
if (genericOptions.hasOwnProperty(key)) {
|
||||||
templateOptions[key] = genericOptions[key];
|
templateOptions[key] = genericOptions[key];
|
||||||
|
|
@ -36,32 +40,31 @@ websitePages.map(function(page) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow each page to have custom options
|
// Allow each page to have custom options
|
||||||
var pageOptions = options[page] || {};
|
const pageOptions = options[page] || {};
|
||||||
for (key in pageOptions) {
|
for (key in pageOptions) {
|
||||||
if (pageOptions.hasOwnProperty(key)) {
|
if (pageOptions.hasOwnProperty(key)) {
|
||||||
templateOptions[key] = pageOptions[key];
|
templateOptions[key] = pageOptions[key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var pagePartial = pagePartialTemplate.render(templateOptions);
|
const pagePartial = pagePartialTemplate.render(templateOptions);
|
||||||
var pageAssets = pageAssetsTemplate.render(templateOptions);
|
const pageAssets = pageAssetsTemplate.render(templateOptions);
|
||||||
var pageScripts = pageScriptsTemplate.render(templateOptions);
|
const pageScripts = pageScriptsTemplate.render(templateOptions);
|
||||||
|
|
||||||
templateOptions.assets = pageAssets;
|
templateOptions.assets = pageAssets;
|
||||||
templateOptions.scripts = pageScripts;
|
templateOptions.scripts = pageScripts;
|
||||||
templateOptions.content = pagePartial;
|
templateOptions.content = pagePartial;
|
||||||
|
|
||||||
var pageHtml = template.render(templateOptions);
|
const pageHtml = template.render(templateOptions);
|
||||||
writeFile('docs/' + page + '.html', pageHtml);
|
writeFile("docs/" + page + ".html", pageHtml);
|
||||||
});
|
});
|
||||||
|
|
||||||
function readFile(filePath) {
|
function readFile(filePath) {
|
||||||
try {
|
try {
|
||||||
return fs.readFileSync(filePath, 'utf8');
|
return fs.readFileSync(filePath, "utf8");
|
||||||
} catch (_ignore) {
|
} catch (_ignore) {}
|
||||||
}
|
|
||||||
|
|
||||||
return '';
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
function writeFile(filePath, content) {
|
function writeFile(filePath, content) {
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,14 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
#
|
|
||||||
# diff2html website release script
|
|
||||||
# by rtfpessoa
|
|
||||||
#
|
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
INPUT_DIR=website
|
SCRIPT_DIRECTORY="$( cd "$( dirname "$0" )" && pwd )"
|
||||||
|
|
||||||
|
INPUT_DIR=${SCRIPT_DIRECTORY}/../website
|
||||||
INPUT_DEMO_JS=${INPUT_DIR}/templates/pages/demo/demo.js
|
INPUT_DEMO_JS=${INPUT_DIR}/templates/pages/demo/demo.js
|
||||||
INPUT_CSS_FILE=${INPUT_DIR}/main.css
|
INPUT_CSS_FILE=${INPUT_DIR}/main.css
|
||||||
|
|
||||||
OUTPUT_DIR=docs
|
OUTPUT_DIR=${SCRIPT_DIRECTORY}/../docs
|
||||||
OUTPUT_DEMO_JS=${OUTPUT_DIR}/demo.js
|
OUTPUT_DEMO_JS=${OUTPUT_DIR}/demo.js
|
||||||
OUTPUT_DEMO_MIN_JS=${OUTPUT_DIR}/demo.min.js
|
OUTPUT_DEMO_MIN_JS=${OUTPUT_DIR}/demo.min.js
|
||||||
OUTPUT_CSS_FILE=${OUTPUT_DIR}/main.css
|
OUTPUT_CSS_FILE=${OUTPUT_DIR}/main.css
|
||||||
|
|
@ -21,7 +18,7 @@ echo "Creating diff2html website release ..."
|
||||||
|
|
||||||
echo "Cleaning previous versions ..."
|
echo "Cleaning previous versions ..."
|
||||||
rm -rf ${OUTPUT_DIR}
|
rm -rf ${OUTPUT_DIR}
|
||||||
mkdir -p ${OUTPUT_DIR}
|
mkdir -p ${OUTPUT_DIR}/assets
|
||||||
|
|
||||||
echo "Minifying ${OUTPUT_CSS_FILE} to ${OUTPUT_MIN_CSS_FILE}"
|
echo "Minifying ${OUTPUT_CSS_FILE} to ${OUTPUT_MIN_CSS_FILE}"
|
||||||
postcss --use autoprefixer -o ${OUTPUT_CSS_FILE} ${INPUT_CSS_FILE}
|
postcss --use autoprefixer -o ${OUTPUT_CSS_FILE} ${INPUT_CSS_FILE}
|
||||||
|
|
@ -31,10 +28,10 @@ echo "Generating website js aggregation file in ${OUTPUT_DEMO_JS}"
|
||||||
browserify -e ${INPUT_DEMO_JS} -o ${OUTPUT_DEMO_JS}
|
browserify -e ${INPUT_DEMO_JS} -o ${OUTPUT_DEMO_JS}
|
||||||
|
|
||||||
echo "Minifying ${OUTPUT_DEMO_JS} to ${OUTPUT_DEMO_MIN_JS}"
|
echo "Minifying ${OUTPUT_DEMO_JS} to ${OUTPUT_DEMO_MIN_JS}"
|
||||||
uglifyjs ${OUTPUT_DEMO_JS} -c -o ${OUTPUT_DEMO_MIN_JS}
|
terser ${OUTPUT_DEMO_JS} -c -o ${OUTPUT_DEMO_MIN_JS}
|
||||||
|
|
||||||
echo "Generating HTMLs from templates ..."
|
echo "Generating HTMLs from templates ..."
|
||||||
node ./scripts/release-website.js
|
node ${SCRIPT_DIRECTORY}/release-website.js
|
||||||
|
|
||||||
echo "Copying static files ..."
|
echo "Copying static files ..."
|
||||||
cp -rf ${INPUT_DIR}/img ${OUTPUT_DIR}/
|
cp -rf ${INPUT_DIR}/img ${OUTPUT_DIR}/
|
||||||
|
|
@ -43,7 +40,9 @@ cp -f ${INPUT_DIR}/favicon.ico ${OUTPUT_DIR}/
|
||||||
cp -f ${INPUT_DIR}/robots.txt ${OUTPUT_DIR}/
|
cp -f ${INPUT_DIR}/robots.txt ${OUTPUT_DIR}/
|
||||||
cp -f ${INPUT_DIR}/sitemap.xml ${OUTPUT_DIR}/
|
cp -f ${INPUT_DIR}/sitemap.xml ${OUTPUT_DIR}/
|
||||||
|
|
||||||
echo "Creating diff2html assets symlink ..."
|
echo "Copying diff2html resources ..."
|
||||||
ln -s ../dist docs/assets
|
cp ${SCRIPT_DIRECTORY}/../build/browser/diff2html.min.js ${SCRIPT_DIRECTORY}/../docs/assets/
|
||||||
|
cp ${SCRIPT_DIRECTORY}/../build/browser/diff2html-ui.min.js ${SCRIPT_DIRECTORY}/../docs/assets/
|
||||||
|
cp ${SCRIPT_DIRECTORY}/../build/css/diff2html.min.css ${SCRIPT_DIRECTORY}/../docs/assets/
|
||||||
|
|
||||||
echo "diff2html website release created successfully!"
|
echo "diff2html website release created successfully!"
|
||||||
|
|
|
||||||
|
|
@ -1,57 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
#
|
|
||||||
# diff2html release script
|
|
||||||
# by rtfpessoa
|
|
||||||
#
|
|
||||||
|
|
||||||
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
|
|
||||||
INPUT_CSS_FILE=${INPUT_UI_DIR}/css/diff2html.css
|
|
||||||
INPUT_TYPINGS_D_TS_FILE=${INPUT_DIR}/diff2html.d.ts
|
|
||||||
|
|
||||||
GENERATED_TEMPLATES_FILE=${INTPUT_TEMPLATES_DIR}/diff2html-templates.js
|
|
||||||
|
|
||||||
OUTPUT_DIR=dist
|
|
||||||
OUTPUT_JS_FILE=${OUTPUT_DIR}/diff2html.js
|
|
||||||
OUTPUT_MIN_JS_FILE=${OUTPUT_DIR}/diff2html.min.js
|
|
||||||
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_TYPINGS_D_TS_FILE=${OUTPUT_DIR}/diff2html.d.ts
|
|
||||||
|
|
||||||
echo "Creating diff2html release ..."
|
|
||||||
|
|
||||||
echo "Cleaning previous versions ..."
|
|
||||||
rm -rf ${OUTPUT_DIR}
|
|
||||||
mkdir -p ${OUTPUT_DIR}
|
|
||||||
|
|
||||||
echo "Minifying ${OUTPUT_CSS_FILE} to ${OUTPUT_MIN_CSS_FILE}"
|
|
||||||
postcss --use autoprefixer -o ${OUTPUT_CSS_FILE} ${INPUT_CSS_FILE}
|
|
||||||
cleancss --advanced --compatibility=ie8 -o ${OUTPUT_MIN_CSS_FILE} ${OUTPUT_CSS_FILE}
|
|
||||||
|
|
||||||
echo "Pre-compile hogan.js templates"
|
|
||||||
yarn run templates
|
|
||||||
|
|
||||||
echo "Generating js aggregation file in ${OUTPUT_JS_FILE}"
|
|
||||||
browserify -e ${INPUT_JS_FILE} -o ${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}"
|
|
||||||
browserify -e ${INPUT_JS_UI_FILE} -o ${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 types ${INPUT_TYPINGS_D_TS_FILE} to ${OUTPUT_TYPINGS_D_TS_FILE}"
|
|
||||||
cp -f ${INPUT_TYPINGS_D_TS_FILE} ${OUTPUT_TYPINGS_D_TS_FILE}
|
|
||||||
|
|
||||||
echo "diff2html release created successfully!"
|
|
||||||
728
src/__tests__/diff-parser-tests.js
Normal file
728
src/__tests__/diff-parser-tests.js
Normal file
|
|
@ -0,0 +1,728 @@
|
||||||
|
const DiffParser = require("../diff-parser.js").DiffParser;
|
||||||
|
|
||||||
|
function checkDiffSample(diff) {
|
||||||
|
const result = DiffParser.generateDiffJson(diff);
|
||||||
|
const file1 = result[0];
|
||||||
|
expect(1).toEqual(result.length);
|
||||||
|
expect(1).toEqual(file1.addedLines);
|
||||||
|
expect(1).toEqual(file1.deletedLines);
|
||||||
|
expect("sample").toEqual(file1.oldName);
|
||||||
|
expect("sample").toEqual(file1.newName);
|
||||||
|
expect(1).toEqual(file1.blocks.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("DiffParser", function() {
|
||||||
|
describe("generateDiffJson", function() {
|
||||||
|
it("should parse unix with \n diff", function() {
|
||||||
|
const diff =
|
||||||
|
"diff --git a/sample b/sample\n" +
|
||||||
|
"index 0000001..0ddf2ba\n" +
|
||||||
|
"--- a/sample\n" +
|
||||||
|
"+++ b/sample\n" +
|
||||||
|
"@@ -1 +1 @@\n" +
|
||||||
|
"-test\n" +
|
||||||
|
"+test1r\n";
|
||||||
|
checkDiffSample(diff);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should parse windows with \r\n diff", function() {
|
||||||
|
const diff =
|
||||||
|
"diff --git a/sample b/sample\r\n" +
|
||||||
|
"index 0000001..0ddf2ba\r\n" +
|
||||||
|
"--- a/sample\r\n" +
|
||||||
|
"+++ b/sample\r\n" +
|
||||||
|
"@@ -1 +1 @@\r\n" +
|
||||||
|
"-test\r\n" +
|
||||||
|
"+test1r\r\n";
|
||||||
|
checkDiffSample(diff);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should parse old os x with \r diff", function() {
|
||||||
|
const diff =
|
||||||
|
"diff --git a/sample b/sample\r" +
|
||||||
|
"index 0000001..0ddf2ba\r" +
|
||||||
|
"--- a/sample\r" +
|
||||||
|
"+++ b/sample\r" +
|
||||||
|
"@@ -1 +1 @@\r" +
|
||||||
|
"-test\r" +
|
||||||
|
"+test1r\r";
|
||||||
|
checkDiffSample(diff);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should parse mixed eols diff", function() {
|
||||||
|
const diff =
|
||||||
|
"diff --git a/sample b/sample\n" +
|
||||||
|
"index 0000001..0ddf2ba\r\n" +
|
||||||
|
"--- a/sample\r" +
|
||||||
|
"+++ b/sample\r\n" +
|
||||||
|
"@@ -1 +1 @@\n" +
|
||||||
|
"-test\r" +
|
||||||
|
"+test1r\n";
|
||||||
|
checkDiffSample(diff);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should parse diff with special characters", function() {
|
||||||
|
const diff =
|
||||||
|
'diff --git "a/bla with \ttab.scala" "b/bla with \ttab.scala"\n' +
|
||||||
|
"index 4c679d7..e9bd385 100644\n" +
|
||||||
|
'--- "a/bla with \ttab.scala"\n' +
|
||||||
|
'+++ "b/bla with \ttab.scala"\n' +
|
||||||
|
"@@ -1 +1,2 @@\n" +
|
||||||
|
"-cenas\n" +
|
||||||
|
"+cenas com ananas\n" +
|
||||||
|
"+bananas";
|
||||||
|
|
||||||
|
const result = DiffParser.generateDiffJson(diff);
|
||||||
|
const file1 = result[0];
|
||||||
|
expect(1).toEqual(result.length);
|
||||||
|
expect(2).toEqual(file1.addedLines);
|
||||||
|
expect(1).toEqual(file1.deletedLines);
|
||||||
|
expect("bla with \ttab.scala").toEqual(file1.oldName);
|
||||||
|
expect("bla with \ttab.scala").toEqual(file1.newName);
|
||||||
|
expect(1).toEqual(file1.blocks.length);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should parse diff with prefix", function() {
|
||||||
|
const diff =
|
||||||
|
'diff --git "\tbla with \ttab.scala" "\tbla with \ttab.scala"\n' +
|
||||||
|
"index 4c679d7..e9bd385 100644\n" +
|
||||||
|
'--- "\tbla with \ttab.scala"\n' +
|
||||||
|
'+++ "\tbla with \ttab.scala"\n' +
|
||||||
|
"@@ -1 +1,2 @@\n" +
|
||||||
|
"-cenas\n" +
|
||||||
|
"+cenas com ananas\n" +
|
||||||
|
"+bananas";
|
||||||
|
|
||||||
|
const result = DiffParser.generateDiffJson(diff, { srcPrefix: "\t", dstPrefix: "\t" });
|
||||||
|
const file1 = result[0];
|
||||||
|
expect(1).toEqual(result.length);
|
||||||
|
expect(2).toEqual(file1.addedLines);
|
||||||
|
expect(1).toEqual(file1.deletedLines);
|
||||||
|
expect("bla with \ttab.scala").toEqual(file1.oldName);
|
||||||
|
expect("bla with \ttab.scala").toEqual(file1.newName);
|
||||||
|
expect(1).toEqual(file1.blocks.length);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should parse diff with deleted file", function() {
|
||||||
|
const diff =
|
||||||
|
"diff --git a/src/var/strundefined.js b/src/var/strundefined.js\n" +
|
||||||
|
"deleted file mode 100644\n" +
|
||||||
|
"index 04e16b0..0000000\n" +
|
||||||
|
"--- a/src/var/strundefined.js\n" +
|
||||||
|
"+++ /dev/null\n" +
|
||||||
|
"@@ -1,3 +0,0 @@\n" +
|
||||||
|
"-define(function() {\n" +
|
||||||
|
"- return typeof undefined;\n" +
|
||||||
|
"-});\n";
|
||||||
|
|
||||||
|
const result = DiffParser.generateDiffJson(diff);
|
||||||
|
expect(1).toEqual(result.length);
|
||||||
|
|
||||||
|
const file1 = result[0];
|
||||||
|
expect(false).toEqual(file1.isCombined);
|
||||||
|
expect(0).toEqual(file1.addedLines);
|
||||||
|
expect(3).toEqual(file1.deletedLines);
|
||||||
|
expect("src/var/strundefined.js").toEqual(file1.oldName);
|
||||||
|
expect("/dev/null").toEqual(file1.newName);
|
||||||
|
expect(1).toEqual(file1.blocks.length);
|
||||||
|
expect(true).toEqual(file1.isDeleted);
|
||||||
|
expect("04e16b0").toEqual(file1.checksumBefore);
|
||||||
|
expect("0000000").toEqual(file1.checksumAfter);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should parse diff with new file", function() {
|
||||||
|
const diff =
|
||||||
|
"diff --git a/test.js b/test.js\n" +
|
||||||
|
"new file mode 100644\n" +
|
||||||
|
"index 0000000..e1e22ec\n" +
|
||||||
|
"--- /dev/null\n" +
|
||||||
|
"+++ b/test.js\n" +
|
||||||
|
"@@ -0,0 +1,5 @@\n" +
|
||||||
|
"+var parser = require('./source/git-parser');\n" +
|
||||||
|
"+\n" +
|
||||||
|
"+var patchLineList = [ false, false, false, false ];\n" +
|
||||||
|
"+\n" +
|
||||||
|
"+console.log(parser.parsePatchDiffResult(text, patchLineList));\n";
|
||||||
|
|
||||||
|
const result = DiffParser.generateDiffJson(diff);
|
||||||
|
expect(1).toEqual(result.length);
|
||||||
|
|
||||||
|
const file1 = result[0];
|
||||||
|
expect(false).toEqual(file1.isCombined);
|
||||||
|
expect(5).toEqual(file1.addedLines);
|
||||||
|
expect(0).toEqual(file1.deletedLines);
|
||||||
|
expect("/dev/null").toEqual(file1.oldName);
|
||||||
|
expect("test.js").toEqual(file1.newName);
|
||||||
|
expect(1).toEqual(file1.blocks.length);
|
||||||
|
expect(true).toEqual(file1.isNew);
|
||||||
|
expect("100644").toEqual(file1.newFileMode);
|
||||||
|
expect("0000000").toEqual(file1.checksumBefore);
|
||||||
|
expect("e1e22ec").toEqual(file1.checksumAfter);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should parse diff with nested diff", function() {
|
||||||
|
const diff =
|
||||||
|
"diff --git a/src/offset.js b/src/offset.js\n" +
|
||||||
|
"index cc6ffb4..fa51f18 100644\n" +
|
||||||
|
"--- a/src/offset.js\n" +
|
||||||
|
"+++ b/src/offset.js\n" +
|
||||||
|
"@@ -1,6 +1,5 @@\n" +
|
||||||
|
"+var parser = require('./source/git-parser');\n" +
|
||||||
|
"+\n" +
|
||||||
|
"+var text = 'diff --git a/components/app/app.html b/components/app/app.html\\nindex ecb7a95..027bd9b 100644\\n--- a/components/app/app.html\\n+++ b/components/app/app.html\\n@@ -52,0 +53,3 @@\\n+\\n+\\n+\\n@@ -56,0 +60,3 @@\\n+\\n+\\n+\\n'\n" +
|
||||||
|
"+var patchLineList = [ false, false, false, false ];\n" +
|
||||||
|
"+\n" +
|
||||||
|
"+console.log(parser.parsePatchDiffResult(text, patchLineList));\n";
|
||||||
|
|
||||||
|
const result = DiffParser.generateDiffJson(diff);
|
||||||
|
expect(1).toEqual(result.length);
|
||||||
|
|
||||||
|
const file1 = result[0];
|
||||||
|
expect(false).toEqual(file1.isCombined);
|
||||||
|
expect(6).toEqual(file1.addedLines);
|
||||||
|
expect(0).toEqual(file1.deletedLines);
|
||||||
|
expect("src/offset.js").toEqual(file1.oldName);
|
||||||
|
expect("src/offset.js").toEqual(file1.newName);
|
||||||
|
expect(1).toEqual(file1.blocks.length);
|
||||||
|
expect(6).toEqual(file1.blocks[0].lines.length);
|
||||||
|
expect("cc6ffb4").toEqual(file1.checksumBefore);
|
||||||
|
expect("fa51f18").toEqual(file1.checksumAfter);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should parse diff with multiple blocks", function() {
|
||||||
|
const diff =
|
||||||
|
"diff --git a/src/attributes/classes.js b/src/attributes/classes.js\n" +
|
||||||
|
"index c617824..c8d1393 100644\n" +
|
||||||
|
"--- a/src/attributes/classes.js\n" +
|
||||||
|
"+++ b/src/attributes/classes.js\n" +
|
||||||
|
"@@ -1,10 +1,9 @@\n" +
|
||||||
|
" define([\n" +
|
||||||
|
' "../core",\n' +
|
||||||
|
' "../var/rnotwhite",\n' +
|
||||||
|
'- "../var/strundefined",\n' +
|
||||||
|
' "../data/var/dataPriv",\n' +
|
||||||
|
' "../core/init"\n' +
|
||||||
|
"-], function( jQuery, rnotwhite, strundefined, dataPriv ) {\n" +
|
||||||
|
"+], function( jQuery, rnotwhite, dataPriv ) {\n" +
|
||||||
|
" \n" +
|
||||||
|
" var rclass = /[\\t\\r\\n\\f]/g;\n" +
|
||||||
|
" \n" +
|
||||||
|
"@@ -128,7 +127,7 @@ jQuery.fn.extend({\n" +
|
||||||
|
" }\n" +
|
||||||
|
" \n" +
|
||||||
|
" // Toggle whole class name\n" +
|
||||||
|
'- } else if ( type === strundefined || type === "boolean" ) {\n' +
|
||||||
|
'+ } else if ( value === undefined || type === "boolean" ) {\n' +
|
||||||
|
" if ( this.className ) {\n" +
|
||||||
|
" // store className if set\n" +
|
||||||
|
' dataPriv.set( this, "__className__", this.className );\n';
|
||||||
|
|
||||||
|
const result = DiffParser.generateDiffJson(diff);
|
||||||
|
expect(1).toEqual(result.length);
|
||||||
|
|
||||||
|
const file1 = result[0];
|
||||||
|
expect(false).toEqual(file1.isCombined);
|
||||||
|
expect(2).toEqual(file1.addedLines);
|
||||||
|
expect(3).toEqual(file1.deletedLines);
|
||||||
|
expect("src/attributes/classes.js").toEqual(file1.oldName);
|
||||||
|
expect("src/attributes/classes.js").toEqual(file1.newName);
|
||||||
|
expect(2).toEqual(file1.blocks.length);
|
||||||
|
expect(11).toEqual(file1.blocks[0].lines.length);
|
||||||
|
expect(8).toEqual(file1.blocks[1].lines.length);
|
||||||
|
expect("c617824").toEqual(file1.checksumBefore);
|
||||||
|
expect("c8d1393").toEqual(file1.checksumAfter);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should parse diff with multiple files", function() {
|
||||||
|
const diff =
|
||||||
|
"diff --git a/src/core/init.js b/src/core/init.js\n" +
|
||||||
|
"index e49196a..50f310c 100644\n" +
|
||||||
|
"--- a/src/core/init.js\n" +
|
||||||
|
"+++ b/src/core/init.js\n" +
|
||||||
|
"@@ -101,7 +101,7 @@ var rootjQuery,\n" +
|
||||||
|
" // HANDLE: $(function)\n" +
|
||||||
|
" // Shortcut for document ready\n" +
|
||||||
|
" } else if ( jQuery.isFunction( selector ) ) {\n" +
|
||||||
|
'- return typeof rootjQuery.ready !== "undefined" ?\n' +
|
||||||
|
"+ return rootjQuery.ready !== undefined ?\n" +
|
||||||
|
" rootjQuery.ready( selector ) :\n" +
|
||||||
|
" // Execute immediately if ready is not present\n" +
|
||||||
|
" selector( jQuery );\n" +
|
||||||
|
"diff --git a/src/event.js b/src/event.js\n" +
|
||||||
|
"index 7336f4d..6183f70 100644\n" +
|
||||||
|
"--- a/src/event.js\n" +
|
||||||
|
"+++ b/src/event.js\n" +
|
||||||
|
"@@ -1,6 +1,5 @@\n" +
|
||||||
|
" define([\n" +
|
||||||
|
' "./core",\n' +
|
||||||
|
'- "./var/strundefined",\n' +
|
||||||
|
' "./var/rnotwhite",\n' +
|
||||||
|
' "./var/hasOwn",\n' +
|
||||||
|
' "./var/slice",\n';
|
||||||
|
|
||||||
|
const result = DiffParser.generateDiffJson(diff);
|
||||||
|
expect(2).toEqual(result.length);
|
||||||
|
|
||||||
|
const file1 = result[0];
|
||||||
|
expect(false).toEqual(file1.isCombined);
|
||||||
|
expect(1).toEqual(file1.addedLines);
|
||||||
|
expect(1).toEqual(file1.deletedLines);
|
||||||
|
expect("src/core/init.js").toEqual(file1.oldName);
|
||||||
|
expect("src/core/init.js").toEqual(file1.newName);
|
||||||
|
expect(1).toEqual(file1.blocks.length);
|
||||||
|
expect(8).toEqual(file1.blocks[0].lines.length);
|
||||||
|
expect("e49196a").toEqual(file1.checksumBefore);
|
||||||
|
expect("50f310c").toEqual(file1.checksumAfter);
|
||||||
|
|
||||||
|
const file2 = result[1];
|
||||||
|
expect(false).toEqual(file2.isCombined);
|
||||||
|
expect(0).toEqual(file2.addedLines);
|
||||||
|
expect(1).toEqual(file2.deletedLines);
|
||||||
|
expect("src/event.js").toEqual(file2.oldName);
|
||||||
|
expect("src/event.js").toEqual(file2.newName);
|
||||||
|
expect(1).toEqual(file2.blocks.length);
|
||||||
|
expect(6).toEqual(file2.blocks[0].lines.length);
|
||||||
|
expect("7336f4d").toEqual(file2.checksumBefore);
|
||||||
|
expect("6183f70").toEqual(file2.checksumAfter);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should parse combined diff", function() {
|
||||||
|
const diff =
|
||||||
|
"diff --combined describe.c\n" +
|
||||||
|
"index fabadb8,cc95eb0..4866510\n" +
|
||||||
|
"--- a/describe.c\n" +
|
||||||
|
"+++ b/describe.c\n" +
|
||||||
|
"@@@ -98,20 -98,12 +98,20 @@@\n" +
|
||||||
|
" return (a_date > b_date) ? -1 : (a_date == b_date) ? 0 : 1;\n" +
|
||||||
|
" }\n" +
|
||||||
|
" \n" +
|
||||||
|
"- static void describe(char *arg)\n" +
|
||||||
|
" -static void describe(struct commit *cmit, int last_one)\n" +
|
||||||
|
"++static void describe(char *arg, int last_one)\n" +
|
||||||
|
" {\n" +
|
||||||
|
" + unsigned char sha1[20];\n" +
|
||||||
|
" + struct commit *cmit;\n" +
|
||||||
|
" struct commit_list *list;\n" +
|
||||||
|
" static int initialized = 0;\n" +
|
||||||
|
" struct commit_name *n;\n" +
|
||||||
|
" \n" +
|
||||||
|
" + if (get_sha1(arg, sha1) < 0)\n" +
|
||||||
|
" + usage(describe_usage);\n" +
|
||||||
|
" + cmit = lookup_commit_reference(sha1);\n" +
|
||||||
|
" + if (!cmit)\n" +
|
||||||
|
" + usage(describe_usage);\n" +
|
||||||
|
" +\n" +
|
||||||
|
" if (!initialized) {\n" +
|
||||||
|
" initialized = 1;\n" +
|
||||||
|
" for_each_ref(get_name);\n";
|
||||||
|
|
||||||
|
const result = DiffParser.generateDiffJson(diff);
|
||||||
|
expect(1).toEqual(result.length);
|
||||||
|
|
||||||
|
const file1 = result[0];
|
||||||
|
expect(true).toEqual(file1.isCombined);
|
||||||
|
expect(9).toEqual(file1.addedLines);
|
||||||
|
expect(2).toEqual(file1.deletedLines);
|
||||||
|
expect("describe.c").toEqual(file1.oldName);
|
||||||
|
expect("describe.c").toEqual(file1.newName);
|
||||||
|
expect(1).toEqual(file1.blocks.length);
|
||||||
|
expect(22).toEqual(file1.blocks[0].lines.length);
|
||||||
|
expect(["4866510", "cc95eb0"].sort()).toEqual(file1.checksumBefore.sort());
|
||||||
|
expect("fabadb8").toEqual(file1.checksumAfter);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should parse diffs with copied files", function() {
|
||||||
|
const diff =
|
||||||
|
"diff --git a/index.js b/more-index.js\n" +
|
||||||
|
"dissimilarity index 5%\n" +
|
||||||
|
"copy from index.js\n" +
|
||||||
|
"copy to more-index.js\n";
|
||||||
|
|
||||||
|
const result = DiffParser.generateDiffJson(diff);
|
||||||
|
expect(1).toEqual(result.length);
|
||||||
|
|
||||||
|
const file1 = result[0];
|
||||||
|
expect(0).toEqual(file1.addedLines);
|
||||||
|
expect(0).toEqual(file1.deletedLines);
|
||||||
|
expect("index.js").toEqual(file1.oldName);
|
||||||
|
expect("more-index.js").toEqual(file1.newName);
|
||||||
|
expect(0).toEqual(file1.blocks.length);
|
||||||
|
expect(true).toEqual(file1.isCopy);
|
||||||
|
expect("5").toEqual(file1.changedPercentage);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should parse diffs with moved files", function() {
|
||||||
|
const diff =
|
||||||
|
"diff --git a/more-index.js b/other-index.js\n" +
|
||||||
|
"similarity index 86%\n" +
|
||||||
|
"rename from more-index.js\n" +
|
||||||
|
"rename to other-index.js\n";
|
||||||
|
|
||||||
|
const result = DiffParser.generateDiffJson(diff);
|
||||||
|
expect(1).toEqual(result.length);
|
||||||
|
|
||||||
|
const file1 = result[0];
|
||||||
|
expect(0).toEqual(file1.addedLines);
|
||||||
|
expect(0).toEqual(file1.deletedLines);
|
||||||
|
expect("more-index.js").toEqual(file1.oldName);
|
||||||
|
expect("other-index.js").toEqual(file1.newName);
|
||||||
|
expect(0).toEqual(file1.blocks.length);
|
||||||
|
expect(true).toEqual(file1.isRename);
|
||||||
|
expect("86").toEqual(file1.unchangedPercentage);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should parse diffs correct line numbers", function() {
|
||||||
|
const diff =
|
||||||
|
"diff --git a/sample b/sample\n" +
|
||||||
|
"index 0000001..0ddf2ba\n" +
|
||||||
|
"--- a/sample\n" +
|
||||||
|
"+++ b/sample\n" +
|
||||||
|
"@@ -1 +1,2 @@\n" +
|
||||||
|
"-test\n" +
|
||||||
|
"+test1r\n";
|
||||||
|
|
||||||
|
const result = DiffParser.generateDiffJson(diff);
|
||||||
|
expect(1).toEqual(result.length);
|
||||||
|
|
||||||
|
const file1 = result[0];
|
||||||
|
expect(1).toEqual(file1.addedLines);
|
||||||
|
expect(1).toEqual(file1.deletedLines);
|
||||||
|
expect("sample").toEqual(file1.oldName);
|
||||||
|
expect("sample").toEqual(file1.newName);
|
||||||
|
expect(1).toEqual(file1.blocks.length);
|
||||||
|
expect(2).toEqual(file1.blocks[0].lines.length);
|
||||||
|
expect(1).toEqual(file1.blocks[0].lines[0].oldNumber);
|
||||||
|
expect(null).toEqual(file1.blocks[0].lines[0].newNumber);
|
||||||
|
expect(null).toEqual(file1.blocks[0].lines[1].oldNumber);
|
||||||
|
expect(1).toEqual(file1.blocks[0].lines[1].newNumber);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should parse unified non git diff and strip timestamps off the headers", function() {
|
||||||
|
const diffs = [
|
||||||
|
// 2 hours ahead of GMT
|
||||||
|
"--- a/sample.js 2016-10-25 11:37:14.000000000 +0200\n" +
|
||||||
|
"+++ b/sample.js 2016-10-25 11:37:14.000000000 +0200\n" +
|
||||||
|
"@@ -1 +1,2 @@\n" +
|
||||||
|
"-test\n" +
|
||||||
|
"+test1r\n" +
|
||||||
|
"+test2r\n",
|
||||||
|
// 2 hours behind GMT
|
||||||
|
"--- a/sample.js 2016-10-25 11:37:14.000000000 -0200\n" +
|
||||||
|
"+++ b/sample.js 2016-10-25 11:37:14.000000000 -0200\n" +
|
||||||
|
"@@ -1 +1,2 @@\n" +
|
||||||
|
"-test\n" +
|
||||||
|
"+test1r\n" +
|
||||||
|
"+test2r\n"
|
||||||
|
];
|
||||||
|
|
||||||
|
diffs.forEach(function(diff) {
|
||||||
|
const result = DiffParser.generateDiffJson(diff);
|
||||||
|
const file1 = result[0];
|
||||||
|
expect(1).toEqual(result.length);
|
||||||
|
expect(2).toEqual(file1.addedLines);
|
||||||
|
expect(1).toEqual(file1.deletedLines);
|
||||||
|
expect("sample.js").toEqual(file1.oldName);
|
||||||
|
expect("sample.js").toEqual(file1.newName);
|
||||||
|
expect(1).toEqual(file1.blocks.length);
|
||||||
|
|
||||||
|
const linesContent = file1.blocks[0].lines.map(function(line) {
|
||||||
|
return line.content;
|
||||||
|
});
|
||||||
|
expect(linesContent).toEqual(["-test", "+test1r", "+test2r"]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should parse unified non git diff", function() {
|
||||||
|
const diff =
|
||||||
|
"--- a/sample.js\n" + "+++ b/sample.js\n" + "@@ -1 +1,2 @@\n" + "-test\n" + "+test1r\n" + "+test2r\n";
|
||||||
|
|
||||||
|
const result = DiffParser.generateDiffJson(diff);
|
||||||
|
const file1 = result[0];
|
||||||
|
expect(1).toEqual(result.length);
|
||||||
|
expect(2).toEqual(file1.addedLines);
|
||||||
|
expect(1).toEqual(file1.deletedLines);
|
||||||
|
expect("sample.js").toEqual(file1.oldName);
|
||||||
|
expect("sample.js").toEqual(file1.newName);
|
||||||
|
expect(1).toEqual(file1.blocks.length);
|
||||||
|
|
||||||
|
const linesContent = file1.blocks[0].lines.map(function(line) {
|
||||||
|
return line.content;
|
||||||
|
});
|
||||||
|
expect(linesContent).toEqual(["-test", "+test1r", "+test2r"]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should parse unified diff with multiple hunks and files", function() {
|
||||||
|
const diff =
|
||||||
|
"--- sample.js\n" +
|
||||||
|
"+++ sample.js\n" +
|
||||||
|
"@@ -1 +1,2 @@\n" +
|
||||||
|
"-test\n" +
|
||||||
|
"@@ -10 +20,2 @@\n" +
|
||||||
|
"+test\n" +
|
||||||
|
"--- sample1.js\n" +
|
||||||
|
"+++ sample1.js\n" +
|
||||||
|
"@@ -1 +1,2 @@\n" +
|
||||||
|
"+test1";
|
||||||
|
|
||||||
|
const result = DiffParser.generateDiffJson(diff);
|
||||||
|
expect(2).toEqual(result.length);
|
||||||
|
|
||||||
|
const file1 = result[0];
|
||||||
|
expect(1).toEqual(file1.addedLines);
|
||||||
|
expect(1).toEqual(file1.deletedLines);
|
||||||
|
expect("sample.js").toEqual(file1.oldName);
|
||||||
|
expect("sample.js").toEqual(file1.newName);
|
||||||
|
expect(2).toEqual(file1.blocks.length);
|
||||||
|
|
||||||
|
const linesContent1 = file1.blocks[0].lines.map(function(line) {
|
||||||
|
return line.content;
|
||||||
|
});
|
||||||
|
expect(linesContent1).toEqual(["-test"]);
|
||||||
|
|
||||||
|
const linesContent2 = file1.blocks[1].lines.map(function(line) {
|
||||||
|
return line.content;
|
||||||
|
});
|
||||||
|
expect(linesContent2).toEqual(["+test"]);
|
||||||
|
|
||||||
|
const file2 = result[1];
|
||||||
|
expect(1).toEqual(file2.addedLines);
|
||||||
|
expect(0).toEqual(file2.deletedLines);
|
||||||
|
expect("sample1.js").toEqual(file2.oldName);
|
||||||
|
expect("sample1.js").toEqual(file2.newName);
|
||||||
|
expect(1).toEqual(file2.blocks.length);
|
||||||
|
|
||||||
|
const linesContent = file2.blocks[0].lines.map(function(line) {
|
||||||
|
return line.content;
|
||||||
|
});
|
||||||
|
expect(linesContent).toEqual(["+test1"]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should parse diff with --- and +++ in the context lines", function() {
|
||||||
|
const diff =
|
||||||
|
"--- sample.js\n" +
|
||||||
|
"+++ sample.js\n" +
|
||||||
|
"@@ -1,8 +1,8 @@\n" +
|
||||||
|
" test\n" +
|
||||||
|
" \n" +
|
||||||
|
"-- 1\n" +
|
||||||
|
"--- 1\n" +
|
||||||
|
"---- 1\n" +
|
||||||
|
" \n" +
|
||||||
|
"++ 2\n" +
|
||||||
|
"+++ 2\n" +
|
||||||
|
"++++ 2";
|
||||||
|
|
||||||
|
const result = DiffParser.generateDiffJson(diff);
|
||||||
|
const file1 = result[0];
|
||||||
|
expect(1).toEqual(result.length);
|
||||||
|
expect(3).toEqual(file1.addedLines);
|
||||||
|
expect(3).toEqual(file1.deletedLines);
|
||||||
|
expect("sample.js").toEqual(file1.oldName);
|
||||||
|
expect("sample.js").toEqual(file1.newName);
|
||||||
|
expect(1).toEqual(file1.blocks.length);
|
||||||
|
|
||||||
|
const linesContent = file1.blocks[0].lines.map(function(line) {
|
||||||
|
return line.content;
|
||||||
|
});
|
||||||
|
expect(linesContent).toEqual([" test", " ", "-- 1", "--- 1", "---- 1", " ", "++ 2", "+++ 2", "++++ 2"]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should parse diff without proper hunk headers", function() {
|
||||||
|
const diff = "--- sample.js\n" + "+++ sample.js\n" + "@@ @@\n" + " test";
|
||||||
|
|
||||||
|
const result = DiffParser.generateDiffJson(diff);
|
||||||
|
const file1 = result[0];
|
||||||
|
expect(1).toEqual(result.length);
|
||||||
|
expect(0).toEqual(file1.addedLines);
|
||||||
|
expect(0).toEqual(file1.deletedLines);
|
||||||
|
expect("sample.js").toEqual(file1.oldName);
|
||||||
|
expect("sample.js").toEqual(file1.newName);
|
||||||
|
expect(1).toEqual(file1.blocks.length);
|
||||||
|
|
||||||
|
const linesContent = file1.blocks[0].lines.map(function(line) {
|
||||||
|
return line.content;
|
||||||
|
});
|
||||||
|
expect(linesContent).toEqual([" test"]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should parse binary file diff", function() {
|
||||||
|
const diff =
|
||||||
|
"diff --git a/last-changes-config.png b/last-changes-config.png\n" +
|
||||||
|
"index 322248b..56fc1f2 100644\n" +
|
||||||
|
"--- a/last-changes-config.png\n" +
|
||||||
|
"+++ b/last-changes-config.png\n" +
|
||||||
|
"Binary files differ";
|
||||||
|
|
||||||
|
const result = DiffParser.generateDiffJson(diff);
|
||||||
|
const file1 = result[0];
|
||||||
|
expect(1).toEqual(result.length);
|
||||||
|
expect(0).toEqual(file1.addedLines);
|
||||||
|
expect(0).toEqual(file1.deletedLines);
|
||||||
|
expect("last-changes-config.png").toEqual(file1.oldName);
|
||||||
|
expect("last-changes-config.png").toEqual(file1.newName);
|
||||||
|
expect(1).toEqual(file1.blocks.length);
|
||||||
|
expect(0).toEqual(file1.blocks[0].lines.length);
|
||||||
|
expect("Binary files differ").toEqual(file1.blocks[0].header);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should parse diff with --find-renames", function() {
|
||||||
|
const diff =
|
||||||
|
"diff --git a/src/test-bar.js b/src/test-baz.js\n" +
|
||||||
|
"similarity index 98%\n" +
|
||||||
|
"rename from src/test-bar.js\n" +
|
||||||
|
"rename to src/test-baz.js\n" +
|
||||||
|
"index e01513b..f14a870 100644\n" +
|
||||||
|
"--- a/src/test-bar.js\n" +
|
||||||
|
"+++ b/src/test-baz.js\n" +
|
||||||
|
"@@ -1,4 +1,32 @@\n" +
|
||||||
|
" function foo() {\n" +
|
||||||
|
'-var bar = "Whoops!";\n' +
|
||||||
|
'+var baz = "Whoops!";\n' +
|
||||||
|
" }\n" +
|
||||||
|
" ";
|
||||||
|
|
||||||
|
const result = DiffParser.generateDiffJson(diff);
|
||||||
|
const file1 = result[0];
|
||||||
|
expect(1).toEqual(result.length);
|
||||||
|
expect(1).toEqual(file1.addedLines);
|
||||||
|
expect(1).toEqual(file1.deletedLines);
|
||||||
|
expect("src/test-bar.js").toEqual(file1.oldName);
|
||||||
|
expect("src/test-baz.js").toEqual(file1.newName);
|
||||||
|
expect(1).toEqual(file1.blocks.length);
|
||||||
|
expect(5).toEqual(file1.blocks[0].lines.length);
|
||||||
|
const linesContent = file1.blocks[0].lines.map(function(line) {
|
||||||
|
return line.content;
|
||||||
|
});
|
||||||
|
expect(linesContent).toEqual([" function foo() {", '-var bar = "Whoops!";', '+var baz = "Whoops!";', " }", " "]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should parse diff with prefix 2", function() {
|
||||||
|
const diff =
|
||||||
|
'diff --git "\tTest.scala" "\tScalaTest.scala"\n' +
|
||||||
|
"similarity index 88%\n" +
|
||||||
|
"rename from Test.scala\n" +
|
||||||
|
"rename to ScalaTest.scala\n" +
|
||||||
|
"index 7d1f9bf..8b13271 100644\n" +
|
||||||
|
'--- "\tTest.scala"\n' +
|
||||||
|
'+++ "\tScalaTest.scala"\n' +
|
||||||
|
"@@ -1,6 +1,8 @@\n" +
|
||||||
|
" class Test {\n" +
|
||||||
|
" \n" +
|
||||||
|
" def method1 = ???\n" +
|
||||||
|
"+\n" +
|
||||||
|
"+ def method2 = ???\n" +
|
||||||
|
" \n" +
|
||||||
|
" def myMethod = ???\n" +
|
||||||
|
" \n" +
|
||||||
|
"@@ -10,7 +12,6 @@ class Test {\n" +
|
||||||
|
" \n" +
|
||||||
|
" def + = ???\n" +
|
||||||
|
" \n" +
|
||||||
|
"- def |> = ???\n" +
|
||||||
|
" \n" +
|
||||||
|
" }\n" +
|
||||||
|
" \n" +
|
||||||
|
'diff --git "\ttardis.png" "\ttardis.png"\n' +
|
||||||
|
"new file mode 100644\n" +
|
||||||
|
"index 0000000..d503a29\n" +
|
||||||
|
'Binary files /dev/null and "\ttardis.png" differ\n' +
|
||||||
|
"diff --git a/src/test-bar.js b/src/test-baz.js\n" +
|
||||||
|
"similarity index 98%\n" +
|
||||||
|
"rename from src/test-bar.js\n" +
|
||||||
|
"rename to src/test-baz.js\n" +
|
||||||
|
"index e01513b..f14a870 100644\n" +
|
||||||
|
"--- a/src/test-bar.js\n" +
|
||||||
|
"+++ b/src/test-baz.js\n" +
|
||||||
|
"@@ -1,4 +1,32 @@\n" +
|
||||||
|
" function foo() {\n" +
|
||||||
|
'-var bar = "Whoops!";\n' +
|
||||||
|
'+var baz = "Whoops!";\n' +
|
||||||
|
" }\n" +
|
||||||
|
" ";
|
||||||
|
|
||||||
|
const result = DiffParser.generateDiffJson(diff, { srcPrefix: "\t", dstPrefix: "\t" });
|
||||||
|
expect(3).toEqual(result.length);
|
||||||
|
|
||||||
|
const file1 = result[0];
|
||||||
|
expect(2).toEqual(file1.addedLines);
|
||||||
|
expect(1).toEqual(file1.deletedLines);
|
||||||
|
expect("Test.scala").toEqual(file1.oldName);
|
||||||
|
expect("ScalaTest.scala").toEqual(file1.newName);
|
||||||
|
expect(2).toEqual(file1.blocks.length);
|
||||||
|
expect(8).toEqual(file1.blocks[0].lines.length);
|
||||||
|
expect(7).toEqual(file1.blocks[1].lines.length);
|
||||||
|
|
||||||
|
const file2 = result[1];
|
||||||
|
expect("/dev/null").toEqual(file2.oldName);
|
||||||
|
expect("tardis.png").toEqual(file2.newName);
|
||||||
|
|
||||||
|
const file3 = result[2];
|
||||||
|
expect(1).toEqual(file3.addedLines);
|
||||||
|
expect(1).toEqual(file3.deletedLines);
|
||||||
|
expect("src/test-bar.js").toEqual(file3.oldName);
|
||||||
|
expect("src/test-baz.js").toEqual(file3.newName);
|
||||||
|
expect(1).toEqual(file3.blocks.length);
|
||||||
|
expect(5).toEqual(file3.blocks[0].lines.length);
|
||||||
|
const linesContent = file3.blocks[0].lines.map(function(line) {
|
||||||
|
return line.content;
|
||||||
|
});
|
||||||
|
expect(linesContent).toEqual([" function foo() {", '-var bar = "Whoops!";', '+var baz = "Whoops!";', " }", " "]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should parse binary with content", function() {
|
||||||
|
const diff =
|
||||||
|
"diff --git a/favicon.png b/favicon.png\n" +
|
||||||
|
"deleted file mode 100644\n" +
|
||||||
|
"index 2a9d516a5647205d7be510dd0dff93a3663eff6f..0000000000000000000000000000000000000000\n" +
|
||||||
|
"GIT binary patch\n" +
|
||||||
|
"literal 0\n" +
|
||||||
|
"HcmV?d00001\n" +
|
||||||
|
"\n" +
|
||||||
|
"literal 471\n" +
|
||||||
|
"zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf<Z~8yL>4nJ\n" +
|
||||||
|
"za0`Jj<E6WGe}IBwC9V-A&PAz-C7Jno3L%-fsSJk3`UaNzMkcGzh!g=;$beJ?=ckpF\n" +
|
||||||
|
"zCl;kLIHu$$r7E~(7NwTw7iAYKI0u`(*t4mJfq_xq)5S5wqIc=!hrWj$cv|<b{x!c(\n" +
|
||||||
|
"z;3r#y;31Y&=1q>qPVOAS4ANVKzqmCp=Cty@U^(7zk!jHsvT~YI{F^=Ex6g|gox78w\n" +
|
||||||
|
"z+Sn2Du3GS9U7qU`1*NYYlJi3u-!<?H-eky}wyIIL;8VU@wCDrb0``&v(jQ*DWSR4K\n" +
|
||||||
|
"zPq(3;isEyho{emNa=%%!jDPE`l3u;5d=q=<+v8kO-=C`*G#t-*AiE-D>-_B#8k9H0\n" +
|
||||||
|
"zGl{FnZs<2$wz5^=Q2h-1XI^s{LQL1#T4epqNPC%Orl(tD_@!*EY++~^Lt2<2&!&%=\n" +
|
||||||
|
"z`m>(TYj6uS7jDdt=eH>iOyQg(QMR<-Fw8)Dk^ZG)XQTuzEgl{`GpS?Cfq9818R9~=\n" +
|
||||||
|
"z{&h9@9n8F^?|qusoPy{k#%tVHzu7H$t26CR`BJZk*Ixf&u36WuS=?6m2^ho-p00i_\n" +
|
||||||
|
"I>zopr0Nz-&lmGw#\n" +
|
||||||
|
"diff --git a/src/test-bar.js b/src/test-baz.js\n" +
|
||||||
|
"similarity index 98%\n" +
|
||||||
|
"rename from src/test-bar.js\n" +
|
||||||
|
"rename to src/test-baz.js\n" +
|
||||||
|
"index e01513b..f14a870 100644\n" +
|
||||||
|
"--- a/src/test-bar.js\n" +
|
||||||
|
"+++ b/src/test-baz.js\n" +
|
||||||
|
"@@ -1,4 +1,32 @@\n" +
|
||||||
|
" function foo() {\n" +
|
||||||
|
'-var bar = "Whoops!";\n' +
|
||||||
|
'+var baz = "Whoops!";\n' +
|
||||||
|
" }\n" +
|
||||||
|
" ";
|
||||||
|
|
||||||
|
const result = DiffParser.generateDiffJson(diff);
|
||||||
|
expect(2).toEqual(result.length);
|
||||||
|
|
||||||
|
const file1 = result[0];
|
||||||
|
expect("favicon.png").toEqual(file1.oldName);
|
||||||
|
expect("favicon.png").toEqual(file1.newName);
|
||||||
|
expect(1).toEqual(file1.blocks.length);
|
||||||
|
expect(0).toEqual(file1.blocks[0].lines.length);
|
||||||
|
|
||||||
|
const file2 = result[1];
|
||||||
|
expect(1).toEqual(file2.addedLines);
|
||||||
|
expect(1).toEqual(file2.deletedLines);
|
||||||
|
expect("src/test-bar.js").toEqual(file2.oldName);
|
||||||
|
expect("src/test-baz.js").toEqual(file2.newName);
|
||||||
|
expect(1).toEqual(file2.blocks.length);
|
||||||
|
expect(5).toEqual(file2.blocks[0].lines.length);
|
||||||
|
const linesContent = file2.blocks[0].lines.map(function(line) {
|
||||||
|
return line.content;
|
||||||
|
});
|
||||||
|
expect(linesContent).toEqual([" function foo() {", '-var bar = "Whoops!";', '+var baz = "Whoops!";', " }", " "]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -1,59 +1,56 @@
|
||||||
var assert = require('assert');
|
const Diff2Html = require("../diff2html.js").Diff2Html;
|
||||||
|
|
||||||
var Diff2Html = require('../src/diff2html.js').Diff2Html;
|
const diffExample1 =
|
||||||
|
"diff --git a/sample b/sample\n" +
|
||||||
|
"index 0000001..0ddf2ba\n" +
|
||||||
|
"--- a/sample\n" +
|
||||||
|
"+++ b/sample\n" +
|
||||||
|
"@@ -1 +1 @@\n" +
|
||||||
|
"-test\n" +
|
||||||
|
"+test1\n";
|
||||||
|
|
||||||
var diffExample1 =
|
const jsonExample1 = [
|
||||||
'diff --git a/sample b/sample\n' +
|
|
||||||
'index 0000001..0ddf2ba\n' +
|
|
||||||
'--- a/sample\n' +
|
|
||||||
'+++ b/sample\n' +
|
|
||||||
'@@ -1 +1 @@\n' +
|
|
||||||
'-test\n' +
|
|
||||||
'+test1\n';
|
|
||||||
|
|
||||||
var jsonExample1 =
|
|
||||||
[
|
|
||||||
{
|
{
|
||||||
blocks: [
|
blocks: [
|
||||||
{
|
{
|
||||||
lines: [
|
lines: [
|
||||||
{
|
{
|
||||||
content: '-test',
|
content: "-test",
|
||||||
type: 'd2h-del',
|
type: "d2h-del",
|
||||||
oldNumber: 1,
|
oldNumber: 1,
|
||||||
newNumber: null
|
newNumber: null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
content: '+test1',
|
content: "+test1",
|
||||||
type: 'd2h-ins',
|
type: "d2h-ins",
|
||||||
oldNumber: null,
|
oldNumber: null,
|
||||||
newNumber: 1
|
newNumber: 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
oldStartLine: '1',
|
oldStartLine: "1",
|
||||||
oldStartLine2: null,
|
oldStartLine2: null,
|
||||||
newStartLine: '1',
|
newStartLine: "1",
|
||||||
header: '@@ -1 +1 @@'
|
header: "@@ -1 +1 @@"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
deletedLines: 1,
|
deletedLines: 1,
|
||||||
addedLines: 1,
|
addedLines: 1,
|
||||||
checksumBefore: '0000001',
|
checksumBefore: "0000001",
|
||||||
checksumAfter: '0ddf2ba',
|
checksumAfter: "0ddf2ba",
|
||||||
oldName: 'sample',
|
oldName: "sample",
|
||||||
language: undefined,
|
language: undefined,
|
||||||
newName: 'sample',
|
newName: "sample",
|
||||||
isCombined: false
|
isCombined: false
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
var filesExample1 =
|
const filesExample1 =
|
||||||
'<div class="d2h-file-list-wrapper">\n' +
|
'<div class="d2h-file-list-wrapper">\n' +
|
||||||
' <div class="d2h-file-list-header">\n' +
|
' <div class="d2h-file-list-header">\n' +
|
||||||
' <span class="d2h-file-list-title">Files changed (1)</span>\n' +
|
' <span class="d2h-file-list-title">Files changed (1)</span>\n' +
|
||||||
' <a class="d2h-file-switch d2h-hide">hide</a>\n' +
|
' <a class="d2h-file-switch d2h-hide">hide</a>\n' +
|
||||||
' <a class="d2h-file-switch d2h-show">show</a>\n' +
|
' <a class="d2h-file-switch d2h-show">show</a>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' <ol class="d2h-file-list">\n' +
|
' <ol class="d2h-file-list">\n' +
|
||||||
' <li class="d2h-file-list-line">\n' +
|
' <li class="d2h-file-list-line">\n' +
|
||||||
' <span class="d2h-file-name-wrapper">\n' +
|
' <span class="d2h-file-name-wrapper">\n' +
|
||||||
|
|
@ -64,13 +61,13 @@ var filesExample1 =
|
||||||
' <span class="d2h-file-stats">\n' +
|
' <span class="d2h-file-stats">\n' +
|
||||||
' <span class="d2h-lines-added">+1</span>\n' +
|
' <span class="d2h-lines-added">+1</span>\n' +
|
||||||
' <span class="d2h-lines-deleted">-1</span>\n' +
|
' <span class="d2h-lines-deleted">-1</span>\n' +
|
||||||
' </span>\n' +
|
" </span>\n" +
|
||||||
' </span>\n' +
|
" </span>\n" +
|
||||||
'</li>\n' +
|
"</li>\n" +
|
||||||
' </ol>\n' +
|
" </ol>\n" +
|
||||||
'</div>';
|
"</div>";
|
||||||
|
|
||||||
var htmlLineExample1 =
|
const htmlLineExample1 =
|
||||||
'<div class="d2h-wrapper">\n' +
|
'<div class="d2h-wrapper">\n' +
|
||||||
' <div id="d2h-675094" class="d2h-file-wrapper" data-lang="">\n' +
|
' <div id="d2h-675094" class="d2h-file-wrapper" data-lang="">\n' +
|
||||||
' <div class="d2h-file-header">\n' +
|
' <div class="d2h-file-header">\n' +
|
||||||
|
|
@ -79,49 +76,49 @@ var htmlLineExample1 =
|
||||||
' <path d="M6 5H2v-1h4v1zM2 8h7v-1H2v1z m0 2h7v-1H2v1z m0 2h7v-1H2v1z m10-7.5v9.5c0 0.55-0.45 1-1 1H1c-0.55 0-1-0.45-1-1V2c0-0.55 0.45-1 1-1h7.5l3.5 3.5z m-1 0.5L8 2H1v12h10V5z"></path>\n' +
|
' <path d="M6 5H2v-1h4v1zM2 8h7v-1H2v1z m0 2h7v-1H2v1z m0 2h7v-1H2v1z m10-7.5v9.5c0 0.55-0.45 1-1 1H1c-0.55 0-1-0.45-1-1V2c0-0.55 0.45-1 1-1h7.5l3.5 3.5z m-1 0.5L8 2H1v12h10V5z"></path>\n' +
|
||||||
' </svg> <span class="d2h-file-name">sample</span>\n' +
|
' </svg> <span class="d2h-file-name">sample</span>\n' +
|
||||||
' <span class="d2h-tag d2h-changed d2h-changed-tag">CHANGED</span></span>\n' +
|
' <span class="d2h-tag d2h-changed d2h-changed-tag">CHANGED</span></span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' <div class="d2h-file-diff">\n' +
|
' <div class="d2h-file-diff">\n' +
|
||||||
' <div class="d2h-code-wrapper">\n' +
|
' <div class="d2h-code-wrapper">\n' +
|
||||||
' <table class="d2h-diff-table">\n' +
|
' <table class="d2h-diff-table">\n' +
|
||||||
' <tbody class="d2h-diff-tbody">\n' +
|
' <tbody class="d2h-diff-tbody">\n' +
|
||||||
' <tr>\n' +
|
" <tr>\n" +
|
||||||
' <td class="d2h-code-linenumber d2h-info"></td>\n' +
|
' <td class="d2h-code-linenumber d2h-info"></td>\n' +
|
||||||
' <td class="d2h-info">\n' +
|
' <td class="d2h-info">\n' +
|
||||||
' <div class="d2h-code-line d2h-info">@@ -1 +1 @@</div>\n' +
|
' <div class="d2h-code-line d2h-info">@@ -1 +1 @@</div>\n' +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr><tr>\n' +
|
"</tr><tr>\n" +
|
||||||
' <td class="d2h-code-linenumber d2h-del">\n' +
|
' <td class="d2h-code-linenumber d2h-del">\n' +
|
||||||
' <div class="line-num1">1</div>\n' +
|
' <div class="line-num1">1</div>\n' +
|
||||||
'<div class="line-num2"></div>\n' +
|
'<div class="line-num2"></div>\n' +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-del">\n' +
|
' <td class="d2h-del">\n' +
|
||||||
' <div class="d2h-code-line d2h-del">\n' +
|
' <div class="d2h-code-line d2h-del">\n' +
|
||||||
' <span class="d2h-code-line-prefix">-</span>\n' +
|
' <span class="d2h-code-line-prefix">-</span>\n' +
|
||||||
' <span class="d2h-code-line-ctn"><del>test</del></span>\n' +
|
' <span class="d2h-code-line-ctn"><del>test</del></span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr><tr>\n' +
|
"</tr><tr>\n" +
|
||||||
' <td class="d2h-code-linenumber d2h-ins">\n' +
|
' <td class="d2h-code-linenumber d2h-ins">\n' +
|
||||||
' <div class="line-num1"></div>\n' +
|
' <div class="line-num1"></div>\n' +
|
||||||
'<div class="line-num2">1</div>\n' +
|
'<div class="line-num2">1</div>\n' +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-ins">\n' +
|
' <td class="d2h-ins">\n' +
|
||||||
' <div class="d2h-code-line d2h-ins">\n' +
|
' <div class="d2h-code-line d2h-ins">\n' +
|
||||||
' <span class="d2h-code-line-prefix">+</span>\n' +
|
' <span class="d2h-code-line-prefix">+</span>\n' +
|
||||||
' <span class="d2h-code-line-ctn"><ins>test1</ins></span>\n' +
|
' <span class="d2h-code-line-ctn"><ins>test1</ins></span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr>\n' +
|
"</tr>\n" +
|
||||||
' </tbody>\n' +
|
" </tbody>\n" +
|
||||||
' </table>\n' +
|
" </table>\n" +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
'</div>\n' +
|
"</div>\n" +
|
||||||
'</div>';
|
"</div>";
|
||||||
|
|
||||||
var htmlLineExample1WithFilesSummary = filesExample1 + htmlLineExample1;
|
const htmlLineExample1WithFilesSummary = filesExample1 + htmlLineExample1;
|
||||||
|
|
||||||
var htmlSideExample1 =
|
const htmlSideExample1 =
|
||||||
'<div class="d2h-wrapper">\n' +
|
'<div class="d2h-wrapper">\n' +
|
||||||
' <div id="d2h-675094" class="d2h-file-wrapper" data-lang="">\n' +
|
' <div id="d2h-675094" class="d2h-file-wrapper" data-lang="">\n' +
|
||||||
' <div class="d2h-file-header">\n' +
|
' <div class="d2h-file-header">\n' +
|
||||||
|
|
@ -130,187 +127,189 @@ var htmlSideExample1 =
|
||||||
' <path d="M6 5H2v-1h4v1zM2 8h7v-1H2v1z m0 2h7v-1H2v1z m0 2h7v-1H2v1z m10-7.5v9.5c0 0.55-0.45 1-1 1H1c-0.55 0-1-0.45-1-1V2c0-0.55 0.45-1 1-1h7.5l3.5 3.5z m-1 0.5L8 2H1v12h10V5z"></path>\n' +
|
' <path d="M6 5H2v-1h4v1zM2 8h7v-1H2v1z m0 2h7v-1H2v1z m0 2h7v-1H2v1z m10-7.5v9.5c0 0.55-0.45 1-1 1H1c-0.55 0-1-0.45-1-1V2c0-0.55 0.45-1 1-1h7.5l3.5 3.5z m-1 0.5L8 2H1v12h10V5z"></path>\n' +
|
||||||
' </svg> <span class="d2h-file-name">sample</span>\n' +
|
' </svg> <span class="d2h-file-name">sample</span>\n' +
|
||||||
' <span class="d2h-tag d2h-changed d2h-changed-tag">CHANGED</span></span>\n' +
|
' <span class="d2h-tag d2h-changed d2h-changed-tag">CHANGED</span></span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' <div class="d2h-files-diff">\n' +
|
' <div class="d2h-files-diff">\n' +
|
||||||
' <div class="d2h-file-side-diff">\n' +
|
' <div class="d2h-file-side-diff">\n' +
|
||||||
' <div class="d2h-code-wrapper">\n' +
|
' <div class="d2h-code-wrapper">\n' +
|
||||||
' <table class="d2h-diff-table">\n' +
|
' <table class="d2h-diff-table">\n' +
|
||||||
' <tbody class="d2h-diff-tbody">\n' +
|
' <tbody class="d2h-diff-tbody">\n' +
|
||||||
' <tr>\n' +
|
" <tr>\n" +
|
||||||
' <td class="d2h-code-side-linenumber d2h-info"></td>\n' +
|
' <td class="d2h-code-side-linenumber d2h-info"></td>\n' +
|
||||||
' <td class="d2h-info">\n' +
|
' <td class="d2h-info">\n' +
|
||||||
' <div class="d2h-code-side-line d2h-info">@@ -1 +1 @@</div>\n' +
|
' <div class="d2h-code-side-line d2h-info">@@ -1 +1 @@</div>\n' +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr><tr>\n' +
|
"</tr><tr>\n" +
|
||||||
' <td class="d2h-code-side-linenumber d2h-del">\n' +
|
' <td class="d2h-code-side-linenumber d2h-del">\n' +
|
||||||
' 1\n' +
|
" 1\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-del">\n' +
|
' <td class="d2h-del">\n' +
|
||||||
' <div class="d2h-code-side-line d2h-del">\n' +
|
' <div class="d2h-code-side-line d2h-del">\n' +
|
||||||
' <span class="d2h-code-line-prefix">-</span>\n' +
|
' <span class="d2h-code-line-prefix">-</span>\n' +
|
||||||
' <span class="d2h-code-line-ctn"><del>test</del></span>\n' +
|
' <span class="d2h-code-line-ctn"><del>test</del></span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr>\n' +
|
"</tr>\n" +
|
||||||
' </tbody>\n' +
|
" </tbody>\n" +
|
||||||
' </table>\n' +
|
" </table>\n" +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' <div class="d2h-file-side-diff">\n' +
|
' <div class="d2h-file-side-diff">\n' +
|
||||||
' <div class="d2h-code-wrapper">\n' +
|
' <div class="d2h-code-wrapper">\n' +
|
||||||
' <table class="d2h-diff-table">\n' +
|
' <table class="d2h-diff-table">\n' +
|
||||||
' <tbody class="d2h-diff-tbody">\n' +
|
' <tbody class="d2h-diff-tbody">\n' +
|
||||||
' <tr>\n' +
|
" <tr>\n" +
|
||||||
' <td class="d2h-code-side-linenumber d2h-info"></td>\n' +
|
' <td class="d2h-code-side-linenumber d2h-info"></td>\n' +
|
||||||
' <td class="d2h-info">\n' +
|
' <td class="d2h-info">\n' +
|
||||||
' <div class="d2h-code-side-line d2h-info"></div>\n' +
|
' <div class="d2h-code-side-line d2h-info"></div>\n' +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr><tr>\n' +
|
"</tr><tr>\n" +
|
||||||
' <td class="d2h-code-side-linenumber d2h-ins">\n' +
|
' <td class="d2h-code-side-linenumber d2h-ins">\n' +
|
||||||
' 1\n' +
|
" 1\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-ins">\n' +
|
' <td class="d2h-ins">\n' +
|
||||||
' <div class="d2h-code-side-line d2h-ins">\n' +
|
' <div class="d2h-code-side-line d2h-ins">\n' +
|
||||||
' <span class="d2h-code-line-prefix">+</span>\n' +
|
' <span class="d2h-code-line-prefix">+</span>\n' +
|
||||||
' <span class="d2h-code-line-ctn"><ins>test1</ins></span>\n' +
|
' <span class="d2h-code-line-ctn"><ins>test1</ins></span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr>\n' +
|
"</tr>\n" +
|
||||||
' </tbody>\n' +
|
" </tbody>\n" +
|
||||||
' </table>\n' +
|
" </table>\n" +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
'</div>\n' +
|
"</div>\n" +
|
||||||
'</div>';
|
"</div>";
|
||||||
|
|
||||||
var htmlSideExample1WithFilesSummary = filesExample1 + htmlSideExample1;
|
const htmlSideExample1WithFilesSummary = filesExample1 + htmlSideExample1;
|
||||||
|
|
||||||
describe('Diff2Html', function() {
|
describe("Diff2Html", function() {
|
||||||
describe('getJsonFromDiff', function() {
|
describe("getJsonFromDiff", function() {
|
||||||
it('should parse simple diff to json', function() {
|
it("should parse simple diff to json", function() {
|
||||||
var diff =
|
const diff =
|
||||||
'diff --git a/sample b/sample\n' +
|
"diff --git a/sample b/sample\n" +
|
||||||
'index 0000001..0ddf2ba\n' +
|
"index 0000001..0ddf2ba\n" +
|
||||||
'--- a/sample\n' +
|
"--- a/sample\n" +
|
||||||
'+++ b/sample\n' +
|
"+++ b/sample\n" +
|
||||||
'@@ -1 +1 @@\n' +
|
"@@ -1 +1 @@\n" +
|
||||||
'-test\n' +
|
"-test\n" +
|
||||||
'+test1\n';
|
"+test1\n";
|
||||||
var result = Diff2Html.getJsonFromDiff(diff);
|
const result = Diff2Html.getJsonFromDiff(diff);
|
||||||
|
|
||||||
var file1 = result[0];
|
const file1 = result[0];
|
||||||
assert.equal(1, result.length);
|
expect(1).toEqual(result.length);
|
||||||
assert.equal(1, file1.addedLines);
|
expect(1).toEqual(file1.addedLines);
|
||||||
assert.equal(1, file1.deletedLines);
|
expect(1).toEqual(file1.deletedLines);
|
||||||
assert.equal('sample', file1.oldName);
|
expect("sample").toEqual(file1.oldName);
|
||||||
assert.equal('sample', file1.newName);
|
expect("sample").toEqual(file1.newName);
|
||||||
assert.equal(1, file1.blocks.length);
|
expect(1).toEqual(file1.blocks.length);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Test case for issue #49
|
// Test case for issue #49
|
||||||
it('should parse diff with added EOF', function() {
|
it("should parse diff with added EOF", function() {
|
||||||
var diff =
|
const diff =
|
||||||
'diff --git a/sample.scala b/sample.scala\n' +
|
"diff --git a/sample.scala b/sample.scala\n" +
|
||||||
'index b583263..8b2fc3e 100644\n' +
|
"index b583263..8b2fc3e 100644\n" +
|
||||||
'--- a/b583263..8b2fc3e\n' +
|
"--- a/b583263..8b2fc3e\n" +
|
||||||
'+++ b/8b2fc3e\n' +
|
"+++ b/8b2fc3e\n" +
|
||||||
'@@ -50,5 +50,7 @@ case class Response[+A](value: Option[A],\n' +
|
"@@ -50,5 +50,7 @@ case class Response[+A](value: Option[A],\n" +
|
||||||
' object ResponseErrorCode extends JsonEnumeration {\n' +
|
" object ResponseErrorCode extends JsonEnumeration {\n" +
|
||||||
' val NoError, ServiceError, JsonError,\n' +
|
" val NoError, ServiceError, JsonError,\n" +
|
||||||
' InvalidPermissions, MissingPermissions, GenericError,\n' +
|
" InvalidPermissions, MissingPermissions, GenericError,\n" +
|
||||||
'- TokenRevoked, MissingToken = Value\n' +
|
"- TokenRevoked, MissingToken = Value\n" +
|
||||||
'-}\n' +
|
"-}\n" +
|
||||||
'\\ No newline at end of file\n' +
|
"\\ No newline at end of file\n" +
|
||||||
'+ TokenRevoked, MissingToken,\n' +
|
"+ TokenRevoked, MissingToken,\n" +
|
||||||
'+ IndexLock, RepositoryError, NotValidRepo, PullRequestNotMergeable, BranchError,\n' +
|
"+ IndexLock, RepositoryError, NotValidRepo, PullRequestNotMergeable, BranchError,\n" +
|
||||||
'+ PluginError, CodeParserError, EngineError = Value\n' +
|
"+ PluginError, CodeParserError, EngineError = Value\n" +
|
||||||
'+}\n';
|
"+}\n";
|
||||||
var result = Diff2Html.getJsonFromDiff(diff);
|
const result = Diff2Html.getJsonFromDiff(diff);
|
||||||
|
|
||||||
assert.equal(50, result[0].blocks[0].lines[0].oldNumber);
|
expect(50).toEqual(result[0].blocks[0].lines[0].oldNumber);
|
||||||
assert.equal(50, result[0].blocks[0].lines[0].newNumber);
|
expect(50).toEqual(result[0].blocks[0].lines[0].newNumber);
|
||||||
|
|
||||||
assert.equal(51, result[0].blocks[0].lines[1].oldNumber);
|
expect(51).toEqual(result[0].blocks[0].lines[1].oldNumber);
|
||||||
assert.equal(51, result[0].blocks[0].lines[1].newNumber);
|
expect(51).toEqual(result[0].blocks[0].lines[1].newNumber);
|
||||||
|
|
||||||
assert.equal(52, result[0].blocks[0].lines[2].oldNumber);
|
expect(52).toEqual(result[0].blocks[0].lines[2].oldNumber);
|
||||||
assert.equal(52, result[0].blocks[0].lines[2].newNumber);
|
expect(52).toEqual(result[0].blocks[0].lines[2].newNumber);
|
||||||
|
|
||||||
assert.equal(53, result[0].blocks[0].lines[3].oldNumber);
|
expect(53).toEqual(result[0].blocks[0].lines[3].oldNumber);
|
||||||
assert.equal(null, result[0].blocks[0].lines[3].newNumber);
|
expect(null).toEqual(result[0].blocks[0].lines[3].newNumber);
|
||||||
|
|
||||||
assert.equal(54, result[0].blocks[0].lines[4].oldNumber);
|
expect(54).toEqual(result[0].blocks[0].lines[4].oldNumber);
|
||||||
assert.equal(null, result[0].blocks[0].lines[4].newNumber);
|
expect(null).toEqual(result[0].blocks[0].lines[4].newNumber);
|
||||||
|
|
||||||
assert.equal(null, result[0].blocks[0].lines[5].oldNumber);
|
expect(null).toEqual(result[0].blocks[0].lines[5].oldNumber);
|
||||||
assert.equal(53, result[0].blocks[0].lines[5].newNumber);
|
expect(53).toEqual(result[0].blocks[0].lines[5].newNumber);
|
||||||
|
|
||||||
assert.equal(null, result[0].blocks[0].lines[6].oldNumber);
|
expect(null).toEqual(result[0].blocks[0].lines[6].oldNumber);
|
||||||
assert.equal(54, result[0].blocks[0].lines[6].newNumber);
|
expect(54).toEqual(result[0].blocks[0].lines[6].newNumber);
|
||||||
|
|
||||||
assert.equal(null, result[0].blocks[0].lines[7].oldNumber);
|
expect(null).toEqual(result[0].blocks[0].lines[7].oldNumber);
|
||||||
assert.equal(55, result[0].blocks[0].lines[7].newNumber);
|
expect(55).toEqual(result[0].blocks[0].lines[7].newNumber);
|
||||||
|
|
||||||
assert.equal(null, result[0].blocks[0].lines[8].oldNumber);
|
expect(null).toEqual(result[0].blocks[0].lines[8].oldNumber);
|
||||||
assert.equal(56, result[0].blocks[0].lines[8].newNumber);
|
expect(56).toEqual(result[0].blocks[0].lines[8].newNumber);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should generate pretty line by line html from diff', function() {
|
it("should generate pretty line by line html from diff", function() {
|
||||||
var result = Diff2Html.getPrettyHtmlFromDiff(diffExample1);
|
const result = Diff2Html.getPrettyHtmlFromDiff(diffExample1);
|
||||||
assert.equal(htmlLineExample1, result);
|
expect(htmlLineExample1).toEqual(result);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should generate pretty line by line html from json', function() {
|
it("should generate pretty line by line html from json", function() {
|
||||||
var result = Diff2Html.getPrettyHtmlFromJson(jsonExample1);
|
const result = Diff2Html.getPrettyHtmlFromJson(jsonExample1);
|
||||||
assert.equal(htmlLineExample1, result);
|
expect(htmlLineExample1).toEqual(result);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should generate pretty diff with files summary', function() {
|
it("should generate pretty diff with files summary", function() {
|
||||||
var result = Diff2Html.getPrettyHtmlFromDiff(diffExample1, {showFiles: true});
|
const result = Diff2Html.getPrettyHtmlFromDiff(diffExample1, { showFiles: true });
|
||||||
assert.equal(htmlLineExample1WithFilesSummary, result);
|
expect(htmlLineExample1WithFilesSummary).toEqual(result);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should generate pretty side by side html from diff', function() {
|
it("should generate pretty side by side html from diff", function() {
|
||||||
var result = Diff2Html.getPrettySideBySideHtmlFromDiff(diffExample1);
|
const result = Diff2Html.getPrettySideBySideHtmlFromDiff(diffExample1);
|
||||||
assert.equal(htmlSideExample1, result);
|
expect(htmlSideExample1).toEqual(result);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should generate pretty side by side html from json', function() {
|
it("should generate pretty side by side html from json", function() {
|
||||||
var result = Diff2Html.getPrettySideBySideHtmlFromJson(jsonExample1);
|
const result = Diff2Html.getPrettySideBySideHtmlFromJson(jsonExample1);
|
||||||
assert.equal(htmlSideExample1, result);
|
expect(htmlSideExample1).toEqual(result);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should generate pretty side by side html from diff', function() {
|
it("should generate pretty side by side html from diff 2", function() {
|
||||||
var result = Diff2Html.getPrettySideBySideHtmlFromDiff(diffExample1, {showFiles: true});
|
const result = Diff2Html.getPrettySideBySideHtmlFromDiff(diffExample1, { showFiles: true });
|
||||||
assert.equal(htmlSideExample1WithFilesSummary, result);
|
expect(htmlSideExample1WithFilesSummary).toEqual(result);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should generate pretty side by side html from diff with html on headers', function() {
|
it("should generate pretty side by side html from diff with html on headers", function() {
|
||||||
var diffExample2 = 'diff --git a/CHANGELOG.md b/CHANGELOG.md\n' +
|
const diffExample2 =
|
||||||
'index fc3e3f4..b486d10 100644\n' +
|
"diff --git a/CHANGELOG.md b/CHANGELOG.md\n" +
|
||||||
'--- a/CHANGELOG.md\n' +
|
"index fc3e3f4..b486d10 100644\n" +
|
||||||
'+++ b/CHANGELOG.md\n' +
|
"--- a/CHANGELOG.md\n" +
|
||||||
'@@ -1,7 +1,6 @@\n' +
|
"+++ b/CHANGELOG.md\n" +
|
||||||
' # Change Log\n' +
|
"@@ -1,7 +1,6 @@\n" +
|
||||||
' All notable changes to this project will be documented in this file.\n' +
|
" # Change Log\n" +
|
||||||
' This project adheres to [Semantic Versioning](http://semver.org/).\n' +
|
" All notable changes to this project will be documented in this file.\n" +
|
||||||
|
" This project adheres to [Semantic Versioning](http://semver.org/).\n" +
|
||||||
'-$a="<table><tr><td>Use the following format for additions: ` - VERSION: [feature/patch (if applicable)] Short description of change. Links to relevant issues/PRs.`\n' +
|
'-$a="<table><tr><td>Use the following format for additions: ` - VERSION: [feature/patch (if applicable)] Short description of change. Links to relevant issues/PRs.`\n' +
|
||||||
' $a="<table><tr><td>\n' +
|
' $a="<table><tr><td>\n' +
|
||||||
" $a=\"<table><tr><td>- 1.1.9: Fix around ubuntu's inability to cache promises. [#877](https://github.com/FredrikNoren/ungit/pull/878)\n" +
|
" $a=\"<table><tr><td>- 1.1.9: Fix around ubuntu's inability to cache promises. [#877](https://github.com/FredrikNoren/ungit/pull/878)\n" +
|
||||||
' - 1.1.8:\n' +
|
" - 1.1.8:\n" +
|
||||||
"@@ -11,7 +10,7 @@ $a=\"<table><tr><td>- 1.1.9: Fix around ubuntu's inability to cache promises. [#8\n" +
|
"@@ -11,7 +10,7 @@ $a=\"<table><tr><td>- 1.1.9: Fix around ubuntu's inability to cache promises. [#8\n" +
|
||||||
' - 1.1.7:\n' +
|
" - 1.1.7:\n" +
|
||||||
' - Fix diff flickering issue and optimization [#865](https://github.com/FredrikNoren/ungit/pull/865)\n' +
|
" - Fix diff flickering issue and optimization [#865](https://github.com/FredrikNoren/ungit/pull/865)\n" +
|
||||||
' - Fix credential dialog issue [#864](https://github.com/FredrikNoren/ungit/pull/864)\n' +
|
" - Fix credential dialog issue [#864](https://github.com/FredrikNoren/ungit/pull/864)\n" +
|
||||||
'- - Fix HEAD branch order when redraw [#858](https://github.com/FredrikNoren/ungit/issues/858)\n' +
|
"- - Fix HEAD branch order when redraw [#858](https://github.com/FredrikNoren/ungit/issues/858)\n" +
|
||||||
'+4 - Fix HEAD branch order when redraw [#858](https://github.com/FredrikNoren/ungit/issues/858)\n' +
|
"+4 - Fix HEAD branch order when redraw [#858](https://github.com/FredrikNoren/ungit/issues/858)\n" +
|
||||||
' - 1.1.6: Fix path auto complete [#861](https://github.com/FredrikNoren/ungit/issues/861)\n' +
|
" - 1.1.6: Fix path auto complete [#861](https://github.com/FredrikNoren/ungit/issues/861)\n" +
|
||||||
' - 1.1.5: Update "Toggle all" button after commit or changing selected files [#859](https://github.com/FredrikNoren/ungit/issues/859)\n' +
|
' - 1.1.5: Update "Toggle all" button after commit or changing selected files [#859](https://github.com/FredrikNoren/ungit/issues/859)\n' +
|
||||||
' - 1.1.4: [patch] Promise refactoring\n' +
|
" - 1.1.4: [patch] Promise refactoring\n" +
|
||||||
' \n';
|
" \n";
|
||||||
|
|
||||||
var htmlExample2 = '<div class="d2h-wrapper">\n' +
|
const htmlExample2 =
|
||||||
|
'<div class="d2h-wrapper">\n' +
|
||||||
' <div id="d2h-211439" class="d2h-file-wrapper" data-lang="md">\n' +
|
' <div id="d2h-211439" class="d2h-file-wrapper" data-lang="md">\n' +
|
||||||
' <div class="d2h-file-header">\n' +
|
' <div class="d2h-file-header">\n' +
|
||||||
' <span class="d2h-file-name-wrapper">\n' +
|
' <span class="d2h-file-name-wrapper">\n' +
|
||||||
|
|
@ -318,207 +317,207 @@ describe('Diff2Html', function() {
|
||||||
' <path d="M6 5H2v-1h4v1zM2 8h7v-1H2v1z m0 2h7v-1H2v1z m0 2h7v-1H2v1z m10-7.5v9.5c0 0.55-0.45 1-1 1H1c-0.55 0-1-0.45-1-1V2c0-0.55 0.45-1 1-1h7.5l3.5 3.5z m-1 0.5L8 2H1v12h10V5z"></path>\n' +
|
' <path d="M6 5H2v-1h4v1zM2 8h7v-1H2v1z m0 2h7v-1H2v1z m0 2h7v-1H2v1z m10-7.5v9.5c0 0.55-0.45 1-1 1H1c-0.55 0-1-0.45-1-1V2c0-0.55 0.45-1 1-1h7.5l3.5 3.5z m-1 0.5L8 2H1v12h10V5z"></path>\n' +
|
||||||
' </svg> <span class="d2h-file-name">CHANGELOG.md</span>\n' +
|
' </svg> <span class="d2h-file-name">CHANGELOG.md</span>\n' +
|
||||||
' <span class="d2h-tag d2h-changed d2h-changed-tag">CHANGED</span></span>\n' +
|
' <span class="d2h-tag d2h-changed d2h-changed-tag">CHANGED</span></span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' <div class="d2h-file-diff">\n' +
|
' <div class="d2h-file-diff">\n' +
|
||||||
' <div class="d2h-code-wrapper">\n' +
|
' <div class="d2h-code-wrapper">\n' +
|
||||||
' <table class="d2h-diff-table">\n' +
|
' <table class="d2h-diff-table">\n' +
|
||||||
' <tbody class="d2h-diff-tbody">\n' +
|
' <tbody class="d2h-diff-tbody">\n' +
|
||||||
' <tr>\n' +
|
" <tr>\n" +
|
||||||
' <td class="d2h-code-linenumber d2h-info"></td>\n' +
|
' <td class="d2h-code-linenumber d2h-info"></td>\n' +
|
||||||
' <td class="d2h-info">\n' +
|
' <td class="d2h-info">\n' +
|
||||||
' <div class="d2h-code-line d2h-info">@@ -1,7 +1,6 @@</div>\n' +
|
' <div class="d2h-code-line d2h-info">@@ -1,7 +1,6 @@</div>\n' +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr><tr>\n' +
|
"</tr><tr>\n" +
|
||||||
' <td class="d2h-code-linenumber d2h-cntx">\n' +
|
' <td class="d2h-code-linenumber d2h-cntx">\n' +
|
||||||
' <div class="line-num1">1</div>\n' +
|
' <div class="line-num1">1</div>\n' +
|
||||||
'<div class="line-num2">1</div>\n' +
|
'<div class="line-num2">1</div>\n' +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-cntx">\n' +
|
' <td class="d2h-cntx">\n' +
|
||||||
' <div class="d2h-code-line d2h-cntx">\n' +
|
' <div class="d2h-code-line d2h-cntx">\n' +
|
||||||
' <span class="d2h-code-line-prefix"> </span>\n' +
|
' <span class="d2h-code-line-prefix"> </span>\n' +
|
||||||
' <span class="d2h-code-line-ctn"># Change Log</span>\n' +
|
' <span class="d2h-code-line-ctn"># Change Log</span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr><tr>\n' +
|
"</tr><tr>\n" +
|
||||||
' <td class="d2h-code-linenumber d2h-cntx">\n' +
|
' <td class="d2h-code-linenumber d2h-cntx">\n' +
|
||||||
' <div class="line-num1">2</div>\n' +
|
' <div class="line-num1">2</div>\n' +
|
||||||
'<div class="line-num2">2</div>\n' +
|
'<div class="line-num2">2</div>\n' +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-cntx">\n' +
|
' <td class="d2h-cntx">\n' +
|
||||||
' <div class="d2h-code-line d2h-cntx">\n' +
|
' <div class="d2h-code-line d2h-cntx">\n' +
|
||||||
' <span class="d2h-code-line-prefix"> </span>\n' +
|
' <span class="d2h-code-line-prefix"> </span>\n' +
|
||||||
' <span class="d2h-code-line-ctn">All notable changes to this project will be documented in this file.</span>\n' +
|
' <span class="d2h-code-line-ctn">All notable changes to this project will be documented in this file.</span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr><tr>\n' +
|
"</tr><tr>\n" +
|
||||||
' <td class="d2h-code-linenumber d2h-cntx">\n' +
|
' <td class="d2h-code-linenumber d2h-cntx">\n' +
|
||||||
' <div class="line-num1">3</div>\n' +
|
' <div class="line-num1">3</div>\n' +
|
||||||
'<div class="line-num2">3</div>\n' +
|
'<div class="line-num2">3</div>\n' +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-cntx">\n' +
|
' <td class="d2h-cntx">\n' +
|
||||||
' <div class="d2h-code-line d2h-cntx">\n' +
|
' <div class="d2h-code-line d2h-cntx">\n' +
|
||||||
' <span class="d2h-code-line-prefix"> </span>\n' +
|
' <span class="d2h-code-line-prefix"> </span>\n' +
|
||||||
' <span class="d2h-code-line-ctn">This project adheres to [Semantic Versioning](http://semver.org/).</span>\n' +
|
' <span class="d2h-code-line-ctn">This project adheres to [Semantic Versioning](http://semver.org/).</span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr><tr>\n' +
|
"</tr><tr>\n" +
|
||||||
' <td class="d2h-code-linenumber d2h-del">\n' +
|
' <td class="d2h-code-linenumber d2h-del">\n' +
|
||||||
' <div class="line-num1">4</div>\n' +
|
' <div class="line-num1">4</div>\n' +
|
||||||
'<div class="line-num2"></div>\n' +
|
'<div class="line-num2"></div>\n' +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-del">\n' +
|
' <td class="d2h-del">\n' +
|
||||||
' <div class="d2h-code-line d2h-del">\n' +
|
' <div class="d2h-code-line d2h-del">\n' +
|
||||||
' <span class="d2h-code-line-prefix">-</span>\n' +
|
' <span class="d2h-code-line-prefix">-</span>\n' +
|
||||||
' <span class="d2h-code-line-ctn">$a="<table><tr><td>Use the following format for additions: ` - VERSION: [feature/patch (if applicable)] Short description of change. Links to relevant issues/PRs.`</span>\n' +
|
' <span class="d2h-code-line-ctn">$a="<table><tr><td>Use the following format for additions: ` - VERSION: [feature/patch (if applicable)] Short description of change. Links to relevant issues/PRs.`</span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr><tr>\n' +
|
"</tr><tr>\n" +
|
||||||
' <td class="d2h-code-linenumber d2h-cntx">\n' +
|
' <td class="d2h-code-linenumber d2h-cntx">\n' +
|
||||||
' <div class="line-num1">5</div>\n' +
|
' <div class="line-num1">5</div>\n' +
|
||||||
'<div class="line-num2">4</div>\n' +
|
'<div class="line-num2">4</div>\n' +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-cntx">\n' +
|
' <td class="d2h-cntx">\n' +
|
||||||
' <div class="d2h-code-line d2h-cntx">\n' +
|
' <div class="d2h-code-line d2h-cntx">\n' +
|
||||||
' <span class="d2h-code-line-prefix"> </span>\n' +
|
' <span class="d2h-code-line-prefix"> </span>\n' +
|
||||||
' <span class="d2h-code-line-ctn">$a="<table><tr><td></span>\n' +
|
' <span class="d2h-code-line-ctn">$a="<table><tr><td></span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr><tr>\n' +
|
"</tr><tr>\n" +
|
||||||
' <td class="d2h-code-linenumber d2h-cntx">\n' +
|
' <td class="d2h-code-linenumber d2h-cntx">\n' +
|
||||||
' <div class="line-num1">6</div>\n' +
|
' <div class="line-num1">6</div>\n' +
|
||||||
'<div class="line-num2">5</div>\n' +
|
'<div class="line-num2">5</div>\n' +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-cntx">\n' +
|
' <td class="d2h-cntx">\n' +
|
||||||
' <div class="d2h-code-line d2h-cntx">\n' +
|
' <div class="d2h-code-line d2h-cntx">\n' +
|
||||||
' <span class="d2h-code-line-prefix"> </span>\n' +
|
' <span class="d2h-code-line-prefix"> </span>\n' +
|
||||||
' <span class="d2h-code-line-ctn">$a="<table><tr><td>- 1.1.9: Fix around ubuntu's inability to cache promises. [#877](https://github.com/FredrikNoren/ungit/pull/878)</span>\n' +
|
' <span class="d2h-code-line-ctn">$a="<table><tr><td>- 1.1.9: Fix around ubuntu's inability to cache promises. [#877](https://github.com/FredrikNoren/ungit/pull/878)</span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr><tr>\n' +
|
"</tr><tr>\n" +
|
||||||
' <td class="d2h-code-linenumber d2h-cntx">\n' +
|
' <td class="d2h-code-linenumber d2h-cntx">\n' +
|
||||||
' <div class="line-num1">7</div>\n' +
|
' <div class="line-num1">7</div>\n' +
|
||||||
'<div class="line-num2">6</div>\n' +
|
'<div class="line-num2">6</div>\n' +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-cntx">\n' +
|
' <td class="d2h-cntx">\n' +
|
||||||
' <div class="d2h-code-line d2h-cntx">\n' +
|
' <div class="d2h-code-line d2h-cntx">\n' +
|
||||||
' <span class="d2h-code-line-prefix"> </span>\n' +
|
' <span class="d2h-code-line-prefix"> </span>\n' +
|
||||||
' <span class="d2h-code-line-ctn">- 1.1.8:</span>\n' +
|
' <span class="d2h-code-line-ctn">- 1.1.8:</span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr>\n' +
|
"</tr>\n" +
|
||||||
'<tr>\n' +
|
"<tr>\n" +
|
||||||
' <td class="d2h-code-linenumber d2h-info"></td>\n' +
|
' <td class="d2h-code-linenumber d2h-info"></td>\n' +
|
||||||
' <td class="d2h-info">\n' +
|
' <td class="d2h-info">\n' +
|
||||||
' <div class="d2h-code-line d2h-info">@@ -11,7 +10,7 @@ $a="<table><tr><td>- 1.1.9: Fix around ubuntu's inability to cache promises. [#8</div>\n' +
|
' <div class="d2h-code-line d2h-info">@@ -11,7 +10,7 @@ $a="<table><tr><td>- 1.1.9: Fix around ubuntu's inability to cache promises. [#8</div>\n' +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr><tr>\n' +
|
"</tr><tr>\n" +
|
||||||
' <td class="d2h-code-linenumber d2h-cntx">\n' +
|
' <td class="d2h-code-linenumber d2h-cntx">\n' +
|
||||||
' <div class="line-num1">11</div>\n' +
|
' <div class="line-num1">11</div>\n' +
|
||||||
'<div class="line-num2">10</div>\n' +
|
'<div class="line-num2">10</div>\n' +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-cntx">\n' +
|
' <td class="d2h-cntx">\n' +
|
||||||
' <div class="d2h-code-line d2h-cntx">\n' +
|
' <div class="d2h-code-line d2h-cntx">\n' +
|
||||||
' <span class="d2h-code-line-prefix"> </span>\n' +
|
' <span class="d2h-code-line-prefix"> </span>\n' +
|
||||||
' <span class="d2h-code-line-ctn">- 1.1.7:</span>\n' +
|
' <span class="d2h-code-line-ctn">- 1.1.7:</span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr><tr>\n' +
|
"</tr><tr>\n" +
|
||||||
' <td class="d2h-code-linenumber d2h-cntx">\n' +
|
' <td class="d2h-code-linenumber d2h-cntx">\n' +
|
||||||
' <div class="line-num1">12</div>\n' +
|
' <div class="line-num1">12</div>\n' +
|
||||||
'<div class="line-num2">11</div>\n' +
|
'<div class="line-num2">11</div>\n' +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-cntx">\n' +
|
' <td class="d2h-cntx">\n' +
|
||||||
' <div class="d2h-code-line d2h-cntx">\n' +
|
' <div class="d2h-code-line d2h-cntx">\n' +
|
||||||
' <span class="d2h-code-line-prefix"> </span>\n' +
|
' <span class="d2h-code-line-prefix"> </span>\n' +
|
||||||
' <span class="d2h-code-line-ctn"> - Fix diff flickering issue and optimization [#865](https://github.com/FredrikNoren/ungit/pull/865)</span>\n' +
|
' <span class="d2h-code-line-ctn"> - Fix diff flickering issue and optimization [#865](https://github.com/FredrikNoren/ungit/pull/865)</span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr><tr>\n' +
|
"</tr><tr>\n" +
|
||||||
' <td class="d2h-code-linenumber d2h-cntx">\n' +
|
' <td class="d2h-code-linenumber d2h-cntx">\n' +
|
||||||
' <div class="line-num1">13</div>\n' +
|
' <div class="line-num1">13</div>\n' +
|
||||||
'<div class="line-num2">12</div>\n' +
|
'<div class="line-num2">12</div>\n' +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-cntx">\n' +
|
' <td class="d2h-cntx">\n' +
|
||||||
' <div class="d2h-code-line d2h-cntx">\n' +
|
' <div class="d2h-code-line d2h-cntx">\n' +
|
||||||
' <span class="d2h-code-line-prefix"> </span>\n' +
|
' <span class="d2h-code-line-prefix"> </span>\n' +
|
||||||
' <span class="d2h-code-line-ctn"> - Fix credential dialog issue [#864](https://github.com/FredrikNoren/ungit/pull/864)</span>\n' +
|
' <span class="d2h-code-line-ctn"> - Fix credential dialog issue [#864](https://github.com/FredrikNoren/ungit/pull/864)</span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr><tr>\n' +
|
"</tr><tr>\n" +
|
||||||
' <td class="d2h-code-linenumber d2h-del">\n' +
|
' <td class="d2h-code-linenumber d2h-del">\n' +
|
||||||
' <div class="line-num1">14</div>\n' +
|
' <div class="line-num1">14</div>\n' +
|
||||||
'<div class="line-num2"></div>\n' +
|
'<div class="line-num2"></div>\n' +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-del">\n' +
|
' <td class="d2h-del">\n' +
|
||||||
' <div class="d2h-code-line d2h-del">\n' +
|
' <div class="d2h-code-line d2h-del">\n' +
|
||||||
' <span class="d2h-code-line-prefix">-</span>\n' +
|
' <span class="d2h-code-line-prefix">-</span>\n' +
|
||||||
' <span class="d2h-code-line-ctn"> - Fix HEAD branch order when redraw [#858](https://github.com/FredrikNoren/ungit/issues/858)</span>\n' +
|
' <span class="d2h-code-line-ctn"> - Fix HEAD branch order when redraw [#858](https://github.com/FredrikNoren/ungit/issues/858)</span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr><tr>\n' +
|
"</tr><tr>\n" +
|
||||||
' <td class="d2h-code-linenumber d2h-ins">\n' +
|
' <td class="d2h-code-linenumber d2h-ins">\n' +
|
||||||
' <div class="line-num1"></div>\n' +
|
' <div class="line-num1"></div>\n' +
|
||||||
'<div class="line-num2">13</div>\n' +
|
'<div class="line-num2">13</div>\n' +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-ins">\n' +
|
' <td class="d2h-ins">\n' +
|
||||||
' <div class="d2h-code-line d2h-ins">\n' +
|
' <div class="d2h-code-line d2h-ins">\n' +
|
||||||
' <span class="d2h-code-line-prefix">+</span>\n' +
|
' <span class="d2h-code-line-prefix">+</span>\n' +
|
||||||
' <span class="d2h-code-line-ctn"><ins>4</ins> - Fix HEAD branch order when redraw [#858](https://github.com/FredrikNoren/ungit/issues/858)</span>\n' +
|
' <span class="d2h-code-line-ctn"><ins>4</ins> - Fix HEAD branch order when redraw [#858](https://github.com/FredrikNoren/ungit/issues/858)</span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr><tr>\n' +
|
"</tr><tr>\n" +
|
||||||
' <td class="d2h-code-linenumber d2h-cntx">\n' +
|
' <td class="d2h-code-linenumber d2h-cntx">\n' +
|
||||||
' <div class="line-num1">15</div>\n' +
|
' <div class="line-num1">15</div>\n' +
|
||||||
'<div class="line-num2">14</div>\n' +
|
'<div class="line-num2">14</div>\n' +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-cntx">\n' +
|
' <td class="d2h-cntx">\n' +
|
||||||
' <div class="d2h-code-line d2h-cntx">\n' +
|
' <div class="d2h-code-line d2h-cntx">\n' +
|
||||||
' <span class="d2h-code-line-prefix"> </span>\n' +
|
' <span class="d2h-code-line-prefix"> </span>\n' +
|
||||||
' <span class="d2h-code-line-ctn">- 1.1.6: Fix path auto complete [#861](https://github.com/FredrikNoren/ungit/issues/861)</span>\n' +
|
' <span class="d2h-code-line-ctn">- 1.1.6: Fix path auto complete [#861](https://github.com/FredrikNoren/ungit/issues/861)</span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr><tr>\n' +
|
"</tr><tr>\n" +
|
||||||
' <td class="d2h-code-linenumber d2h-cntx">\n' +
|
' <td class="d2h-code-linenumber d2h-cntx">\n' +
|
||||||
' <div class="line-num1">16</div>\n' +
|
' <div class="line-num1">16</div>\n' +
|
||||||
'<div class="line-num2">15</div>\n' +
|
'<div class="line-num2">15</div>\n' +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-cntx">\n' +
|
' <td class="d2h-cntx">\n' +
|
||||||
' <div class="d2h-code-line d2h-cntx">\n' +
|
' <div class="d2h-code-line d2h-cntx">\n' +
|
||||||
' <span class="d2h-code-line-prefix"> </span>\n' +
|
' <span class="d2h-code-line-prefix"> </span>\n' +
|
||||||
' <span class="d2h-code-line-ctn">- 1.1.5: Update "Toggle all" button after commit or changing selected files [#859](https://github.com/FredrikNoren/ungit/issues/859)</span>\n' +
|
' <span class="d2h-code-line-ctn">- 1.1.5: Update "Toggle all" button after commit or changing selected files [#859](https://github.com/FredrikNoren/ungit/issues/859)</span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr><tr>\n' +
|
"</tr><tr>\n" +
|
||||||
' <td class="d2h-code-linenumber d2h-cntx">\n' +
|
' <td class="d2h-code-linenumber d2h-cntx">\n' +
|
||||||
' <div class="line-num1">17</div>\n' +
|
' <div class="line-num1">17</div>\n' +
|
||||||
'<div class="line-num2">16</div>\n' +
|
'<div class="line-num2">16</div>\n' +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-cntx">\n' +
|
' <td class="d2h-cntx">\n' +
|
||||||
' <div class="d2h-code-line d2h-cntx">\n' +
|
' <div class="d2h-code-line d2h-cntx">\n' +
|
||||||
' <span class="d2h-code-line-prefix"> </span>\n' +
|
' <span class="d2h-code-line-prefix"> </span>\n' +
|
||||||
' <span class="d2h-code-line-ctn">- 1.1.4: [patch] Promise refactoring</span>\n' +
|
' <span class="d2h-code-line-ctn">- 1.1.4: [patch] Promise refactoring</span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr><tr>\n' +
|
"</tr><tr>\n" +
|
||||||
' <td class="d2h-code-linenumber d2h-cntx">\n' +
|
' <td class="d2h-code-linenumber d2h-cntx">\n' +
|
||||||
' <div class="line-num1">18</div>\n' +
|
' <div class="line-num1">18</div>\n' +
|
||||||
'<div class="line-num2">17</div>\n' +
|
'<div class="line-num2">17</div>\n' +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-cntx">\n' +
|
' <td class="d2h-cntx">\n' +
|
||||||
' <div class="d2h-code-line d2h-cntx">\n' +
|
' <div class="d2h-code-line d2h-cntx">\n' +
|
||||||
' <span class="d2h-code-line-prefix"> </span>\n' +
|
' <span class="d2h-code-line-prefix"> </span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr>\n' +
|
"</tr>\n" +
|
||||||
' </tbody>\n' +
|
" </tbody>\n" +
|
||||||
' </table>\n' +
|
" </table>\n" +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
'</div>\n' +
|
"</div>\n" +
|
||||||
'</div>';
|
"</div>";
|
||||||
|
|
||||||
var result = Diff2Html.getPrettyHtmlFromDiff(diffExample2);
|
const result = Diff2Html.getPrettyHtmlFromDiff(diffExample2);
|
||||||
assert.equal(result, htmlExample2);
|
expect(result).toEqual(htmlExample2);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -1,92 +1,102 @@
|
||||||
var assert = require('assert');
|
const FileListPrinter = require("../file-list-printer.js").FileListPrinter;
|
||||||
var FileListPrinter = require('../src/file-list-printer.js').FileListPrinter;
|
|
||||||
|
|
||||||
describe('FileListPrinter', function() {
|
describe("FileListPrinter", function() {
|
||||||
describe('generateFileList', function() {
|
describe("generateFileList", function() {
|
||||||
it('should expose old and new files to templates', function() {
|
it("should expose old and new files to templates", function() {
|
||||||
var files = [{
|
const files = [
|
||||||
|
{
|
||||||
addedlines: 12,
|
addedlines: 12,
|
||||||
deletedlines: 41,
|
deletedlines: 41,
|
||||||
language: 'js',
|
language: "js",
|
||||||
oldName: 'my/file/name.js',
|
oldName: "my/file/name.js",
|
||||||
newName: 'my/file/name.js'
|
newName: "my/file/name.js"
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
addedLines: 12,
|
addedLines: 12,
|
||||||
deletedLines: 41,
|
deletedLines: 41,
|
||||||
language: 'js',
|
language: "js",
|
||||||
oldName: 'my/file/name1.js',
|
oldName: "my/file/name1.js",
|
||||||
newName: 'my/file/name2.js'
|
newName: "my/file/name2.js"
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
addedLines: 12,
|
addedLines: 12,
|
||||||
deletedLines: 0,
|
deletedLines: 0,
|
||||||
language: 'js',
|
language: "js",
|
||||||
oldName: 'dev/null',
|
oldName: "dev/null",
|
||||||
newName: 'my/file/name.js',
|
newName: "my/file/name.js",
|
||||||
isNew: true
|
isNew: true
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
addedLines: 0,
|
addedLines: 0,
|
||||||
deletedLines: 41,
|
deletedLines: 41,
|
||||||
language: 'js',
|
language: "js",
|
||||||
oldName: 'my/file/name.js',
|
oldName: "my/file/name.js",
|
||||||
newName: 'dev/null',
|
newName: "dev/null",
|
||||||
isDeleted: true
|
isDeleted: true
|
||||||
}];
|
}
|
||||||
|
];
|
||||||
|
|
||||||
var fileListPrinter = new FileListPrinter({
|
const fileListPrinter = new FileListPrinter({
|
||||||
rawTemplates: {
|
rawTemplates: {
|
||||||
'file-summary-wrapper': '{{{files}}}',
|
"file-summary-wrapper": "{{{files}}}",
|
||||||
'file-summary-line': '{{oldName}}, {{newName}}, {{fileName}}'
|
"file-summary-line": "{{oldName}}, {{newName}}, {{fileName}}"
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var fileHtml = fileListPrinter.generateFileList(files);
|
const fileHtml = fileListPrinter.generateFileList(files);
|
||||||
var expected = 'my/file/name.js, my/file/name.js, my/file/name.js\n' +
|
const expected =
|
||||||
'my/file/name1.js, my/file/name2.js, my/file/{name1.js → name2.js}\n' +
|
"my/file/name.js, my/file/name.js, my/file/name.js\n" +
|
||||||
'dev/null, my/file/name.js, my/file/name.js\n' +
|
"my/file/name1.js, my/file/name2.js, my/file/{name1.js → name2.js}\n" +
|
||||||
'my/file/name.js, dev/null, my/file/name.js';
|
"dev/null, my/file/name.js, my/file/name.js\n" +
|
||||||
|
"my/file/name.js, dev/null, my/file/name.js";
|
||||||
|
|
||||||
assert.equal(expected, fileHtml);
|
expect(expected).toEqual(fileHtml);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work for all kinds of files', function() {
|
it("should work for all kinds of files", function() {
|
||||||
var files = [{
|
const files = [
|
||||||
|
{
|
||||||
addedLines: 12,
|
addedLines: 12,
|
||||||
deletedLines: 41,
|
deletedLines: 41,
|
||||||
language: 'js',
|
language: "js",
|
||||||
oldName: 'my/file/name.js',
|
oldName: "my/file/name.js",
|
||||||
newName: 'my/file/name.js'
|
newName: "my/file/name.js"
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
addedLines: 12,
|
addedLines: 12,
|
||||||
deletedLines: 41,
|
deletedLines: 41,
|
||||||
language: 'js',
|
language: "js",
|
||||||
oldName: 'my/file/name1.js',
|
oldName: "my/file/name1.js",
|
||||||
newName: 'my/file/name2.js'
|
newName: "my/file/name2.js"
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
addedLines: 12,
|
addedLines: 12,
|
||||||
deletedLines: 0,
|
deletedLines: 0,
|
||||||
language: 'js',
|
language: "js",
|
||||||
oldName: 'dev/null',
|
oldName: "dev/null",
|
||||||
newName: 'my/file/name.js',
|
newName: "my/file/name.js",
|
||||||
isNew: true
|
isNew: true
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
addedLines: 0,
|
addedLines: 0,
|
||||||
deletedLines: 41,
|
deletedLines: 41,
|
||||||
language: 'js',
|
language: "js",
|
||||||
oldName: 'my/file/name.js',
|
oldName: "my/file/name.js",
|
||||||
newName: 'dev/null',
|
newName: "dev/null",
|
||||||
isDeleted: true
|
isDeleted: true
|
||||||
}];
|
}
|
||||||
|
];
|
||||||
|
|
||||||
var fileListPrinter = new FileListPrinter();
|
const fileListPrinter = new FileListPrinter();
|
||||||
var fileHtml = fileListPrinter.generateFileList(files);
|
const fileHtml = fileListPrinter.generateFileList(files);
|
||||||
|
|
||||||
var expected =
|
const expected =
|
||||||
'<div class="d2h-file-list-wrapper">\n' +
|
'<div class="d2h-file-list-wrapper">\n' +
|
||||||
' <div class="d2h-file-list-header">\n' +
|
' <div class="d2h-file-list-header">\n' +
|
||||||
' <span class="d2h-file-list-title">Files changed (4)</span>\n' +
|
' <span class="d2h-file-list-title">Files changed (4)</span>\n' +
|
||||||
' <a class="d2h-file-switch d2h-hide">hide</a>\n' +
|
' <a class="d2h-file-switch d2h-hide">hide</a>\n' +
|
||||||
' <a class="d2h-file-switch d2h-show">show</a>\n' +
|
' <a class="d2h-file-switch d2h-show">show</a>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' <ol class="d2h-file-list">\n' +
|
' <ol class="d2h-file-list">\n' +
|
||||||
' <li class="d2h-file-list-line">\n' +
|
' <li class="d2h-file-list-line">\n' +
|
||||||
' <span class="d2h-file-name-wrapper">\n' +
|
' <span class="d2h-file-name-wrapper">\n' +
|
||||||
|
|
@ -97,9 +107,9 @@ describe('FileListPrinter', function() {
|
||||||
' <span class="d2h-file-stats">\n' +
|
' <span class="d2h-file-stats">\n' +
|
||||||
' <span class="d2h-lines-added">+12</span>\n' +
|
' <span class="d2h-lines-added">+12</span>\n' +
|
||||||
' <span class="d2h-lines-deleted">-41</span>\n' +
|
' <span class="d2h-lines-deleted">-41</span>\n' +
|
||||||
' </span>\n' +
|
" </span>\n" +
|
||||||
' </span>\n' +
|
" </span>\n" +
|
||||||
'</li>\n' +
|
"</li>\n" +
|
||||||
'<li class="d2h-file-list-line">\n' +
|
'<li class="d2h-file-list-line">\n' +
|
||||||
' <span class="d2h-file-name-wrapper">\n' +
|
' <span class="d2h-file-name-wrapper">\n' +
|
||||||
' <svg aria-hidden="true" class="d2h-icon d2h-moved" height="16" title="renamed" version="1.1"\n' +
|
' <svg aria-hidden="true" class="d2h-icon d2h-moved" height="16" title="renamed" version="1.1"\n' +
|
||||||
|
|
@ -109,9 +119,9 @@ describe('FileListPrinter', function() {
|
||||||
' <span class="d2h-file-stats">\n' +
|
' <span class="d2h-file-stats">\n' +
|
||||||
' <span class="d2h-lines-added">+12</span>\n' +
|
' <span class="d2h-lines-added">+12</span>\n' +
|
||||||
' <span class="d2h-lines-deleted">-41</span>\n' +
|
' <span class="d2h-lines-deleted">-41</span>\n' +
|
||||||
' </span>\n' +
|
" </span>\n" +
|
||||||
' </span>\n' +
|
" </span>\n" +
|
||||||
'</li>\n' +
|
"</li>\n" +
|
||||||
'<li class="d2h-file-list-line">\n' +
|
'<li class="d2h-file-list-line">\n' +
|
||||||
' <span class="d2h-file-name-wrapper">\n' +
|
' <span class="d2h-file-name-wrapper">\n' +
|
||||||
' <svg aria-hidden="true" class="d2h-icon d2h-added" height="16" title="added" version="1.1" viewBox="0 0 14 16"\n' +
|
' <svg aria-hidden="true" class="d2h-icon d2h-added" height="16" title="added" version="1.1" viewBox="0 0 14 16"\n' +
|
||||||
|
|
@ -121,9 +131,9 @@ describe('FileListPrinter', function() {
|
||||||
' <span class="d2h-file-stats">\n' +
|
' <span class="d2h-file-stats">\n' +
|
||||||
' <span class="d2h-lines-added">+12</span>\n' +
|
' <span class="d2h-lines-added">+12</span>\n' +
|
||||||
' <span class="d2h-lines-deleted">-0</span>\n' +
|
' <span class="d2h-lines-deleted">-0</span>\n' +
|
||||||
' </span>\n' +
|
" </span>\n" +
|
||||||
' </span>\n' +
|
" </span>\n" +
|
||||||
'</li>\n' +
|
"</li>\n" +
|
||||||
'<li class="d2h-file-list-line">\n' +
|
'<li class="d2h-file-list-line">\n' +
|
||||||
' <span class="d2h-file-name-wrapper">\n' +
|
' <span class="d2h-file-name-wrapper">\n' +
|
||||||
' <svg aria-hidden="true" class="d2h-icon d2h-deleted" height="16" title="removed" version="1.1"\n' +
|
' <svg aria-hidden="true" class="d2h-icon d2h-deleted" height="16" title="removed" version="1.1"\n' +
|
||||||
|
|
@ -133,13 +143,13 @@ describe('FileListPrinter', function() {
|
||||||
' <span class="d2h-file-stats">\n' +
|
' <span class="d2h-file-stats">\n' +
|
||||||
' <span class="d2h-lines-added">+0</span>\n' +
|
' <span class="d2h-lines-added">+0</span>\n' +
|
||||||
' <span class="d2h-lines-deleted">-41</span>\n' +
|
' <span class="d2h-lines-deleted">-41</span>\n' +
|
||||||
' </span>\n' +
|
" </span>\n" +
|
||||||
' </span>\n' +
|
" </span>\n" +
|
||||||
'</li>\n' +
|
"</li>\n" +
|
||||||
' </ol>\n' +
|
" </ol>\n" +
|
||||||
'</div>';
|
"</div>";
|
||||||
|
|
||||||
assert.equal(expected, fileHtml);
|
expect(expected).toEqual(fileHtml);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
73
src/__tests__/hogan-cache-tests.js
Normal file
73
src/__tests__/hogan-cache-tests.js
Normal file
|
|
@ -0,0 +1,73 @@
|
||||||
|
const HoganJsUtils = new (require("../hoganjs-utils.js")).HoganJsUtils();
|
||||||
|
const diffParser = require("../diff-parser.js").DiffParser;
|
||||||
|
|
||||||
|
describe("HoganJsUtils", function() {
|
||||||
|
describe("render", function() {
|
||||||
|
const emptyDiffHtml =
|
||||||
|
"<tr>\n" +
|
||||||
|
' <td class="d2h-info">\n' +
|
||||||
|
' <div class="d2h-code-line d2h-info">\n' +
|
||||||
|
" File without changes\n" +
|
||||||
|
" </div>\n" +
|
||||||
|
" </td>\n" +
|
||||||
|
"</tr>";
|
||||||
|
|
||||||
|
it("should render view", function() {
|
||||||
|
const result = HoganJsUtils.render("generic", "empty-diff", {
|
||||||
|
contentClass: "d2h-code-line",
|
||||||
|
diffParser: diffParser
|
||||||
|
});
|
||||||
|
expect(emptyDiffHtml).toEqual(result);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should render view without cache", function() {
|
||||||
|
const result = HoganJsUtils.render(
|
||||||
|
"generic",
|
||||||
|
"empty-diff",
|
||||||
|
{
|
||||||
|
contentClass: "d2h-code-line",
|
||||||
|
diffParser: diffParser
|
||||||
|
},
|
||||||
|
{ noCache: true }
|
||||||
|
);
|
||||||
|
expect(emptyDiffHtml).toEqual(result);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return null if template is missing", function() {
|
||||||
|
const hoganUtils = new (require("../hoganjs-utils.js")).HoganJsUtils({ noCache: true });
|
||||||
|
const result = hoganUtils.render("generic", "missing-template", {});
|
||||||
|
expect(null).toEqual(result);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should allow templates to be overridden with compiled templates", function() {
|
||||||
|
const emptyDiffTemplate = HoganJsUtils.compile("<p>{{myName}}</p>");
|
||||||
|
|
||||||
|
const config = { templates: { "generic-empty-diff": emptyDiffTemplate } };
|
||||||
|
const hoganUtils = new (require("../hoganjs-utils.js")).HoganJsUtils(config);
|
||||||
|
const result = hoganUtils.render("generic", "empty-diff", { myName: "Rodrigo Fernandes" });
|
||||||
|
expect("<p>Rodrigo Fernandes</p>").toEqual(result);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should allow templates to be overridden with uncompiled templates", function() {
|
||||||
|
const emptyDiffTemplate = "<p>{{myName}}</p>";
|
||||||
|
|
||||||
|
const config = { rawTemplates: { "generic-empty-diff": emptyDiffTemplate } };
|
||||||
|
const hoganUtils = new (require("../hoganjs-utils.js")).HoganJsUtils(config);
|
||||||
|
const result = hoganUtils.render("generic", "empty-diff", { myName: "Rodrigo Fernandes" });
|
||||||
|
expect("<p>Rodrigo Fernandes</p>").toEqual(result);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should allow templates to be overridden giving priority to compiled templates", function() {
|
||||||
|
const emptyDiffTemplate = HoganJsUtils.compile("<p>{{myName}}</p>");
|
||||||
|
const emptyDiffTemplateUncompiled = "<p>Not used!</p>";
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
templates: { "generic-empty-diff": emptyDiffTemplate },
|
||||||
|
rawTemplates: { "generic-empty-diff": emptyDiffTemplateUncompiled }
|
||||||
|
};
|
||||||
|
const hoganUtils = new (require("../hoganjs-utils.js")).HoganJsUtils(config);
|
||||||
|
const result = hoganUtils.render("generic", "empty-diff", { myName: "Rodrigo Fernandes" });
|
||||||
|
expect("<p>Rodrigo Fernandes</p>").toEqual(result);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -1,153 +1,152 @@
|
||||||
var assert = require('assert');
|
const LineByLinePrinter = require("../line-by-line-printer.js").LineByLinePrinter;
|
||||||
|
|
||||||
var LineByLinePrinter = require('../src/line-by-line-printer.js').LineByLinePrinter;
|
describe("LineByLinePrinter", function() {
|
||||||
|
describe("_generateEmptyDiff", function() {
|
||||||
describe('LineByLinePrinter', function() {
|
it("should return an empty diff", function() {
|
||||||
describe('_generateEmptyDiff', function() {
|
const lineByLinePrinter = new LineByLinePrinter({});
|
||||||
it('should return an empty diff', function() {
|
const fileHtml = lineByLinePrinter._generateEmptyDiff();
|
||||||
var lineByLinePrinter = new LineByLinePrinter({});
|
const expected =
|
||||||
var fileHtml = lineByLinePrinter._generateEmptyDiff();
|
"<tr>\n" +
|
||||||
var expected = '<tr>\n' +
|
|
||||||
' <td class="d2h-info">\n' +
|
' <td class="d2h-info">\n' +
|
||||||
' <div class="d2h-code-line d2h-info">\n' +
|
' <div class="d2h-code-line d2h-info">\n' +
|
||||||
' File without changes\n' +
|
" File without changes\n" +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr>';
|
"</tr>";
|
||||||
|
|
||||||
assert.equal(expected, fileHtml);
|
expect(expected).toEqual(fileHtml);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('makeLineHtml', function() {
|
describe("makeLineHtml", function() {
|
||||||
it('should work for insertions', function() {
|
it("should work for insertions", function() {
|
||||||
var diffParser = require('../src/diff-parser.js').DiffParser;
|
const diffParser = require("../diff-parser.js").DiffParser;
|
||||||
var lineByLinePrinter = new LineByLinePrinter({});
|
const lineByLinePrinter = new LineByLinePrinter({});
|
||||||
var fileHtml = lineByLinePrinter.makeLineHtml(false,
|
let fileHtml = lineByLinePrinter.makeLineHtml(false, diffParser.LINE_TYPE.INSERTS, "", 30, "test", "+");
|
||||||
diffParser.LINE_TYPE.INSERTS, '', 30, 'test', '+');
|
fileHtml = fileHtml.replace(/\n\n+/g, "\n");
|
||||||
fileHtml = fileHtml.replace(/\n\n+/g, '\n');
|
const expected =
|
||||||
var expected = '<tr>\n' +
|
"<tr>\n" +
|
||||||
' <td class="d2h-code-linenumber d2h-ins">\n' +
|
' <td class="d2h-code-linenumber d2h-ins">\n' +
|
||||||
' <div class="line-num1"></div>\n' +
|
' <div class="line-num1"></div>\n' +
|
||||||
'<div class="line-num2">30</div>\n' +
|
'<div class="line-num2">30</div>\n' +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-ins">\n' +
|
' <td class="d2h-ins">\n' +
|
||||||
' <div class="d2h-code-line d2h-ins">\n' +
|
' <div class="d2h-code-line d2h-ins">\n' +
|
||||||
' <span class="d2h-code-line-prefix">+</span>\n' +
|
' <span class="d2h-code-line-prefix">+</span>\n' +
|
||||||
' <span class="d2h-code-line-ctn">test</span>\n' +
|
' <span class="d2h-code-line-ctn">test</span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr>';
|
"</tr>";
|
||||||
|
|
||||||
assert.equal(expected, fileHtml);
|
expect(expected).toEqual(fileHtml);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work for deletions', function() {
|
it("should work for deletions", function() {
|
||||||
var diffParser = require('../src/diff-parser.js').DiffParser;
|
const diffParser = require("../diff-parser.js").DiffParser;
|
||||||
var lineByLinePrinter = new LineByLinePrinter({});
|
const lineByLinePrinter = new LineByLinePrinter({});
|
||||||
var fileHtml = lineByLinePrinter.makeLineHtml(false,
|
let fileHtml = lineByLinePrinter.makeLineHtml(false, diffParser.LINE_TYPE.DELETES, 30, "", "test", "-");
|
||||||
diffParser.LINE_TYPE.DELETES, 30, '', 'test', '-');
|
fileHtml = fileHtml.replace(/\n\n+/g, "\n");
|
||||||
fileHtml = fileHtml.replace(/\n\n+/g, '\n');
|
const expected =
|
||||||
var expected = '<tr>\n' +
|
"<tr>\n" +
|
||||||
' <td class="d2h-code-linenumber d2h-del">\n' +
|
' <td class="d2h-code-linenumber d2h-del">\n' +
|
||||||
' <div class="line-num1">30</div>\n' +
|
' <div class="line-num1">30</div>\n' +
|
||||||
'<div class="line-num2"></div>\n' +
|
'<div class="line-num2"></div>\n' +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-del">\n' +
|
' <td class="d2h-del">\n' +
|
||||||
' <div class="d2h-code-line d2h-del">\n' +
|
' <div class="d2h-code-line d2h-del">\n' +
|
||||||
' <span class="d2h-code-line-prefix">-</span>\n' +
|
' <span class="d2h-code-line-prefix">-</span>\n' +
|
||||||
' <span class="d2h-code-line-ctn">test</span>\n' +
|
' <span class="d2h-code-line-ctn">test</span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr>';
|
"</tr>";
|
||||||
|
|
||||||
assert.equal(expected, fileHtml);
|
expect(expected).toEqual(fileHtml);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should convert indents into non breakin spaces (2 white spaces)', function() {
|
it("should convert indents into non breakin spaces (2 white spaces)", function() {
|
||||||
var diffParser = require('../src/diff-parser.js').DiffParser;
|
const diffParser = require("../diff-parser.js").DiffParser;
|
||||||
var lineByLinePrinter = new LineByLinePrinter({});
|
const lineByLinePrinter = new LineByLinePrinter({});
|
||||||
var fileHtml = lineByLinePrinter.makeLineHtml(false,
|
let fileHtml = lineByLinePrinter.makeLineHtml(false, diffParser.LINE_TYPE.INSERTS, "", 30, " test", "+");
|
||||||
diffParser.LINE_TYPE.INSERTS, '', 30, ' test', '+');
|
fileHtml = fileHtml.replace(/\n\n+/g, "\n");
|
||||||
fileHtml = fileHtml.replace(/\n\n+/g, '\n');
|
const expected =
|
||||||
var expected = '<tr>\n' +
|
"<tr>\n" +
|
||||||
' <td class="d2h-code-linenumber d2h-ins">\n' +
|
' <td class="d2h-code-linenumber d2h-ins">\n' +
|
||||||
' <div class="line-num1"></div>\n' +
|
' <div class="line-num1"></div>\n' +
|
||||||
'<div class="line-num2">30</div>\n' +
|
'<div class="line-num2">30</div>\n' +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-ins">\n' +
|
' <td class="d2h-ins">\n' +
|
||||||
' <div class="d2h-code-line d2h-ins">\n' +
|
' <div class="d2h-code-line d2h-ins">\n' +
|
||||||
' <span class="d2h-code-line-prefix">+</span>\n' +
|
' <span class="d2h-code-line-prefix">+</span>\n' +
|
||||||
' <span class="d2h-code-line-ctn"> test</span>\n' +
|
' <span class="d2h-code-line-ctn"> test</span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr>';
|
"</tr>";
|
||||||
|
|
||||||
assert.equal(expected, fileHtml);
|
expect(expected).toEqual(fileHtml);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should convert indents into non breakin spaces (4 white spaces)', function() {
|
it("should convert indents into non breakin spaces (4 white spaces)", function() {
|
||||||
var diffParser = require('../src/diff-parser.js').DiffParser;
|
const diffParser = require("../diff-parser.js").DiffParser;
|
||||||
var lineByLinePrinter = new LineByLinePrinter({});
|
const lineByLinePrinter = new LineByLinePrinter({});
|
||||||
var fileHtml = lineByLinePrinter.makeLineHtml(false,
|
let fileHtml = lineByLinePrinter.makeLineHtml(false, diffParser.LINE_TYPE.INSERTS, "", 30, " test", "+");
|
||||||
diffParser.LINE_TYPE.INSERTS, '', 30, ' test', '+');
|
fileHtml = fileHtml.replace(/\n\n+/g, "\n");
|
||||||
fileHtml = fileHtml.replace(/\n\n+/g, '\n');
|
const expected =
|
||||||
var expected = '<tr>\n' +
|
"<tr>\n" +
|
||||||
' <td class="d2h-code-linenumber d2h-ins">\n' +
|
' <td class="d2h-code-linenumber d2h-ins">\n' +
|
||||||
' <div class="line-num1"></div>\n' +
|
' <div class="line-num1"></div>\n' +
|
||||||
'<div class="line-num2">30</div>\n' +
|
'<div class="line-num2">30</div>\n' +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-ins">\n' +
|
' <td class="d2h-ins">\n' +
|
||||||
' <div class="d2h-code-line d2h-ins">\n' +
|
' <div class="d2h-code-line d2h-ins">\n' +
|
||||||
' <span class="d2h-code-line-prefix">+</span>\n' +
|
' <span class="d2h-code-line-prefix">+</span>\n' +
|
||||||
' <span class="d2h-code-line-ctn"> test</span>\n' +
|
' <span class="d2h-code-line-ctn"> test</span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr>';
|
"</tr>";
|
||||||
|
|
||||||
assert.equal(expected, fileHtml);
|
expect(expected).toEqual(fileHtml);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should preserve tabs', function() {
|
it("should preserve tabs", function() {
|
||||||
var diffParser = require('../src/diff-parser.js').DiffParser;
|
const diffParser = require("../diff-parser.js").DiffParser;
|
||||||
var lineByLinePrinter = new LineByLinePrinter({});
|
const lineByLinePrinter = new LineByLinePrinter({});
|
||||||
var fileHtml = lineByLinePrinter.makeLineHtml(false,
|
let fileHtml = lineByLinePrinter.makeLineHtml(false, diffParser.LINE_TYPE.INSERTS, "", 30, "\ttest", "+");
|
||||||
diffParser.LINE_TYPE.INSERTS, '', 30, '\ttest', '+');
|
fileHtml = fileHtml.replace(/\n\n+/g, "\n");
|
||||||
fileHtml = fileHtml.replace(/\n\n+/g, '\n');
|
const expected =
|
||||||
var expected = '<tr>\n' +
|
"<tr>\n" +
|
||||||
' <td class="d2h-code-linenumber d2h-ins">\n' +
|
' <td class="d2h-code-linenumber d2h-ins">\n' +
|
||||||
' <div class="line-num1"></div>\n' +
|
' <div class="line-num1"></div>\n' +
|
||||||
'' +
|
"" +
|
||||||
'<div class="line-num2">30</div>\n' +
|
'<div class="line-num2">30</div>\n' +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-ins">\n' +
|
' <td class="d2h-ins">\n' +
|
||||||
' <div class="d2h-code-line d2h-ins">\n' +
|
' <div class="d2h-code-line d2h-ins">\n' +
|
||||||
' <span class="d2h-code-line-prefix">+</span>\n' +
|
' <span class="d2h-code-line-prefix">+</span>\n' +
|
||||||
' <span class="d2h-code-line-ctn">\ttest</span>\n' +
|
' <span class="d2h-code-line-ctn">\ttest</span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr>';
|
"</tr>";
|
||||||
|
|
||||||
assert.equal(expected, fileHtml);
|
expect(expected).toEqual(fileHtml);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('makeFileDiffHtml', function() {
|
describe("makeFileDiffHtml", function() {
|
||||||
it('should work for simple file', function() {
|
it("should work for simple file", function() {
|
||||||
var lineByLinePrinter = new LineByLinePrinter({});
|
const lineByLinePrinter = new LineByLinePrinter({});
|
||||||
|
|
||||||
var file = {
|
const file = {
|
||||||
addedLines: 12,
|
addedLines: 12,
|
||||||
deletedLines: 41,
|
deletedLines: 41,
|
||||||
language: 'js',
|
language: "js",
|
||||||
oldName: 'my/file/name.js',
|
oldName: "my/file/name.js",
|
||||||
newName: 'my/file/name.js'
|
newName: "my/file/name.js"
|
||||||
};
|
};
|
||||||
var diffs = '<span>Random Html</span>';
|
const diffs = "<span>Random Html</span>";
|
||||||
|
|
||||||
var fileHtml = lineByLinePrinter.makeFileDiffHtml(file, diffs);
|
const fileHtml = lineByLinePrinter.makeFileDiffHtml(file, diffs);
|
||||||
|
|
||||||
var expected =
|
const expected =
|
||||||
'<div id="d2h-781444" class="d2h-file-wrapper" data-lang="js">\n' +
|
'<div id="d2h-781444" class="d2h-file-wrapper" data-lang="js">\n' +
|
||||||
' <div class="d2h-file-header">\n' +
|
' <div class="d2h-file-header">\n' +
|
||||||
' <span class="d2h-file-name-wrapper">\n' +
|
' <span class="d2h-file-name-wrapper">\n' +
|
||||||
|
|
@ -155,36 +154,36 @@ describe('LineByLinePrinter', function() {
|
||||||
' <path d="M6 5H2v-1h4v1zM2 8h7v-1H2v1z m0 2h7v-1H2v1z m0 2h7v-1H2v1z m10-7.5v9.5c0 0.55-0.45 1-1 1H1c-0.55 0-1-0.45-1-1V2c0-0.55 0.45-1 1-1h7.5l3.5 3.5z m-1 0.5L8 2H1v12h10V5z"></path>\n' +
|
' <path d="M6 5H2v-1h4v1zM2 8h7v-1H2v1z m0 2h7v-1H2v1z m0 2h7v-1H2v1z m10-7.5v9.5c0 0.55-0.45 1-1 1H1c-0.55 0-1-0.45-1-1V2c0-0.55 0.45-1 1-1h7.5l3.5 3.5z m-1 0.5L8 2H1v12h10V5z"></path>\n' +
|
||||||
' </svg> <span class="d2h-file-name">my/file/name.js</span>\n' +
|
' </svg> <span class="d2h-file-name">my/file/name.js</span>\n' +
|
||||||
' <span class="d2h-tag d2h-changed d2h-changed-tag">CHANGED</span></span>\n' +
|
' <span class="d2h-tag d2h-changed d2h-changed-tag">CHANGED</span></span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' <div class="d2h-file-diff">\n' +
|
' <div class="d2h-file-diff">\n' +
|
||||||
' <div class="d2h-code-wrapper">\n' +
|
' <div class="d2h-code-wrapper">\n' +
|
||||||
' <table class="d2h-diff-table">\n' +
|
' <table class="d2h-diff-table">\n' +
|
||||||
' <tbody class="d2h-diff-tbody">\n' +
|
' <tbody class="d2h-diff-tbody">\n' +
|
||||||
' <span>Random Html</span>\n' +
|
" <span>Random Html</span>\n" +
|
||||||
' </tbody>\n' +
|
" </tbody>\n" +
|
||||||
' </table>\n' +
|
" </table>\n" +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
'</div>';
|
"</div>";
|
||||||
|
|
||||||
assert.equal(expected, fileHtml);
|
expect(expected).toEqual(fileHtml);
|
||||||
});
|
});
|
||||||
it('should work for simple added file', function() {
|
it("should work for simple added file", function() {
|
||||||
var lineByLinePrinter = new LineByLinePrinter({});
|
const lineByLinePrinter = new LineByLinePrinter({});
|
||||||
|
|
||||||
var file = {
|
const file = {
|
||||||
addedLines: 12,
|
addedLines: 12,
|
||||||
deletedLines: 0,
|
deletedLines: 0,
|
||||||
language: 'js',
|
language: "js",
|
||||||
oldName: 'dev/null',
|
oldName: "dev/null",
|
||||||
newName: 'my/file/name.js',
|
newName: "my/file/name.js",
|
||||||
isNew: true
|
isNew: true
|
||||||
};
|
};
|
||||||
var diffs = '<span>Random Html</span>';
|
const diffs = "<span>Random Html</span>";
|
||||||
|
|
||||||
var fileHtml = lineByLinePrinter.makeFileDiffHtml(file, diffs);
|
const fileHtml = lineByLinePrinter.makeFileDiffHtml(file, diffs);
|
||||||
|
|
||||||
var expected =
|
const expected =
|
||||||
'<div id="d2h-781444" class="d2h-file-wrapper" data-lang="js">\n' +
|
'<div id="d2h-781444" class="d2h-file-wrapper" data-lang="js">\n' +
|
||||||
' <div class="d2h-file-header">\n' +
|
' <div class="d2h-file-header">\n' +
|
||||||
' <span class="d2h-file-name-wrapper">\n' +
|
' <span class="d2h-file-name-wrapper">\n' +
|
||||||
|
|
@ -192,36 +191,36 @@ describe('LineByLinePrinter', function() {
|
||||||
' <path d="M6 5H2v-1h4v1zM2 8h7v-1H2v1z m0 2h7v-1H2v1z m0 2h7v-1H2v1z m10-7.5v9.5c0 0.55-0.45 1-1 1H1c-0.55 0-1-0.45-1-1V2c0-0.55 0.45-1 1-1h7.5l3.5 3.5z m-1 0.5L8 2H1v12h10V5z"></path>\n' +
|
' <path d="M6 5H2v-1h4v1zM2 8h7v-1H2v1z m0 2h7v-1H2v1z m0 2h7v-1H2v1z m10-7.5v9.5c0 0.55-0.45 1-1 1H1c-0.55 0-1-0.45-1-1V2c0-0.55 0.45-1 1-1h7.5l3.5 3.5z m-1 0.5L8 2H1v12h10V5z"></path>\n' +
|
||||||
' </svg> <span class="d2h-file-name">my/file/name.js</span>\n' +
|
' </svg> <span class="d2h-file-name">my/file/name.js</span>\n' +
|
||||||
' <span class="d2h-tag d2h-added d2h-added-tag">ADDED</span></span>\n' +
|
' <span class="d2h-tag d2h-added d2h-added-tag">ADDED</span></span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' <div class="d2h-file-diff">\n' +
|
' <div class="d2h-file-diff">\n' +
|
||||||
' <div class="d2h-code-wrapper">\n' +
|
' <div class="d2h-code-wrapper">\n' +
|
||||||
' <table class="d2h-diff-table">\n' +
|
' <table class="d2h-diff-table">\n' +
|
||||||
' <tbody class="d2h-diff-tbody">\n' +
|
' <tbody class="d2h-diff-tbody">\n' +
|
||||||
' <span>Random Html</span>\n' +
|
" <span>Random Html</span>\n" +
|
||||||
' </tbody>\n' +
|
" </tbody>\n" +
|
||||||
' </table>\n' +
|
" </table>\n" +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
'</div>';
|
"</div>";
|
||||||
|
|
||||||
assert.equal(expected, fileHtml);
|
expect(expected).toEqual(fileHtml);
|
||||||
});
|
});
|
||||||
it('should work for simple deleted file', function() {
|
it("should work for simple deleted file", function() {
|
||||||
var lineByLinePrinter = new LineByLinePrinter({});
|
const lineByLinePrinter = new LineByLinePrinter({});
|
||||||
|
|
||||||
var file = {
|
const file = {
|
||||||
addedLines: 0,
|
addedLines: 0,
|
||||||
deletedLines: 41,
|
deletedLines: 41,
|
||||||
language: 'js',
|
language: "js",
|
||||||
oldName: 'my/file/name.js',
|
oldName: "my/file/name.js",
|
||||||
newName: 'dev/null',
|
newName: "dev/null",
|
||||||
isDeleted: true
|
isDeleted: true
|
||||||
};
|
};
|
||||||
var diffs = '<span>Random Html</span>';
|
const diffs = "<span>Random Html</span>";
|
||||||
|
|
||||||
var fileHtml = lineByLinePrinter.makeFileDiffHtml(file, diffs);
|
const fileHtml = lineByLinePrinter.makeFileDiffHtml(file, diffs);
|
||||||
|
|
||||||
var expected =
|
const expected =
|
||||||
'<div id="d2h-781444" class="d2h-file-wrapper" data-lang="js">\n' +
|
'<div id="d2h-781444" class="d2h-file-wrapper" data-lang="js">\n' +
|
||||||
' <div class="d2h-file-header">\n' +
|
' <div class="d2h-file-header">\n' +
|
||||||
' <span class="d2h-file-name-wrapper">\n' +
|
' <span class="d2h-file-name-wrapper">\n' +
|
||||||
|
|
@ -229,36 +228,36 @@ describe('LineByLinePrinter', function() {
|
||||||
' <path d="M6 5H2v-1h4v1zM2 8h7v-1H2v1z m0 2h7v-1H2v1z m0 2h7v-1H2v1z m10-7.5v9.5c0 0.55-0.45 1-1 1H1c-0.55 0-1-0.45-1-1V2c0-0.55 0.45-1 1-1h7.5l3.5 3.5z m-1 0.5L8 2H1v12h10V5z"></path>\n' +
|
' <path d="M6 5H2v-1h4v1zM2 8h7v-1H2v1z m0 2h7v-1H2v1z m0 2h7v-1H2v1z m10-7.5v9.5c0 0.55-0.45 1-1 1H1c-0.55 0-1-0.45-1-1V2c0-0.55 0.45-1 1-1h7.5l3.5 3.5z m-1 0.5L8 2H1v12h10V5z"></path>\n' +
|
||||||
' </svg> <span class="d2h-file-name">my/file/name.js</span>\n' +
|
' </svg> <span class="d2h-file-name">my/file/name.js</span>\n' +
|
||||||
' <span class="d2h-tag d2h-deleted d2h-deleted-tag">DELETED</span></span>\n' +
|
' <span class="d2h-tag d2h-deleted d2h-deleted-tag">DELETED</span></span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' <div class="d2h-file-diff">\n' +
|
' <div class="d2h-file-diff">\n' +
|
||||||
' <div class="d2h-code-wrapper">\n' +
|
' <div class="d2h-code-wrapper">\n' +
|
||||||
' <table class="d2h-diff-table">\n' +
|
' <table class="d2h-diff-table">\n' +
|
||||||
' <tbody class="d2h-diff-tbody">\n' +
|
' <tbody class="d2h-diff-tbody">\n' +
|
||||||
' <span>Random Html</span>\n' +
|
" <span>Random Html</span>\n" +
|
||||||
' </tbody>\n' +
|
" </tbody>\n" +
|
||||||
' </table>\n' +
|
" </table>\n" +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
'</div>';
|
"</div>";
|
||||||
|
|
||||||
assert.equal(expected, fileHtml);
|
expect(expected).toEqual(fileHtml);
|
||||||
});
|
});
|
||||||
it('should work for simple renamed file', function() {
|
it("should work for simple renamed file", function() {
|
||||||
var lineByLinePrinter = new LineByLinePrinter({});
|
const lineByLinePrinter = new LineByLinePrinter({});
|
||||||
|
|
||||||
var file = {
|
const file = {
|
||||||
addedLines: 12,
|
addedLines: 12,
|
||||||
deletedLines: 41,
|
deletedLines: 41,
|
||||||
language: 'js',
|
language: "js",
|
||||||
oldName: 'my/file/name1.js',
|
oldName: "my/file/name1.js",
|
||||||
newName: 'my/file/name2.js',
|
newName: "my/file/name2.js",
|
||||||
isRename: true
|
isRename: true
|
||||||
};
|
};
|
||||||
var diffs = '<span>Random Html</span>';
|
const diffs = "<span>Random Html</span>";
|
||||||
|
|
||||||
var fileHtml = lineByLinePrinter.makeFileDiffHtml(file, diffs);
|
const fileHtml = lineByLinePrinter.makeFileDiffHtml(file, diffs);
|
||||||
|
|
||||||
var expected =
|
const expected =
|
||||||
'<div id="d2h-662683" class="d2h-file-wrapper" data-lang="js">\n' +
|
'<div id="d2h-662683" class="d2h-file-wrapper" data-lang="js">\n' +
|
||||||
' <div class="d2h-file-header">\n' +
|
' <div class="d2h-file-header">\n' +
|
||||||
' <span class="d2h-file-name-wrapper">\n' +
|
' <span class="d2h-file-name-wrapper">\n' +
|
||||||
|
|
@ -266,93 +265,90 @@ describe('LineByLinePrinter', function() {
|
||||||
' <path d="M6 5H2v-1h4v1zM2 8h7v-1H2v1z m0 2h7v-1H2v1z m0 2h7v-1H2v1z m10-7.5v9.5c0 0.55-0.45 1-1 1H1c-0.55 0-1-0.45-1-1V2c0-0.55 0.45-1 1-1h7.5l3.5 3.5z m-1 0.5L8 2H1v12h10V5z"></path>\n' +
|
' <path d="M6 5H2v-1h4v1zM2 8h7v-1H2v1z m0 2h7v-1H2v1z m0 2h7v-1H2v1z m10-7.5v9.5c0 0.55-0.45 1-1 1H1c-0.55 0-1-0.45-1-1V2c0-0.55 0.45-1 1-1h7.5l3.5 3.5z m-1 0.5L8 2H1v12h10V5z"></path>\n' +
|
||||||
' </svg> <span class="d2h-file-name">my/file/{name1.js → name2.js}</span>\n' +
|
' </svg> <span class="d2h-file-name">my/file/{name1.js → name2.js}</span>\n' +
|
||||||
' <span class="d2h-tag d2h-moved d2h-moved-tag">RENAMED</span></span>\n' +
|
' <span class="d2h-tag d2h-moved d2h-moved-tag">RENAMED</span></span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' <div class="d2h-file-diff">\n' +
|
' <div class="d2h-file-diff">\n' +
|
||||||
' <div class="d2h-code-wrapper">\n' +
|
' <div class="d2h-code-wrapper">\n' +
|
||||||
' <table class="d2h-diff-table">\n' +
|
' <table class="d2h-diff-table">\n' +
|
||||||
' <tbody class="d2h-diff-tbody">\n' +
|
' <tbody class="d2h-diff-tbody">\n' +
|
||||||
' <span>Random Html</span>\n' +
|
" <span>Random Html</span>\n" +
|
||||||
' </tbody>\n' +
|
" </tbody>\n" +
|
||||||
' </table>\n' +
|
" </table>\n" +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
'</div>';
|
"</div>";
|
||||||
|
|
||||||
assert.equal(expected, fileHtml);
|
expect(expected).toEqual(fileHtml);
|
||||||
});
|
});
|
||||||
it('should return empty when option renderNothingWhenEmpty is true and file blocks not present', function() {
|
it("should return empty when option renderNothingWhenEmpty is true and file blocks not present", function() {
|
||||||
var lineByLinePrinter = new LineByLinePrinter({
|
const lineByLinePrinter = new LineByLinePrinter({
|
||||||
renderNothingWhenEmpty: true
|
renderNothingWhenEmpty: true
|
||||||
});
|
});
|
||||||
|
|
||||||
var file = {
|
const file = {
|
||||||
blocks: []
|
blocks: []
|
||||||
};
|
};
|
||||||
|
|
||||||
var diffs = '<span>Random Html</span>';
|
const diffs = "<span>Random Html</span>";
|
||||||
|
|
||||||
var fileHtml = lineByLinePrinter.makeFileDiffHtml(file, diffs);
|
const fileHtml = lineByLinePrinter.makeFileDiffHtml(file, diffs);
|
||||||
|
|
||||||
var expected = '';
|
const expected = "";
|
||||||
|
|
||||||
assert.equal(expected, fileHtml);
|
expect(expected).toEqual(fileHtml);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('makeLineByLineHtmlWrapper', function() {
|
describe("makeLineByLineHtmlWrapper", function() {
|
||||||
it('should work for simple content', function() {
|
it("should work for simple content", function() {
|
||||||
var lineByLinePrinter = new LineByLinePrinter({});
|
const lineByLinePrinter = new LineByLinePrinter({});
|
||||||
var fileHtml = lineByLinePrinter.makeLineByLineHtmlWrapper('<span>Random Html</span>');
|
const fileHtml = lineByLinePrinter.makeLineByLineHtmlWrapper("<span>Random Html</span>");
|
||||||
|
|
||||||
var expected =
|
const expected = '<div class="d2h-wrapper">\n' + " <span>Random Html</span>\n" + "</div>";
|
||||||
'<div class="d2h-wrapper">\n' +
|
|
||||||
' <span>Random Html</span>\n' +
|
|
||||||
'</div>';
|
|
||||||
|
|
||||||
assert.equal(expected, fileHtml);
|
expect(expected).toEqual(fileHtml);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('generateLineByLineJsonHtml', function() {
|
describe("generateLineByLineJsonHtml", function() {
|
||||||
it('should work for list of files', function() {
|
it("should work for list of files", function() {
|
||||||
var exampleJson = [
|
const exampleJson = [
|
||||||
{
|
{
|
||||||
blocks: [
|
blocks: [
|
||||||
{
|
{
|
||||||
lines: [
|
lines: [
|
||||||
{
|
{
|
||||||
content: '-test',
|
content: "-test",
|
||||||
type: 'd2h-del',
|
type: "d2h-del",
|
||||||
oldNumber: 1,
|
oldNumber: 1,
|
||||||
newNumber: null
|
newNumber: null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
content: '+test1r',
|
content: "+test1r",
|
||||||
type: 'd2h-ins',
|
type: "d2h-ins",
|
||||||
oldNumber: null,
|
oldNumber: null,
|
||||||
newNumber: 1
|
newNumber: 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
oldStartLine: '1',
|
oldStartLine: "1",
|
||||||
oldStartLine2: null,
|
oldStartLine2: null,
|
||||||
newStartLine: '1',
|
newStartLine: "1",
|
||||||
header: '@@ -1 +1 @@'
|
header: "@@ -1 +1 @@"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
deletedLines: 1,
|
deletedLines: 1,
|
||||||
addedLines: 1,
|
addedLines: 1,
|
||||||
checksumBefore: '0000001',
|
checksumBefore: "0000001",
|
||||||
checksumAfter: '0ddf2ba',
|
checksumAfter: "0ddf2ba",
|
||||||
oldName: 'sample',
|
oldName: "sample",
|
||||||
language: undefined,
|
language: undefined,
|
||||||
newName: 'sample',
|
newName: "sample",
|
||||||
isCombined: false
|
isCombined: false
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
var lineByLinePrinter = new LineByLinePrinter({matching: 'lines'});
|
const lineByLinePrinter = new LineByLinePrinter({ matching: "lines" });
|
||||||
var html = lineByLinePrinter.generateLineByLineJsonHtml(exampleJson);
|
const html = lineByLinePrinter.generateLineByLineJsonHtml(exampleJson);
|
||||||
var expected =
|
const expected =
|
||||||
'<div class="d2h-wrapper">\n' +
|
'<div class="d2h-wrapper">\n' +
|
||||||
' <div id="d2h-675094" class="d2h-file-wrapper" data-lang="">\n' +
|
' <div id="d2h-675094" class="d2h-file-wrapper" data-lang="">\n' +
|
||||||
' <div class="d2h-file-header">\n' +
|
' <div class="d2h-file-header">\n' +
|
||||||
|
|
@ -361,63 +357,65 @@ describe('LineByLinePrinter', function() {
|
||||||
' <path d="M6 5H2v-1h4v1zM2 8h7v-1H2v1z m0 2h7v-1H2v1z m0 2h7v-1H2v1z m10-7.5v9.5c0 0.55-0.45 1-1 1H1c-0.55 0-1-0.45-1-1V2c0-0.55 0.45-1 1-1h7.5l3.5 3.5z m-1 0.5L8 2H1v12h10V5z"></path>\n' +
|
' <path d="M6 5H2v-1h4v1zM2 8h7v-1H2v1z m0 2h7v-1H2v1z m0 2h7v-1H2v1z m10-7.5v9.5c0 0.55-0.45 1-1 1H1c-0.55 0-1-0.45-1-1V2c0-0.55 0.45-1 1-1h7.5l3.5 3.5z m-1 0.5L8 2H1v12h10V5z"></path>\n' +
|
||||||
' </svg> <span class="d2h-file-name">sample</span>\n' +
|
' </svg> <span class="d2h-file-name">sample</span>\n' +
|
||||||
' <span class="d2h-tag d2h-changed d2h-changed-tag">CHANGED</span></span>\n' +
|
' <span class="d2h-tag d2h-changed d2h-changed-tag">CHANGED</span></span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' <div class="d2h-file-diff">\n' +
|
' <div class="d2h-file-diff">\n' +
|
||||||
' <div class="d2h-code-wrapper">\n' +
|
' <div class="d2h-code-wrapper">\n' +
|
||||||
' <table class="d2h-diff-table">\n' +
|
' <table class="d2h-diff-table">\n' +
|
||||||
' <tbody class="d2h-diff-tbody">\n' +
|
' <tbody class="d2h-diff-tbody">\n' +
|
||||||
' <tr>\n' +
|
" <tr>\n" +
|
||||||
' <td class="d2h-code-linenumber d2h-info"></td>\n' +
|
' <td class="d2h-code-linenumber d2h-info"></td>\n' +
|
||||||
' <td class="d2h-info">\n' +
|
' <td class="d2h-info">\n' +
|
||||||
' <div class="d2h-code-line d2h-info">@@ -1 +1 @@</div>\n' +
|
' <div class="d2h-code-line d2h-info">@@ -1 +1 @@</div>\n' +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr><tr>\n' +
|
"</tr><tr>\n" +
|
||||||
' <td class="d2h-code-linenumber d2h-del">\n' +
|
' <td class="d2h-code-linenumber d2h-del">\n' +
|
||||||
' <div class="line-num1">1</div>\n' +
|
' <div class="line-num1">1</div>\n' +
|
||||||
'<div class="line-num2"></div>\n' +
|
'<div class="line-num2"></div>\n' +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-del">\n' +
|
' <td class="d2h-del">\n' +
|
||||||
' <div class="d2h-code-line d2h-del">\n' +
|
' <div class="d2h-code-line d2h-del">\n' +
|
||||||
' <span class="d2h-code-line-prefix">-</span>\n' +
|
' <span class="d2h-code-line-prefix">-</span>\n' +
|
||||||
' <span class="d2h-code-line-ctn"><del>test</del></span>\n' +
|
' <span class="d2h-code-line-ctn"><del>test</del></span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr><tr>\n' +
|
"</tr><tr>\n" +
|
||||||
' <td class="d2h-code-linenumber d2h-ins">\n' +
|
' <td class="d2h-code-linenumber d2h-ins">\n' +
|
||||||
' <div class="line-num1"></div>\n' +
|
' <div class="line-num1"></div>\n' +
|
||||||
'<div class="line-num2">1</div>\n' +
|
'<div class="line-num2">1</div>\n' +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-ins">\n' +
|
' <td class="d2h-ins">\n' +
|
||||||
' <div class="d2h-code-line d2h-ins">\n' +
|
' <div class="d2h-code-line d2h-ins">\n' +
|
||||||
' <span class="d2h-code-line-prefix">+</span>\n' +
|
' <span class="d2h-code-line-prefix">+</span>\n' +
|
||||||
' <span class="d2h-code-line-ctn"><ins>test1r</ins></span>\n' +
|
' <span class="d2h-code-line-ctn"><ins>test1r</ins></span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr>\n' +
|
"</tr>\n" +
|
||||||
' </tbody>\n' +
|
" </tbody>\n" +
|
||||||
' </table>\n' +
|
" </table>\n" +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
'</div>\n' +
|
"</div>\n" +
|
||||||
'</div>';
|
"</div>";
|
||||||
|
|
||||||
assert.equal(expected, html);
|
expect(expected).toEqual(html);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work for empty blocks', function() {
|
it("should work for empty blocks", function() {
|
||||||
var exampleJson = [{
|
const exampleJson = [
|
||||||
|
{
|
||||||
blocks: [],
|
blocks: [],
|
||||||
deletedLines: 0,
|
deletedLines: 0,
|
||||||
addedLines: 0,
|
addedLines: 0,
|
||||||
oldName: 'sample',
|
oldName: "sample",
|
||||||
language: 'js',
|
language: "js",
|
||||||
newName: 'sample',
|
newName: "sample",
|
||||||
isCombined: false
|
isCombined: false
|
||||||
}];
|
}
|
||||||
|
];
|
||||||
|
|
||||||
var lineByLinePrinter = new LineByLinePrinter({ renderNothingWhenEmpty: false });
|
const lineByLinePrinter = new LineByLinePrinter({ renderNothingWhenEmpty: false });
|
||||||
var html = lineByLinePrinter.generateLineByLineJsonHtml(exampleJson);
|
const html = lineByLinePrinter.generateLineByLineJsonHtml(exampleJson);
|
||||||
var expected =
|
const expected =
|
||||||
'<div class="d2h-wrapper">\n' +
|
'<div class="d2h-wrapper">\n' +
|
||||||
' <div id="d2h-675094" class="d2h-file-wrapper" data-lang="js">\n' +
|
' <div id="d2h-675094" class="d2h-file-wrapper" data-lang="js">\n' +
|
||||||
' <div class="d2h-file-header">\n' +
|
' <div class="d2h-file-header">\n' +
|
||||||
|
|
@ -426,179 +424,183 @@ describe('LineByLinePrinter', function() {
|
||||||
' <path d="M6 5H2v-1h4v1zM2 8h7v-1H2v1z m0 2h7v-1H2v1z m0 2h7v-1H2v1z m10-7.5v9.5c0 0.55-0.45 1-1 1H1c-0.55 0-1-0.45-1-1V2c0-0.55 0.45-1 1-1h7.5l3.5 3.5z m-1 0.5L8 2H1v12h10V5z"></path>\n' +
|
' <path d="M6 5H2v-1h4v1zM2 8h7v-1H2v1z m0 2h7v-1H2v1z m0 2h7v-1H2v1z m10-7.5v9.5c0 0.55-0.45 1-1 1H1c-0.55 0-1-0.45-1-1V2c0-0.55 0.45-1 1-1h7.5l3.5 3.5z m-1 0.5L8 2H1v12h10V5z"></path>\n' +
|
||||||
' </svg> <span class="d2h-file-name">sample</span>\n' +
|
' </svg> <span class="d2h-file-name">sample</span>\n' +
|
||||||
' <span class="d2h-tag d2h-changed d2h-changed-tag">CHANGED</span></span>\n' +
|
' <span class="d2h-tag d2h-changed d2h-changed-tag">CHANGED</span></span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' <div class="d2h-file-diff">\n' +
|
' <div class="d2h-file-diff">\n' +
|
||||||
' <div class="d2h-code-wrapper">\n' +
|
' <div class="d2h-code-wrapper">\n' +
|
||||||
' <table class="d2h-diff-table">\n' +
|
' <table class="d2h-diff-table">\n' +
|
||||||
' <tbody class="d2h-diff-tbody">\n' +
|
' <tbody class="d2h-diff-tbody">\n' +
|
||||||
' <tr>\n' +
|
" <tr>\n" +
|
||||||
' <td class="d2h-info">\n' +
|
' <td class="d2h-info">\n' +
|
||||||
' <div class="d2h-code-line d2h-info">\n' +
|
' <div class="d2h-code-line d2h-info">\n' +
|
||||||
' File without changes\n' +
|
" File without changes\n" +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr>\n' +
|
"</tr>\n" +
|
||||||
' </tbody>\n' +
|
" </tbody>\n" +
|
||||||
' </table>\n' +
|
" </table>\n" +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
'</div>\n' +
|
"</div>\n" +
|
||||||
'</div>';
|
"</div>";
|
||||||
|
|
||||||
assert.equal(expected, html);
|
expect(expected).toEqual(html);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('_processLines', function() {
|
describe("_processLines", function() {
|
||||||
it('should work for simple block header', function() {
|
it("should work for simple block header", function() {
|
||||||
var lineByLinePrinter = new LineByLinePrinter({});
|
const lineByLinePrinter = new LineByLinePrinter({});
|
||||||
var oldLines = [{
|
const oldLines = [
|
||||||
content: '-test',
|
{
|
||||||
type: 'd2h-del',
|
content: "-test",
|
||||||
|
type: "d2h-del",
|
||||||
oldNumber: 1,
|
oldNumber: 1,
|
||||||
newNumber: null
|
newNumber: null
|
||||||
}];
|
}
|
||||||
var newLines = [{
|
];
|
||||||
content: '+test1r',
|
const newLines = [
|
||||||
type: 'd2h-ins',
|
{
|
||||||
|
content: "+test1r",
|
||||||
|
type: "d2h-ins",
|
||||||
oldNumber: null,
|
oldNumber: null,
|
||||||
newNumber: 1
|
newNumber: 1
|
||||||
}];
|
}
|
||||||
|
];
|
||||||
|
|
||||||
var html = lineByLinePrinter._processLines(false, oldLines, newLines);
|
const html = lineByLinePrinter._processLines(false, oldLines, newLines);
|
||||||
|
|
||||||
var expected =
|
const expected =
|
||||||
'<tr>\n' +
|
"<tr>\n" +
|
||||||
' <td class="d2h-code-linenumber d2h-del">\n' +
|
' <td class="d2h-code-linenumber d2h-del">\n' +
|
||||||
' <div class="line-num1">1</div>\n' +
|
' <div class="line-num1">1</div>\n' +
|
||||||
'<div class="line-num2"></div>\n' +
|
'<div class="line-num2"></div>\n' +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-del">\n' +
|
' <td class="d2h-del">\n' +
|
||||||
' <div class="d2h-code-line d2h-del">\n' +
|
' <div class="d2h-code-line d2h-del">\n' +
|
||||||
' <span class="d2h-code-line-prefix">-</span>\n' +
|
' <span class="d2h-code-line-prefix">-</span>\n' +
|
||||||
' <span class="d2h-code-line-ctn">test</span>\n' +
|
' <span class="d2h-code-line-ctn">test</span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr><tr>\n' +
|
"</tr><tr>\n" +
|
||||||
' <td class="d2h-code-linenumber d2h-ins">\n' +
|
' <td class="d2h-code-linenumber d2h-ins">\n' +
|
||||||
' <div class="line-num1"></div>\n' +
|
' <div class="line-num1"></div>\n' +
|
||||||
'<div class="line-num2">1</div>\n' +
|
'<div class="line-num2">1</div>\n' +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-ins">\n' +
|
' <td class="d2h-ins">\n' +
|
||||||
' <div class="d2h-code-line d2h-ins">\n' +
|
' <div class="d2h-code-line d2h-ins">\n' +
|
||||||
' <span class="d2h-code-line-prefix">+</span>\n' +
|
' <span class="d2h-code-line-prefix">+</span>\n' +
|
||||||
' <span class="d2h-code-line-ctn">test1r</span>\n' +
|
' <span class="d2h-code-line-ctn">test1r</span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr>';
|
"</tr>";
|
||||||
|
|
||||||
assert.equal(expected, html);
|
expect(expected).toEqual(html);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('_generateFileHtml', function() {
|
describe("_generateFileHtml", function() {
|
||||||
it('should work for simple file', function() {
|
it("should work for simple file", function() {
|
||||||
var lineByLinePrinter = new LineByLinePrinter({});
|
const lineByLinePrinter = new LineByLinePrinter({});
|
||||||
var file = {
|
const file = {
|
||||||
blocks: [
|
blocks: [
|
||||||
{
|
{
|
||||||
lines: [
|
lines: [
|
||||||
{
|
{
|
||||||
content: ' one context line',
|
content: " one context line",
|
||||||
type: 'd2h-cntx',
|
type: "d2h-cntx",
|
||||||
oldNumber: 1,
|
oldNumber: 1,
|
||||||
newNumber: 1
|
newNumber: 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
content: '-test',
|
content: "-test",
|
||||||
type: 'd2h-del',
|
type: "d2h-del",
|
||||||
oldNumber: 2,
|
oldNumber: 2,
|
||||||
newNumber: null
|
newNumber: null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
content: '+test1r',
|
content: "+test1r",
|
||||||
type: 'd2h-ins',
|
type: "d2h-ins",
|
||||||
oldNumber: null,
|
oldNumber: null,
|
||||||
newNumber: 2
|
newNumber: 2
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
content: '+test2r',
|
content: "+test2r",
|
||||||
type: 'd2h-ins',
|
type: "d2h-ins",
|
||||||
oldNumber: null,
|
oldNumber: null,
|
||||||
newNumber: 3
|
newNumber: 3
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
oldStartLine: '1',
|
oldStartLine: "1",
|
||||||
oldStartLine2: null,
|
oldStartLine2: null,
|
||||||
newStartLine: '1',
|
newStartLine: "1",
|
||||||
header: '@@ -1 +1 @@'
|
header: "@@ -1 +1 @@"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
deletedLines: 1,
|
deletedLines: 1,
|
||||||
addedLines: 1,
|
addedLines: 1,
|
||||||
checksumBefore: '0000001',
|
checksumBefore: "0000001",
|
||||||
checksumAfter: '0ddf2ba',
|
checksumAfter: "0ddf2ba",
|
||||||
oldName: 'sample',
|
oldName: "sample",
|
||||||
language: undefined,
|
language: undefined,
|
||||||
newName: 'sample',
|
newName: "sample",
|
||||||
isCombined: false
|
isCombined: false
|
||||||
};
|
};
|
||||||
|
|
||||||
var html = lineByLinePrinter._generateFileHtml(file);
|
const html = lineByLinePrinter._generateFileHtml(file);
|
||||||
|
|
||||||
var expected =
|
const expected =
|
||||||
'<tr>\n' +
|
"<tr>\n" +
|
||||||
' <td class="d2h-code-linenumber d2h-info"></td>\n' +
|
' <td class="d2h-code-linenumber d2h-info"></td>\n' +
|
||||||
' <td class="d2h-info">\n' +
|
' <td class="d2h-info">\n' +
|
||||||
' <div class="d2h-code-line d2h-info">@@ -1 +1 @@</div>\n' +
|
' <div class="d2h-code-line d2h-info">@@ -1 +1 @@</div>\n' +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr><tr>\n' +
|
"</tr><tr>\n" +
|
||||||
' <td class="d2h-code-linenumber d2h-cntx">\n' +
|
' <td class="d2h-code-linenumber d2h-cntx">\n' +
|
||||||
' <div class="line-num1">1</div>\n' +
|
' <div class="line-num1">1</div>\n' +
|
||||||
'<div class="line-num2">1</div>\n' +
|
'<div class="line-num2">1</div>\n' +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-cntx">\n' +
|
' <td class="d2h-cntx">\n' +
|
||||||
' <div class="d2h-code-line d2h-cntx">\n' +
|
' <div class="d2h-code-line d2h-cntx">\n' +
|
||||||
' <span class="d2h-code-line-prefix"> </span>\n' +
|
' <span class="d2h-code-line-prefix"> </span>\n' +
|
||||||
' <span class="d2h-code-line-ctn">one context line</span>\n' +
|
' <span class="d2h-code-line-ctn">one context line</span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr><tr>\n' +
|
"</tr><tr>\n" +
|
||||||
' <td class="d2h-code-linenumber d2h-del">\n' +
|
' <td class="d2h-code-linenumber d2h-del">\n' +
|
||||||
' <div class="line-num1">2</div>\n' +
|
' <div class="line-num1">2</div>\n' +
|
||||||
'<div class="line-num2"></div>\n' +
|
'<div class="line-num2"></div>\n' +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-del">\n' +
|
' <td class="d2h-del">\n' +
|
||||||
' <div class="d2h-code-line d2h-del">\n' +
|
' <div class="d2h-code-line d2h-del">\n' +
|
||||||
' <span class="d2h-code-line-prefix">-</span>\n' +
|
' <span class="d2h-code-line-prefix">-</span>\n' +
|
||||||
' <span class="d2h-code-line-ctn"><del>test</del></span>\n' +
|
' <span class="d2h-code-line-ctn"><del>test</del></span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr><tr>\n' +
|
"</tr><tr>\n" +
|
||||||
' <td class="d2h-code-linenumber d2h-ins">\n' +
|
' <td class="d2h-code-linenumber d2h-ins">\n' +
|
||||||
' <div class="line-num1"></div>\n' +
|
' <div class="line-num1"></div>\n' +
|
||||||
'<div class="line-num2">2</div>\n' +
|
'<div class="line-num2">2</div>\n' +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-ins">\n' +
|
' <td class="d2h-ins">\n' +
|
||||||
' <div class="d2h-code-line d2h-ins">\n' +
|
' <div class="d2h-code-line d2h-ins">\n' +
|
||||||
' <span class="d2h-code-line-prefix">+</span>\n' +
|
' <span class="d2h-code-line-prefix">+</span>\n' +
|
||||||
' <span class="d2h-code-line-ctn"><ins>test1r</ins></span>\n' +
|
' <span class="d2h-code-line-ctn"><ins>test1r</ins></span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr><tr>\n' +
|
"</tr><tr>\n" +
|
||||||
' <td class="d2h-code-linenumber d2h-ins">\n' +
|
' <td class="d2h-code-linenumber d2h-ins">\n' +
|
||||||
' <div class="line-num1"></div>\n' +
|
' <div class="line-num1"></div>\n' +
|
||||||
'<div class="line-num2">3</div>\n' +
|
'<div class="line-num2">3</div>\n' +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-ins">\n' +
|
' <td class="d2h-ins">\n' +
|
||||||
' <div class="d2h-code-line d2h-ins">\n' +
|
' <div class="d2h-code-line d2h-ins">\n' +
|
||||||
' <span class="d2h-code-line-prefix">+</span>\n' +
|
' <span class="d2h-code-line-prefix">+</span>\n' +
|
||||||
' <span class="d2h-code-line-ctn">test2r</span>\n' +
|
' <span class="d2h-code-line-ctn">test2r</span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr>';
|
"</tr>";
|
||||||
|
|
||||||
assert.equal(expected, html);
|
expect(expected).toEqual(html);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
126
src/__tests__/printer-utils-tests.js
Normal file
126
src/__tests__/printer-utils-tests.js
Normal file
|
|
@ -0,0 +1,126 @@
|
||||||
|
const PrinterUtils = require("../printer-utils.js").PrinterUtils;
|
||||||
|
|
||||||
|
describe("Utils", function() {
|
||||||
|
describe("getHtmlId", function() {
|
||||||
|
it("should generate file unique id", function() {
|
||||||
|
const result = PrinterUtils.getHtmlId({
|
||||||
|
oldName: "sample.js",
|
||||||
|
newName: "sample.js"
|
||||||
|
});
|
||||||
|
expect("d2h-960013").toEqual(result);
|
||||||
|
});
|
||||||
|
it("should generate file unique id for empty hashes", function() {
|
||||||
|
const result = PrinterUtils.getHtmlId({
|
||||||
|
oldName: "sample.js",
|
||||||
|
newName: "sample.js"
|
||||||
|
});
|
||||||
|
expect("d2h-960013").toEqual(result);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("getDiffName", function() {
|
||||||
|
it("should generate the file name for a changed file", function() {
|
||||||
|
const result = PrinterUtils.getDiffName({
|
||||||
|
oldName: "sample.js",
|
||||||
|
newName: "sample.js"
|
||||||
|
});
|
||||||
|
expect("sample.js").toEqual(result);
|
||||||
|
});
|
||||||
|
it("should generate the file name for a changed file and full rename", function() {
|
||||||
|
const result = PrinterUtils.getDiffName({
|
||||||
|
oldName: "sample1.js",
|
||||||
|
newName: "sample2.js"
|
||||||
|
});
|
||||||
|
expect("sample1.js → sample2.js").toEqual(result);
|
||||||
|
});
|
||||||
|
it("should generate the file name for a changed file and prefix rename", function() {
|
||||||
|
const result = PrinterUtils.getDiffName({
|
||||||
|
oldName: "src/path/sample.js",
|
||||||
|
newName: "source/path/sample.js"
|
||||||
|
});
|
||||||
|
expect("{src → source}/path/sample.js").toEqual(result);
|
||||||
|
});
|
||||||
|
it("should generate the file name for a changed file and suffix rename", function() {
|
||||||
|
const result = PrinterUtils.getDiffName({
|
||||||
|
oldName: "src/path/sample1.js",
|
||||||
|
newName: "src/path/sample2.js"
|
||||||
|
});
|
||||||
|
expect("src/path/{sample1.js → sample2.js}").toEqual(result);
|
||||||
|
});
|
||||||
|
it("should generate the file name for a changed file and middle rename", function() {
|
||||||
|
const result = PrinterUtils.getDiffName({
|
||||||
|
oldName: "src/really/big/path/sample.js",
|
||||||
|
newName: "src/small/path/sample.js"
|
||||||
|
});
|
||||||
|
expect("src/{really/big → small}/path/sample.js").toEqual(result);
|
||||||
|
});
|
||||||
|
it("should generate the file name for a deleted file", function() {
|
||||||
|
const result = PrinterUtils.getDiffName({
|
||||||
|
oldName: "src/my/file.js",
|
||||||
|
newName: "/dev/null"
|
||||||
|
});
|
||||||
|
expect("src/my/file.js").toEqual(result);
|
||||||
|
});
|
||||||
|
it("should generate the file name for a new file", function() {
|
||||||
|
const result = PrinterUtils.getDiffName({
|
||||||
|
oldName: "/dev/null",
|
||||||
|
newName: "src/my/file.js"
|
||||||
|
});
|
||||||
|
expect("src/my/file.js").toEqual(result);
|
||||||
|
});
|
||||||
|
it("should generate handle undefined filename", function() {
|
||||||
|
const result = PrinterUtils.getDiffName({});
|
||||||
|
expect("unknown/file/path").toEqual(result);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("diffHighlight", function() {
|
||||||
|
it("should highlight two lines", function() {
|
||||||
|
const result = PrinterUtils.diffHighlight("-var myVar = 2;", "+var myVariable = 3;", { matching: "words" });
|
||||||
|
|
||||||
|
expect({
|
||||||
|
first: {
|
||||||
|
prefix: "-",
|
||||||
|
line: "var <del>myVar</del> = <del>2</del>;"
|
||||||
|
},
|
||||||
|
second: {
|
||||||
|
prefix: "+",
|
||||||
|
line: "var <ins>myVariable</ins> = <ins>3</ins>;"
|
||||||
|
}
|
||||||
|
}).toEqual(result);
|
||||||
|
});
|
||||||
|
it("should highlight two lines char by char", function() {
|
||||||
|
const result = PrinterUtils.diffHighlight("-var myVar = 2;", "+var myVariable = 3;", { diffStyle: "char" });
|
||||||
|
|
||||||
|
expect({
|
||||||
|
first: {
|
||||||
|
prefix: "-",
|
||||||
|
line: "var myVar = <del>2</del>;"
|
||||||
|
},
|
||||||
|
second: {
|
||||||
|
prefix: "+",
|
||||||
|
line: "var myVar<ins>iable</ins> = <ins>3</ins>;"
|
||||||
|
}
|
||||||
|
}).toEqual(result);
|
||||||
|
});
|
||||||
|
it("should highlight combined diff lines", function() {
|
||||||
|
const result = PrinterUtils.diffHighlight(" -var myVar = 2;", " +var myVariable = 3;", {
|
||||||
|
diffStyle: "word",
|
||||||
|
isCombined: true,
|
||||||
|
matching: "words",
|
||||||
|
matchWordsThreshold: 1.0
|
||||||
|
});
|
||||||
|
|
||||||
|
expect({
|
||||||
|
first: {
|
||||||
|
prefix: " -",
|
||||||
|
line: 'var <del class="d2h-change">myVar</del> = <del class="d2h-change">2</del>;'
|
||||||
|
},
|
||||||
|
second: {
|
||||||
|
prefix: " +",
|
||||||
|
line: 'var <ins class="d2h-change">myVariable</ins> = <ins class="d2h-change">3</ins>;'
|
||||||
|
}
|
||||||
|
}).toEqual(result);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -1,240 +1,239 @@
|
||||||
var assert = require('assert');
|
const SideBySidePrinter = require("../side-by-side-printer.js").SideBySidePrinter;
|
||||||
|
|
||||||
var SideBySidePrinter = require('../src/side-by-side-printer.js').SideBySidePrinter;
|
describe("SideBySidePrinter", function() {
|
||||||
|
describe("generateEmptyDiff", function() {
|
||||||
describe('SideBySidePrinter', function() {
|
it("should return an empty diff", function() {
|
||||||
describe('generateEmptyDiff', function() {
|
const sideBySidePrinter = new SideBySidePrinter({});
|
||||||
it('should return an empty diff', function() {
|
const fileHtml = sideBySidePrinter.generateEmptyDiff();
|
||||||
var sideBySidePrinter = new SideBySidePrinter({});
|
const expectedRight = "";
|
||||||
var fileHtml = sideBySidePrinter.generateEmptyDiff();
|
const expectedLeft =
|
||||||
var expectedRight = '';
|
"<tr>\n" +
|
||||||
var expectedLeft = '<tr>\n' +
|
|
||||||
' <td class="d2h-info">\n' +
|
' <td class="d2h-info">\n' +
|
||||||
' <div class="d2h-code-side-line d2h-info">\n' +
|
' <div class="d2h-code-side-line d2h-info">\n' +
|
||||||
' File without changes\n' +
|
" File without changes\n" +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr>';
|
"</tr>";
|
||||||
|
|
||||||
assert.equal(expectedRight, fileHtml.right);
|
expect(expectedRight).toEqual(fileHtml.right);
|
||||||
assert.equal(expectedLeft, fileHtml.left);
|
expect(expectedLeft).toEqual(fileHtml.left);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('generateSideBySideFileHtml', function() {
|
describe("generateSideBySideFileHtml", function() {
|
||||||
it('should generate lines with the right prefixes', function() {
|
it("should generate lines with the right prefixes", function() {
|
||||||
var sideBySidePrinter = new SideBySidePrinter({});
|
const sideBySidePrinter = new SideBySidePrinter({});
|
||||||
|
|
||||||
var file = {
|
const file = {
|
||||||
'blocks': [
|
blocks: [
|
||||||
{
|
{
|
||||||
'lines': [
|
lines: [
|
||||||
{
|
{
|
||||||
'content': ' context',
|
content: " context",
|
||||||
'type': 'd2h-cntx',
|
type: "d2h-cntx",
|
||||||
'oldNumber': 19,
|
oldNumber: 19,
|
||||||
'newNumber': 19
|
newNumber: 19
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'content': '-removed',
|
content: "-removed",
|
||||||
'type': 'd2h-del',
|
type: "d2h-del",
|
||||||
'oldNumber': 20,
|
oldNumber: 20,
|
||||||
'newNumber': null
|
newNumber: null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'content': '+added',
|
content: "+added",
|
||||||
'type': 'd2h-ins',
|
type: "d2h-ins",
|
||||||
'oldNumber': null,
|
oldNumber: null,
|
||||||
'newNumber': 20
|
newNumber: 20
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'content': '+another added',
|
content: "+another added",
|
||||||
'type': 'd2h-ins',
|
type: "d2h-ins",
|
||||||
'oldNumber': null,
|
oldNumber: null,
|
||||||
'newNumber': 21
|
newNumber: 21
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
'oldStartLine': '19',
|
oldStartLine: "19",
|
||||||
'newStartLine': '19',
|
newStartLine: "19",
|
||||||
'header': '@@ -19,7 +19,7 @@'
|
header: "@@ -19,7 +19,7 @@"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
'deletedLines': 1,
|
deletedLines: 1,
|
||||||
'addedLines': 1,
|
addedLines: 1,
|
||||||
'checksumBefore': 'fc56817',
|
checksumBefore: "fc56817",
|
||||||
'checksumAfter': 'e8e7e49',
|
checksumAfter: "e8e7e49",
|
||||||
'mode': '100644',
|
mode: "100644",
|
||||||
'oldName': 'coverage.init',
|
oldName: "coverage.init",
|
||||||
'language': 'init',
|
language: "init",
|
||||||
'newName': 'coverage.init',
|
newName: "coverage.init",
|
||||||
'isCombined': false
|
isCombined: false
|
||||||
};
|
};
|
||||||
|
|
||||||
var fileHtml = sideBySidePrinter.generateSideBySideFileHtml(file);
|
const fileHtml = sideBySidePrinter.generateSideBySideFileHtml(file);
|
||||||
|
|
||||||
var expectedLeft =
|
const expectedLeft =
|
||||||
'<tr>\n' +
|
"<tr>\n" +
|
||||||
' <td class="d2h-code-side-linenumber d2h-info"></td>\n' +
|
' <td class="d2h-code-side-linenumber d2h-info"></td>\n' +
|
||||||
' <td class="d2h-info">\n' +
|
' <td class="d2h-info">\n' +
|
||||||
' <div class="d2h-code-side-line d2h-info">@@ -19,7 +19,7 @@</div>\n' +
|
' <div class="d2h-code-side-line d2h-info">@@ -19,7 +19,7 @@</div>\n' +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr><tr>\n' +
|
"</tr><tr>\n" +
|
||||||
' <td class="d2h-code-side-linenumber d2h-cntx">\n' +
|
' <td class="d2h-code-side-linenumber d2h-cntx">\n' +
|
||||||
' 19\n' +
|
" 19\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-cntx">\n' +
|
' <td class="d2h-cntx">\n' +
|
||||||
' <div class="d2h-code-side-line d2h-cntx">\n' +
|
' <div class="d2h-code-side-line d2h-cntx">\n' +
|
||||||
' <span class="d2h-code-line-prefix"> </span>\n' +
|
' <span class="d2h-code-line-prefix"> </span>\n' +
|
||||||
' <span class="d2h-code-line-ctn">context</span>\n' +
|
' <span class="d2h-code-line-ctn">context</span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr><tr>\n' +
|
"</tr><tr>\n" +
|
||||||
' <td class="d2h-code-side-linenumber d2h-del">\n' +
|
' <td class="d2h-code-side-linenumber d2h-del">\n' +
|
||||||
' 20\n' +
|
" 20\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-del">\n' +
|
' <td class="d2h-del">\n' +
|
||||||
' <div class="d2h-code-side-line d2h-del">\n' +
|
' <div class="d2h-code-side-line d2h-del">\n' +
|
||||||
' <span class="d2h-code-line-prefix">-</span>\n' +
|
' <span class="d2h-code-line-prefix">-</span>\n' +
|
||||||
' <span class="d2h-code-line-ctn"><del>removed</del></span>\n' +
|
' <span class="d2h-code-line-ctn"><del>removed</del></span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr><tr>\n' +
|
"</tr><tr>\n" +
|
||||||
' <td class="d2h-code-side-linenumber d2h-code-side-emptyplaceholder d2h-cntx d2h-emptyplaceholder">\n' +
|
' <td class="d2h-code-side-linenumber d2h-code-side-emptyplaceholder d2h-cntx d2h-emptyplaceholder">\n' +
|
||||||
' ' +
|
" " +
|
||||||
'\n' +
|
"\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-cntx d2h-emptyplaceholder">\n' +
|
' <td class="d2h-cntx d2h-emptyplaceholder">\n' +
|
||||||
' <div class="d2h-code-side-line d2h-code-side-emptyplaceholder d2h-cntx d2h-emptyplaceholder">\n' +
|
' <div class="d2h-code-side-line d2h-code-side-emptyplaceholder d2h-cntx d2h-emptyplaceholder">\n' +
|
||||||
' <span class="d2h-code-line-prefix"> </span>\n' +
|
' <span class="d2h-code-line-prefix"> </span>\n' +
|
||||||
' <span class="d2h-code-line-ctn"> </span>\n' +
|
' <span class="d2h-code-line-ctn"> </span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr>';
|
"</tr>";
|
||||||
|
|
||||||
var expectedRight =
|
const expectedRight =
|
||||||
'<tr>\n' +
|
"<tr>\n" +
|
||||||
' <td class="d2h-code-side-linenumber d2h-info"></td>\n' +
|
' <td class="d2h-code-side-linenumber d2h-info"></td>\n' +
|
||||||
' <td class="d2h-info">\n' +
|
' <td class="d2h-info">\n' +
|
||||||
' <div class="d2h-code-side-line d2h-info"></div>\n' +
|
' <div class="d2h-code-side-line d2h-info"></div>\n' +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr><tr>\n' +
|
"</tr><tr>\n" +
|
||||||
' <td class="d2h-code-side-linenumber d2h-cntx">\n' +
|
' <td class="d2h-code-side-linenumber d2h-cntx">\n' +
|
||||||
' 19\n' +
|
" 19\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-cntx">\n' +
|
' <td class="d2h-cntx">\n' +
|
||||||
' <div class="d2h-code-side-line d2h-cntx">\n' +
|
' <div class="d2h-code-side-line d2h-cntx">\n' +
|
||||||
' <span class="d2h-code-line-prefix"> </span>\n' +
|
' <span class="d2h-code-line-prefix"> </span>\n' +
|
||||||
' <span class="d2h-code-line-ctn">context</span>\n' +
|
' <span class="d2h-code-line-ctn">context</span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr><tr>\n' +
|
"</tr><tr>\n" +
|
||||||
' <td class="d2h-code-side-linenumber d2h-ins">\n' +
|
' <td class="d2h-code-side-linenumber d2h-ins">\n' +
|
||||||
' 20\n' +
|
" 20\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-ins">\n' +
|
' <td class="d2h-ins">\n' +
|
||||||
' <div class="d2h-code-side-line d2h-ins">\n' +
|
' <div class="d2h-code-side-line d2h-ins">\n' +
|
||||||
' <span class="d2h-code-line-prefix">+</span>\n' +
|
' <span class="d2h-code-line-prefix">+</span>\n' +
|
||||||
' <span class="d2h-code-line-ctn"><ins>added</ins></span>\n' +
|
' <span class="d2h-code-line-ctn"><ins>added</ins></span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr><tr>\n' +
|
"</tr><tr>\n" +
|
||||||
' <td class="d2h-code-side-linenumber d2h-ins">\n' +
|
' <td class="d2h-code-side-linenumber d2h-ins">\n' +
|
||||||
' 21\n' +
|
" 21\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-ins">\n' +
|
' <td class="d2h-ins">\n' +
|
||||||
' <div class="d2h-code-side-line d2h-ins">\n' +
|
' <div class="d2h-code-side-line d2h-ins">\n' +
|
||||||
' <span class="d2h-code-line-prefix">+</span>\n' +
|
' <span class="d2h-code-line-prefix">+</span>\n' +
|
||||||
' <span class="d2h-code-line-ctn">another added</span>\n' +
|
' <span class="d2h-code-line-ctn">another added</span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr>';
|
"</tr>";
|
||||||
|
|
||||||
assert.equal(expectedLeft, fileHtml.left);
|
expect(expectedLeft).toEqual(fileHtml.left);
|
||||||
assert.equal(expectedRight, fileHtml.right);
|
expect(expectedRight).toEqual(fileHtml.right);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('generateSingleLineHtml', function() {
|
describe("generateSingleLineHtml", function() {
|
||||||
it('should work for insertions', function() {
|
it("should work for insertions", function() {
|
||||||
var diffParser = require('../src/diff-parser.js').DiffParser;
|
const diffParser = require("../diff-parser.js").DiffParser;
|
||||||
var sideBySidePrinter = new SideBySidePrinter({});
|
const sideBySidePrinter = new SideBySidePrinter({});
|
||||||
var fileHtml = sideBySidePrinter.generateSingleLineHtml(false,
|
const fileHtml = sideBySidePrinter.generateSingleLineHtml(false, diffParser.LINE_TYPE.INSERTS, 30, "test", "+");
|
||||||
diffParser.LINE_TYPE.INSERTS, 30, 'test', '+');
|
const expected =
|
||||||
var expected = '<tr>\n' +
|
"<tr>\n" +
|
||||||
' <td class="d2h-code-side-linenumber d2h-ins">\n' +
|
' <td class="d2h-code-side-linenumber d2h-ins">\n' +
|
||||||
' 30\n' +
|
" 30\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-ins">\n' +
|
' <td class="d2h-ins">\n' +
|
||||||
' <div class="d2h-code-side-line d2h-ins">\n' +
|
' <div class="d2h-code-side-line d2h-ins">\n' +
|
||||||
' <span class="d2h-code-line-prefix">+</span>\n' +
|
' <span class="d2h-code-line-prefix">+</span>\n' +
|
||||||
' <span class="d2h-code-line-ctn">test</span>\n' +
|
' <span class="d2h-code-line-ctn">test</span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr>';
|
"</tr>";
|
||||||
|
|
||||||
assert.equal(expected, fileHtml);
|
expect(expected).toEqual(fileHtml);
|
||||||
});
|
});
|
||||||
it('should work for deletions', function() {
|
it("should work for deletions", function() {
|
||||||
var diffParser = require('../src/diff-parser.js').DiffParser;
|
const diffParser = require("../diff-parser.js").DiffParser;
|
||||||
var sideBySidePrinter = new SideBySidePrinter({});
|
const sideBySidePrinter = new SideBySidePrinter({});
|
||||||
var fileHtml = sideBySidePrinter.generateSingleLineHtml(false,
|
const fileHtml = sideBySidePrinter.generateSingleLineHtml(false, diffParser.LINE_TYPE.DELETES, 30, "test", "-");
|
||||||
diffParser.LINE_TYPE.DELETES, 30, 'test', '-');
|
const expected =
|
||||||
var expected = '<tr>\n' +
|
"<tr>\n" +
|
||||||
' <td class="d2h-code-side-linenumber d2h-del">\n' +
|
' <td class="d2h-code-side-linenumber d2h-del">\n' +
|
||||||
' 30\n' +
|
" 30\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-del">\n' +
|
' <td class="d2h-del">\n' +
|
||||||
' <div class="d2h-code-side-line d2h-del">\n' +
|
' <div class="d2h-code-side-line d2h-del">\n' +
|
||||||
' <span class="d2h-code-line-prefix">-</span>\n' +
|
' <span class="d2h-code-line-prefix">-</span>\n' +
|
||||||
' <span class="d2h-code-line-ctn">test</span>\n' +
|
' <span class="d2h-code-line-ctn">test</span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr>';
|
"</tr>";
|
||||||
|
|
||||||
assert.equal(expected, fileHtml);
|
expect(expected).toEqual(fileHtml);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('generateSideBySideJsonHtml', function() {
|
describe("generateSideBySideJsonHtml", function() {
|
||||||
it('should work for list of files', function() {
|
it("should work for list of files", function() {
|
||||||
var exampleJson = [
|
const exampleJson = [
|
||||||
{
|
{
|
||||||
blocks: [
|
blocks: [
|
||||||
{
|
{
|
||||||
lines: [
|
lines: [
|
||||||
{
|
{
|
||||||
content: '-test',
|
content: "-test",
|
||||||
type: 'd2h-del',
|
type: "d2h-del",
|
||||||
oldNumber: 1,
|
oldNumber: 1,
|
||||||
newNumber: null
|
newNumber: null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
content: '+test1r',
|
content: "+test1r",
|
||||||
type: 'd2h-ins',
|
type: "d2h-ins",
|
||||||
oldNumber: null,
|
oldNumber: null,
|
||||||
newNumber: 1
|
newNumber: 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
oldStartLine: '1',
|
oldStartLine: "1",
|
||||||
oldStartLine2: null,
|
oldStartLine2: null,
|
||||||
newStartLine: '1',
|
newStartLine: "1",
|
||||||
header: '@@ -1 +1 @@'
|
header: "@@ -1 +1 @@"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
deletedLines: 1,
|
deletedLines: 1,
|
||||||
addedLines: 1,
|
addedLines: 1,
|
||||||
checksumBefore: '0000001',
|
checksumBefore: "0000001",
|
||||||
checksumAfter: '0ddf2ba',
|
checksumAfter: "0ddf2ba",
|
||||||
oldName: 'sample',
|
oldName: "sample",
|
||||||
language: undefined,
|
language: undefined,
|
||||||
newName: 'sample',
|
newName: "sample",
|
||||||
isCombined: false
|
isCombined: false
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
var sideBySidePrinter = new SideBySidePrinter({matching: 'lines'});
|
const sideBySidePrinter = new SideBySidePrinter({ matching: "lines" });
|
||||||
var html = sideBySidePrinter.generateSideBySideJsonHtml(exampleJson);
|
const html = sideBySidePrinter.generateSideBySideJsonHtml(exampleJson);
|
||||||
var expected =
|
const expected =
|
||||||
'<div class="d2h-wrapper">\n' +
|
'<div class="d2h-wrapper">\n' +
|
||||||
' <div id="d2h-675094" class="d2h-file-wrapper" data-lang="">\n' +
|
' <div id="d2h-675094" class="d2h-file-wrapper" data-lang="">\n' +
|
||||||
' <div class="d2h-file-header">\n' +
|
' <div class="d2h-file-header">\n' +
|
||||||
|
|
@ -243,74 +242,76 @@ describe('SideBySidePrinter', function() {
|
||||||
' <path d="M6 5H2v-1h4v1zM2 8h7v-1H2v1z m0 2h7v-1H2v1z m0 2h7v-1H2v1z m10-7.5v9.5c0 0.55-0.45 1-1 1H1c-0.55 0-1-0.45-1-1V2c0-0.55 0.45-1 1-1h7.5l3.5 3.5z m-1 0.5L8 2H1v12h10V5z"></path>\n' +
|
' <path d="M6 5H2v-1h4v1zM2 8h7v-1H2v1z m0 2h7v-1H2v1z m0 2h7v-1H2v1z m10-7.5v9.5c0 0.55-0.45 1-1 1H1c-0.55 0-1-0.45-1-1V2c0-0.55 0.45-1 1-1h7.5l3.5 3.5z m-1 0.5L8 2H1v12h10V5z"></path>\n' +
|
||||||
' </svg> <span class="d2h-file-name">sample</span>\n' +
|
' </svg> <span class="d2h-file-name">sample</span>\n' +
|
||||||
' <span class="d2h-tag d2h-changed d2h-changed-tag">CHANGED</span></span>\n' +
|
' <span class="d2h-tag d2h-changed d2h-changed-tag">CHANGED</span></span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' <div class="d2h-files-diff">\n' +
|
' <div class="d2h-files-diff">\n' +
|
||||||
' <div class="d2h-file-side-diff">\n' +
|
' <div class="d2h-file-side-diff">\n' +
|
||||||
' <div class="d2h-code-wrapper">\n' +
|
' <div class="d2h-code-wrapper">\n' +
|
||||||
' <table class="d2h-diff-table">\n' +
|
' <table class="d2h-diff-table">\n' +
|
||||||
' <tbody class="d2h-diff-tbody">\n' +
|
' <tbody class="d2h-diff-tbody">\n' +
|
||||||
' <tr>\n' +
|
" <tr>\n" +
|
||||||
' <td class="d2h-code-side-linenumber d2h-info"></td>\n' +
|
' <td class="d2h-code-side-linenumber d2h-info"></td>\n' +
|
||||||
' <td class="d2h-info">\n' +
|
' <td class="d2h-info">\n' +
|
||||||
' <div class="d2h-code-side-line d2h-info">@@ -1 +1 @@</div>\n' +
|
' <div class="d2h-code-side-line d2h-info">@@ -1 +1 @@</div>\n' +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr><tr>\n' +
|
"</tr><tr>\n" +
|
||||||
' <td class="d2h-code-side-linenumber d2h-del">\n' +
|
' <td class="d2h-code-side-linenumber d2h-del">\n' +
|
||||||
' 1\n' +
|
" 1\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-del">\n' +
|
' <td class="d2h-del">\n' +
|
||||||
' <div class="d2h-code-side-line d2h-del">\n' +
|
' <div class="d2h-code-side-line d2h-del">\n' +
|
||||||
' <span class="d2h-code-line-prefix">-</span>\n' +
|
' <span class="d2h-code-line-prefix">-</span>\n' +
|
||||||
' <span class="d2h-code-line-ctn"><del>test</del></span>\n' +
|
' <span class="d2h-code-line-ctn"><del>test</del></span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr>\n' +
|
"</tr>\n" +
|
||||||
' </tbody>\n' +
|
" </tbody>\n" +
|
||||||
' </table>\n' +
|
" </table>\n" +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' <div class="d2h-file-side-diff">\n' +
|
' <div class="d2h-file-side-diff">\n' +
|
||||||
' <div class="d2h-code-wrapper">\n' +
|
' <div class="d2h-code-wrapper">\n' +
|
||||||
' <table class="d2h-diff-table">\n' +
|
' <table class="d2h-diff-table">\n' +
|
||||||
' <tbody class="d2h-diff-tbody">\n' +
|
' <tbody class="d2h-diff-tbody">\n' +
|
||||||
' <tr>\n' +
|
" <tr>\n" +
|
||||||
' <td class="d2h-code-side-linenumber d2h-info"></td>\n' +
|
' <td class="d2h-code-side-linenumber d2h-info"></td>\n' +
|
||||||
' <td class="d2h-info">\n' +
|
' <td class="d2h-info">\n' +
|
||||||
' <div class="d2h-code-side-line d2h-info"></div>\n' +
|
' <div class="d2h-code-side-line d2h-info"></div>\n' +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr><tr>\n' +
|
"</tr><tr>\n" +
|
||||||
' <td class="d2h-code-side-linenumber d2h-ins">\n' +
|
' <td class="d2h-code-side-linenumber d2h-ins">\n' +
|
||||||
' 1\n' +
|
" 1\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-ins">\n' +
|
' <td class="d2h-ins">\n' +
|
||||||
' <div class="d2h-code-side-line d2h-ins">\n' +
|
' <div class="d2h-code-side-line d2h-ins">\n' +
|
||||||
' <span class="d2h-code-line-prefix">+</span>\n' +
|
' <span class="d2h-code-line-prefix">+</span>\n' +
|
||||||
' <span class="d2h-code-line-ctn"><ins>test1r</ins></span>\n' +
|
' <span class="d2h-code-line-ctn"><ins>test1r</ins></span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr>\n' +
|
"</tr>\n" +
|
||||||
' </tbody>\n' +
|
" </tbody>\n" +
|
||||||
' </table>\n' +
|
" </table>\n" +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
'</div>\n' +
|
"</div>\n" +
|
||||||
'</div>';
|
"</div>";
|
||||||
|
|
||||||
assert.equal(expected, html);
|
expect(expected).toEqual(html);
|
||||||
});
|
});
|
||||||
it('should work for files without blocks', function() {
|
it("should work for files without blocks", function() {
|
||||||
var exampleJson = [{
|
const exampleJson = [
|
||||||
|
{
|
||||||
blocks: [],
|
blocks: [],
|
||||||
oldName: 'sample',
|
oldName: "sample",
|
||||||
language: 'js',
|
language: "js",
|
||||||
newName: 'sample',
|
newName: "sample",
|
||||||
isCombined: false
|
isCombined: false
|
||||||
}];
|
}
|
||||||
|
];
|
||||||
|
|
||||||
var sideBySidePrinter = new SideBySidePrinter();
|
const sideBySidePrinter = new SideBySidePrinter();
|
||||||
var html = sideBySidePrinter.generateSideBySideJsonHtml(exampleJson);
|
const html = sideBySidePrinter.generateSideBySideJsonHtml(exampleJson);
|
||||||
var expected =
|
const expected =
|
||||||
'<div class="d2h-wrapper">\n' +
|
'<div class="d2h-wrapper">\n' +
|
||||||
' <div id="d2h-675094" class="d2h-file-wrapper" data-lang="js">\n' +
|
' <div id="d2h-675094" class="d2h-file-wrapper" data-lang="js">\n' +
|
||||||
' <div class="d2h-file-header">\n' +
|
' <div class="d2h-file-header">\n' +
|
||||||
|
|
@ -319,86 +320,90 @@ describe('SideBySidePrinter', function() {
|
||||||
' <path d="M6 5H2v-1h4v1zM2 8h7v-1H2v1z m0 2h7v-1H2v1z m0 2h7v-1H2v1z m10-7.5v9.5c0 0.55-0.45 1-1 1H1c-0.55 0-1-0.45-1-1V2c0-0.55 0.45-1 1-1h7.5l3.5 3.5z m-1 0.5L8 2H1v12h10V5z"></path>\n' +
|
' <path d="M6 5H2v-1h4v1zM2 8h7v-1H2v1z m0 2h7v-1H2v1z m0 2h7v-1H2v1z m10-7.5v9.5c0 0.55-0.45 1-1 1H1c-0.55 0-1-0.45-1-1V2c0-0.55 0.45-1 1-1h7.5l3.5 3.5z m-1 0.5L8 2H1v12h10V5z"></path>\n' +
|
||||||
' </svg> <span class="d2h-file-name">sample</span>\n' +
|
' </svg> <span class="d2h-file-name">sample</span>\n' +
|
||||||
' <span class="d2h-tag d2h-changed d2h-changed-tag">CHANGED</span></span>\n' +
|
' <span class="d2h-tag d2h-changed d2h-changed-tag">CHANGED</span></span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' <div class="d2h-files-diff">\n' +
|
' <div class="d2h-files-diff">\n' +
|
||||||
' <div class="d2h-file-side-diff">\n' +
|
' <div class="d2h-file-side-diff">\n' +
|
||||||
' <div class="d2h-code-wrapper">\n' +
|
' <div class="d2h-code-wrapper">\n' +
|
||||||
' <table class="d2h-diff-table">\n' +
|
' <table class="d2h-diff-table">\n' +
|
||||||
' <tbody class="d2h-diff-tbody">\n' +
|
' <tbody class="d2h-diff-tbody">\n' +
|
||||||
' <tr>\n' +
|
" <tr>\n" +
|
||||||
' <td class="d2h-info">\n' +
|
' <td class="d2h-info">\n' +
|
||||||
' <div class="d2h-code-side-line d2h-info">\n' +
|
' <div class="d2h-code-side-line d2h-info">\n' +
|
||||||
' File without changes\n' +
|
" File without changes\n" +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr>\n' +
|
"</tr>\n" +
|
||||||
' </tbody>\n' +
|
" </tbody>\n" +
|
||||||
' </table>\n' +
|
" </table>\n" +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' <div class="d2h-file-side-diff">\n' +
|
' <div class="d2h-file-side-diff">\n' +
|
||||||
' <div class="d2h-code-wrapper">\n' +
|
' <div class="d2h-code-wrapper">\n' +
|
||||||
' <table class="d2h-diff-table">\n' +
|
' <table class="d2h-diff-table">\n' +
|
||||||
' <tbody class="d2h-diff-tbody">\n' +
|
' <tbody class="d2h-diff-tbody">\n' +
|
||||||
' \n' +
|
" \n" +
|
||||||
' </tbody>\n' +
|
" </tbody>\n" +
|
||||||
' </table>\n' +
|
" </table>\n" +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
'</div>\n' +
|
"</div>\n" +
|
||||||
'</div>';
|
"</div>";
|
||||||
|
|
||||||
assert.equal(expected, html);
|
expect(expected).toEqual(html);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('processLines', function() {
|
describe("processLines", function() {
|
||||||
it('should process file lines', function() {
|
it("should process file lines", function() {
|
||||||
var oldLines = [{
|
const oldLines = [
|
||||||
content: '-test',
|
{
|
||||||
type: 'd2h-del',
|
content: "-test",
|
||||||
|
type: "d2h-del",
|
||||||
oldNumber: 1,
|
oldNumber: 1,
|
||||||
newNumber: null
|
newNumber: null
|
||||||
}];
|
}
|
||||||
|
];
|
||||||
|
|
||||||
var newLines = [{
|
const newLines = [
|
||||||
content: '+test1r',
|
{
|
||||||
type: 'd2h-ins',
|
content: "+test1r",
|
||||||
|
type: "d2h-ins",
|
||||||
oldNumber: null,
|
oldNumber: null,
|
||||||
newNumber: 1
|
newNumber: 1
|
||||||
}];
|
}
|
||||||
|
];
|
||||||
|
|
||||||
var sideBySidePrinter = new SideBySidePrinter({matching: 'lines'});
|
const sideBySidePrinter = new SideBySidePrinter({ matching: "lines" });
|
||||||
var html = sideBySidePrinter.processLines(false, oldLines, newLines);
|
const html = sideBySidePrinter.processLines(false, oldLines, newLines);
|
||||||
var expectedLeft =
|
const expectedLeft =
|
||||||
'<tr>\n' +
|
"<tr>\n" +
|
||||||
' <td class="d2h-code-side-linenumber d2h-del">\n' +
|
' <td class="d2h-code-side-linenumber d2h-del">\n' +
|
||||||
' 1\n' +
|
" 1\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-del">\n' +
|
' <td class="d2h-del">\n' +
|
||||||
' <div class="d2h-code-side-line d2h-del">\n' +
|
' <div class="d2h-code-side-line d2h-del">\n' +
|
||||||
' <span class="d2h-code-line-prefix">-</span>\n' +
|
' <span class="d2h-code-line-prefix">-</span>\n' +
|
||||||
' <span class="d2h-code-line-ctn">test</span>\n' +
|
' <span class="d2h-code-line-ctn">test</span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr>';
|
"</tr>";
|
||||||
|
|
||||||
var expectedRight =
|
const expectedRight =
|
||||||
'<tr>\n' +
|
"<tr>\n" +
|
||||||
' <td class="d2h-code-side-linenumber d2h-ins">\n' +
|
' <td class="d2h-code-side-linenumber d2h-ins">\n' +
|
||||||
' 1\n' +
|
" 1\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
' <td class="d2h-ins">\n' +
|
' <td class="d2h-ins">\n' +
|
||||||
' <div class="d2h-code-side-line d2h-ins">\n' +
|
' <div class="d2h-code-side-line d2h-ins">\n' +
|
||||||
' <span class="d2h-code-line-prefix">+</span>\n' +
|
' <span class="d2h-code-line-prefix">+</span>\n' +
|
||||||
' <span class="d2h-code-line-ctn">test1r</span>\n' +
|
' <span class="d2h-code-line-ctn">test1r</span>\n' +
|
||||||
' </div>\n' +
|
" </div>\n" +
|
||||||
' </td>\n' +
|
" </td>\n" +
|
||||||
'</tr>';
|
"</tr>";
|
||||||
|
|
||||||
assert.equal(expectedLeft, html.left);
|
expect(expectedLeft).toEqual(html.left);
|
||||||
assert.equal(expectedRight, html.right);
|
expect(expectedRight).toEqual(html.right);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
23
src/__tests__/utils-tests.js
Normal file
23
src/__tests__/utils-tests.js
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
const Utils = require("../utils.js").Utils;
|
||||||
|
|
||||||
|
describe("Utils", function() {
|
||||||
|
describe("escape", function() {
|
||||||
|
it("should escape & with &", function() {
|
||||||
|
const result = Utils.escape("&");
|
||||||
|
expect("&").toEqual(result);
|
||||||
|
});
|
||||||
|
it("should escape < with <", function() {
|
||||||
|
const result = Utils.escape("<");
|
||||||
|
expect("<").toEqual(result);
|
||||||
|
});
|
||||||
|
it("should escape > with >", function() {
|
||||||
|
const result = Utils.escape(">");
|
||||||
|
expect(">").toEqual(result);
|
||||||
|
});
|
||||||
|
it("should escape a string with multiple problematic characters", function() {
|
||||||
|
const result = Utils.escape('<a href="#">\tlink text</a>');
|
||||||
|
const expected = "<a href="#">\tlink text</a>";
|
||||||
|
expect(expected).toEqual(result);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -6,39 +6,38 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
var utils = require('./utils.js').Utils;
|
const utils = require("./utils.js").Utils;
|
||||||
|
|
||||||
var LINE_TYPE = {
|
const LINE_TYPE = {
|
||||||
INSERTS: 'd2h-ins',
|
INSERTS: "d2h-ins",
|
||||||
DELETES: 'd2h-del',
|
DELETES: "d2h-del",
|
||||||
INSERT_CHANGES: 'd2h-ins d2h-change',
|
INSERT_CHANGES: "d2h-ins d2h-change",
|
||||||
DELETE_CHANGES: 'd2h-del d2h-change',
|
DELETE_CHANGES: "d2h-del d2h-change",
|
||||||
CONTEXT: 'd2h-cntx',
|
CONTEXT: "d2h-cntx",
|
||||||
INFO: 'd2h-info'
|
INFO: "d2h-info"
|
||||||
};
|
};
|
||||||
|
|
||||||
function DiffParser() {
|
function DiffParser() {}
|
||||||
}
|
|
||||||
|
|
||||||
DiffParser.prototype.LINE_TYPE = LINE_TYPE;
|
DiffParser.prototype.LINE_TYPE = LINE_TYPE;
|
||||||
|
|
||||||
DiffParser.prototype.generateDiffJson = function(diffInput, configuration) {
|
DiffParser.prototype.generateDiffJson = function(diffInput, configuration) {
|
||||||
var config = configuration || {};
|
const config = configuration || {};
|
||||||
|
|
||||||
var files = [];
|
const files = [];
|
||||||
var currentFile = null;
|
let currentFile = null;
|
||||||
var currentBlock = null;
|
let currentBlock = null;
|
||||||
var oldLine = null;
|
let oldLine = null;
|
||||||
var oldLine2 = null; // Used for combined diff
|
let oldLine2 = null; // Used for combined diff
|
||||||
var newLine = null;
|
let newLine = null;
|
||||||
|
|
||||||
var possibleOldName;
|
let possibleOldName;
|
||||||
var possibleNewName;
|
let possibleNewName;
|
||||||
|
|
||||||
/* Diff Header */
|
/* Diff Header */
|
||||||
var oldFileNameHeader = '--- ';
|
const oldFileNameHeader = "--- ";
|
||||||
var newFileNameHeader = '+++ ';
|
const newFileNameHeader = "+++ ";
|
||||||
var hunkHeaderPrefix = '@@';
|
const hunkHeaderPrefix = "@@";
|
||||||
|
|
||||||
/* Add previous block(if exists) before start a new file */
|
/* Add previous block(if exists) before start a new file */
|
||||||
function saveBlock() {
|
function saveBlock() {
|
||||||
|
|
@ -86,7 +85,7 @@
|
||||||
function startBlock(line) {
|
function startBlock(line) {
|
||||||
saveBlock();
|
saveBlock();
|
||||||
|
|
||||||
var values;
|
let values;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* From Range:
|
* From Range:
|
||||||
|
|
@ -113,7 +112,7 @@
|
||||||
newLine = values[3];
|
newLine = values[3];
|
||||||
} else {
|
} else {
|
||||||
if (utils.startsWith(line, hunkHeaderPrefix)) {
|
if (utils.startsWith(line, hunkHeaderPrefix)) {
|
||||||
console.error('Failed to parse lines, starting in 0!');
|
console.error("Failed to parse lines, starting in 0!");
|
||||||
}
|
}
|
||||||
|
|
||||||
oldLine = 0;
|
oldLine = 0;
|
||||||
|
|
@ -131,11 +130,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function createLine(line) {
|
function createLine(line) {
|
||||||
var currentLine = {};
|
const currentLine = {};
|
||||||
currentLine.content = line;
|
currentLine.content = line;
|
||||||
|
|
||||||
var newLinePrefixes = !currentFile.isCombined ? ['+'] : ['+', ' +'];
|
const newLinePrefixes = !currentFile.isCombined ? ["+"] : ["+", " +"];
|
||||||
var delLinePrefixes = !currentFile.isCombined ? ['-'] : ['-', ' -'];
|
const delLinePrefixes = !currentFile.isCombined ? ["-"] : ["-", " -"];
|
||||||
|
|
||||||
/* Fill the line data */
|
/* Fill the line data */
|
||||||
if (utils.startsWith(line, newLinePrefixes)) {
|
if (utils.startsWith(line, newLinePrefixes)) {
|
||||||
|
|
@ -169,10 +168,10 @@
|
||||||
* Hunk header is a group of three lines started by ( `--- ` , `+++ ` , `@@` )
|
* Hunk header is a group of three lines started by ( `--- ` , `+++ ` , `@@` )
|
||||||
*/
|
*/
|
||||||
function existHunkHeader(line, lineIdx) {
|
function existHunkHeader(line, lineIdx) {
|
||||||
var idx = lineIdx;
|
let idx = lineIdx;
|
||||||
|
|
||||||
while (idx < diffLines.length - 3) {
|
while (idx < diffLines.length - 3) {
|
||||||
if (utils.startsWith(line, 'diff')) {
|
if (utils.startsWith(line, "diff")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -190,56 +189,56 @@
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var diffLines =
|
var diffLines = diffInput
|
||||||
diffInput.replace(/\\ No newline at end of file/g, '')
|
.replace(/\\ No newline at end of file/g, "")
|
||||||
.replace(/\r\n?/g, '\n')
|
.replace(/\r\n?/g, "\n")
|
||||||
.split('\n');
|
.split("\n");
|
||||||
|
|
||||||
/* Diff */
|
/* Diff */
|
||||||
var oldMode = /^old mode (\d{6})/;
|
const oldMode = /^old mode (\d{6})/;
|
||||||
var newMode = /^new mode (\d{6})/;
|
const newMode = /^new mode (\d{6})/;
|
||||||
var deletedFileMode = /^deleted file mode (\d{6})/;
|
const deletedFileMode = /^deleted file mode (\d{6})/;
|
||||||
var newFileMode = /^new file mode (\d{6})/;
|
const newFileMode = /^new file mode (\d{6})/;
|
||||||
|
|
||||||
var copyFrom = /^copy from "?(.+)"?/;
|
const copyFrom = /^copy from "?(.+)"?/;
|
||||||
var copyTo = /^copy to "?(.+)"?/;
|
const copyTo = /^copy to "?(.+)"?/;
|
||||||
|
|
||||||
var renameFrom = /^rename from "?(.+)"?/;
|
const renameFrom = /^rename from "?(.+)"?/;
|
||||||
var renameTo = /^rename to "?(.+)"?/;
|
const renameTo = /^rename to "?(.+)"?/;
|
||||||
|
|
||||||
var similarityIndex = /^similarity index (\d+)%/;
|
const similarityIndex = /^similarity index (\d+)%/;
|
||||||
var dissimilarityIndex = /^dissimilarity index (\d+)%/;
|
const dissimilarityIndex = /^dissimilarity index (\d+)%/;
|
||||||
var index = /^index ([0-9a-z]+)\.\.([0-9a-z]+)\s*(\d{6})?/;
|
const index = /^index ([0-9a-z]+)\.\.([0-9a-z]+)\s*(\d{6})?/;
|
||||||
|
|
||||||
var binaryFiles = /^Binary files (.*) and (.*) differ/;
|
const binaryFiles = /^Binary files (.*) and (.*) differ/;
|
||||||
var binaryDiff = /^GIT binary patch/;
|
const binaryDiff = /^GIT binary patch/;
|
||||||
|
|
||||||
/* Combined Diff */
|
/* Combined Diff */
|
||||||
var combinedIndex = /^index ([0-9a-z]+),([0-9a-z]+)\.\.([0-9a-z]+)/;
|
const combinedIndex = /^index ([0-9a-z]+),([0-9a-z]+)\.\.([0-9a-z]+)/;
|
||||||
var combinedMode = /^mode (\d{6}),(\d{6})\.\.(\d{6})/;
|
const combinedMode = /^mode (\d{6}),(\d{6})\.\.(\d{6})/;
|
||||||
var combinedNewFile = /^new file mode (\d{6})/;
|
const combinedNewFile = /^new file mode (\d{6})/;
|
||||||
var combinedDeletedFile = /^deleted file mode (\d{6}),(\d{6})/;
|
const combinedDeletedFile = /^deleted file mode (\d{6}),(\d{6})/;
|
||||||
|
|
||||||
diffLines.forEach(function(line, lineIndex) {
|
diffLines.forEach(function(line, lineIndex) {
|
||||||
// Unmerged paths, and possibly other non-diffable files
|
// Unmerged paths, and possibly other non-diffable files
|
||||||
// https://github.com/scottgonzalez/pretty-diff/issues/11
|
// https://github.com/scottgonzalez/pretty-diff/issues/11
|
||||||
// Also, remove some useless lines
|
// Also, remove some useless lines
|
||||||
if (!line || utils.startsWith(line, '*')) {
|
if (!line || utils.startsWith(line, "*")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used to store regex capture groups
|
// Used to store regex capture groups
|
||||||
var values;
|
let values;
|
||||||
|
|
||||||
var prevLine = diffLines[lineIndex - 1];
|
const prevLine = diffLines[lineIndex - 1];
|
||||||
var nxtLine = diffLines[lineIndex + 1];
|
const nxtLine = diffLines[lineIndex + 1];
|
||||||
var afterNxtLine = diffLines[lineIndex + 2];
|
const afterNxtLine = diffLines[lineIndex + 2];
|
||||||
|
|
||||||
if (utils.startsWith(line, 'diff')) {
|
if (utils.startsWith(line, "diff")) {
|
||||||
startFile();
|
startFile();
|
||||||
|
|
||||||
// diff --git a/blocked_delta_results.png b/blocked_delta_results.png
|
// diff --git a/blocked_delta_results.png b/blocked_delta_results.png
|
||||||
var gitDiffStart = /^diff --git "?(.+)"? "?(.+)"?/;
|
const gitDiffStart = /^diff --git "?(.+)"? "?(.+)"?/;
|
||||||
if ((values = gitDiffStart.exec(line))) {
|
if ((values = gitDiffStart.exec(line))) {
|
||||||
possibleOldName = _getFilename(null, values[1], config.dstPrefix);
|
possibleOldName = _getFilename(null, values[1], config.dstPrefix);
|
||||||
possibleNewName = _getFilename(null, values[2], config.srcPrefix);
|
possibleNewName = _getFilename(null, values[2], config.srcPrefix);
|
||||||
|
|
@ -249,15 +248,14 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!currentFile || // If we do not have a file yet, we should crete one
|
if (
|
||||||
(
|
!currentFile || // If we do not have a file yet, we should crete one
|
||||||
!currentFile.isGitDiff && currentFile && // If we already have some file in progress and
|
(!currentFile.isGitDiff &&
|
||||||
(
|
currentFile && // If we already have some file in progress and
|
||||||
utils.startsWith(line, oldFileNameHeader) && // If we get to an old file path header line
|
(utils.startsWith(line, oldFileNameHeader) && // If we get to an old file path header line
|
||||||
// And is followed by the new file path header line and the hunk header line
|
// And is followed by the new file path header line and the hunk header line
|
||||||
utils.startsWith(nxtLine, newFileNameHeader) && utils.startsWith(afterNxtLine, hunkHeaderPrefix)
|
utils.startsWith(nxtLine, newFileNameHeader) &&
|
||||||
)
|
utils.startsWith(afterNxtLine, hunkHeaderPrefix)))
|
||||||
)
|
|
||||||
) {
|
) {
|
||||||
startFile();
|
startFile();
|
||||||
}
|
}
|
||||||
|
|
@ -268,18 +266,19 @@
|
||||||
* - https://github.com/rtfpessoa/diff2html/issues/87
|
* - https://github.com/rtfpessoa/diff2html/issues/87
|
||||||
*/
|
*/
|
||||||
if (
|
if (
|
||||||
(utils.startsWith(line, oldFileNameHeader) &&
|
(utils.startsWith(line, oldFileNameHeader) && utils.startsWith(nxtLine, newFileNameHeader)) ||
|
||||||
utils.startsWith(nxtLine, newFileNameHeader)) ||
|
(utils.startsWith(line, newFileNameHeader) && utils.startsWith(prevLine, oldFileNameHeader))
|
||||||
|
|
||||||
(utils.startsWith(line, newFileNameHeader) &&
|
|
||||||
utils.startsWith(prevLine, oldFileNameHeader))
|
|
||||||
) {
|
) {
|
||||||
/*
|
/*
|
||||||
* --- Date Timestamp[FractionalSeconds] TimeZone
|
* --- Date Timestamp[FractionalSeconds] TimeZone
|
||||||
* --- 2002-02-21 23:30:39.942229878 -0800
|
* --- 2002-02-21 23:30:39.942229878 -0800
|
||||||
*/
|
*/
|
||||||
if (currentFile && !currentFile.oldName &&
|
if (
|
||||||
utils.startsWith(line, '--- ') && (values = getSrcFilename(line, config))) {
|
currentFile &&
|
||||||
|
!currentFile.oldName &&
|
||||||
|
utils.startsWith(line, "--- ") &&
|
||||||
|
(values = getSrcFilename(line, config))
|
||||||
|
) {
|
||||||
currentFile.oldName = values;
|
currentFile.oldName = values;
|
||||||
currentFile.language = getExtension(currentFile.oldName, currentFile.language);
|
currentFile.language = getExtension(currentFile.oldName, currentFile.language);
|
||||||
return;
|
return;
|
||||||
|
|
@ -289,8 +288,12 @@
|
||||||
* +++ Date Timestamp[FractionalSeconds] TimeZone
|
* +++ Date Timestamp[FractionalSeconds] TimeZone
|
||||||
* +++ 2002-02-21 23:30:39.942229878 -0800
|
* +++ 2002-02-21 23:30:39.942229878 -0800
|
||||||
*/
|
*/
|
||||||
if (currentFile && !currentFile.newName &&
|
if (
|
||||||
utils.startsWith(line, '+++ ') && (values = getDstFilename(line, config))) {
|
currentFile &&
|
||||||
|
!currentFile.newName &&
|
||||||
|
utils.startsWith(line, "+++ ") &&
|
||||||
|
(values = getDstFilename(line, config))
|
||||||
|
) {
|
||||||
currentFile.newName = values;
|
currentFile.newName = values;
|
||||||
currentFile.language = getExtension(currentFile.newName, currentFile.language);
|
currentFile.language = getExtension(currentFile.newName, currentFile.language);
|
||||||
return;
|
return;
|
||||||
|
|
@ -311,12 +314,12 @@
|
||||||
* 2. Old line starts with: -
|
* 2. Old line starts with: -
|
||||||
* 3. Context line starts with: <SPACE>
|
* 3. Context line starts with: <SPACE>
|
||||||
*/
|
*/
|
||||||
if (currentBlock && (utils.startsWith(line, '+') || utils.startsWith(line, '-') || utils.startsWith(line, ' '))) {
|
if (currentBlock && (utils.startsWith(line, "+") || utils.startsWith(line, "-") || utils.startsWith(line, " "))) {
|
||||||
createLine(line);
|
createLine(line);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var doesNotExistHunkHeader = !existHunkHeader(line, lineIndex);
|
const doesNotExistHunkHeader = !existHunkHeader(line, lineIndex);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Git diffs provide more information regarding files modes, renames, copies,
|
* Git diffs provide more information regarding files modes, renames, copies,
|
||||||
|
|
@ -356,7 +359,7 @@
|
||||||
currentFile.isBinary = true;
|
currentFile.isBinary = true;
|
||||||
currentFile.oldName = _getFilename(null, values[1], config.srcPrefix);
|
currentFile.oldName = _getFilename(null, values[1], config.srcPrefix);
|
||||||
currentFile.newName = _getFilename(null, values[2], config.dstPrefix);
|
currentFile.newName = _getFilename(null, values[2], config.dstPrefix);
|
||||||
startBlock('Binary file');
|
startBlock("Binary file");
|
||||||
} else if ((values = binaryDiff.exec(line))) {
|
} else if ((values = binaryDiff.exec(line))) {
|
||||||
currentFile.isBinary = true;
|
currentFile.isBinary = true;
|
||||||
startBlock(line);
|
startBlock(line);
|
||||||
|
|
@ -390,7 +393,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
function getExtension(filename, language) {
|
function getExtension(filename, language) {
|
||||||
var nameSplit = filename.split('.');
|
const nameSplit = filename.split(".");
|
||||||
if (nameSplit.length > 1) {
|
if (nameSplit.length > 1) {
|
||||||
return nameSplit[nameSplit.length - 1];
|
return nameSplit[nameSplit.length - 1];
|
||||||
}
|
}
|
||||||
|
|
@ -399,31 +402,31 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSrcFilename(line, cfg) {
|
function getSrcFilename(line, cfg) {
|
||||||
return _getFilename('---', line, cfg.srcPrefix);
|
return _getFilename("---", line, cfg.srcPrefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDstFilename(line, cfg) {
|
function getDstFilename(line, cfg) {
|
||||||
return _getFilename('\\+\\+\\+', line, cfg.dstPrefix);
|
return _getFilename("\\+\\+\\+", line, cfg.dstPrefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _getFilename(linePrefix, line, extraPrefix) {
|
function _getFilename(linePrefix, line, extraPrefix) {
|
||||||
var prefixes = ['a/', 'b/', 'i/', 'w/', 'c/', 'o/'];
|
const prefixes = ["a/", "b/", "i/", "w/", "c/", "o/"];
|
||||||
if (extraPrefix) {
|
if (extraPrefix) {
|
||||||
prefixes.push(extraPrefix);
|
prefixes.push(extraPrefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
var FilenameRegExp;
|
let FilenameRegExp;
|
||||||
if (linePrefix) {
|
if (linePrefix) {
|
||||||
FilenameRegExp = new RegExp('^' + linePrefix + ' "?(.+?)"?$');
|
FilenameRegExp = new RegExp("^" + linePrefix + ' "?(.+?)"?$');
|
||||||
} else {
|
} else {
|
||||||
FilenameRegExp = new RegExp('^"?(.+?)"?$');
|
FilenameRegExp = new RegExp('^"?(.+?)"?$');
|
||||||
}
|
}
|
||||||
|
|
||||||
var filename;
|
let filename;
|
||||||
var values = FilenameRegExp.exec(line);
|
const values = FilenameRegExp.exec(line);
|
||||||
if (values && values[1]) {
|
if (values && values[1]) {
|
||||||
filename = values[1];
|
filename = values[1];
|
||||||
var matchingPrefixes = prefixes.filter(function(p) {
|
const matchingPrefixes = prefixes.filter(function(p) {
|
||||||
return filename.indexOf(p) === 0;
|
return filename.indexOf(p) === 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -435,7 +438,7 @@
|
||||||
// Cleanup timestamps generated by the unified diff (diff command) as specified in
|
// Cleanup timestamps generated by the unified diff (diff command) as specified in
|
||||||
// https://www.gnu.org/software/diffutils/manual/html_node/Detailed-Unified.html
|
// https://www.gnu.org/software/diffutils/manual/html_node/Detailed-Unified.html
|
||||||
// Ie: 2016-10-25 11:37:14.000000000 +0200
|
// Ie: 2016-10-25 11:37:14.000000000 +0200
|
||||||
filename = filename.replace(/\s+\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}(?:\.\d+)? [-+]\d{4}.*$/, '');
|
filename = filename.replace(/\s+\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}(?:\.\d+)? [-+]\d{4}.*$/, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
return filename;
|
return filename;
|
||||||
|
|
|
||||||
11
src/diff2html.d.ts
vendored
11
src/diff2html.d.ts
vendored
|
|
@ -4,13 +4,12 @@
|
||||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||||
|
|
||||||
declare namespace Diff2Html {
|
declare namespace Diff2Html {
|
||||||
|
|
||||||
export interface Options {
|
export interface Options {
|
||||||
inputFormat?: 'diff' | 'json';
|
inputFormat?: "diff" | "json";
|
||||||
outputFormat?: 'line-by-line' | 'side-by-side';
|
outputFormat?: "line-by-line" | "side-by-side";
|
||||||
showFiles?: boolean;
|
showFiles?: boolean;
|
||||||
diffStyle?: 'word' | 'char';
|
diffStyle?: "word" | "char";
|
||||||
matching?: 'lines' | 'words' | 'none';
|
matching?: "lines" | "words" | "none";
|
||||||
matchWordsThreshold?: number;
|
matchWordsThreshold?: number;
|
||||||
matchingMaxComparisons?: number;
|
matchingMaxComparisons?: number;
|
||||||
maxLineSizeInBlockForComparison?: number;
|
maxLineSizeInBlockForComparison?: number;
|
||||||
|
|
@ -66,6 +65,6 @@ declare namespace Diff2Html {
|
||||||
}
|
}
|
||||||
|
|
||||||
declare module "diff2html" {
|
declare module "diff2html" {
|
||||||
var d2h: { "Diff2Html": Diff2Html.Diff2Html };
|
var d2h: { Diff2Html: Diff2Html.Diff2Html };
|
||||||
export = d2h;
|
export = d2h;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,19 +6,18 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
var diffParser = require('./diff-parser.js').DiffParser;
|
const diffParser = require("./diff-parser.js").DiffParser;
|
||||||
var htmlPrinter = require('./html-printer.js').HtmlPrinter;
|
const htmlPrinter = require("./html-printer.js").HtmlPrinter;
|
||||||
var utils = require('./utils.js').Utils;
|
const utils = require("./utils.js").Utils;
|
||||||
|
|
||||||
function Diff2Html() {
|
function Diff2Html() {}
|
||||||
}
|
|
||||||
|
|
||||||
var defaultConfig = {
|
const defaultConfig = {
|
||||||
inputFormat: 'diff',
|
inputFormat: "diff",
|
||||||
outputFormat: 'line-by-line',
|
outputFormat: "line-by-line",
|
||||||
showFiles: false,
|
showFiles: false,
|
||||||
diffStyle: 'word',
|
diffStyle: "word",
|
||||||
matching: 'none',
|
matching: "none",
|
||||||
matchWordsThreshold: 0.25,
|
matchWordsThreshold: 0.25,
|
||||||
matchingMaxComparisons: 2500,
|
matchingMaxComparisons: 2500,
|
||||||
maxLineSizeInBlockForComparison: 200,
|
maxLineSizeInBlockForComparison: 200,
|
||||||
|
|
@ -32,7 +31,7 @@
|
||||||
* Generates json object from string diff input
|
* Generates json object from string diff input
|
||||||
*/
|
*/
|
||||||
Diff2Html.prototype.getJsonFromDiff = function(diffInput, config) {
|
Diff2Html.prototype.getJsonFromDiff = function(diffInput, config) {
|
||||||
var cfg = utils.safeConfig(config, defaultConfig);
|
const cfg = utils.safeConfig(config, defaultConfig);
|
||||||
return diffParser.generateDiffJson(diffInput, cfg);
|
return diffParser.generateDiffJson(diffInput, cfg);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -40,20 +39,20 @@
|
||||||
* Generates the html diff. The config parameter configures the output/input formats and other options
|
* Generates the html diff. The config parameter configures the output/input formats and other options
|
||||||
*/
|
*/
|
||||||
Diff2Html.prototype.getPrettyHtml = function(diffInput, config) {
|
Diff2Html.prototype.getPrettyHtml = function(diffInput, config) {
|
||||||
var cfg = utils.safeConfig(config, defaultConfig);
|
const cfg = utils.safeConfig(config, defaultConfig);
|
||||||
|
|
||||||
var diffJson = diffInput;
|
let diffJson = diffInput;
|
||||||
if (!cfg.inputFormat || cfg.inputFormat === 'diff') {
|
if (!cfg.inputFormat || cfg.inputFormat === "diff") {
|
||||||
diffJson = diffParser.generateDiffJson(diffInput, cfg);
|
diffJson = diffParser.generateDiffJson(diffInput, cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
var fileList = '';
|
let fileList = "";
|
||||||
if (cfg.showFiles === true) {
|
if (cfg.showFiles === true) {
|
||||||
fileList = htmlPrinter.generateFileListSummary(diffJson, cfg);
|
fileList = htmlPrinter.generateFileListSummary(diffJson, cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
var diffOutput = '';
|
let diffOutput = "";
|
||||||
if (cfg.outputFormat === 'side-by-side') {
|
if (cfg.outputFormat === "side-by-side") {
|
||||||
diffOutput = htmlPrinter.generateSideBySideJsonHtml(diffJson, cfg);
|
diffOutput = htmlPrinter.generateSideBySideJsonHtml(diffJson, cfg);
|
||||||
} else {
|
} else {
|
||||||
diffOutput = htmlPrinter.generateLineByLineJsonHtml(diffJson, cfg);
|
diffOutput = htmlPrinter.generateLineByLineJsonHtml(diffJson, cfg);
|
||||||
|
|
@ -70,9 +69,9 @@
|
||||||
* Generates pretty html from string diff input
|
* Generates pretty html from string diff input
|
||||||
*/
|
*/
|
||||||
Diff2Html.prototype.getPrettyHtmlFromDiff = function(diffInput, config) {
|
Diff2Html.prototype.getPrettyHtmlFromDiff = function(diffInput, config) {
|
||||||
var cfg = utils.safeConfig(config, defaultConfig);
|
const cfg = utils.safeConfig(config, defaultConfig);
|
||||||
cfg.inputFormat = 'diff';
|
cfg.inputFormat = "diff";
|
||||||
cfg.outputFormat = 'line-by-line';
|
cfg.outputFormat = "line-by-line";
|
||||||
return this.getPrettyHtml(diffInput, cfg);
|
return this.getPrettyHtml(diffInput, cfg);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -80,9 +79,9 @@
|
||||||
* Generates pretty html from a json object
|
* Generates pretty html from a json object
|
||||||
*/
|
*/
|
||||||
Diff2Html.prototype.getPrettyHtmlFromJson = function(diffJson, config) {
|
Diff2Html.prototype.getPrettyHtmlFromJson = function(diffJson, config) {
|
||||||
var cfg = utils.safeConfig(config, defaultConfig);
|
const cfg = utils.safeConfig(config, defaultConfig);
|
||||||
cfg.inputFormat = 'json';
|
cfg.inputFormat = "json";
|
||||||
cfg.outputFormat = 'line-by-line';
|
cfg.outputFormat = "line-by-line";
|
||||||
return this.getPrettyHtml(diffJson, cfg);
|
return this.getPrettyHtml(diffJson, cfg);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -90,9 +89,9 @@
|
||||||
* Generates pretty side by side html from string diff input
|
* Generates pretty side by side html from string diff input
|
||||||
*/
|
*/
|
||||||
Diff2Html.prototype.getPrettySideBySideHtmlFromDiff = function(diffInput, config) {
|
Diff2Html.prototype.getPrettySideBySideHtmlFromDiff = function(diffInput, config) {
|
||||||
var cfg = utils.safeConfig(config, defaultConfig);
|
const cfg = utils.safeConfig(config, defaultConfig);
|
||||||
cfg.inputFormat = 'diff';
|
cfg.inputFormat = "diff";
|
||||||
cfg.outputFormat = 'side-by-side';
|
cfg.outputFormat = "side-by-side";
|
||||||
return this.getPrettyHtml(diffInput, cfg);
|
return this.getPrettyHtml(diffInput, cfg);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -100,13 +99,13 @@
|
||||||
* Generates pretty side by side html from a json object
|
* Generates pretty side by side html from a json object
|
||||||
*/
|
*/
|
||||||
Diff2Html.prototype.getPrettySideBySideHtmlFromJson = function(diffJson, config) {
|
Diff2Html.prototype.getPrettySideBySideHtmlFromJson = function(diffJson, config) {
|
||||||
var cfg = utils.safeConfig(config, defaultConfig);
|
const cfg = utils.safeConfig(config, defaultConfig);
|
||||||
cfg.inputFormat = 'json';
|
cfg.inputFormat = "json";
|
||||||
cfg.outputFormat = 'side-by-side';
|
cfg.outputFormat = "side-by-side";
|
||||||
return this.getPrettyHtml(diffJson, cfg);
|
return this.getPrettyHtml(diffJson, cfg);
|
||||||
};
|
};
|
||||||
|
|
||||||
var diffObject = new Diff2Html();
|
const diffObject = new Diff2Html();
|
||||||
module.exports.Diff2Html = diffObject;
|
module.exports.Diff2Html = diffObject;
|
||||||
|
|
||||||
// Expose diff2html in the browser
|
// Expose diff2html in the browser
|
||||||
|
|
|
||||||
|
|
@ -6,40 +6,45 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
var printerUtils = require('./printer-utils.js').PrinterUtils;
|
const printerUtils = require("./printer-utils.js").PrinterUtils;
|
||||||
|
|
||||||
var hoganUtils;
|
let hoganUtils;
|
||||||
|
|
||||||
var baseTemplatesPath = 'file-summary';
|
const baseTemplatesPath = "file-summary";
|
||||||
var iconsBaseTemplatesPath = 'icon';
|
const iconsBaseTemplatesPath = "icon";
|
||||||
|
|
||||||
function FileListPrinter(config) {
|
function FileListPrinter(config) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
|
|
||||||
var HoganJsUtils = require('./hoganjs-utils.js').HoganJsUtils;
|
const HoganJsUtils = require("./hoganjs-utils.js").HoganJsUtils;
|
||||||
hoganUtils = new HoganJsUtils(config);
|
hoganUtils = new HoganJsUtils(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
FileListPrinter.prototype.generateFileList = function(diffFiles) {
|
FileListPrinter.prototype.generateFileList = function(diffFiles) {
|
||||||
var lineTemplate = hoganUtils.template(baseTemplatesPath, 'line');
|
const lineTemplate = hoganUtils.template(baseTemplatesPath, "line");
|
||||||
|
|
||||||
var files = diffFiles.map(function(file) {
|
const files = diffFiles
|
||||||
var fileTypeName = printerUtils.getFileTypeIcon(file);
|
.map(function(file) {
|
||||||
var iconTemplate = hoganUtils.template(iconsBaseTemplatesPath, fileTypeName);
|
const fileTypeName = printerUtils.getFileTypeIcon(file);
|
||||||
|
const iconTemplate = hoganUtils.template(iconsBaseTemplatesPath, fileTypeName);
|
||||||
|
|
||||||
return lineTemplate.render({
|
return lineTemplate.render(
|
||||||
|
{
|
||||||
fileHtmlId: printerUtils.getHtmlId(file),
|
fileHtmlId: printerUtils.getHtmlId(file),
|
||||||
oldName: file.oldName,
|
oldName: file.oldName,
|
||||||
newName: file.newName,
|
newName: file.newName,
|
||||||
fileName: printerUtils.getDiffName(file),
|
fileName: printerUtils.getDiffName(file),
|
||||||
deletedLines: '-' + file.deletedLines,
|
deletedLines: "-" + file.deletedLines,
|
||||||
addedLines: '+' + file.addedLines
|
addedLines: "+" + file.addedLines
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
fileIcon: iconTemplate
|
fileIcon: iconTemplate
|
||||||
});
|
}
|
||||||
}).join('\n');
|
);
|
||||||
|
})
|
||||||
|
.join("\n");
|
||||||
|
|
||||||
return hoganUtils.render(baseTemplatesPath, 'wrapper', {
|
return hoganUtils.render(baseTemplatesPath, "wrapper", {
|
||||||
filesNumber: diffFiles.length,
|
filesNumber: diffFiles.length,
|
||||||
files: files
|
files: files
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -6,20 +6,20 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
var fs = require('fs');
|
const fs = require("fs");
|
||||||
var path = require('path');
|
const path = require("path");
|
||||||
var hogan = require('hogan.js');
|
const hogan = require("hogan.js");
|
||||||
|
|
||||||
var hoganTemplates = require('./templates/diff2html-templates.js');
|
const hoganTemplates = require("./diff2html-templates.js");
|
||||||
|
|
||||||
var extraTemplates;
|
let extraTemplates;
|
||||||
|
|
||||||
function HoganJsUtils(configuration) {
|
function HoganJsUtils(configuration) {
|
||||||
this.config = configuration || {};
|
this.config = configuration || {};
|
||||||
extraTemplates = this.config.templates || {};
|
extraTemplates = this.config.templates || {};
|
||||||
|
|
||||||
var rawTemplates = this.config.rawTemplates || {};
|
const rawTemplates = this.config.rawTemplates || {};
|
||||||
for (var templateName in rawTemplates) {
|
for (const templateName in rawTemplates) {
|
||||||
if (rawTemplates.hasOwnProperty(templateName)) {
|
if (rawTemplates.hasOwnProperty(templateName)) {
|
||||||
if (!extraTemplates[templateName]) extraTemplates[templateName] = this.compile(rawTemplates[templateName]);
|
if (!extraTemplates[templateName]) extraTemplates[templateName] = this.compile(rawTemplates[templateName]);
|
||||||
}
|
}
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
HoganJsUtils.prototype.render = function(namespace, view, params) {
|
HoganJsUtils.prototype.render = function(namespace, view, params) {
|
||||||
var template = this.template(namespace, view);
|
const template = this.template(namespace, view);
|
||||||
if (template) {
|
if (template) {
|
||||||
return template.render(params);
|
return template.render(params);
|
||||||
}
|
}
|
||||||
|
|
@ -36,13 +36,13 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
HoganJsUtils.prototype.template = function(namespace, view) {
|
HoganJsUtils.prototype.template = function(namespace, view) {
|
||||||
var templateKey = this._templateKey(namespace, view);
|
const templateKey = this._templateKey(namespace, view);
|
||||||
|
|
||||||
return this._getTemplate(templateKey);
|
return this._getTemplate(templateKey);
|
||||||
};
|
};
|
||||||
|
|
||||||
HoganJsUtils.prototype._getTemplate = function(templateKey) {
|
HoganJsUtils.prototype._getTemplate = function(templateKey) {
|
||||||
var template;
|
let template;
|
||||||
|
|
||||||
if (!this.config.noCache) {
|
if (!this.config.noCache) {
|
||||||
template = this._readFromCache(templateKey);
|
template = this._readFromCache(templateKey);
|
||||||
|
|
@ -56,18 +56,18 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
HoganJsUtils.prototype._loadTemplate = function(templateKey) {
|
HoganJsUtils.prototype._loadTemplate = function(templateKey) {
|
||||||
var template;
|
let template;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (fs.readFileSync) {
|
if (fs.readFileSync) {
|
||||||
var templatesPath = path.resolve(__dirname, 'templates');
|
const templatesPath = path.resolve(__dirname, "templates");
|
||||||
var templatePath = path.join(templatesPath, templateKey);
|
const templatePath = path.join(templatesPath, templateKey);
|
||||||
var templateContent = fs.readFileSync(templatePath + '.mustache', 'utf8');
|
const templateContent = fs.readFileSync(templatePath + ".mustache", "utf8");
|
||||||
template = hogan.compile(templateContent);
|
template = hogan.compile(templateContent);
|
||||||
hoganTemplates[templateKey] = template;
|
hoganTemplates[templateKey] = template;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Failed to read (template: ' + templateKey + ') from fs: ' + e.message);
|
console.error("Failed to read (template: " + templateKey + ") from fs: " + e.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
return template;
|
return template;
|
||||||
|
|
@ -78,7 +78,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
HoganJsUtils.prototype._templateKey = function(namespace, view) {
|
HoganJsUtils.prototype._templateKey = function(namespace, view) {
|
||||||
return namespace + '-' + view;
|
return namespace + "-" + view;
|
||||||
};
|
};
|
||||||
|
|
||||||
HoganJsUtils.prototype.compile = function(templateStr) {
|
HoganJsUtils.prototype.compile = function(templateStr) {
|
||||||
|
|
|
||||||
|
|
@ -6,25 +6,24 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
var LineByLinePrinter = require('./line-by-line-printer.js').LineByLinePrinter;
|
const LineByLinePrinter = require("./line-by-line-printer.js").LineByLinePrinter;
|
||||||
var SideBySidePrinter = require('./side-by-side-printer.js').SideBySidePrinter;
|
const SideBySidePrinter = require("./side-by-side-printer.js").SideBySidePrinter;
|
||||||
var FileListPrinter = require('./file-list-printer.js').FileListPrinter;
|
const FileListPrinter = require("./file-list-printer.js").FileListPrinter;
|
||||||
|
|
||||||
function HtmlPrinter() {
|
function HtmlPrinter() {}
|
||||||
}
|
|
||||||
|
|
||||||
HtmlPrinter.prototype.generateLineByLineJsonHtml = function(diffFiles, config) {
|
HtmlPrinter.prototype.generateLineByLineJsonHtml = function(diffFiles, config) {
|
||||||
var lineByLinePrinter = new LineByLinePrinter(config);
|
const lineByLinePrinter = new LineByLinePrinter(config);
|
||||||
return lineByLinePrinter.generateLineByLineJsonHtml(diffFiles);
|
return lineByLinePrinter.generateLineByLineJsonHtml(diffFiles);
|
||||||
};
|
};
|
||||||
|
|
||||||
HtmlPrinter.prototype.generateSideBySideJsonHtml = function(diffFiles, config) {
|
HtmlPrinter.prototype.generateSideBySideJsonHtml = function(diffFiles, config) {
|
||||||
var sideBySidePrinter = new SideBySidePrinter(config);
|
const sideBySidePrinter = new SideBySidePrinter(config);
|
||||||
return sideBySidePrinter.generateSideBySideJsonHtml(diffFiles);
|
return sideBySidePrinter.generateSideBySideJsonHtml(diffFiles);
|
||||||
};
|
};
|
||||||
|
|
||||||
HtmlPrinter.prototype.generateFileListSummary = function(diffJson, config) {
|
HtmlPrinter.prototype.generateFileListSummary = function(diffJson, config) {
|
||||||
var fileListPrinter = new FileListPrinter(config);
|
const fileListPrinter = new FileListPrinter(config);
|
||||||
return fileListPrinter.generateFileList(diffJson);
|
return fileListPrinter.generateFileList(diffJson);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,54 +6,57 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
var diffParser = require('./diff-parser.js').DiffParser;
|
const diffParser = require("./diff-parser.js").DiffParser;
|
||||||
var printerUtils = require('./printer-utils.js').PrinterUtils;
|
const printerUtils = require("./printer-utils.js").PrinterUtils;
|
||||||
var utils = require('./utils.js').Utils;
|
const utils = require("./utils.js").Utils;
|
||||||
var Rematch = require('./rematch.js').Rematch;
|
const Rematch = require("./rematch.js").Rematch;
|
||||||
|
|
||||||
var hoganUtils;
|
let hoganUtils;
|
||||||
|
|
||||||
var genericTemplatesPath = 'generic';
|
const genericTemplatesPath = "generic";
|
||||||
var baseTemplatesPath = 'line-by-line';
|
const baseTemplatesPath = "line-by-line";
|
||||||
var iconsBaseTemplatesPath = 'icon';
|
const iconsBaseTemplatesPath = "icon";
|
||||||
var tagsBaseTemplatesPath = 'tag';
|
const tagsBaseTemplatesPath = "tag";
|
||||||
|
|
||||||
function LineByLinePrinter(config) {
|
function LineByLinePrinter(config) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
|
|
||||||
var HoganJsUtils = require('./hoganjs-utils.js').HoganJsUtils;
|
const HoganJsUtils = require("./hoganjs-utils.js").HoganJsUtils;
|
||||||
hoganUtils = new HoganJsUtils(config);
|
hoganUtils = new HoganJsUtils(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
LineByLinePrinter.prototype.makeFileDiffHtml = function(file, diffs) {
|
LineByLinePrinter.prototype.makeFileDiffHtml = function(file, diffs) {
|
||||||
if (this.config.renderNothingWhenEmpty && file.blocks && !file.blocks.length) return '';
|
if (this.config.renderNothingWhenEmpty && file.blocks && !file.blocks.length) return "";
|
||||||
|
|
||||||
var fileDiffTemplate = hoganUtils.template(baseTemplatesPath, 'file-diff');
|
const fileDiffTemplate = hoganUtils.template(baseTemplatesPath, "file-diff");
|
||||||
var filePathTemplate = hoganUtils.template(genericTemplatesPath, 'file-path');
|
const filePathTemplate = hoganUtils.template(genericTemplatesPath, "file-path");
|
||||||
var fileIconTemplate = hoganUtils.template(iconsBaseTemplatesPath, 'file');
|
const fileIconTemplate = hoganUtils.template(iconsBaseTemplatesPath, "file");
|
||||||
var fileTagTemplate = hoganUtils.template(tagsBaseTemplatesPath, printerUtils.getFileTypeIcon(file));
|
const fileTagTemplate = hoganUtils.template(tagsBaseTemplatesPath, printerUtils.getFileTypeIcon(file));
|
||||||
|
|
||||||
return fileDiffTemplate.render({
|
return fileDiffTemplate.render({
|
||||||
file: file,
|
file: file,
|
||||||
fileHtmlId: printerUtils.getHtmlId(file),
|
fileHtmlId: printerUtils.getHtmlId(file),
|
||||||
diffs: diffs,
|
diffs: diffs,
|
||||||
filePath: filePathTemplate.render({
|
filePath: filePathTemplate.render(
|
||||||
|
{
|
||||||
fileDiffName: printerUtils.getDiffName(file)
|
fileDiffName: printerUtils.getDiffName(file)
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
fileIcon: fileIconTemplate,
|
fileIcon: fileIconTemplate,
|
||||||
fileTag: fileTagTemplate
|
fileTag: fileTagTemplate
|
||||||
})
|
}
|
||||||
|
)
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
LineByLinePrinter.prototype.makeLineByLineHtmlWrapper = function(content) {
|
LineByLinePrinter.prototype.makeLineByLineHtmlWrapper = function(content) {
|
||||||
return hoganUtils.render(genericTemplatesPath, 'wrapper', {'content': content});
|
return hoganUtils.render(genericTemplatesPath, "wrapper", { content: content });
|
||||||
};
|
};
|
||||||
|
|
||||||
LineByLinePrinter.prototype.generateLineByLineJsonHtml = function(diffFiles) {
|
LineByLinePrinter.prototype.generateLineByLineJsonHtml = function(diffFiles) {
|
||||||
var that = this;
|
const that = this;
|
||||||
var htmlDiffs = diffFiles.map(function(file) {
|
const htmlDiffs = diffFiles.map(function(file) {
|
||||||
var diffs;
|
let diffs;
|
||||||
if (file.blocks.length) {
|
if (file.blocks.length) {
|
||||||
diffs = that._generateFileHtml(file);
|
diffs = that._generateFileHtml(file);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -62,49 +65,53 @@
|
||||||
return that.makeFileDiffHtml(file, diffs);
|
return that.makeFileDiffHtml(file, diffs);
|
||||||
});
|
});
|
||||||
|
|
||||||
return this.makeLineByLineHtmlWrapper(htmlDiffs.join('\n'));
|
return this.makeLineByLineHtmlWrapper(htmlDiffs.join("\n"));
|
||||||
};
|
};
|
||||||
|
|
||||||
var matcher = Rematch.rematch(function(a, b) {
|
const matcher = Rematch.rematch(function(a, b) {
|
||||||
var amod = a.content.substr(1);
|
const amod = a.content.substr(1);
|
||||||
var bmod = b.content.substr(1);
|
const bmod = b.content.substr(1);
|
||||||
|
|
||||||
return Rematch.distance(amod, bmod);
|
return Rematch.distance(amod, bmod);
|
||||||
});
|
});
|
||||||
|
|
||||||
LineByLinePrinter.prototype.makeColumnLineNumberHtml = function(block) {
|
LineByLinePrinter.prototype.makeColumnLineNumberHtml = function(block) {
|
||||||
return hoganUtils.render(genericTemplatesPath, 'column-line-number', {
|
return hoganUtils.render(genericTemplatesPath, "column-line-number", {
|
||||||
diffParser: diffParser,
|
diffParser: diffParser,
|
||||||
blockHeader: utils.escape(block.header),
|
blockHeader: utils.escape(block.header),
|
||||||
lineClass: 'd2h-code-linenumber',
|
lineClass: "d2h-code-linenumber",
|
||||||
contentClass: 'd2h-code-line'
|
contentClass: "d2h-code-line"
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
LineByLinePrinter.prototype._generateFileHtml = function(file) {
|
LineByLinePrinter.prototype._generateFileHtml = function(file) {
|
||||||
var that = this;
|
const that = this;
|
||||||
return file.blocks.map(function(block) {
|
return file.blocks
|
||||||
var lines = that.makeColumnLineNumberHtml(block);
|
.map(function(block) {
|
||||||
var oldLines = [];
|
let lines = that.makeColumnLineNumberHtml(block);
|
||||||
var newLines = [];
|
let oldLines = [];
|
||||||
|
let newLines = [];
|
||||||
|
|
||||||
function processChangeBlock() {
|
function processChangeBlock() {
|
||||||
var matches;
|
let matches;
|
||||||
var insertType;
|
let insertType;
|
||||||
var deleteType;
|
let deleteType;
|
||||||
|
|
||||||
var comparisons = oldLines.length * newLines.length;
|
const comparisons = oldLines.length * newLines.length;
|
||||||
|
|
||||||
var maxLineSizeInBlock = Math.max.apply(null,
|
const maxLineSizeInBlock = Math.max.apply(
|
||||||
[0].concat((oldLines.concat(newLines)).map(
|
null,
|
||||||
function(elem) {
|
[0].concat(
|
||||||
|
oldLines.concat(newLines).map(function(elem) {
|
||||||
return elem.content.length;
|
return elem.content.length;
|
||||||
}
|
})
|
||||||
)));
|
)
|
||||||
|
);
|
||||||
|
|
||||||
var doMatching = comparisons < that.config.matchingMaxComparisons &&
|
const doMatching =
|
||||||
|
comparisons < that.config.matchingMaxComparisons &&
|
||||||
maxLineSizeInBlock < that.config.maxLineSizeInBlockForComparison &&
|
maxLineSizeInBlock < that.config.maxLineSizeInBlockForComparison &&
|
||||||
(that.config.matching === 'lines' || that.config.matching === 'words');
|
(that.config.matching === "lines" || that.config.matching === "words");
|
||||||
|
|
||||||
if (doMatching) {
|
if (doMatching) {
|
||||||
matches = matcher(oldLines, newLines);
|
matches = matcher(oldLines, newLines);
|
||||||
|
|
@ -120,25 +127,35 @@
|
||||||
oldLines = match[0];
|
oldLines = match[0];
|
||||||
newLines = match[1];
|
newLines = match[1];
|
||||||
|
|
||||||
var processedOldLines = [];
|
let processedOldLines = [];
|
||||||
var processedNewLines = [];
|
let processedNewLines = [];
|
||||||
|
|
||||||
var common = Math.min(oldLines.length, newLines.length);
|
const common = Math.min(oldLines.length, newLines.length);
|
||||||
|
|
||||||
var oldLine, newLine;
|
let oldLine, newLine;
|
||||||
for (var j = 0; j < common; j++) {
|
for (let j = 0; j < common; j++) {
|
||||||
oldLine = oldLines[j];
|
oldLine = oldLines[j];
|
||||||
newLine = newLines[j];
|
newLine = newLines[j];
|
||||||
|
|
||||||
that.config.isCombined = file.isCombined;
|
that.config.isCombined = file.isCombined;
|
||||||
var diff = printerUtils.diffHighlight(oldLine.content, newLine.content, that.config);
|
const diff = printerUtils.diffHighlight(oldLine.content, newLine.content, that.config);
|
||||||
|
|
||||||
processedOldLines +=
|
processedOldLines += that.makeLineHtml(
|
||||||
that.makeLineHtml(file.isCombined, deleteType, oldLine.oldNumber, oldLine.newNumber,
|
file.isCombined,
|
||||||
diff.first.line, diff.first.prefix);
|
deleteType,
|
||||||
processedNewLines +=
|
oldLine.oldNumber,
|
||||||
that.makeLineHtml(file.isCombined, insertType, newLine.oldNumber, newLine.newNumber,
|
oldLine.newNumber,
|
||||||
diff.second.line, diff.second.prefix);
|
diff.first.line,
|
||||||
|
diff.first.prefix
|
||||||
|
);
|
||||||
|
processedNewLines += that.makeLineHtml(
|
||||||
|
file.isCombined,
|
||||||
|
insertType,
|
||||||
|
newLine.oldNumber,
|
||||||
|
newLine.newNumber,
|
||||||
|
diff.second.line,
|
||||||
|
diff.second.prefix
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
lines += processedOldLines + processedNewLines;
|
lines += processedOldLines + processedNewLines;
|
||||||
|
|
@ -149,12 +166,14 @@
|
||||||
newLines = [];
|
newLines = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = 0; i < block.lines.length; i++) {
|
for (let i = 0; i < block.lines.length; i++) {
|
||||||
var line = block.lines[i];
|
const line = block.lines[i];
|
||||||
var escapedLine = utils.escape(line.content);
|
const escapedLine = utils.escape(line.content);
|
||||||
|
|
||||||
if (line.type !== diffParser.LINE_TYPE.INSERTS &&
|
if (
|
||||||
(newLines.length > 0 || (line.type !== diffParser.LINE_TYPE.DELETES && oldLines.length > 0))) {
|
line.type !== diffParser.LINE_TYPE.INSERTS &&
|
||||||
|
(newLines.length > 0 || (line.type !== diffParser.LINE_TYPE.DELETES && oldLines.length > 0))
|
||||||
|
) {
|
||||||
processChangeBlock();
|
processChangeBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -167,7 +186,7 @@
|
||||||
} else if (line.type === diffParser.LINE_TYPE.INSERTS && Boolean(oldLines.length)) {
|
} else if (line.type === diffParser.LINE_TYPE.INSERTS && Boolean(oldLines.length)) {
|
||||||
newLines.push(line);
|
newLines.push(line);
|
||||||
} else {
|
} else {
|
||||||
console.error('Unknown state in html line-by-line generator');
|
console.error("Unknown state in html line-by-line generator");
|
||||||
processChangeBlock();
|
processChangeBlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -175,21 +194,22 @@
|
||||||
processChangeBlock();
|
processChangeBlock();
|
||||||
|
|
||||||
return lines;
|
return lines;
|
||||||
}).join('\n');
|
})
|
||||||
|
.join("\n");
|
||||||
};
|
};
|
||||||
|
|
||||||
LineByLinePrinter.prototype._processLines = function(isCombined, oldLines, newLines) {
|
LineByLinePrinter.prototype._processLines = function(isCombined, oldLines, newLines) {
|
||||||
var lines = '';
|
let lines = "";
|
||||||
|
|
||||||
for (var i = 0; i < oldLines.length; i++) {
|
for (let i = 0; i < oldLines.length; i++) {
|
||||||
var oldLine = oldLines[i];
|
const oldLine = oldLines[i];
|
||||||
var oldEscapedLine = utils.escape(oldLine.content);
|
const oldEscapedLine = utils.escape(oldLine.content);
|
||||||
lines += this.makeLineHtml(isCombined, oldLine.type, oldLine.oldNumber, oldLine.newNumber, oldEscapedLine);
|
lines += this.makeLineHtml(isCombined, oldLine.type, oldLine.oldNumber, oldLine.newNumber, oldEscapedLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var j = 0; j < newLines.length; j++) {
|
for (let j = 0; j < newLines.length; j++) {
|
||||||
var newLine = newLines[j];
|
const newLine = newLines[j];
|
||||||
var newEscapedLine = utils.escape(newLine.content);
|
const newEscapedLine = utils.escape(newLine.content);
|
||||||
lines += this.makeLineHtml(isCombined, newLine.type, newLine.oldNumber, newLine.newNumber, newEscapedLine);
|
lines += this.makeLineHtml(isCombined, newLine.type, newLine.oldNumber, newLine.newNumber, newEscapedLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -197,29 +217,28 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
LineByLinePrinter.prototype.makeLineHtml = function(isCombined, type, oldNumber, newNumber, content, possiblePrefix) {
|
LineByLinePrinter.prototype.makeLineHtml = function(isCombined, type, oldNumber, newNumber, content, possiblePrefix) {
|
||||||
var lineNumberTemplate = hoganUtils.render(baseTemplatesPath, 'numbers', {
|
const lineNumberTemplate = hoganUtils.render(baseTemplatesPath, "numbers", {
|
||||||
oldNumber: utils.valueOrEmpty(oldNumber),
|
oldNumber: utils.valueOrEmpty(oldNumber),
|
||||||
newNumber: utils.valueOrEmpty(newNumber)
|
newNumber: utils.valueOrEmpty(newNumber)
|
||||||
});
|
});
|
||||||
|
|
||||||
var lineWithoutPrefix = content;
|
let lineWithoutPrefix = content;
|
||||||
var prefix = possiblePrefix;
|
let prefix = possiblePrefix;
|
||||||
|
|
||||||
if (!prefix) {
|
if (!prefix) {
|
||||||
var lineWithPrefix = printerUtils.separatePrefix(isCombined, content);
|
const lineWithPrefix = printerUtils.separatePrefix(isCombined, content);
|
||||||
prefix = lineWithPrefix.prefix;
|
prefix = lineWithPrefix.prefix;
|
||||||
lineWithoutPrefix = lineWithPrefix.line;
|
lineWithoutPrefix = lineWithPrefix.line;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prefix === ' ') {
|
if (prefix === " ") {
|
||||||
prefix = ' ';
|
prefix = " ";
|
||||||
}
|
}
|
||||||
|
|
||||||
return hoganUtils.render(genericTemplatesPath, 'line',
|
return hoganUtils.render(genericTemplatesPath, "line", {
|
||||||
{
|
|
||||||
type: type,
|
type: type,
|
||||||
lineClass: 'd2h-code-linenumber',
|
lineClass: "d2h-code-linenumber",
|
||||||
contentClass: 'd2h-code-line',
|
contentClass: "d2h-code-line",
|
||||||
prefix: prefix,
|
prefix: prefix,
|
||||||
content: lineWithoutPrefix,
|
content: lineWithoutPrefix,
|
||||||
lineNumber: lineNumberTemplate
|
lineNumber: lineNumberTemplate
|
||||||
|
|
@ -227,8 +246,8 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
LineByLinePrinter.prototype._generateEmptyDiff = function() {
|
LineByLinePrinter.prototype._generateEmptyDiff = function() {
|
||||||
return hoganUtils.render(genericTemplatesPath, 'empty-diff', {
|
return hoganUtils.render(genericTemplatesPath, "empty-diff", {
|
||||||
contentClass: 'd2h-code-line',
|
contentClass: "d2h-code-line",
|
||||||
diffParser: diffParser
|
diffParser: diffParser
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -6,18 +6,17 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
var jsDiff = require('diff');
|
const jsDiff = require("diff");
|
||||||
var utils = require('./utils.js').Utils;
|
const utils = require("./utils.js").Utils;
|
||||||
var Rematch = require('./rematch.js').Rematch;
|
const Rematch = require("./rematch.js").Rematch;
|
||||||
|
|
||||||
var separator = '/';
|
const separator = "/";
|
||||||
|
|
||||||
function PrinterUtils() {
|
function PrinterUtils() {}
|
||||||
}
|
|
||||||
|
|
||||||
PrinterUtils.prototype.separatePrefix = function(isCombined, line) {
|
PrinterUtils.prototype.separatePrefix = function(isCombined, line) {
|
||||||
var prefix;
|
let prefix;
|
||||||
var lineWithoutPrefix;
|
let lineWithoutPrefix;
|
||||||
|
|
||||||
if (isCombined) {
|
if (isCombined) {
|
||||||
prefix = line.substring(0, 2);
|
prefix = line.substring(0, 2);
|
||||||
|
|
@ -28,45 +27,56 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'prefix': prefix,
|
prefix: prefix,
|
||||||
'line': lineWithoutPrefix
|
line: lineWithoutPrefix
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
PrinterUtils.prototype.getHtmlId = function(file) {
|
PrinterUtils.prototype.getHtmlId = function(file) {
|
||||||
var hashCode = function(text) {
|
const hashCode = function(text) {
|
||||||
var i, chr, len;
|
let i, chr, len;
|
||||||
var hash = 0;
|
let hash = 0;
|
||||||
|
|
||||||
for (i = 0, len = text.length; i < len; i++) {
|
for (i = 0, len = text.length; i < len; i++) {
|
||||||
chr = text.charCodeAt(i);
|
chr = text.charCodeAt(i);
|
||||||
hash = ((hash << 5) - hash) + chr;
|
hash = (hash << 5) - hash + chr;
|
||||||
hash |= 0; // Convert to 32bit integer
|
hash |= 0; // Convert to 32bit integer
|
||||||
}
|
}
|
||||||
|
|
||||||
return hash;
|
return hash;
|
||||||
};
|
};
|
||||||
|
|
||||||
return 'd2h-' + hashCode(this.getDiffName(file)).toString().slice(-6);
|
return (
|
||||||
|
"d2h-" +
|
||||||
|
hashCode(this.getDiffName(file))
|
||||||
|
.toString()
|
||||||
|
.slice(-6)
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
PrinterUtils.prototype.getDiffName = function(file) {
|
PrinterUtils.prototype.getDiffName = function(file) {
|
||||||
var oldFilename = unifyPath(file.oldName);
|
const oldFilename = unifyPath(file.oldName);
|
||||||
var newFilename = unifyPath(file.newName);
|
const newFilename = unifyPath(file.newName);
|
||||||
|
|
||||||
if (oldFilename && newFilename && oldFilename !== newFilename && !isDevNullName(oldFilename) && !isDevNullName(newFilename)) {
|
if (
|
||||||
var prefixPaths = [];
|
oldFilename &&
|
||||||
var suffixPaths = [];
|
newFilename &&
|
||||||
|
oldFilename !== newFilename &&
|
||||||
|
!isDevNullName(oldFilename) &&
|
||||||
|
!isDevNullName(newFilename)
|
||||||
|
) {
|
||||||
|
const prefixPaths = [];
|
||||||
|
const suffixPaths = [];
|
||||||
|
|
||||||
var oldFilenameParts = oldFilename.split(separator);
|
const oldFilenameParts = oldFilename.split(separator);
|
||||||
var newFilenameParts = newFilename.split(separator);
|
const newFilenameParts = newFilename.split(separator);
|
||||||
|
|
||||||
var oldFilenamePartsSize = oldFilenameParts.length;
|
const oldFilenamePartsSize = oldFilenameParts.length;
|
||||||
var newFilenamePartsSize = newFilenameParts.length;
|
const newFilenamePartsSize = newFilenameParts.length;
|
||||||
|
|
||||||
var i = 0;
|
let i = 0;
|
||||||
var j = oldFilenamePartsSize - 1;
|
let j = oldFilenamePartsSize - 1;
|
||||||
var k = newFilenamePartsSize - 1;
|
let k = newFilenamePartsSize - 1;
|
||||||
|
|
||||||
while (i < j && i < k) {
|
while (i < j && i < k) {
|
||||||
if (oldFilenameParts[i] === newFilenameParts[i]) {
|
if (oldFilenameParts[i] === newFilenameParts[i]) {
|
||||||
|
|
@ -87,53 +97,55 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var finalPrefix = prefixPaths.join(separator);
|
const finalPrefix = prefixPaths.join(separator);
|
||||||
var finalSuffix = suffixPaths.join(separator);
|
const finalSuffix = suffixPaths.join(separator);
|
||||||
|
|
||||||
var oldRemainingPath = oldFilenameParts.slice(i, j + 1).join(separator);
|
const oldRemainingPath = oldFilenameParts.slice(i, j + 1).join(separator);
|
||||||
var newRemainingPath = newFilenameParts.slice(i, k + 1).join(separator);
|
const newRemainingPath = newFilenameParts.slice(i, k + 1).join(separator);
|
||||||
|
|
||||||
if (finalPrefix.length && finalSuffix.length) {
|
if (finalPrefix.length && finalSuffix.length) {
|
||||||
return finalPrefix + separator + '{' + oldRemainingPath + ' → ' + newRemainingPath + '}' + separator + finalSuffix;
|
return (
|
||||||
|
finalPrefix + separator + "{" + oldRemainingPath + " → " + newRemainingPath + "}" + separator + finalSuffix
|
||||||
|
);
|
||||||
} else if (finalPrefix.length) {
|
} else if (finalPrefix.length) {
|
||||||
return finalPrefix + separator + '{' + oldRemainingPath + ' → ' + newRemainingPath + '}';
|
return finalPrefix + separator + "{" + oldRemainingPath + " → " + newRemainingPath + "}";
|
||||||
} else if (finalSuffix.length) {
|
} else if (finalSuffix.length) {
|
||||||
return '{' + oldRemainingPath + ' → ' + newRemainingPath + '}' + separator + finalSuffix;
|
return "{" + oldRemainingPath + " → " + newRemainingPath + "}" + separator + finalSuffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
return oldFilename + ' → ' + newFilename;
|
return oldFilename + " → " + newFilename;
|
||||||
} else if (newFilename && !isDevNullName(newFilename)) {
|
} else if (newFilename && !isDevNullName(newFilename)) {
|
||||||
return newFilename;
|
return newFilename;
|
||||||
} else if (oldFilename) {
|
} else if (oldFilename) {
|
||||||
return oldFilename;
|
return oldFilename;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 'unknown/file/path';
|
return "unknown/file/path";
|
||||||
};
|
};
|
||||||
|
|
||||||
PrinterUtils.prototype.getFileTypeIcon = function(file) {
|
PrinterUtils.prototype.getFileTypeIcon = function(file) {
|
||||||
var templateName = 'file-changed';
|
let templateName = "file-changed";
|
||||||
|
|
||||||
if (file.isRename) {
|
if (file.isRename) {
|
||||||
templateName = 'file-renamed';
|
templateName = "file-renamed";
|
||||||
} else if (file.isCopy) {
|
} else if (file.isCopy) {
|
||||||
templateName = 'file-renamed';
|
templateName = "file-renamed";
|
||||||
} else if (file.isNew) {
|
} else if (file.isNew) {
|
||||||
templateName = 'file-added';
|
templateName = "file-added";
|
||||||
} else if (file.isDeleted) {
|
} else if (file.isDeleted) {
|
||||||
templateName = 'file-deleted';
|
templateName = "file-deleted";
|
||||||
} else if (file.newName !== file.oldName) {
|
} else if (file.newName !== file.oldName) {
|
||||||
// If file is not Added, not Deleted and the names changed it must be a rename :)
|
// If file is not Added, not Deleted and the names changed it must be a rename :)
|
||||||
templateName = 'file-renamed';
|
templateName = "file-renamed";
|
||||||
}
|
}
|
||||||
|
|
||||||
return templateName;
|
return templateName;
|
||||||
};
|
};
|
||||||
|
|
||||||
PrinterUtils.prototype.diffHighlight = function(diffLine1, diffLine2, config) {
|
PrinterUtils.prototype.diffHighlight = function(diffLine1, diffLine2, config) {
|
||||||
var linePrefix1, linePrefix2, unprefixedLine1, unprefixedLine2;
|
let linePrefix1, linePrefix2, unprefixedLine1, unprefixedLine2;
|
||||||
|
|
||||||
var prefixSize = 1;
|
let prefixSize = 1;
|
||||||
|
|
||||||
if (config.isCombined) {
|
if (config.isCombined) {
|
||||||
prefixSize = 2;
|
prefixSize = 2;
|
||||||
|
|
@ -144,8 +156,10 @@
|
||||||
unprefixedLine1 = diffLine1.substr(prefixSize);
|
unprefixedLine1 = diffLine1.substr(prefixSize);
|
||||||
unprefixedLine2 = diffLine2.substr(prefixSize);
|
unprefixedLine2 = diffLine2.substr(prefixSize);
|
||||||
|
|
||||||
if (unprefixedLine1.length > config.maxLineLengthHighlight ||
|
if (
|
||||||
unprefixedLine2.length > config.maxLineLengthHighlight) {
|
unprefixedLine1.length > config.maxLineLengthHighlight ||
|
||||||
|
unprefixedLine2.length > config.maxLineLengthHighlight
|
||||||
|
) {
|
||||||
return {
|
return {
|
||||||
first: {
|
first: {
|
||||||
prefix: linePrefix1,
|
prefix: linePrefix1,
|
||||||
|
|
@ -158,42 +172,42 @@
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
var diff;
|
let diff;
|
||||||
if (config.diffStyle === 'char') {
|
if (config.diffStyle === "char") {
|
||||||
diff = jsDiff.diffChars(unprefixedLine1, unprefixedLine2);
|
diff = jsDiff.diffChars(unprefixedLine1, unprefixedLine2);
|
||||||
} else {
|
} else {
|
||||||
diff = jsDiff.diffWordsWithSpace(unprefixedLine1, unprefixedLine2);
|
diff = jsDiff.diffWordsWithSpace(unprefixedLine1, unprefixedLine2);
|
||||||
}
|
}
|
||||||
|
|
||||||
var highlightedLine = '';
|
let highlightedLine = "";
|
||||||
|
|
||||||
var changedWords = [];
|
const changedWords = [];
|
||||||
if (config.diffStyle === 'word' && config.matching === 'words') {
|
if (config.diffStyle === "word" && config.matching === "words") {
|
||||||
var treshold = 0.25;
|
let treshold = 0.25;
|
||||||
|
|
||||||
if (typeof (config.matchWordsThreshold) !== 'undefined') {
|
if (typeof config.matchWordsThreshold !== "undefined") {
|
||||||
treshold = config.matchWordsThreshold;
|
treshold = config.matchWordsThreshold;
|
||||||
}
|
}
|
||||||
|
|
||||||
var matcher = Rematch.rematch(function(a, b) {
|
const matcher = Rematch.rematch(function(a, b) {
|
||||||
var amod = a.value;
|
const amod = a.value;
|
||||||
var bmod = b.value;
|
const bmod = b.value;
|
||||||
|
|
||||||
return Rematch.distance(amod, bmod);
|
return Rematch.distance(amod, bmod);
|
||||||
});
|
});
|
||||||
|
|
||||||
var removed = diff.filter(function isRemoved(element) {
|
const removed = diff.filter(function isRemoved(element) {
|
||||||
return element.removed;
|
return element.removed;
|
||||||
});
|
});
|
||||||
|
|
||||||
var added = diff.filter(function isAdded(element) {
|
const added = diff.filter(function isAdded(element) {
|
||||||
return element.added;
|
return element.added;
|
||||||
});
|
});
|
||||||
|
|
||||||
var chunks = matcher(added, removed);
|
const chunks = matcher(added, removed);
|
||||||
chunks.forEach(function(chunk) {
|
chunks.forEach(function(chunk) {
|
||||||
if (chunk[0].length === 1 && chunk[1].length === 1) {
|
if (chunk[0].length === 1 && chunk[1].length === 1) {
|
||||||
var dist = Rematch.distance(chunk[0][0].value, chunk[1][0].value);
|
const dist = Rematch.distance(chunk[0][0].value, chunk[1][0].value);
|
||||||
if (dist < treshold) {
|
if (dist < treshold) {
|
||||||
changedWords.push(chunk[0][0]);
|
changedWords.push(chunk[0][0]);
|
||||||
changedWords.push(chunk[1][0]);
|
changedWords.push(chunk[1][0]);
|
||||||
|
|
@ -203,12 +217,12 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
diff.forEach(function(part) {
|
diff.forEach(function(part) {
|
||||||
var addClass = changedWords.indexOf(part) > -1 ? ' class="d2h-change"' : '';
|
const addClass = changedWords.indexOf(part) > -1 ? ' class="d2h-change"' : "";
|
||||||
var elemType = part.added ? 'ins' : part.removed ? 'del' : null;
|
const elemType = part.added ? "ins" : part.removed ? "del" : null;
|
||||||
var escapedValue = utils.escape(part.value);
|
const escapedValue = utils.escape(part.value);
|
||||||
|
|
||||||
if (elemType !== null) {
|
if (elemType !== null) {
|
||||||
highlightedLine += '<' + elemType + addClass + '>' + escapedValue + '</' + elemType + '>';
|
highlightedLine += "<" + elemType + addClass + ">" + escapedValue + "</" + elemType + ">";
|
||||||
} else {
|
} else {
|
||||||
highlightedLine += escapedValue;
|
highlightedLine += escapedValue;
|
||||||
}
|
}
|
||||||
|
|
@ -228,22 +242,22 @@
|
||||||
|
|
||||||
function unifyPath(path) {
|
function unifyPath(path) {
|
||||||
if (path) {
|
if (path) {
|
||||||
return path.replace('\\', '/');
|
return path.replace("\\", "/");
|
||||||
}
|
}
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isDevNullName(name) {
|
function isDevNullName(name) {
|
||||||
return name.indexOf('dev/null') !== -1;
|
return name.indexOf("dev/null") !== -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeIns(line) {
|
function removeIns(line) {
|
||||||
return line.replace(/(<ins[^>]*>((.|\n)*?)<\/ins>)/g, '');
|
return line.replace(/(<ins[^>]*>((.|\n)*?)<\/ins>)/g, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeDel(line) {
|
function removeDel(line) {
|
||||||
return line.replace(/(<del[^>]*>((.|\n)*?)<\/del>)/g, '');
|
return line.replace(/(<del[^>]*>((.|\n)*?)<\/del>)/g, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.PrinterUtils = new PrinterUtils();
|
module.exports.PrinterUtils = new PrinterUtils();
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
var Rematch = {};
|
const Rematch = {};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Copyright (c) 2011 Andrei Mackenzie
|
Copyright (c) 2011 Andrei Mackenzie
|
||||||
|
|
@ -29,16 +29,16 @@
|
||||||
return a.length;
|
return a.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
var matrix = [];
|
const matrix = [];
|
||||||
|
|
||||||
// Increment along the first column of each row
|
// Increment along the first column of each row
|
||||||
var i;
|
let i;
|
||||||
for (i = 0; i <= b.length; i++) {
|
for (i = 0; i <= b.length; i++) {
|
||||||
matrix[i] = [i];
|
matrix[i] = [i];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Increment each column in the first row
|
// Increment each column in the first row
|
||||||
var j;
|
let j;
|
||||||
for (j = 0; j <= a.length; j++) {
|
for (j = 0; j <= a.length; j++) {
|
||||||
matrix[0][j] = j;
|
matrix[0][j] = j;
|
||||||
}
|
}
|
||||||
|
|
@ -49,9 +49,13 @@
|
||||||
if (b.charAt(i - 1) === a.charAt(j - 1)) {
|
if (b.charAt(i - 1) === a.charAt(j - 1)) {
|
||||||
matrix[i][j] = matrix[i - 1][j - 1];
|
matrix[i][j] = matrix[i - 1][j - 1];
|
||||||
} else {
|
} else {
|
||||||
matrix[i][j] = Math.min(matrix[i - 1][j - 1] + 1, // Substitution
|
matrix[i][j] = Math.min(
|
||||||
Math.min(matrix[i][j - 1] + 1, // Insertion
|
matrix[i - 1][j - 1] + 1, // Substitution
|
||||||
matrix[i - 1][j] + 1)); // Deletion
|
Math.min(
|
||||||
|
matrix[i][j - 1] + 1, // Insertion
|
||||||
|
matrix[i - 1][j] + 1
|
||||||
|
)
|
||||||
|
); // Deletion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -64,19 +68,19 @@
|
||||||
Rematch.distance = function distance(x, y) {
|
Rematch.distance = function distance(x, y) {
|
||||||
x = x.trim();
|
x = x.trim();
|
||||||
y = y.trim();
|
y = y.trim();
|
||||||
var lev = levenshtein(x, y);
|
const lev = levenshtein(x, y);
|
||||||
var score = lev / (x.length + y.length);
|
const score = lev / (x.length + y.length);
|
||||||
|
|
||||||
return score;
|
return score;
|
||||||
};
|
};
|
||||||
|
|
||||||
Rematch.rematch = function rematch(distanceFunction) {
|
Rematch.rematch = function rematch(distanceFunction) {
|
||||||
function findBestMatch(a, b, cache) {
|
function findBestMatch(a, b, cache) {
|
||||||
var bestMatchDist = Infinity;
|
let bestMatchDist = Infinity;
|
||||||
var bestMatch;
|
let bestMatch;
|
||||||
for (var i = 0; i < a.length; ++i) {
|
for (let i = 0; i < a.length; ++i) {
|
||||||
for (var j = 0; j < b.length; ++j) {
|
for (let j = 0; j < b.length; ++j) {
|
||||||
var cacheKey = JSON.stringify([a[i], b[j]]);
|
const cacheKey = JSON.stringify([a[i], b[j]]);
|
||||||
var md;
|
var md;
|
||||||
if (cache.hasOwnProperty(cacheKey)) {
|
if (cache.hasOwnProperty(cacheKey)) {
|
||||||
md = cache[cacheKey];
|
md = cache[cacheKey];
|
||||||
|
|
@ -95,33 +99,33 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function group(a, b, level, cache) {
|
function group(a, b, level, cache) {
|
||||||
if (typeof (cache) === 'undefined') {
|
if (typeof cache === "undefined") {
|
||||||
cache = {};
|
cache = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
var bm = findBestMatch(a, b, cache);
|
const bm = findBestMatch(a, b, cache);
|
||||||
|
|
||||||
if (!level) {
|
if (!level) {
|
||||||
level = 0;
|
level = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bm || (a.length + b.length < 3)) {
|
if (!bm || a.length + b.length < 3) {
|
||||||
return [[a, b]];
|
return [[a, b]];
|
||||||
}
|
}
|
||||||
|
|
||||||
var a1 = a.slice(0, bm.indexA);
|
const a1 = a.slice(0, bm.indexA);
|
||||||
var b1 = b.slice(0, bm.indexB);
|
const b1 = b.slice(0, bm.indexB);
|
||||||
var aMatch = [a[bm.indexA]];
|
const aMatch = [a[bm.indexA]];
|
||||||
var bMatch = [b[bm.indexB]];
|
const bMatch = [b[bm.indexB]];
|
||||||
var tailA = bm.indexA + 1;
|
const tailA = bm.indexA + 1;
|
||||||
var tailB = bm.indexB + 1;
|
const tailB = bm.indexB + 1;
|
||||||
var a2 = a.slice(tailA);
|
const a2 = a.slice(tailA);
|
||||||
var b2 = b.slice(tailB);
|
const b2 = b.slice(tailB);
|
||||||
|
|
||||||
var group1 = group(a1, b1, level + 1, cache);
|
const group1 = group(a1, b1, level + 1, cache);
|
||||||
var groupMatch = group(aMatch, bMatch, level + 1, cache);
|
const groupMatch = group(aMatch, bMatch, level + 1, cache);
|
||||||
var group2 = group(a2, b2, level + 1, cache);
|
const group2 = group(a2, b2, level + 1, cache);
|
||||||
var result = groupMatch;
|
let result = groupMatch;
|
||||||
|
|
||||||
if (bm.indexA > 0 || bm.indexB > 0) {
|
if (bm.indexA > 0 || bm.indexB > 0) {
|
||||||
result = group1.concat(result);
|
result = group1.concat(result);
|
||||||
|
|
|
||||||
|
|
@ -6,21 +6,21 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
var diffParser = require('./diff-parser.js').DiffParser;
|
const diffParser = require("./diff-parser.js").DiffParser;
|
||||||
var printerUtils = require('./printer-utils.js').PrinterUtils;
|
const printerUtils = require("./printer-utils.js").PrinterUtils;
|
||||||
var utils = require('./utils.js').Utils;
|
const utils = require("./utils.js").Utils;
|
||||||
var Rematch = require('./rematch.js').Rematch;
|
const Rematch = require("./rematch.js").Rematch;
|
||||||
|
|
||||||
var hoganUtils;
|
let hoganUtils;
|
||||||
|
|
||||||
var genericTemplatesPath = 'generic';
|
const genericTemplatesPath = "generic";
|
||||||
var baseTemplatesPath = 'side-by-side';
|
const baseTemplatesPath = "side-by-side";
|
||||||
var iconsBaseTemplatesPath = 'icon';
|
const iconsBaseTemplatesPath = "icon";
|
||||||
var tagsBaseTemplatesPath = 'tag';
|
const tagsBaseTemplatesPath = "tag";
|
||||||
|
|
||||||
var matcher = Rematch.rematch(function(a, b) {
|
const matcher = Rematch.rematch(function(a, b) {
|
||||||
var amod = a.content.substr(1);
|
const amod = a.content.substr(1);
|
||||||
var bmod = b.content.substr(1);
|
const bmod = b.content.substr(1);
|
||||||
|
|
||||||
return Rematch.distance(amod, bmod);
|
return Rematch.distance(amod, bmod);
|
||||||
});
|
});
|
||||||
|
|
@ -28,34 +28,38 @@
|
||||||
function SideBySidePrinter(config) {
|
function SideBySidePrinter(config) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
|
|
||||||
var HoganJsUtils = require('./hoganjs-utils.js').HoganJsUtils;
|
const HoganJsUtils = require("./hoganjs-utils.js").HoganJsUtils;
|
||||||
hoganUtils = new HoganJsUtils(config);
|
hoganUtils = new HoganJsUtils(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
SideBySidePrinter.prototype.makeDiffHtml = function(file, diffs) {
|
SideBySidePrinter.prototype.makeDiffHtml = function(file, diffs) {
|
||||||
var fileDiffTemplate = hoganUtils.template(baseTemplatesPath, 'file-diff');
|
const fileDiffTemplate = hoganUtils.template(baseTemplatesPath, "file-diff");
|
||||||
var filePathTemplate = hoganUtils.template(genericTemplatesPath, 'file-path');
|
const filePathTemplate = hoganUtils.template(genericTemplatesPath, "file-path");
|
||||||
var fileIconTemplate = hoganUtils.template(iconsBaseTemplatesPath, 'file');
|
const fileIconTemplate = hoganUtils.template(iconsBaseTemplatesPath, "file");
|
||||||
var fileTagTemplate = hoganUtils.template(tagsBaseTemplatesPath, printerUtils.getFileTypeIcon(file));
|
const fileTagTemplate = hoganUtils.template(tagsBaseTemplatesPath, printerUtils.getFileTypeIcon(file));
|
||||||
|
|
||||||
return fileDiffTemplate.render({
|
return fileDiffTemplate.render({
|
||||||
file: file,
|
file: file,
|
||||||
fileHtmlId: printerUtils.getHtmlId(file),
|
fileHtmlId: printerUtils.getHtmlId(file),
|
||||||
diffs: diffs,
|
diffs: diffs,
|
||||||
filePath: filePathTemplate.render({
|
filePath: filePathTemplate.render(
|
||||||
|
{
|
||||||
fileDiffName: printerUtils.getDiffName(file)
|
fileDiffName: printerUtils.getDiffName(file)
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
fileIcon: fileIconTemplate,
|
fileIcon: fileIconTemplate,
|
||||||
fileTag: fileTagTemplate
|
fileTag: fileTagTemplate
|
||||||
})
|
}
|
||||||
|
)
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
SideBySidePrinter.prototype.generateSideBySideJsonHtml = function(diffFiles) {
|
SideBySidePrinter.prototype.generateSideBySideJsonHtml = function(diffFiles) {
|
||||||
var that = this;
|
const that = this;
|
||||||
|
|
||||||
var content = diffFiles.map(function(file) {
|
const content = diffFiles
|
||||||
var diffs;
|
.map(function(file) {
|
||||||
|
let diffs;
|
||||||
if (file.blocks.length) {
|
if (file.blocks.length) {
|
||||||
diffs = that.generateSideBySideFileHtml(file);
|
diffs = that.generateSideBySideFileHtml(file);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -63,47 +67,52 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
return that.makeDiffHtml(file, diffs);
|
return that.makeDiffHtml(file, diffs);
|
||||||
}).join('\n');
|
})
|
||||||
|
.join("\n");
|
||||||
|
|
||||||
return hoganUtils.render(genericTemplatesPath, 'wrapper', {'content': content});
|
return hoganUtils.render(genericTemplatesPath, "wrapper", { content: content });
|
||||||
};
|
};
|
||||||
|
|
||||||
SideBySidePrinter.prototype.makeSideHtml = function(blockHeader) {
|
SideBySidePrinter.prototype.makeSideHtml = function(blockHeader) {
|
||||||
return hoganUtils.render(genericTemplatesPath, 'column-line-number', {
|
return hoganUtils.render(genericTemplatesPath, "column-line-number", {
|
||||||
diffParser: diffParser,
|
diffParser: diffParser,
|
||||||
blockHeader: utils.escape(blockHeader),
|
blockHeader: utils.escape(blockHeader),
|
||||||
lineClass: 'd2h-code-side-linenumber',
|
lineClass: "d2h-code-side-linenumber",
|
||||||
contentClass: 'd2h-code-side-line'
|
contentClass: "d2h-code-side-line"
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
SideBySidePrinter.prototype.generateSideBySideFileHtml = function(file) {
|
SideBySidePrinter.prototype.generateSideBySideFileHtml = function(file) {
|
||||||
var that = this;
|
const that = this;
|
||||||
var fileHtml = {};
|
const fileHtml = {};
|
||||||
fileHtml.left = '';
|
fileHtml.left = "";
|
||||||
fileHtml.right = '';
|
fileHtml.right = "";
|
||||||
|
|
||||||
file.blocks.forEach(function(block) {
|
file.blocks.forEach(function(block) {
|
||||||
fileHtml.left += that.makeSideHtml(block.header);
|
fileHtml.left += that.makeSideHtml(block.header);
|
||||||
fileHtml.right += that.makeSideHtml('');
|
fileHtml.right += that.makeSideHtml("");
|
||||||
|
|
||||||
var oldLines = [];
|
let oldLines = [];
|
||||||
var newLines = [];
|
let newLines = [];
|
||||||
|
|
||||||
function processChangeBlock() {
|
function processChangeBlock() {
|
||||||
var matches;
|
let matches;
|
||||||
var insertType;
|
let insertType;
|
||||||
var deleteType;
|
let deleteType;
|
||||||
|
|
||||||
var comparisons = oldLines.length * newLines.length;
|
const comparisons = oldLines.length * newLines.length;
|
||||||
|
|
||||||
var maxLineSizeInBlock = Math.max.apply(null, (oldLines.concat(newLines)).map(function(elem) {
|
const maxLineSizeInBlock = Math.max.apply(
|
||||||
|
null,
|
||||||
|
oldLines.concat(newLines).map(function(elem) {
|
||||||
return elem.length;
|
return elem.length;
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
|
|
||||||
var doMatching = comparisons < that.config.matchingMaxComparisons &&
|
const doMatching =
|
||||||
|
comparisons < that.config.matchingMaxComparisons &&
|
||||||
maxLineSizeInBlock < that.config.maxLineSizeInBlockForComparison &&
|
maxLineSizeInBlock < that.config.maxLineSizeInBlockForComparison &&
|
||||||
(that.config.matching === 'lines' || that.config.matching === 'words');
|
(that.config.matching === "lines" || that.config.matching === "words");
|
||||||
|
|
||||||
if (doMatching) {
|
if (doMatching) {
|
||||||
matches = matcher(oldLines, newLines);
|
matches = matcher(oldLines, newLines);
|
||||||
|
|
@ -119,30 +128,38 @@
|
||||||
oldLines = match[0];
|
oldLines = match[0];
|
||||||
newLines = match[1];
|
newLines = match[1];
|
||||||
|
|
||||||
var common = Math.min(oldLines.length, newLines.length);
|
const common = Math.min(oldLines.length, newLines.length);
|
||||||
var max = Math.max(oldLines.length, newLines.length);
|
const max = Math.max(oldLines.length, newLines.length);
|
||||||
|
|
||||||
for (var j = 0; j < common; j++) {
|
for (let j = 0; j < common; j++) {
|
||||||
var oldLine = oldLines[j];
|
const oldLine = oldLines[j];
|
||||||
var newLine = newLines[j];
|
const newLine = newLines[j];
|
||||||
|
|
||||||
that.config.isCombined = file.isCombined;
|
that.config.isCombined = file.isCombined;
|
||||||
|
|
||||||
var diff = printerUtils.diffHighlight(oldLine.content, newLine.content, that.config);
|
const diff = printerUtils.diffHighlight(oldLine.content, newLine.content, that.config);
|
||||||
|
|
||||||
fileHtml.left +=
|
fileHtml.left += that.generateSingleLineHtml(
|
||||||
that.generateSingleLineHtml(file.isCombined, deleteType, oldLine.oldNumber,
|
file.isCombined,
|
||||||
diff.first.line, diff.first.prefix);
|
deleteType,
|
||||||
fileHtml.right +=
|
oldLine.oldNumber,
|
||||||
that.generateSingleLineHtml(file.isCombined, insertType, newLine.newNumber,
|
diff.first.line,
|
||||||
diff.second.line, diff.second.prefix);
|
diff.first.prefix
|
||||||
|
);
|
||||||
|
fileHtml.right += that.generateSingleLineHtml(
|
||||||
|
file.isCombined,
|
||||||
|
insertType,
|
||||||
|
newLine.newNumber,
|
||||||
|
diff.second.line,
|
||||||
|
diff.second.prefix
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (max > common) {
|
if (max > common) {
|
||||||
var oldSlice = oldLines.slice(common);
|
const oldSlice = oldLines.slice(common);
|
||||||
var newSlice = newLines.slice(common);
|
const newSlice = newLines.slice(common);
|
||||||
|
|
||||||
var tmpHtml = that.processLines(file.isCombined, oldSlice, newSlice);
|
const tmpHtml = that.processLines(file.isCombined, oldSlice, newSlice);
|
||||||
fileHtml.left += tmpHtml.left;
|
fileHtml.left += tmpHtml.left;
|
||||||
fileHtml.right += tmpHtml.right;
|
fileHtml.right += tmpHtml.right;
|
||||||
}
|
}
|
||||||
|
|
@ -152,28 +169,42 @@
|
||||||
newLines = [];
|
newLines = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = 0; i < block.lines.length; i++) {
|
for (let i = 0; i < block.lines.length; i++) {
|
||||||
var line = block.lines[i];
|
const line = block.lines[i];
|
||||||
var prefix = line.content[0];
|
const prefix = line.content[0];
|
||||||
var escapedLine = utils.escape(line.content.substr(1));
|
const escapedLine = utils.escape(line.content.substr(1));
|
||||||
|
|
||||||
if (line.type !== diffParser.LINE_TYPE.INSERTS &&
|
if (
|
||||||
(newLines.length > 0 || (line.type !== diffParser.LINE_TYPE.DELETES && oldLines.length > 0))) {
|
line.type !== diffParser.LINE_TYPE.INSERTS &&
|
||||||
|
(newLines.length > 0 || (line.type !== diffParser.LINE_TYPE.DELETES && oldLines.length > 0))
|
||||||
|
) {
|
||||||
processChangeBlock();
|
processChangeBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (line.type === diffParser.LINE_TYPE.CONTEXT) {
|
if (line.type === diffParser.LINE_TYPE.CONTEXT) {
|
||||||
fileHtml.left += that.generateSingleLineHtml(file.isCombined, line.type, line.oldNumber, escapedLine, prefix);
|
fileHtml.left += that.generateSingleLineHtml(file.isCombined, line.type, line.oldNumber, escapedLine, prefix);
|
||||||
fileHtml.right += that.generateSingleLineHtml(file.isCombined, line.type, line.newNumber, escapedLine, prefix);
|
fileHtml.right += that.generateSingleLineHtml(
|
||||||
|
file.isCombined,
|
||||||
|
line.type,
|
||||||
|
line.newNumber,
|
||||||
|
escapedLine,
|
||||||
|
prefix
|
||||||
|
);
|
||||||
} else if (line.type === diffParser.LINE_TYPE.INSERTS && !oldLines.length) {
|
} else if (line.type === diffParser.LINE_TYPE.INSERTS && !oldLines.length) {
|
||||||
fileHtml.left += that.generateSingleLineHtml(file.isCombined, diffParser.LINE_TYPE.CONTEXT, '', '', '');
|
fileHtml.left += that.generateSingleLineHtml(file.isCombined, diffParser.LINE_TYPE.CONTEXT, "", "", "");
|
||||||
fileHtml.right += that.generateSingleLineHtml(file.isCombined, line.type, line.newNumber, escapedLine, prefix);
|
fileHtml.right += that.generateSingleLineHtml(
|
||||||
|
file.isCombined,
|
||||||
|
line.type,
|
||||||
|
line.newNumber,
|
||||||
|
escapedLine,
|
||||||
|
prefix
|
||||||
|
);
|
||||||
} else if (line.type === diffParser.LINE_TYPE.DELETES) {
|
} else if (line.type === diffParser.LINE_TYPE.DELETES) {
|
||||||
oldLines.push(line);
|
oldLines.push(line);
|
||||||
} else if (line.type === diffParser.LINE_TYPE.INSERTS && Boolean(oldLines.length)) {
|
} else if (line.type === diffParser.LINE_TYPE.INSERTS && Boolean(oldLines.length)) {
|
||||||
newLines.push(line);
|
newLines.push(line);
|
||||||
} else {
|
} else {
|
||||||
console.error('unknown state in html side-by-side generator');
|
console.error("unknown state in html side-by-side generator");
|
||||||
processChangeBlock();
|
processChangeBlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -185,15 +216,15 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
SideBySidePrinter.prototype.processLines = function(isCombined, oldLines, newLines) {
|
SideBySidePrinter.prototype.processLines = function(isCombined, oldLines, newLines) {
|
||||||
var that = this;
|
const that = this;
|
||||||
var fileHtml = {};
|
const fileHtml = {};
|
||||||
fileHtml.left = '';
|
fileHtml.left = "";
|
||||||
fileHtml.right = '';
|
fileHtml.right = "";
|
||||||
|
|
||||||
var maxLinesNumber = Math.max(oldLines.length, newLines.length);
|
const maxLinesNumber = Math.max(oldLines.length, newLines.length);
|
||||||
for (var i = 0; i < maxLinesNumber; i++) {
|
for (let i = 0; i < maxLinesNumber; i++) {
|
||||||
var oldLine = oldLines[i];
|
const oldLine = oldLines[i];
|
||||||
var newLine = newLines[i];
|
const newLine = newLines[i];
|
||||||
var oldContent;
|
var oldContent;
|
||||||
var newContent;
|
var newContent;
|
||||||
var oldPrefix;
|
var oldPrefix;
|
||||||
|
|
@ -210,16 +241,40 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oldLine && newLine) {
|
if (oldLine && newLine) {
|
||||||
fileHtml.left += that.generateSingleLineHtml(isCombined, oldLine.type, oldLine.oldNumber, oldContent, oldPrefix);
|
fileHtml.left += that.generateSingleLineHtml(
|
||||||
fileHtml.right += that.generateSingleLineHtml(isCombined, newLine.type, newLine.newNumber, newContent, newPrefix);
|
isCombined,
|
||||||
|
oldLine.type,
|
||||||
|
oldLine.oldNumber,
|
||||||
|
oldContent,
|
||||||
|
oldPrefix
|
||||||
|
);
|
||||||
|
fileHtml.right += that.generateSingleLineHtml(
|
||||||
|
isCombined,
|
||||||
|
newLine.type,
|
||||||
|
newLine.newNumber,
|
||||||
|
newContent,
|
||||||
|
newPrefix
|
||||||
|
);
|
||||||
} else if (oldLine) {
|
} else if (oldLine) {
|
||||||
fileHtml.left += that.generateSingleLineHtml(isCombined, oldLine.type, oldLine.oldNumber, oldContent, oldPrefix);
|
fileHtml.left += that.generateSingleLineHtml(
|
||||||
fileHtml.right += that.generateSingleLineHtml(isCombined, diffParser.LINE_TYPE.CONTEXT, '', '', '');
|
isCombined,
|
||||||
|
oldLine.type,
|
||||||
|
oldLine.oldNumber,
|
||||||
|
oldContent,
|
||||||
|
oldPrefix
|
||||||
|
);
|
||||||
|
fileHtml.right += that.generateSingleLineHtml(isCombined, diffParser.LINE_TYPE.CONTEXT, "", "", "");
|
||||||
} else if (newLine) {
|
} else if (newLine) {
|
||||||
fileHtml.left += that.generateSingleLineHtml(isCombined, diffParser.LINE_TYPE.CONTEXT, '', '', '');
|
fileHtml.left += that.generateSingleLineHtml(isCombined, diffParser.LINE_TYPE.CONTEXT, "", "", "");
|
||||||
fileHtml.right += that.generateSingleLineHtml(isCombined, newLine.type, newLine.newNumber, newContent, newPrefix);
|
fileHtml.right += that.generateSingleLineHtml(
|
||||||
|
isCombined,
|
||||||
|
newLine.type,
|
||||||
|
newLine.newNumber,
|
||||||
|
newContent,
|
||||||
|
newPrefix
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
console.error('How did it get here?');
|
console.error("How did it get here?");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -227,29 +282,28 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
SideBySidePrinter.prototype.generateSingleLineHtml = function(isCombined, type, number, content, possiblePrefix) {
|
SideBySidePrinter.prototype.generateSingleLineHtml = function(isCombined, type, number, content, possiblePrefix) {
|
||||||
var lineWithoutPrefix = content;
|
let lineWithoutPrefix = content;
|
||||||
var prefix = possiblePrefix;
|
let prefix = possiblePrefix;
|
||||||
var lineClass = 'd2h-code-side-linenumber';
|
let lineClass = "d2h-code-side-linenumber";
|
||||||
var contentClass = 'd2h-code-side-line';
|
let contentClass = "d2h-code-side-line";
|
||||||
|
|
||||||
if (!number && !content) {
|
if (!number && !content) {
|
||||||
lineClass += ' d2h-code-side-emptyplaceholder';
|
lineClass += " d2h-code-side-emptyplaceholder";
|
||||||
contentClass += ' d2h-code-side-emptyplaceholder';
|
contentClass += " d2h-code-side-emptyplaceholder";
|
||||||
type += ' d2h-emptyplaceholder';
|
type += " d2h-emptyplaceholder";
|
||||||
prefix = ' ';
|
prefix = " ";
|
||||||
lineWithoutPrefix = ' ';
|
lineWithoutPrefix = " ";
|
||||||
} else if (!prefix) {
|
} else if (!prefix) {
|
||||||
var lineWithPrefix = printerUtils.separatePrefix(isCombined, content);
|
const lineWithPrefix = printerUtils.separatePrefix(isCombined, content);
|
||||||
prefix = lineWithPrefix.prefix;
|
prefix = lineWithPrefix.prefix;
|
||||||
lineWithoutPrefix = lineWithPrefix.line;
|
lineWithoutPrefix = lineWithPrefix.line;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prefix === ' ') {
|
if (prefix === " ") {
|
||||||
prefix = ' ';
|
prefix = " ";
|
||||||
}
|
}
|
||||||
|
|
||||||
return hoganUtils.render(genericTemplatesPath, 'line',
|
return hoganUtils.render(genericTemplatesPath, "line", {
|
||||||
{
|
|
||||||
type: type,
|
type: type,
|
||||||
lineClass: lineClass,
|
lineClass: lineClass,
|
||||||
contentClass: contentClass,
|
contentClass: contentClass,
|
||||||
|
|
@ -260,11 +314,11 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
SideBySidePrinter.prototype.generateEmptyDiff = function() {
|
SideBySidePrinter.prototype.generateEmptyDiff = function() {
|
||||||
var fileHtml = {};
|
const fileHtml = {};
|
||||||
fileHtml.right = '';
|
fileHtml.right = "";
|
||||||
|
|
||||||
fileHtml.left = hoganUtils.render(genericTemplatesPath, 'empty-diff', {
|
fileHtml.left = hoganUtils.render(genericTemplatesPath, "empty-diff", {
|
||||||
contentClass: 'd2h-code-side-line',
|
contentClass: "d2h-code-side-line",
|
||||||
diffParser: diffParser
|
diffParser: diffParser
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
(function() {
|
|
||||||
if (!!!global.browserTemplates) global.browserTemplates = {};
|
|
||||||
var Hogan = require("hogan.js");global.browserTemplates["file-summary-line"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<li class=\"d2h-file-list-line\">");t.b("\n" + i);t.b(" <span class=\"d2h-file-name-wrapper\">");t.b("\n" + i);t.b(t.rp("<fileIcon0",c,p," "));t.b(" <a href=\"#");t.b(t.v(t.f("fileHtmlId",c,p,0)));t.b("\" class=\"d2h-file-name\">");t.b(t.v(t.f("fileName",c,p,0)));t.b("</a>");t.b("\n" + i);t.b(" <span class=\"d2h-file-stats\">");t.b("\n" + i);t.b(" <span class=\"d2h-lines-added\">");t.b(t.v(t.f("addedLines",c,p,0)));t.b("</span>");t.b("\n" + i);t.b(" <span class=\"d2h-lines-deleted\">");t.b(t.v(t.f("deletedLines",c,p,0)));t.b("</span>");t.b("\n" + i);t.b(" </span>");t.b("\n" + i);t.b(" </span>");t.b("\n" + i);t.b("</li>");return t.fl(); },partials: {"<fileIcon0":{name:"fileIcon", partials: {}, subs: { }}}, subs: { }});
|
|
||||||
global.browserTemplates["file-summary-wrapper"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<div class=\"d2h-file-list-wrapper\">");t.b("\n" + i);t.b(" <div class=\"d2h-file-list-header\">");t.b("\n" + i);t.b(" <span class=\"d2h-file-list-title\">Files changed (");t.b(t.v(t.f("filesNumber",c,p,0)));t.b(")</span>");t.b("\n" + i);t.b(" <a class=\"d2h-file-switch d2h-hide\">hide</a>");t.b("\n" + i);t.b(" <a class=\"d2h-file-switch d2h-show\">show</a>");t.b("\n" + i);t.b(" </div>");t.b("\n" + i);t.b(" <ol class=\"d2h-file-list\">");t.b("\n" + i);t.b(" ");t.b(t.t(t.f("files",c,p,0)));t.b("\n" + i);t.b(" </ol>");t.b("\n" + i);t.b("</div>");return t.fl(); },partials: {}, subs: { }});
|
|
||||||
global.browserTemplates["generic-column-line-number"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<tr>");t.b("\n" + i);t.b(" <td class=\"");t.b(t.v(t.f("lineClass",c,p,0)));t.b(" ");t.b(t.v(t.d("diffParser.LINE_TYPE.INFO",c,p,0)));t.b("\"></td>");t.b("\n" + i);t.b(" <td class=\"");t.b(t.v(t.d("diffParser.LINE_TYPE.INFO",c,p,0)));t.b("\">");t.b("\n" + i);t.b(" <div class=\"");t.b(t.v(t.f("contentClass",c,p,0)));t.b(" ");t.b(t.v(t.d("diffParser.LINE_TYPE.INFO",c,p,0)));t.b("\">");t.b(t.t(t.f("blockHeader",c,p,0)));t.b("</div>");t.b("\n" + i);t.b(" </td>");t.b("\n" + i);t.b("</tr>");return t.fl(); },partials: {}, subs: { }});
|
|
||||||
global.browserTemplates["generic-empty-diff"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<tr>");t.b("\n" + i);t.b(" <td class=\"");t.b(t.v(t.d("diffParser.LINE_TYPE.INFO",c,p,0)));t.b("\">");t.b("\n" + i);t.b(" <div class=\"");t.b(t.v(t.f("contentClass",c,p,0)));t.b(" ");t.b(t.v(t.d("diffParser.LINE_TYPE.INFO",c,p,0)));t.b("\">");t.b("\n" + i);t.b(" File without changes");t.b("\n" + i);t.b(" </div>");t.b("\n" + i);t.b(" </td>");t.b("\n" + i);t.b("</tr>");return t.fl(); },partials: {}, subs: { }});
|
|
||||||
global.browserTemplates["generic-file-path"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<span class=\"d2h-file-name-wrapper\">");t.b("\n" + i);t.b(t.rp("<fileIcon0",c,p," "));t.b(" <span class=\"d2h-file-name\">");t.b(t.v(t.f("fileDiffName",c,p,0)));t.b("</span>");t.b("\n" + i);t.b(t.rp("<fileTag1",c,p," "));t.b("</span>");return t.fl(); },partials: {"<fileIcon0":{name:"fileIcon", partials: {}, subs: { }},"<fileTag1":{name:"fileTag", partials: {}, subs: { }}}, subs: { }});
|
|
||||||
global.browserTemplates["generic-line"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<tr>");t.b("\n" + i);t.b(" <td class=\"");t.b(t.v(t.f("lineClass",c,p,0)));t.b(" ");t.b(t.v(t.f("type",c,p,0)));t.b("\">");t.b("\n" + i);t.b(" ");t.b(t.t(t.f("lineNumber",c,p,0)));t.b("\n" + i);t.b(" </td>");t.b("\n" + i);t.b(" <td class=\"");t.b(t.v(t.f("type",c,p,0)));t.b("\">");t.b("\n" + i);t.b(" <div class=\"");t.b(t.v(t.f("contentClass",c,p,0)));t.b(" ");t.b(t.v(t.f("type",c,p,0)));t.b("\">");t.b("\n" + i);if(t.s(t.f("prefix",c,p,1),c,p,0,171,247,"{{ }}")){t.rs(c,p,function(c,p,t){t.b(" <span class=\"d2h-code-line-prefix\">");t.b(t.t(t.f("prefix",c,p,0)));t.b("</span>");t.b("\n" + i);});c.pop();}if(t.s(t.f("content",c,p,1),c,p,0,279,353,"{{ }}")){t.rs(c,p,function(c,p,t){t.b(" <span class=\"d2h-code-line-ctn\">");t.b(t.t(t.f("content",c,p,0)));t.b("</span>");t.b("\n" + i);});c.pop();}t.b(" </div>");t.b("\n" + i);t.b(" </td>");t.b("\n" + i);t.b("</tr>");return t.fl(); },partials: {}, subs: { }});
|
|
||||||
global.browserTemplates["generic-wrapper"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<div class=\"d2h-wrapper\">");t.b("\n" + i);t.b(" ");t.b(t.t(t.f("content",c,p,0)));t.b("\n" + i);t.b("</div>");return t.fl(); },partials: {}, subs: { }});
|
|
||||||
global.browserTemplates["icon-file-added"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<svg aria-hidden=\"true\" class=\"d2h-icon d2h-added\" height=\"16\" title=\"added\" version=\"1.1\" viewBox=\"0 0 14 16\"");t.b("\n" + i);t.b(" width=\"14\">");t.b("\n" + i);t.b(" <path d=\"M13 1H1C0.45 1 0 1.45 0 2v12c0 0.55 0.45 1 1 1h12c0.55 0 1-0.45 1-1V2c0-0.55-0.45-1-1-1z m0 13H1V2h12v12zM6 9H3V7h3V4h2v3h3v2H8v3H6V9z\"></path>");t.b("\n" + i);t.b("</svg>");return t.fl(); },partials: {}, subs: { }});
|
|
||||||
global.browserTemplates["icon-file-changed"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<svg aria-hidden=\"true\" class=\"d2h-icon d2h-changed\" height=\"16\" title=\"modified\" version=\"1.1\"");t.b("\n" + i);t.b(" viewBox=\"0 0 14 16\" width=\"14\">");t.b("\n" + i);t.b(" <path d=\"M13 1H1C0.45 1 0 1.45 0 2v12c0 0.55 0.45 1 1 1h12c0.55 0 1-0.45 1-1V2c0-0.55-0.45-1-1-1z m0 13H1V2h12v12zM4 8c0-1.66 1.34-3 3-3s3 1.34 3 3-1.34 3-3 3-3-1.34-3-3z\"></path>");t.b("\n" + i);t.b("</svg>");return t.fl(); },partials: {}, subs: { }});
|
|
||||||
global.browserTemplates["icon-file-deleted"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<svg aria-hidden=\"true\" class=\"d2h-icon d2h-deleted\" height=\"16\" title=\"removed\" version=\"1.1\"");t.b("\n" + i);t.b(" viewBox=\"0 0 14 16\" width=\"14\">");t.b("\n" + i);t.b(" <path d=\"M13 1H1C0.45 1 0 1.45 0 2v12c0 0.55 0.45 1 1 1h12c0.55 0 1-0.45 1-1V2c0-0.55-0.45-1-1-1z m0 13H1V2h12v12zM11 9H3V7h8v2z\"></path>");t.b("\n" + i);t.b("</svg>");return t.fl(); },partials: {}, subs: { }});
|
|
||||||
global.browserTemplates["icon-file-renamed"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<svg aria-hidden=\"true\" class=\"d2h-icon d2h-moved\" height=\"16\" title=\"renamed\" version=\"1.1\"");t.b("\n" + i);t.b(" viewBox=\"0 0 14 16\" width=\"14\">");t.b("\n" + i);t.b(" <path d=\"M6 9H3V7h3V4l5 4-5 4V9z m8-7v12c0 0.55-0.45 1-1 1H1c-0.55 0-1-0.45-1-1V2c0-0.55 0.45-1 1-1h12c0.55 0 1 0.45 1 1z m-1 0H1v12h12V2z\"></path>");t.b("\n" + i);t.b("</svg>");return t.fl(); },partials: {}, subs: { }});
|
|
||||||
global.browserTemplates["icon-file"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<svg aria-hidden=\"true\" class=\"d2h-icon\" height=\"16\" version=\"1.1\" viewBox=\"0 0 12 16\" width=\"12\">");t.b("\n" + i);t.b(" <path d=\"M6 5H2v-1h4v1zM2 8h7v-1H2v1z m0 2h7v-1H2v1z m0 2h7v-1H2v1z m10-7.5v9.5c0 0.55-0.45 1-1 1H1c-0.55 0-1-0.45-1-1V2c0-0.55 0.45-1 1-1h7.5l3.5 3.5z m-1 0.5L8 2H1v12h10V5z\"></path>");t.b("\n" + i);t.b("</svg>");return t.fl(); },partials: {}, subs: { }});
|
|
||||||
global.browserTemplates["line-by-line-file-diff"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<div id=\"");t.b(t.v(t.f("fileHtmlId",c,p,0)));t.b("\" class=\"d2h-file-wrapper\" data-lang=\"");t.b(t.v(t.d("file.language",c,p,0)));t.b("\">");t.b("\n" + i);t.b(" <div class=\"d2h-file-header\">");t.b("\n" + i);t.b(" ");t.b(t.t(t.f("filePath",c,p,0)));t.b("\n" + i);t.b(" </div>");t.b("\n" + i);t.b(" <div class=\"d2h-file-diff\">");t.b("\n" + i);t.b(" <div class=\"d2h-code-wrapper\">");t.b("\n" + i);t.b(" <table class=\"d2h-diff-table\">");t.b("\n" + i);t.b(" <tbody class=\"d2h-diff-tbody\">");t.b("\n" + i);t.b(" ");t.b(t.t(t.f("diffs",c,p,0)));t.b("\n" + i);t.b(" </tbody>");t.b("\n" + i);t.b(" </table>");t.b("\n" + i);t.b(" </div>");t.b("\n" + i);t.b(" </div>");t.b("\n" + i);t.b("</div>");return t.fl(); },partials: {}, subs: { }});
|
|
||||||
global.browserTemplates["line-by-line-numbers"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<div class=\"line-num1\">");t.b(t.v(t.f("oldNumber",c,p,0)));t.b("</div>");t.b("\n" + i);t.b("<div class=\"line-num2\">");t.b(t.v(t.f("newNumber",c,p,0)));t.b("</div>");return t.fl(); },partials: {}, subs: { }});
|
|
||||||
global.browserTemplates["side-by-side-file-diff"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<div id=\"");t.b(t.v(t.f("fileHtmlId",c,p,0)));t.b("\" class=\"d2h-file-wrapper\" data-lang=\"");t.b(t.v(t.d("file.language",c,p,0)));t.b("\">");t.b("\n" + i);t.b(" <div class=\"d2h-file-header\">");t.b("\n" + i);t.b(" ");t.b(t.t(t.f("filePath",c,p,0)));t.b("\n" + i);t.b(" </div>");t.b("\n" + i);t.b(" <div class=\"d2h-files-diff\">");t.b("\n" + i);t.b(" <div class=\"d2h-file-side-diff\">");t.b("\n" + i);t.b(" <div class=\"d2h-code-wrapper\">");t.b("\n" + i);t.b(" <table class=\"d2h-diff-table\">");t.b("\n" + i);t.b(" <tbody class=\"d2h-diff-tbody\">");t.b("\n" + i);t.b(" ");t.b(t.t(t.d("diffs.left",c,p,0)));t.b("\n" + i);t.b(" </tbody>");t.b("\n" + i);t.b(" </table>");t.b("\n" + i);t.b(" </div>");t.b("\n" + i);t.b(" </div>");t.b("\n" + i);t.b(" <div class=\"d2h-file-side-diff\">");t.b("\n" + i);t.b(" <div class=\"d2h-code-wrapper\">");t.b("\n" + i);t.b(" <table class=\"d2h-diff-table\">");t.b("\n" + i);t.b(" <tbody class=\"d2h-diff-tbody\">");t.b("\n" + i);t.b(" ");t.b(t.t(t.d("diffs.right",c,p,0)));t.b("\n" + i);t.b(" </tbody>");t.b("\n" + i);t.b(" </table>");t.b("\n" + i);t.b(" </div>");t.b("\n" + i);t.b(" </div>");t.b("\n" + i);t.b(" </div>");t.b("\n" + i);t.b("</div>");return t.fl(); },partials: {}, subs: { }});
|
|
||||||
global.browserTemplates["tag-file-added"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<span class=\"d2h-tag d2h-added d2h-added-tag\">ADDED</span>");return t.fl(); },partials: {}, subs: { }});
|
|
||||||
global.browserTemplates["tag-file-changed"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<span class=\"d2h-tag d2h-changed d2h-changed-tag\">CHANGED</span>");return t.fl(); },partials: {}, subs: { }});
|
|
||||||
global.browserTemplates["tag-file-deleted"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<span class=\"d2h-tag d2h-deleted d2h-deleted-tag\">DELETED</span>");return t.fl(); },partials: {}, subs: { }});
|
|
||||||
global.browserTemplates["tag-file-renamed"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<span class=\"d2h-tag d2h-moved d2h-moved-tag\">RENAMED</span>");return t.fl(); },partials: {}, subs: { }});
|
|
||||||
module.exports = global.browserTemplates;
|
|
||||||
})();
|
|
||||||
|
|
@ -11,14 +11,14 @@
|
||||||
/* global $, hljs, Diff2Html */
|
/* global $, hljs, Diff2Html */
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
var highlightJS = require('./highlight.js-internals.js').HighlightJS;
|
const highlightJS = require("./highlight.js-internals.js").HighlightJS;
|
||||||
|
|
||||||
var diffJson = null;
|
let diffJson = null;
|
||||||
var defaultTarget = 'body';
|
const defaultTarget = "body";
|
||||||
var currentSelectionColumnId = -1;
|
let currentSelectionColumnId = -1;
|
||||||
|
|
||||||
function Diff2HtmlUI(config) {
|
function Diff2HtmlUI(config) {
|
||||||
var cfg = config || {};
|
const cfg = config || {};
|
||||||
|
|
||||||
if (cfg.diff) {
|
if (cfg.diff) {
|
||||||
diffJson = Diff2Html.getJsonFromDiff(cfg.diff);
|
diffJson = Diff2Html.getJsonFromDiff(cfg.diff);
|
||||||
|
|
@ -30,9 +30,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
Diff2HtmlUI.prototype.draw = function(targetId, config) {
|
Diff2HtmlUI.prototype.draw = function(targetId, config) {
|
||||||
var cfg = config || {};
|
const cfg = config || {};
|
||||||
cfg.inputFormat = 'json';
|
cfg.inputFormat = "json";
|
||||||
var $target = this._getTarget(targetId);
|
const $target = this._getTarget(targetId);
|
||||||
$target.html(Diff2Html.getPrettyHtml(diffJson, cfg));
|
$target.html(Diff2Html.getPrettyHtml(diffJson, cfg));
|
||||||
|
|
||||||
if (cfg.synchronisedScroll) {
|
if (cfg.synchronisedScroll) {
|
||||||
|
|
@ -41,25 +41,27 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
Diff2HtmlUI.prototype.synchronisedScroll = function(targetId) {
|
Diff2HtmlUI.prototype.synchronisedScroll = function(targetId) {
|
||||||
var $target = this._getTarget(targetId);
|
const $target = this._getTarget(targetId);
|
||||||
$target.find('.d2h-file-side-diff').scroll(function() {
|
$target.find(".d2h-file-side-diff").scroll(function() {
|
||||||
var $this = $(this);
|
const $this = $(this);
|
||||||
$this.closest('.d2h-file-wrapper').find('.d2h-file-side-diff')
|
$this
|
||||||
|
.closest(".d2h-file-wrapper")
|
||||||
|
.find(".d2h-file-side-diff")
|
||||||
.scrollLeft($this.scrollLeft());
|
.scrollLeft($this.scrollLeft());
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Diff2HtmlUI.prototype.fileListCloseable = function(targetId, startVisible) {
|
Diff2HtmlUI.prototype.fileListCloseable = function(targetId, startVisible) {
|
||||||
var $target = this._getTarget(targetId);
|
const $target = this._getTarget(targetId);
|
||||||
|
|
||||||
var hashTag = this._getHashTag();
|
const hashTag = this._getHashTag();
|
||||||
|
|
||||||
var $showBtn = $target.find('.d2h-show');
|
const $showBtn = $target.find(".d2h-show");
|
||||||
var $hideBtn = $target.find('.d2h-hide');
|
const $hideBtn = $target.find(".d2h-hide");
|
||||||
var $fileList = $target.find('.d2h-file-list');
|
const $fileList = $target.find(".d2h-file-list");
|
||||||
|
|
||||||
if (hashTag === 'files-summary-show') show();
|
if (hashTag === "files-summary-show") show();
|
||||||
else if (hashTag === 'files-summary-hide') hide();
|
else if (hashTag === "files-summary-hide") hide();
|
||||||
else if (startVisible) show();
|
else if (startVisible) show();
|
||||||
else hide();
|
else hide();
|
||||||
|
|
||||||
|
|
@ -80,51 +82,53 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
Diff2HtmlUI.prototype.highlightCode = function(targetId) {
|
Diff2HtmlUI.prototype.highlightCode = function(targetId) {
|
||||||
var that = this;
|
const that = this;
|
||||||
|
|
||||||
var $target = that._getTarget(targetId);
|
const $target = that._getTarget(targetId);
|
||||||
|
|
||||||
// collect all the diff files and execute the highlight on their lines
|
// collect all the diff files and execute the highlight on their lines
|
||||||
var $files = $target.find('.d2h-file-wrapper');
|
const $files = $target.find(".d2h-file-wrapper");
|
||||||
$files.map(function(_i, file) {
|
$files.map(function(_i, file) {
|
||||||
var oldLinesState;
|
let oldLinesState;
|
||||||
var newLinesState;
|
let newLinesState;
|
||||||
var $file = $(file);
|
const $file = $(file);
|
||||||
var language = $file.data('lang');
|
const language = $file.data("lang");
|
||||||
|
|
||||||
// collect all the code lines and execute the highlight on them
|
// collect all the code lines and execute the highlight on them
|
||||||
var $codeLines = $file.find('.d2h-code-line-ctn');
|
const $codeLines = $file.find(".d2h-code-line-ctn");
|
||||||
$codeLines.map(function(_j, line) {
|
$codeLines.map(function(_j, line) {
|
||||||
var $line = $(line);
|
const $line = $(line);
|
||||||
var text = line.textContent;
|
const text = line.textContent;
|
||||||
var lineParent = line.parentNode;
|
const lineParent = line.parentNode;
|
||||||
|
|
||||||
var lineState;
|
let lineState;
|
||||||
if (lineParent.className.indexOf('d2h-del') !== -1) {
|
if (lineParent.className.indexOf("d2h-del") !== -1) {
|
||||||
lineState = oldLinesState;
|
lineState = oldLinesState;
|
||||||
} else {
|
} else {
|
||||||
lineState = newLinesState;
|
lineState = newLinesState;
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = hljs.getLanguage(language) ? hljs.highlight(language, text, true, lineState) : hljs.highlightAuto(text);
|
const result = hljs.getLanguage(language)
|
||||||
|
? hljs.highlight(language, text, true, lineState)
|
||||||
|
: hljs.highlightAuto(text);
|
||||||
|
|
||||||
if (lineParent.className.indexOf('d2h-del') !== -1) {
|
if (lineParent.className.indexOf("d2h-del") !== -1) {
|
||||||
oldLinesState = result.top;
|
oldLinesState = result.top;
|
||||||
} else if (lineParent.className.indexOf('d2h-ins') !== -1) {
|
} else if (lineParent.className.indexOf("d2h-ins") !== -1) {
|
||||||
newLinesState = result.top;
|
newLinesState = result.top;
|
||||||
} else {
|
} else {
|
||||||
oldLinesState = result.top;
|
oldLinesState = result.top;
|
||||||
newLinesState = result.top;
|
newLinesState = result.top;
|
||||||
}
|
}
|
||||||
|
|
||||||
var originalStream = highlightJS.nodeStream(line);
|
const originalStream = highlightJS.nodeStream(line);
|
||||||
if (originalStream.length) {
|
if (originalStream.length) {
|
||||||
var resultNode = document.createElementNS('http://www.w3.org/1999/xhtml', 'div');
|
const resultNode = document.createElementNS("http://www.w3.org/1999/xhtml", "div");
|
||||||
resultNode.innerHTML = result.value;
|
resultNode.innerHTML = result.value;
|
||||||
result.value = highlightJS.mergeStreams(originalStream, highlightJS.nodeStream(resultNode), text);
|
result.value = highlightJS.mergeStreams(originalStream, highlightJS.nodeStream(resultNode), text);
|
||||||
}
|
}
|
||||||
|
|
||||||
$line.addClass('hljs');
|
$line.addClass("hljs");
|
||||||
$line.addClass(result.language);
|
$line.addClass(result.language);
|
||||||
$line.html(result.value);
|
$line.html(result.value);
|
||||||
});
|
});
|
||||||
|
|
@ -132,15 +136,15 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
Diff2HtmlUI.prototype._getTarget = function(targetId) {
|
Diff2HtmlUI.prototype._getTarget = function(targetId) {
|
||||||
var $target;
|
let $target;
|
||||||
|
|
||||||
if (typeof targetId === 'object' && targetId instanceof jQuery) {
|
if (typeof targetId === "object" && targetId instanceof jQuery) {
|
||||||
$target = targetId;
|
$target = targetId;
|
||||||
} else if (typeof targetId === 'string') {
|
} else if (typeof targetId === "string") {
|
||||||
$target = $(targetId);
|
$target = $(targetId);
|
||||||
} else {
|
} else {
|
||||||
console.error("Wrong target provided! Falling back to default value 'body'.");
|
console.error("Wrong target provided! Falling back to default value 'body'.");
|
||||||
console.log('Please provide a jQuery object or a valid DOM query string.');
|
console.log("Please provide a jQuery object or a valid DOM query string.");
|
||||||
$target = $(defaultTarget);
|
$target = $(defaultTarget);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -148,10 +152,10 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
Diff2HtmlUI.prototype._getHashTag = function() {
|
Diff2HtmlUI.prototype._getHashTag = function() {
|
||||||
var docUrl = document.URL;
|
const docUrl = document.URL;
|
||||||
var hashTagIndex = docUrl.indexOf('#');
|
const hashTagIndex = docUrl.indexOf("#");
|
||||||
|
|
||||||
var hashTag = null;
|
let hashTag = null;
|
||||||
if (hashTagIndex !== -1) {
|
if (hashTagIndex !== -1) {
|
||||||
hashTag = docUrl.substr(hashTagIndex + 1);
|
hashTag = docUrl.substr(hashTagIndex + 1);
|
||||||
}
|
}
|
||||||
|
|
@ -166,46 +170,46 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
Diff2HtmlUI.prototype._initSelection = function() {
|
Diff2HtmlUI.prototype._initSelection = function() {
|
||||||
var body = $('body');
|
const body = $("body");
|
||||||
var that = this;
|
const that = this;
|
||||||
|
|
||||||
body.on('mousedown', '.d2h-diff-table', function(event) {
|
body.on("mousedown", ".d2h-diff-table", function(event) {
|
||||||
var target = $(event.target);
|
const target = $(event.target);
|
||||||
var table = target.closest('.d2h-diff-table');
|
const table = target.closest(".d2h-diff-table");
|
||||||
|
|
||||||
if (target.closest('.d2h-code-line,.d2h-code-side-line').length) {
|
if (target.closest(".d2h-code-line,.d2h-code-side-line").length) {
|
||||||
table.removeClass('selecting-left');
|
table.removeClass("selecting-left");
|
||||||
table.addClass('selecting-right');
|
table.addClass("selecting-right");
|
||||||
currentSelectionColumnId = 1;
|
currentSelectionColumnId = 1;
|
||||||
} else if (target.closest('.d2h-code-linenumber,.d2h-code-side-linenumber').length) {
|
} else if (target.closest(".d2h-code-linenumber,.d2h-code-side-linenumber").length) {
|
||||||
table.removeClass('selecting-right');
|
table.removeClass("selecting-right");
|
||||||
table.addClass('selecting-left');
|
table.addClass("selecting-left");
|
||||||
currentSelectionColumnId = 0;
|
currentSelectionColumnId = 0;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
body.on('copy', '.d2h-diff-table', function(event) {
|
body.on("copy", ".d2h-diff-table", function(event) {
|
||||||
var clipboardData = event.originalEvent.clipboardData;
|
const clipboardData = event.originalEvent.clipboardData;
|
||||||
var text = that._getSelectedText();
|
const text = that._getSelectedText();
|
||||||
clipboardData.setData('text', text);
|
clipboardData.setData("text", text);
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Diff2HtmlUI.prototype._getSelectedText = function() {
|
Diff2HtmlUI.prototype._getSelectedText = function() {
|
||||||
var sel = window.getSelection();
|
const sel = window.getSelection();
|
||||||
var range = sel.getRangeAt(0);
|
const range = sel.getRangeAt(0);
|
||||||
var doc = range.cloneContents();
|
const doc = range.cloneContents();
|
||||||
var nodes = doc.querySelectorAll('tr');
|
const nodes = doc.querySelectorAll("tr");
|
||||||
var text = '';
|
let text = "";
|
||||||
var idx = currentSelectionColumnId;
|
const idx = currentSelectionColumnId;
|
||||||
|
|
||||||
if (nodes.length === 0) {
|
if (nodes.length === 0) {
|
||||||
text = doc.textContent;
|
text = doc.textContent;
|
||||||
} else {
|
} else {
|
||||||
[].forEach.call(nodes, function(tr, i) {
|
[].forEach.call(nodes, function(tr, i) {
|
||||||
var td = tr.cells[tr.cells.length === 1 ? 0 : idx];
|
const td = tr.cells[tr.cells.length === 1 ? 0 : idx];
|
||||||
text += (i ? '\n' : '') + td.textContent.replace(/(?:\r\n|\r|\n)/g, '');
|
text += (i ? "\n" : "") + td.textContent.replace(/(?:\r\n|\r|\n)/g, "");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
function HighlightJS() {
|
function HighlightJS() {}
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copied from Highlight.js Private API
|
* Copied from Highlight.js Private API
|
||||||
|
|
@ -16,12 +15,15 @@
|
||||||
|
|
||||||
/* Utility vars */
|
/* Utility vars */
|
||||||
|
|
||||||
var ArrayProto = [];
|
const ArrayProto = [];
|
||||||
|
|
||||||
/* Utility functions */
|
/* Utility functions */
|
||||||
|
|
||||||
function escape(value) {
|
function escape(value) {
|
||||||
return value.replace(/&/gm, '&').replace(/</gm, '<').replace(/>/gm, '>');
|
return value
|
||||||
|
.replace(/&/gm, "&")
|
||||||
|
.replace(/</gm, "<")
|
||||||
|
.replace(/>/gm, ">");
|
||||||
}
|
}
|
||||||
|
|
||||||
function tag(node) {
|
function tag(node) {
|
||||||
|
|
@ -31,14 +33,14 @@
|
||||||
/* Stream merging */
|
/* Stream merging */
|
||||||
|
|
||||||
HighlightJS.prototype.nodeStream = function(node) {
|
HighlightJS.prototype.nodeStream = function(node) {
|
||||||
var result = [];
|
const result = [];
|
||||||
(function _nodeStream(node, offset) {
|
(function _nodeStream(node, offset) {
|
||||||
for (var child = node.firstChild; child; child = child.nextSibling) {
|
for (let child = node.firstChild; child; child = child.nextSibling) {
|
||||||
if (child.nodeType === 3) {
|
if (child.nodeType === 3) {
|
||||||
offset += child.nodeValue.length;
|
offset += child.nodeValue.length;
|
||||||
} else if (child.nodeType === 1) {
|
} else if (child.nodeType === 1) {
|
||||||
result.push({
|
result.push({
|
||||||
event: 'start',
|
event: "start",
|
||||||
offset: offset,
|
offset: offset,
|
||||||
node: child
|
node: child
|
||||||
});
|
});
|
||||||
|
|
@ -48,7 +50,7 @@
|
||||||
// but we list only those realistically expected in code display.
|
// but we list only those realistically expected in code display.
|
||||||
if (!tag(child).match(/br|hr|img|input/)) {
|
if (!tag(child).match(/br|hr|img|input/)) {
|
||||||
result.push({
|
result.push({
|
||||||
event: 'stop',
|
event: "stop",
|
||||||
offset: offset,
|
offset: offset,
|
||||||
node: child
|
node: child
|
||||||
});
|
});
|
||||||
|
|
@ -61,16 +63,16 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
HighlightJS.prototype.mergeStreams = function(original, highlighted, value) {
|
HighlightJS.prototype.mergeStreams = function(original, highlighted, value) {
|
||||||
var processed = 0;
|
let processed = 0;
|
||||||
var result = '';
|
let result = "";
|
||||||
var nodeStack = [];
|
const nodeStack = [];
|
||||||
|
|
||||||
function selectStream() {
|
function selectStream() {
|
||||||
if (!original.length || !highlighted.length) {
|
if (!original.length || !highlighted.length) {
|
||||||
return original.length ? original : highlighted;
|
return original.length ? original : highlighted;
|
||||||
}
|
}
|
||||||
if (original[0].offset !== highlighted[0].offset) {
|
if (original[0].offset !== highlighted[0].offset) {
|
||||||
return (original[0].offset < highlighted[0].offset) ? original : highlighted;
|
return original[0].offset < highlighted[0].offset ? original : highlighted;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -86,27 +88,27 @@
|
||||||
return highlighted;
|
return highlighted;
|
||||||
... which is collapsed to:
|
... which is collapsed to:
|
||||||
*/
|
*/
|
||||||
return highlighted[0].event === 'start' ? original : highlighted;
|
return highlighted[0].event === "start" ? original : highlighted;
|
||||||
}
|
}
|
||||||
|
|
||||||
function open(node) {
|
function open(node) {
|
||||||
function attr_str(a) {
|
function attr_str(a) {
|
||||||
return ' ' + a.nodeName + '="' + escape(a.value) + '"';
|
return " " + a.nodeName + '="' + escape(a.value) + '"';
|
||||||
}
|
}
|
||||||
|
|
||||||
result += '<' + tag(node) + ArrayProto.map.call(node.attributes, attr_str).join('') + '>';
|
result += "<" + tag(node) + ArrayProto.map.call(node.attributes, attr_str).join("") + ">";
|
||||||
}
|
}
|
||||||
|
|
||||||
function close(node) {
|
function close(node) {
|
||||||
result += '</' + tag(node) + '>';
|
result += "</" + tag(node) + ">";
|
||||||
}
|
}
|
||||||
|
|
||||||
function render(event) {
|
function render(event) {
|
||||||
(event.event === 'start' ? open : close)(event.node);
|
(event.event === "start" ? open : close)(event.node);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (original.length || highlighted.length) {
|
while (original.length || highlighted.length) {
|
||||||
var stream = selectStream();
|
let stream = selectStream();
|
||||||
result += escape(value.substring(processed, stream[0].offset));
|
result += escape(value.substring(processed, stream[0].offset));
|
||||||
processed = stream[0].offset;
|
processed = stream[0].offset;
|
||||||
if (stream === original) {
|
if (stream === original) {
|
||||||
|
|
@ -123,7 +125,7 @@
|
||||||
} while (stream === original && stream.length && stream[0].offset === processed);
|
} while (stream === original && stream.length && stream[0].offset === processed);
|
||||||
nodeStack.reverse().forEach(open);
|
nodeStack.reverse().forEach(open);
|
||||||
} else {
|
} else {
|
||||||
if (stream[0].event === 'start') {
|
if (stream[0].event === "start") {
|
||||||
nodeStack.push(stream[0].node);
|
nodeStack.push(stream[0].node);
|
||||||
} else {
|
} else {
|
||||||
nodeStack.pop();
|
nodeStack.pop();
|
||||||
|
|
|
||||||
26
src/utils.js
26
src/utils.js
|
|
@ -6,24 +6,24 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
var merge = require('merge');
|
const merge = require("merge");
|
||||||
|
|
||||||
function Utils() {
|
function Utils() {}
|
||||||
}
|
|
||||||
|
|
||||||
Utils.prototype.escape = function(str) {
|
Utils.prototype.escape = function(str) {
|
||||||
return str.slice(0)
|
return str
|
||||||
.replace(/&/g, '&')
|
.slice(0)
|
||||||
.replace(/</g, '<')
|
.replace(/&/g, "&")
|
||||||
.replace(/>/g, '>')
|
.replace(/</g, "<")
|
||||||
.replace(/"/g, '"')
|
.replace(/>/g, ">")
|
||||||
.replace(/'/g, ''')
|
.replace(/"/g, """)
|
||||||
.replace(/\//g, '/');
|
.replace(/'/g, "'")
|
||||||
|
.replace(/\//g, "/");
|
||||||
};
|
};
|
||||||
|
|
||||||
Utils.prototype.startsWith = function(str, start) {
|
Utils.prototype.startsWith = function(str, start) {
|
||||||
if (typeof start === 'object') {
|
if (typeof start === "object") {
|
||||||
var result = false;
|
let result = false;
|
||||||
start.forEach(function(s) {
|
start.forEach(function(s) {
|
||||||
if (str.indexOf(s) === 0) {
|
if (str.indexOf(s) === 0) {
|
||||||
result = true;
|
result = true;
|
||||||
|
|
@ -37,7 +37,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
Utils.prototype.valueOrEmpty = function(value) {
|
Utils.prototype.valueOrEmpty = function(value) {
|
||||||
return value || '';
|
return value || "";
|
||||||
};
|
};
|
||||||
|
|
||||||
Utils.prototype.safeConfig = function(cfg, defaultConfig) {
|
Utils.prototype.safeConfig = function(cfg, defaultConfig) {
|
||||||
|
|
|
||||||
|
|
@ -1,743 +0,0 @@
|
||||||
var assert = require('assert');
|
|
||||||
|
|
||||||
var DiffParser = require('../src/diff-parser.js').DiffParser;
|
|
||||||
|
|
||||||
describe('DiffParser', function() {
|
|
||||||
describe('generateDiffJson', function() {
|
|
||||||
it('should parse unix with \n diff', function() {
|
|
||||||
var diff =
|
|
||||||
'diff --git a/sample b/sample\n' +
|
|
||||||
'index 0000001..0ddf2ba\n' +
|
|
||||||
'--- a/sample\n' +
|
|
||||||
'+++ b/sample\n' +
|
|
||||||
'@@ -1 +1 @@\n' +
|
|
||||||
'-test\n' +
|
|
||||||
'+test1r\n';
|
|
||||||
checkDiffSample(diff);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should parse windows with \r\n diff', function() {
|
|
||||||
var diff =
|
|
||||||
'diff --git a/sample b/sample\r\n' +
|
|
||||||
'index 0000001..0ddf2ba\r\n' +
|
|
||||||
'--- a/sample\r\n' +
|
|
||||||
'+++ b/sample\r\n' +
|
|
||||||
'@@ -1 +1 @@\r\n' +
|
|
||||||
'-test\r\n' +
|
|
||||||
'+test1r\r\n';
|
|
||||||
checkDiffSample(diff);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should parse old os x with \r diff', function() {
|
|
||||||
var diff =
|
|
||||||
'diff --git a/sample b/sample\r' +
|
|
||||||
'index 0000001..0ddf2ba\r' +
|
|
||||||
'--- a/sample\r' +
|
|
||||||
'+++ b/sample\r' +
|
|
||||||
'@@ -1 +1 @@\r' +
|
|
||||||
'-test\r' +
|
|
||||||
'+test1r\r';
|
|
||||||
checkDiffSample(diff);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should parse mixed eols diff', function() {
|
|
||||||
var diff =
|
|
||||||
'diff --git a/sample b/sample\n' +
|
|
||||||
'index 0000001..0ddf2ba\r\n' +
|
|
||||||
'--- a/sample\r' +
|
|
||||||
'+++ b/sample\r\n' +
|
|
||||||
'@@ -1 +1 @@\n' +
|
|
||||||
'-test\r' +
|
|
||||||
'+test1r\n';
|
|
||||||
checkDiffSample(diff);
|
|
||||||
});
|
|
||||||
|
|
||||||
function checkDiffSample(diff) {
|
|
||||||
var result = DiffParser.generateDiffJson(diff);
|
|
||||||
var file1 = result[0];
|
|
||||||
assert.equal(1, result.length);
|
|
||||||
assert.equal(1, file1.addedLines);
|
|
||||||
assert.equal(1, file1.deletedLines);
|
|
||||||
assert.equal('sample', file1.oldName);
|
|
||||||
assert.equal('sample', file1.newName);
|
|
||||||
assert.equal(1, file1.blocks.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
it('should parse diff with special characters', function() {
|
|
||||||
var diff =
|
|
||||||
'diff --git "a/bla with \ttab.scala" "b/bla with \ttab.scala"\n' +
|
|
||||||
'index 4c679d7..e9bd385 100644\n' +
|
|
||||||
'--- "a/bla with \ttab.scala"\n' +
|
|
||||||
'+++ "b/bla with \ttab.scala"\n' +
|
|
||||||
'@@ -1 +1,2 @@\n' +
|
|
||||||
'-cenas\n' +
|
|
||||||
'+cenas com ananas\n' +
|
|
||||||
'+bananas';
|
|
||||||
|
|
||||||
var result = DiffParser.generateDiffJson(diff);
|
|
||||||
var file1 = result[0];
|
|
||||||
assert.equal(1, result.length);
|
|
||||||
assert.equal(2, file1.addedLines);
|
|
||||||
assert.equal(1, file1.deletedLines);
|
|
||||||
assert.equal('bla with \ttab.scala', file1.oldName);
|
|
||||||
assert.equal('bla with \ttab.scala', file1.newName);
|
|
||||||
assert.equal(1, file1.blocks.length);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should parse diff with prefix', function() {
|
|
||||||
var diff =
|
|
||||||
'diff --git "\tbla with \ttab.scala" "\tbla with \ttab.scala"\n' +
|
|
||||||
'index 4c679d7..e9bd385 100644\n' +
|
|
||||||
'--- "\tbla with \ttab.scala"\n' +
|
|
||||||
'+++ "\tbla with \ttab.scala"\n' +
|
|
||||||
'@@ -1 +1,2 @@\n' +
|
|
||||||
'-cenas\n' +
|
|
||||||
'+cenas com ananas\n' +
|
|
||||||
'+bananas';
|
|
||||||
|
|
||||||
var result = DiffParser.generateDiffJson(diff, {'srcPrefix': '\t', 'dstPrefix': '\t'});
|
|
||||||
var file1 = result[0];
|
|
||||||
assert.equal(1, result.length);
|
|
||||||
assert.equal(2, file1.addedLines);
|
|
||||||
assert.equal(1, file1.deletedLines);
|
|
||||||
assert.equal('bla with \ttab.scala', file1.oldName);
|
|
||||||
assert.equal('bla with \ttab.scala', file1.newName);
|
|
||||||
assert.equal(1, file1.blocks.length);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should parse diff with deleted file', function() {
|
|
||||||
var diff =
|
|
||||||
'diff --git a/src/var/strundefined.js b/src/var/strundefined.js\n' +
|
|
||||||
'deleted file mode 100644\n' +
|
|
||||||
'index 04e16b0..0000000\n' +
|
|
||||||
'--- a/src/var/strundefined.js\n' +
|
|
||||||
'+++ /dev/null\n' +
|
|
||||||
'@@ -1,3 +0,0 @@\n' +
|
|
||||||
'-define(function() {\n' +
|
|
||||||
'- return typeof undefined;\n' +
|
|
||||||
'-});\n';
|
|
||||||
|
|
||||||
var result = DiffParser.generateDiffJson(diff);
|
|
||||||
assert.equal(1, result.length);
|
|
||||||
|
|
||||||
var file1 = result[0];
|
|
||||||
assert.equal(false, file1.isCombined);
|
|
||||||
assert.equal(0, file1.addedLines);
|
|
||||||
assert.equal(3, file1.deletedLines);
|
|
||||||
assert.equal('src/var/strundefined.js', file1.oldName);
|
|
||||||
assert.equal('/dev/null', file1.newName);
|
|
||||||
assert.equal(1, file1.blocks.length);
|
|
||||||
assert.equal(true, file1.isDeleted);
|
|
||||||
assert.equal('04e16b0', file1.checksumBefore);
|
|
||||||
assert.equal('0000000', file1.checksumAfter);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should parse diff with new file', function() {
|
|
||||||
var diff =
|
|
||||||
'diff --git a/test.js b/test.js\n' +
|
|
||||||
'new file mode 100644\n' +
|
|
||||||
'index 0000000..e1e22ec\n' +
|
|
||||||
'--- /dev/null\n' +
|
|
||||||
'+++ b/test.js\n' +
|
|
||||||
'@@ -0,0 +1,5 @@\n' +
|
|
||||||
"+var parser = require('./source/git-parser');\n" +
|
|
||||||
'+\n' +
|
|
||||||
'+var patchLineList = [ false, false, false, false ];\n' +
|
|
||||||
'+\n' +
|
|
||||||
'+console.log(parser.parsePatchDiffResult(text, patchLineList));\n';
|
|
||||||
|
|
||||||
var result = DiffParser.generateDiffJson(diff);
|
|
||||||
assert.equal(1, result.length);
|
|
||||||
|
|
||||||
var file1 = result[0];
|
|
||||||
assert.equal(false, file1.isCombined);
|
|
||||||
assert.equal(5, file1.addedLines);
|
|
||||||
assert.equal(0, file1.deletedLines);
|
|
||||||
assert.equal('/dev/null', file1.oldName);
|
|
||||||
assert.equal('test.js', file1.newName);
|
|
||||||
assert.equal(1, file1.blocks.length);
|
|
||||||
assert.equal(true, file1.isNew);
|
|
||||||
assert.equal(100644, file1.newFileMode);
|
|
||||||
assert.equal('0000000', file1.checksumBefore);
|
|
||||||
assert.equal('e1e22ec', file1.checksumAfter);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should parse diff with nested diff', function() {
|
|
||||||
var diff =
|
|
||||||
'diff --git a/src/offset.js b/src/offset.js\n' +
|
|
||||||
'index cc6ffb4..fa51f18 100644\n' +
|
|
||||||
'--- a/src/offset.js\n' +
|
|
||||||
'+++ b/src/offset.js\n' +
|
|
||||||
'@@ -1,6 +1,5 @@\n' +
|
|
||||||
"+var parser = require('./source/git-parser');\n" +
|
|
||||||
'+\n' +
|
|
||||||
"+var text = 'diff --git a/components/app/app.html b/components/app/app.html\\nindex ecb7a95..027bd9b 100644\\n--- a/components/app/app.html\\n+++ b/components/app/app.html\\n@@ -52,0 +53,3 @@\\n+\\n+\\n+\\n@@ -56,0 +60,3 @@\\n+\\n+\\n+\\n'\n" +
|
|
||||||
'+var patchLineList = [ false, false, false, false ];\n' +
|
|
||||||
'+\n' +
|
|
||||||
'+console.log(parser.parsePatchDiffResult(text, patchLineList));\n';
|
|
||||||
|
|
||||||
var result = DiffParser.generateDiffJson(diff);
|
|
||||||
assert.equal(1, result.length);
|
|
||||||
|
|
||||||
var file1 = result[0];
|
|
||||||
assert.equal(false, file1.isCombined);
|
|
||||||
assert.equal(6, file1.addedLines);
|
|
||||||
assert.equal(0, file1.deletedLines);
|
|
||||||
assert.equal('src/offset.js', file1.oldName);
|
|
||||||
assert.equal('src/offset.js', file1.newName);
|
|
||||||
assert.equal(1, file1.blocks.length);
|
|
||||||
assert.equal(6, file1.blocks[0].lines.length);
|
|
||||||
assert.equal('cc6ffb4', file1.checksumBefore);
|
|
||||||
assert.equal('fa51f18', file1.checksumAfter);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should parse diff with multiple blocks', function() {
|
|
||||||
var diff =
|
|
||||||
'diff --git a/src/attributes/classes.js b/src/attributes/classes.js\n' +
|
|
||||||
'index c617824..c8d1393 100644\n' +
|
|
||||||
'--- a/src/attributes/classes.js\n' +
|
|
||||||
'+++ b/src/attributes/classes.js\n' +
|
|
||||||
'@@ -1,10 +1,9 @@\n' +
|
|
||||||
' define([\n' +
|
|
||||||
' "../core",\n' +
|
|
||||||
' "../var/rnotwhite",\n' +
|
|
||||||
'- "../var/strundefined",\n' +
|
|
||||||
' "../data/var/dataPriv",\n' +
|
|
||||||
' "../core/init"\n' +
|
|
||||||
'-], function( jQuery, rnotwhite, strundefined, dataPriv ) {\n' +
|
|
||||||
'+], function( jQuery, rnotwhite, dataPriv ) {\n' +
|
|
||||||
' \n' +
|
|
||||||
' var rclass = /[\\t\\r\\n\\f]/g;\n' +
|
|
||||||
' \n' +
|
|
||||||
'@@ -128,7 +127,7 @@ jQuery.fn.extend({\n' +
|
|
||||||
' }\n' +
|
|
||||||
' \n' +
|
|
||||||
' // Toggle whole class name\n' +
|
|
||||||
'- } else if ( type === strundefined || type === "boolean" ) {\n' +
|
|
||||||
'+ } else if ( value === undefined || type === "boolean" ) {\n' +
|
|
||||||
' if ( this.className ) {\n' +
|
|
||||||
' // store className if set\n' +
|
|
||||||
' dataPriv.set( this, "__className__", this.className );\n';
|
|
||||||
|
|
||||||
var result = DiffParser.generateDiffJson(diff);
|
|
||||||
assert.equal(1, result.length);
|
|
||||||
|
|
||||||
var file1 = result[0];
|
|
||||||
assert.equal(false, file1.isCombined);
|
|
||||||
assert.equal(2, file1.addedLines);
|
|
||||||
assert.equal(3, file1.deletedLines);
|
|
||||||
assert.equal('src/attributes/classes.js', file1.oldName);
|
|
||||||
assert.equal('src/attributes/classes.js', file1.newName);
|
|
||||||
assert.equal(2, file1.blocks.length);
|
|
||||||
assert.equal(11, file1.blocks[0].lines.length);
|
|
||||||
assert.equal(8, file1.blocks[1].lines.length);
|
|
||||||
assert.equal('c617824', file1.checksumBefore);
|
|
||||||
assert.equal('c8d1393', file1.checksumAfter);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should parse diff with multiple files', function() {
|
|
||||||
var diff =
|
|
||||||
'diff --git a/src/core/init.js b/src/core/init.js\n' +
|
|
||||||
'index e49196a..50f310c 100644\n' +
|
|
||||||
'--- a/src/core/init.js\n' +
|
|
||||||
'+++ b/src/core/init.js\n' +
|
|
||||||
'@@ -101,7 +101,7 @@ var rootjQuery,\n' +
|
|
||||||
' // HANDLE: $(function)\n' +
|
|
||||||
' // Shortcut for document ready\n' +
|
|
||||||
' } else if ( jQuery.isFunction( selector ) ) {\n' +
|
|
||||||
'- return typeof rootjQuery.ready !== "undefined" ?\n' +
|
|
||||||
'+ return rootjQuery.ready !== undefined ?\n' +
|
|
||||||
' rootjQuery.ready( selector ) :\n' +
|
|
||||||
' // Execute immediately if ready is not present\n' +
|
|
||||||
' selector( jQuery );\n' +
|
|
||||||
'diff --git a/src/event.js b/src/event.js\n' +
|
|
||||||
'index 7336f4d..6183f70 100644\n' +
|
|
||||||
'--- a/src/event.js\n' +
|
|
||||||
'+++ b/src/event.js\n' +
|
|
||||||
'@@ -1,6 +1,5 @@\n' +
|
|
||||||
' define([\n' +
|
|
||||||
' "./core",\n' +
|
|
||||||
'- "./var/strundefined",\n' +
|
|
||||||
' "./var/rnotwhite",\n' +
|
|
||||||
' "./var/hasOwn",\n' +
|
|
||||||
' "./var/slice",\n';
|
|
||||||
|
|
||||||
var result = DiffParser.generateDiffJson(diff);
|
|
||||||
assert.equal(2, result.length);
|
|
||||||
|
|
||||||
var file1 = result[0];
|
|
||||||
assert.equal(false, file1.isCombined);
|
|
||||||
assert.equal(1, file1.addedLines);
|
|
||||||
assert.equal(1, file1.deletedLines);
|
|
||||||
assert.equal('src/core/init.js', file1.oldName);
|
|
||||||
assert.equal('src/core/init.js', file1.newName);
|
|
||||||
assert.equal(1, file1.blocks.length);
|
|
||||||
assert.equal(8, file1.blocks[0].lines.length);
|
|
||||||
assert.equal('e49196a', file1.checksumBefore);
|
|
||||||
assert.equal('50f310c', file1.checksumAfter);
|
|
||||||
|
|
||||||
var file2 = result[1];
|
|
||||||
assert.equal(false, file2.isCombined);
|
|
||||||
assert.equal(0, file2.addedLines);
|
|
||||||
assert.equal(1, file2.deletedLines);
|
|
||||||
assert.equal('src/event.js', file2.oldName);
|
|
||||||
assert.equal('src/event.js', file2.newName);
|
|
||||||
assert.equal(1, file2.blocks.length);
|
|
||||||
assert.equal(6, file2.blocks[0].lines.length);
|
|
||||||
assert.equal('7336f4d', file2.checksumBefore);
|
|
||||||
assert.equal('6183f70', file2.checksumAfter);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should parse combined diff', function() {
|
|
||||||
var diff =
|
|
||||||
'diff --combined describe.c\n' +
|
|
||||||
'index fabadb8,cc95eb0..4866510\n' +
|
|
||||||
'--- a/describe.c\n' +
|
|
||||||
'+++ b/describe.c\n' +
|
|
||||||
'@@@ -98,20 -98,12 +98,20 @@@\n' +
|
|
||||||
' return (a_date > b_date) ? -1 : (a_date == b_date) ? 0 : 1;\n' +
|
|
||||||
' }\n' +
|
|
||||||
' \n' +
|
|
||||||
'- static void describe(char *arg)\n' +
|
|
||||||
' -static void describe(struct commit *cmit, int last_one)\n' +
|
|
||||||
'++static void describe(char *arg, int last_one)\n' +
|
|
||||||
' {\n' +
|
|
||||||
' + unsigned char sha1[20];\n' +
|
|
||||||
' + struct commit *cmit;\n' +
|
|
||||||
' struct commit_list *list;\n' +
|
|
||||||
' static int initialized = 0;\n' +
|
|
||||||
' struct commit_name *n;\n' +
|
|
||||||
' \n' +
|
|
||||||
' + if (get_sha1(arg, sha1) < 0)\n' +
|
|
||||||
' + usage(describe_usage);\n' +
|
|
||||||
' + cmit = lookup_commit_reference(sha1);\n' +
|
|
||||||
' + if (!cmit)\n' +
|
|
||||||
' + usage(describe_usage);\n' +
|
|
||||||
' +\n' +
|
|
||||||
' if (!initialized) {\n' +
|
|
||||||
' initialized = 1;\n' +
|
|
||||||
' for_each_ref(get_name);\n';
|
|
||||||
|
|
||||||
var result = DiffParser.generateDiffJson(diff);
|
|
||||||
assert.equal(1, result.length);
|
|
||||||
|
|
||||||
var file1 = result[0];
|
|
||||||
assert.equal(true, file1.isCombined);
|
|
||||||
assert.equal(9, file1.addedLines);
|
|
||||||
assert.equal(2, file1.deletedLines);
|
|
||||||
assert.equal('describe.c', file1.oldName);
|
|
||||||
assert.equal('describe.c', file1.newName);
|
|
||||||
assert.equal(1, file1.blocks.length);
|
|
||||||
assert.equal(22, file1.blocks[0].lines.length);
|
|
||||||
assert.deepEqual(['4866510', 'cc95eb0'].sort(), file1.checksumBefore.sort());
|
|
||||||
assert.equal('fabadb8', file1.checksumAfter);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should parse diffs with copied files', function() {
|
|
||||||
var diff =
|
|
||||||
'diff --git a/index.js b/more-index.js\n' +
|
|
||||||
'dissimilarity index 5%\n' +
|
|
||||||
'copy from index.js\n' +
|
|
||||||
'copy to more-index.js\n';
|
|
||||||
|
|
||||||
var result = DiffParser.generateDiffJson(diff);
|
|
||||||
assert.equal(1, result.length);
|
|
||||||
|
|
||||||
var file1 = result[0];
|
|
||||||
assert.equal(0, file1.addedLines);
|
|
||||||
assert.equal(0, file1.deletedLines);
|
|
||||||
assert.equal('index.js', file1.oldName);
|
|
||||||
assert.equal('more-index.js', file1.newName);
|
|
||||||
assert.equal(0, file1.blocks.length);
|
|
||||||
assert.equal(true, file1.isCopy);
|
|
||||||
assert.equal(5, file1.changedPercentage);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should parse diffs with moved files', function() {
|
|
||||||
var diff =
|
|
||||||
'diff --git a/more-index.js b/other-index.js\n' +
|
|
||||||
'similarity index 86%\n' +
|
|
||||||
'rename from more-index.js\n' +
|
|
||||||
'rename to other-index.js\n';
|
|
||||||
|
|
||||||
var result = DiffParser.generateDiffJson(diff);
|
|
||||||
assert.equal(1, result.length);
|
|
||||||
|
|
||||||
var file1 = result[0];
|
|
||||||
assert.equal(0, file1.addedLines);
|
|
||||||
assert.equal(0, file1.deletedLines);
|
|
||||||
assert.equal('more-index.js', file1.oldName);
|
|
||||||
assert.equal('other-index.js', file1.newName);
|
|
||||||
assert.equal(0, file1.blocks.length);
|
|
||||||
assert.equal(true, file1.isRename);
|
|
||||||
assert.equal(86, file1.unchangedPercentage);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should parse diffs correct line numbers', function() {
|
|
||||||
var diff =
|
|
||||||
'diff --git a/sample b/sample\n' +
|
|
||||||
'index 0000001..0ddf2ba\n' +
|
|
||||||
'--- a/sample\n' +
|
|
||||||
'+++ b/sample\n' +
|
|
||||||
'@@ -1 +1,2 @@\n' +
|
|
||||||
'-test\n' +
|
|
||||||
'+test1r\n';
|
|
||||||
|
|
||||||
var result = DiffParser.generateDiffJson(diff);
|
|
||||||
assert.equal(1, result.length);
|
|
||||||
|
|
||||||
var file1 = result[0];
|
|
||||||
assert.equal(1, file1.addedLines);
|
|
||||||
assert.equal(1, file1.deletedLines);
|
|
||||||
assert.equal('sample', file1.oldName);
|
|
||||||
assert.equal('sample', file1.newName);
|
|
||||||
assert.equal(1, file1.blocks.length);
|
|
||||||
assert.equal(2, file1.blocks[0].lines.length);
|
|
||||||
assert.equal(1, file1.blocks[0].lines[0].oldNumber);
|
|
||||||
assert.equal(null, file1.blocks[0].lines[0].newNumber);
|
|
||||||
assert.equal(null, file1.blocks[0].lines[1].oldNumber);
|
|
||||||
assert.equal(1, file1.blocks[0].lines[1].newNumber);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should parse unified non git diff and strip timestamps off the headers', function() {
|
|
||||||
var diffs = [
|
|
||||||
// 2 hours ahead of GMT
|
|
||||||
'--- a/sample.js 2016-10-25 11:37:14.000000000 +0200\n' +
|
|
||||||
'+++ b/sample.js 2016-10-25 11:37:14.000000000 +0200\n' +
|
|
||||||
'@@ -1 +1,2 @@\n' +
|
|
||||||
'-test\n' +
|
|
||||||
'+test1r\n' +
|
|
||||||
'+test2r\n',
|
|
||||||
// 2 hours behind GMT
|
|
||||||
'--- a/sample.js 2016-10-25 11:37:14.000000000 -0200\n' +
|
|
||||||
'+++ b/sample.js 2016-10-25 11:37:14.000000000 -0200\n' +
|
|
||||||
'@@ -1 +1,2 @@\n' +
|
|
||||||
'-test\n' +
|
|
||||||
'+test1r\n' +
|
|
||||||
'+test2r\n'
|
|
||||||
];
|
|
||||||
|
|
||||||
diffs.forEach(function(diff) {
|
|
||||||
var result = DiffParser.generateDiffJson(diff);
|
|
||||||
var file1 = result[0];
|
|
||||||
assert.equal(1, result.length);
|
|
||||||
assert.equal(2, file1.addedLines);
|
|
||||||
assert.equal(1, file1.deletedLines);
|
|
||||||
assert.equal('sample.js', file1.oldName);
|
|
||||||
assert.equal('sample.js', file1.newName);
|
|
||||||
assert.equal(1, file1.blocks.length);
|
|
||||||
|
|
||||||
var linesContent = file1.blocks[0].lines.map(function(line) {
|
|
||||||
return line.content;
|
|
||||||
});
|
|
||||||
assert.deepEqual(linesContent, ['-test', '+test1r', '+test2r']);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should parse unified non git diff', function() {
|
|
||||||
var diff =
|
|
||||||
'--- a/sample.js\n' +
|
|
||||||
'+++ b/sample.js\n' +
|
|
||||||
'@@ -1 +1,2 @@\n' +
|
|
||||||
'-test\n' +
|
|
||||||
'+test1r\n' +
|
|
||||||
'+test2r\n';
|
|
||||||
|
|
||||||
var result = DiffParser.generateDiffJson(diff);
|
|
||||||
var file1 = result[0];
|
|
||||||
assert.equal(1, result.length);
|
|
||||||
assert.equal(2, file1.addedLines);
|
|
||||||
assert.equal(1, file1.deletedLines);
|
|
||||||
assert.equal('sample.js', file1.oldName);
|
|
||||||
assert.equal('sample.js', file1.newName);
|
|
||||||
assert.equal(1, file1.blocks.length);
|
|
||||||
|
|
||||||
var linesContent = file1.blocks[0].lines.map(function(line) {
|
|
||||||
return line.content;
|
|
||||||
});
|
|
||||||
assert.deepEqual(linesContent, ['-test', '+test1r', '+test2r']);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should parse unified diff with multiple hunks and files', function() {
|
|
||||||
var diff =
|
|
||||||
'--- sample.js\n' +
|
|
||||||
'+++ sample.js\n' +
|
|
||||||
'@@ -1 +1,2 @@\n' +
|
|
||||||
'-test\n' +
|
|
||||||
'@@ -10 +20,2 @@\n' +
|
|
||||||
'+test\n' +
|
|
||||||
'--- sample1.js\n' +
|
|
||||||
'+++ sample1.js\n' +
|
|
||||||
'@@ -1 +1,2 @@\n' +
|
|
||||||
'+test1';
|
|
||||||
|
|
||||||
var result = DiffParser.generateDiffJson(diff);
|
|
||||||
assert.equal(2, result.length);
|
|
||||||
|
|
||||||
var file1 = result[0];
|
|
||||||
assert.equal(1, file1.addedLines);
|
|
||||||
assert.equal(1, file1.deletedLines);
|
|
||||||
assert.equal('sample.js', file1.oldName);
|
|
||||||
assert.equal('sample.js', file1.newName);
|
|
||||||
assert.equal(2, file1.blocks.length);
|
|
||||||
|
|
||||||
var linesContent1 = file1.blocks[0].lines.map(function(line) {
|
|
||||||
return line.content;
|
|
||||||
});
|
|
||||||
assert.deepEqual(linesContent1, ['-test']);
|
|
||||||
|
|
||||||
var linesContent2 = file1.blocks[1].lines.map(function(line) {
|
|
||||||
return line.content;
|
|
||||||
});
|
|
||||||
assert.deepEqual(linesContent2, ['+test']);
|
|
||||||
|
|
||||||
var file2 = result[1];
|
|
||||||
assert.equal(1, file2.addedLines);
|
|
||||||
assert.equal(0, file2.deletedLines);
|
|
||||||
assert.equal('sample1.js', file2.oldName);
|
|
||||||
assert.equal('sample1.js', file2.newName);
|
|
||||||
assert.equal(1, file2.blocks.length);
|
|
||||||
|
|
||||||
var linesContent = file2.blocks[0].lines.map(function(line) {
|
|
||||||
return line.content;
|
|
||||||
});
|
|
||||||
assert.deepEqual(linesContent, ['+test1']);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should parse diff with --- and +++ in the context lines', function() {
|
|
||||||
var diff =
|
|
||||||
'--- sample.js\n' +
|
|
||||||
'+++ sample.js\n' +
|
|
||||||
'@@ -1,8 +1,8 @@\n' +
|
|
||||||
' test\n' +
|
|
||||||
' \n' +
|
|
||||||
'-- 1\n' +
|
|
||||||
'--- 1\n' +
|
|
||||||
'---- 1\n' +
|
|
||||||
' \n' +
|
|
||||||
'++ 2\n' +
|
|
||||||
'+++ 2\n' +
|
|
||||||
'++++ 2';
|
|
||||||
|
|
||||||
var result = DiffParser.generateDiffJson(diff);
|
|
||||||
var file1 = result[0];
|
|
||||||
assert.equal(1, result.length);
|
|
||||||
assert.equal(3, file1.addedLines);
|
|
||||||
assert.equal(3, file1.deletedLines);
|
|
||||||
assert.equal('sample.js', file1.oldName);
|
|
||||||
assert.equal('sample.js', file1.newName);
|
|
||||||
assert.equal(1, file1.blocks.length);
|
|
||||||
|
|
||||||
var linesContent = file1.blocks[0].lines.map(function(line) {
|
|
||||||
return line.content;
|
|
||||||
});
|
|
||||||
assert.deepEqual(linesContent,
|
|
||||||
[' test', ' ', '-- 1', '--- 1', '---- 1', ' ', '++ 2', '+++ 2', '++++ 2']);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should parse diff without proper hunk headers', function() {
|
|
||||||
var diff =
|
|
||||||
'--- sample.js\n' +
|
|
||||||
'+++ sample.js\n' +
|
|
||||||
'@@ @@\n' +
|
|
||||||
' test';
|
|
||||||
|
|
||||||
var result = DiffParser.generateDiffJson(diff);
|
|
||||||
var file1 = result[0];
|
|
||||||
assert.equal(1, result.length);
|
|
||||||
assert.equal(0, file1.addedLines);
|
|
||||||
assert.equal(0, file1.deletedLines);
|
|
||||||
assert.equal('sample.js', file1.oldName);
|
|
||||||
assert.equal('sample.js', file1.newName);
|
|
||||||
assert.equal(1, file1.blocks.length);
|
|
||||||
|
|
||||||
var linesContent = file1.blocks[0].lines.map(function(line) {
|
|
||||||
return line.content;
|
|
||||||
});
|
|
||||||
assert.deepEqual(linesContent, [' test']);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should parse binary file diff', function() {
|
|
||||||
var diff =
|
|
||||||
'diff --git a/last-changes-config.png b/last-changes-config.png\n' +
|
|
||||||
'index 322248b..56fc1f2 100644\n' +
|
|
||||||
'--- a/last-changes-config.png\n' +
|
|
||||||
'+++ b/last-changes-config.png\n' +
|
|
||||||
'Binary files differ';
|
|
||||||
|
|
||||||
var result = DiffParser.generateDiffJson(diff);
|
|
||||||
var file1 = result[0];
|
|
||||||
assert.equal(1, result.length);
|
|
||||||
assert.equal(0, file1.addedLines);
|
|
||||||
assert.equal(0, file1.deletedLines);
|
|
||||||
assert.equal('last-changes-config.png', file1.oldName);
|
|
||||||
assert.equal('last-changes-config.png', file1.newName);
|
|
||||||
assert.equal(1, file1.blocks.length);
|
|
||||||
assert.equal(0, file1.blocks[0].lines.length);
|
|
||||||
assert.equal('Binary files differ', file1.blocks[0].header);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should parse diff with --find-renames', function() {
|
|
||||||
var diff =
|
|
||||||
'diff --git a/src/test-bar.js b/src/test-baz.js\n' +
|
|
||||||
'similarity index 98%\n' +
|
|
||||||
'rename from src/test-bar.js\n' +
|
|
||||||
'rename to src/test-baz.js\n' +
|
|
||||||
'index e01513b..f14a870 100644\n' +
|
|
||||||
'--- a/src/test-bar.js\n' +
|
|
||||||
'+++ b/src/test-baz.js\n' +
|
|
||||||
'@@ -1,4 +1,32 @@\n' +
|
|
||||||
' function foo() {\n' +
|
|
||||||
'-var bar = "Whoops!";\n' +
|
|
||||||
'+var baz = "Whoops!";\n' +
|
|
||||||
' }\n' +
|
|
||||||
' ';
|
|
||||||
|
|
||||||
var result = DiffParser.generateDiffJson(diff);
|
|
||||||
var file1 = result[0];
|
|
||||||
assert.equal(1, result.length);
|
|
||||||
assert.equal(1, file1.addedLines);
|
|
||||||
assert.equal(1, file1.deletedLines);
|
|
||||||
assert.equal('src/test-bar.js', file1.oldName);
|
|
||||||
assert.equal('src/test-baz.js', file1.newName);
|
|
||||||
assert.equal(1, file1.blocks.length);
|
|
||||||
assert.equal(5, file1.blocks[0].lines.length);
|
|
||||||
var linesContent = file1.blocks[0].lines.map(function(line) {
|
|
||||||
return line.content;
|
|
||||||
});
|
|
||||||
assert.deepEqual(linesContent,
|
|
||||||
[' function foo() {', '-var bar = "Whoops!";', '+var baz = "Whoops!";', ' }', ' ']);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should parse diff with prefix', function() {
|
|
||||||
var diff =
|
|
||||||
'diff --git "\tTest.scala" "\tScalaTest.scala"\n' +
|
|
||||||
'similarity index 88%\n' +
|
|
||||||
'rename from Test.scala\n' +
|
|
||||||
'rename to ScalaTest.scala\n' +
|
|
||||||
'index 7d1f9bf..8b13271 100644\n' +
|
|
||||||
'--- "\tTest.scala"\n' +
|
|
||||||
'+++ "\tScalaTest.scala"\n' +
|
|
||||||
'@@ -1,6 +1,8 @@\n' +
|
|
||||||
' class Test {\n' +
|
|
||||||
' \n' +
|
|
||||||
' def method1 = ???\n' +
|
|
||||||
'+\n' +
|
|
||||||
'+ def method2 = ???\n' +
|
|
||||||
' \n' +
|
|
||||||
' def myMethod = ???\n' +
|
|
||||||
' \n' +
|
|
||||||
'@@ -10,7 +12,6 @@ class Test {\n' +
|
|
||||||
' \n' +
|
|
||||||
' def + = ???\n' +
|
|
||||||
' \n' +
|
|
||||||
'- def |> = ???\n' +
|
|
||||||
' \n' +
|
|
||||||
' }\n' +
|
|
||||||
' \n' +
|
|
||||||
'diff --git "\ttardis.png" "\ttardis.png"\n' +
|
|
||||||
'new file mode 100644\n' +
|
|
||||||
'index 0000000..d503a29\n' +
|
|
||||||
'Binary files /dev/null and "\ttardis.png" differ\n' +
|
|
||||||
'diff --git a/src/test-bar.js b/src/test-baz.js\n' +
|
|
||||||
'similarity index 98%\n' +
|
|
||||||
'rename from src/test-bar.js\n' +
|
|
||||||
'rename to src/test-baz.js\n' +
|
|
||||||
'index e01513b..f14a870 100644\n' +
|
|
||||||
'--- a/src/test-bar.js\n' +
|
|
||||||
'+++ b/src/test-baz.js\n' +
|
|
||||||
'@@ -1,4 +1,32 @@\n' +
|
|
||||||
' function foo() {\n' +
|
|
||||||
'-var bar = "Whoops!";\n' +
|
|
||||||
'+var baz = "Whoops!";\n' +
|
|
||||||
' }\n' +
|
|
||||||
' ';
|
|
||||||
|
|
||||||
var result = DiffParser.generateDiffJson(diff, {'srcPrefix': '\t', 'dstPrefix': '\t'});
|
|
||||||
assert.equal(3, result.length);
|
|
||||||
|
|
||||||
var file1 = result[0];
|
|
||||||
assert.equal(2, file1.addedLines);
|
|
||||||
assert.equal(1, file1.deletedLines);
|
|
||||||
assert.equal('Test.scala', file1.oldName);
|
|
||||||
assert.equal('ScalaTest.scala', file1.newName);
|
|
||||||
assert.equal(2, file1.blocks.length);
|
|
||||||
assert.equal(8, file1.blocks[0].lines.length);
|
|
||||||
assert.equal(7, file1.blocks[1].lines.length);
|
|
||||||
|
|
||||||
var file2 = result[1];
|
|
||||||
assert.equal('/dev/null', file2.oldName);
|
|
||||||
assert.equal('tardis.png', file2.newName);
|
|
||||||
|
|
||||||
var file3 = result[2];
|
|
||||||
assert.equal(1, file3.addedLines);
|
|
||||||
assert.equal(1, file3.deletedLines);
|
|
||||||
assert.equal('src/test-bar.js', file3.oldName);
|
|
||||||
assert.equal('src/test-baz.js', file3.newName);
|
|
||||||
assert.equal(1, file3.blocks.length);
|
|
||||||
assert.equal(5, file3.blocks[0].lines.length);
|
|
||||||
var linesContent = file3.blocks[0].lines.map(function(line) {
|
|
||||||
return line.content;
|
|
||||||
});
|
|
||||||
assert.deepEqual(linesContent,
|
|
||||||
[' function foo() {', '-var bar = "Whoops!";', '+var baz = "Whoops!";', ' }', ' ']);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should parse binary with content', function() {
|
|
||||||
var diff =
|
|
||||||
'diff --git a/favicon.png b/favicon.png\n' +
|
|
||||||
'deleted file mode 100644\n' +
|
|
||||||
'index 2a9d516a5647205d7be510dd0dff93a3663eff6f..0000000000000000000000000000000000000000\n' +
|
|
||||||
'GIT binary patch\n' +
|
|
||||||
'literal 0\n' +
|
|
||||||
'HcmV?d00001\n' +
|
|
||||||
'\n' +
|
|
||||||
'literal 471\n' +
|
|
||||||
'zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf<Z~8yL>4nJ\n' +
|
|
||||||
'za0`Jj<E6WGe}IBwC9V-A&PAz-C7Jno3L%-fsSJk3`UaNzMkcGzh!g=;$beJ?=ckpF\n' +
|
|
||||||
'zCl;kLIHu$$r7E~(7NwTw7iAYKI0u`(*t4mJfq_xq)5S5wqIc=!hrWj$cv|<b{x!c(\n' +
|
|
||||||
'z;3r#y;31Y&=1q>qPVOAS4ANVKzqmCp=Cty@U^(7zk!jHsvT~YI{F^=Ex6g|gox78w\n' +
|
|
||||||
'z+Sn2Du3GS9U7qU`1*NYYlJi3u-!<?H-eky}wyIIL;8VU@wCDrb0``&v(jQ*DWSR4K\n' +
|
|
||||||
'zPq(3;isEyho{emNa=%%!jDPE`l3u;5d=q=<+v8kO-=C`*G#t-*AiE-D>-_B#8k9H0\n' +
|
|
||||||
'zGl{FnZs<2$wz5^=Q2h-1XI^s{LQL1#T4epqNPC%Orl(tD_@!*EY++~^Lt2<2&!&%=\n' +
|
|
||||||
'z`m>(TYj6uS7jDdt=eH>iOyQg(QMR<-Fw8)Dk^ZG)XQTuzEgl{`GpS?Cfq9818R9~=\n' +
|
|
||||||
'z{&h9@9n8F^?|qusoPy{k#%tVHzu7H$t26CR`BJZk*Ixf&u36WuS=?6m2^ho-p00i_\n' +
|
|
||||||
'I>zopr0Nz-&lmGw#\n' +
|
|
||||||
'diff --git a/src/test-bar.js b/src/test-baz.js\n' +
|
|
||||||
'similarity index 98%\n' +
|
|
||||||
'rename from src/test-bar.js\n' +
|
|
||||||
'rename to src/test-baz.js\n' +
|
|
||||||
'index e01513b..f14a870 100644\n' +
|
|
||||||
'--- a/src/test-bar.js\n' +
|
|
||||||
'+++ b/src/test-baz.js\n' +
|
|
||||||
'@@ -1,4 +1,32 @@\n' +
|
|
||||||
' function foo() {\n' +
|
|
||||||
'-var bar = "Whoops!";\n' +
|
|
||||||
'+var baz = "Whoops!";\n' +
|
|
||||||
' }\n' +
|
|
||||||
' ';
|
|
||||||
|
|
||||||
var result = DiffParser.generateDiffJson(diff);
|
|
||||||
assert.equal(2, result.length);
|
|
||||||
|
|
||||||
var file1 = result[0];
|
|
||||||
assert.equal('favicon.png', file1.oldName);
|
|
||||||
assert.equal('favicon.png', file1.newName);
|
|
||||||
assert.equal(1, file1.blocks.length);
|
|
||||||
assert.equal(0, file1.blocks[0].lines.length);
|
|
||||||
|
|
||||||
var file2 = result[1];
|
|
||||||
assert.equal(1, file2.addedLines);
|
|
||||||
assert.equal(1, file2.deletedLines);
|
|
||||||
assert.equal('src/test-bar.js', file2.oldName);
|
|
||||||
assert.equal('src/test-baz.js', file2.newName);
|
|
||||||
assert.equal(1, file2.blocks.length);
|
|
||||||
assert.equal(5, file2.blocks[0].lines.length);
|
|
||||||
var linesContent = file2.blocks[0].lines.map(function(line) {
|
|
||||||
return line.content;
|
|
||||||
});
|
|
||||||
assert.deepEqual(linesContent,
|
|
||||||
[' function foo() {', '-var bar = "Whoops!";', '+var baz = "Whoops!";', ' }', ' ']);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,70 +0,0 @@
|
||||||
var assert = require('assert');
|
|
||||||
|
|
||||||
var HoganJsUtils = new (require('../src/hoganjs-utils.js').HoganJsUtils)();
|
|
||||||
var diffParser = require('../src/diff-parser.js').DiffParser;
|
|
||||||
|
|
||||||
describe('HoganJsUtils', function() {
|
|
||||||
describe('render', function() {
|
|
||||||
var emptyDiffHtml =
|
|
||||||
'<tr>\n' +
|
|
||||||
' <td class="d2h-info">\n' +
|
|
||||||
' <div class="d2h-code-line d2h-info">\n' +
|
|
||||||
' File without changes\n' +
|
|
||||||
' </div>\n' +
|
|
||||||
' </td>\n' +
|
|
||||||
'</tr>';
|
|
||||||
|
|
||||||
it('should render view', function() {
|
|
||||||
var result = HoganJsUtils.render('generic', 'empty-diff', {
|
|
||||||
contentClass: 'd2h-code-line',
|
|
||||||
diffParser: diffParser
|
|
||||||
});
|
|
||||||
assert.equal(emptyDiffHtml, result);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render view without cache', function() {
|
|
||||||
var result = HoganJsUtils.render('generic', 'empty-diff', {
|
|
||||||
contentClass: 'd2h-code-line',
|
|
||||||
diffParser: diffParser
|
|
||||||
}, {noCache: true});
|
|
||||||
assert.equal(emptyDiffHtml, result);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return null if template is missing', function() {
|
|
||||||
var hoganUtils = new (require('../src/hoganjs-utils.js').HoganJsUtils)({noCache: true});
|
|
||||||
var result = hoganUtils.render('generic', 'missing-template', {});
|
|
||||||
assert.equal(null, result);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should allow templates to be overridden with compiled templates', function() {
|
|
||||||
var emptyDiffTemplate = HoganJsUtils.compile('<p>{{myName}}</p>');
|
|
||||||
|
|
||||||
var config = {templates: {'generic-empty-diff': emptyDiffTemplate}};
|
|
||||||
var hoganUtils = new (require('../src/hoganjs-utils.js').HoganJsUtils)(config);
|
|
||||||
var result = hoganUtils.render('generic', 'empty-diff', {myName: 'Rodrigo Fernandes'});
|
|
||||||
assert.equal('<p>Rodrigo Fernandes</p>', result);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should allow templates to be overridden with uncompiled templates', function() {
|
|
||||||
var emptyDiffTemplate = '<p>{{myName}}</p>';
|
|
||||||
|
|
||||||
var config = {rawTemplates: {'generic-empty-diff': emptyDiffTemplate}};
|
|
||||||
var hoganUtils = new (require('../src/hoganjs-utils.js').HoganJsUtils)(config);
|
|
||||||
var result = hoganUtils.render('generic', 'empty-diff', {myName: 'Rodrigo Fernandes'});
|
|
||||||
assert.equal('<p>Rodrigo Fernandes</p>', result);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should allow templates to be overridden giving priority to compiled templates', function() {
|
|
||||||
var emptyDiffTemplate = HoganJsUtils.compile('<p>{{myName}}</p>');
|
|
||||||
var emptyDiffTemplateUncompiled = '<p>Not used!</p>';
|
|
||||||
|
|
||||||
var config = {
|
|
||||||
templates: {'generic-empty-diff': emptyDiffTemplate},
|
|
||||||
rawTemplates: {'generic-empty-diff': emptyDiffTemplateUncompiled}
|
|
||||||
};
|
|
||||||
var hoganUtils = new (require('../src/hoganjs-utils.js').HoganJsUtils)(config);
|
|
||||||
var result = hoganUtils.render('generic', 'empty-diff', {myName: 'Rodrigo Fernandes'});
|
|
||||||
assert.equal('<p>Rodrigo Fernandes</p>', result);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,140 +0,0 @@
|
||||||
var assert = require('assert');
|
|
||||||
|
|
||||||
var PrinterUtils = require('../src/printer-utils.js').PrinterUtils;
|
|
||||||
|
|
||||||
describe('Utils', function() {
|
|
||||||
describe('getHtmlId', function() {
|
|
||||||
it('should generate file unique id', function() {
|
|
||||||
var result = PrinterUtils.getHtmlId({
|
|
||||||
oldName: 'sample.js',
|
|
||||||
newName: 'sample.js'
|
|
||||||
});
|
|
||||||
assert.equal('d2h-960013', result);
|
|
||||||
});
|
|
||||||
it('should generate file unique id for empty hashes', function() {
|
|
||||||
var result = PrinterUtils.getHtmlId({
|
|
||||||
oldName: 'sample.js',
|
|
||||||
newName: 'sample.js'
|
|
||||||
});
|
|
||||||
assert.equal('d2h-960013', result);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getDiffName', function() {
|
|
||||||
it('should generate the file name for a changed file', function() {
|
|
||||||
var result = PrinterUtils.getDiffName({
|
|
||||||
oldName: 'sample.js',
|
|
||||||
newName: 'sample.js'
|
|
||||||
});
|
|
||||||
assert.equal('sample.js', result);
|
|
||||||
});
|
|
||||||
it('should generate the file name for a changed file and full rename', function() {
|
|
||||||
var result = PrinterUtils.getDiffName({
|
|
||||||
oldName: 'sample1.js',
|
|
||||||
newName: 'sample2.js'
|
|
||||||
});
|
|
||||||
assert.equal('sample1.js → sample2.js', result);
|
|
||||||
});
|
|
||||||
it('should generate the file name for a changed file and prefix rename', function() {
|
|
||||||
var result = PrinterUtils.getDiffName({
|
|
||||||
oldName: 'src/path/sample.js',
|
|
||||||
newName: 'source/path/sample.js'
|
|
||||||
});
|
|
||||||
assert.equal('{src → source}/path/sample.js', result);
|
|
||||||
});
|
|
||||||
it('should generate the file name for a changed file and suffix rename', function() {
|
|
||||||
var result = PrinterUtils.getDiffName({
|
|
||||||
oldName: 'src/path/sample1.js',
|
|
||||||
newName: 'src/path/sample2.js'
|
|
||||||
});
|
|
||||||
assert.equal('src/path/{sample1.js → sample2.js}', result);
|
|
||||||
});
|
|
||||||
it('should generate the file name for a changed file and middle rename', function() {
|
|
||||||
var result = PrinterUtils.getDiffName({
|
|
||||||
oldName: 'src/really/big/path/sample.js',
|
|
||||||
newName: 'src/small/path/sample.js'
|
|
||||||
});
|
|
||||||
assert.equal('src/{really/big → small}/path/sample.js', result);
|
|
||||||
});
|
|
||||||
it('should generate the file name for a deleted file', function() {
|
|
||||||
var result = PrinterUtils.getDiffName({
|
|
||||||
oldName: 'src/my/file.js',
|
|
||||||
newName: '/dev/null'
|
|
||||||
});
|
|
||||||
assert.equal('src/my/file.js', result);
|
|
||||||
});
|
|
||||||
it('should generate the file name for a new file', function() {
|
|
||||||
var result = PrinterUtils.getDiffName({
|
|
||||||
oldName: '/dev/null',
|
|
||||||
newName: 'src/my/file.js'
|
|
||||||
});
|
|
||||||
assert.equal('src/my/file.js', result);
|
|
||||||
});
|
|
||||||
it('should generate handle undefined filename', function() {
|
|
||||||
var result = PrinterUtils.getDiffName({});
|
|
||||||
assert.equal('unknown/file/path', result);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('diffHighlight', function() {
|
|
||||||
it('should highlight two lines', function() {
|
|
||||||
var result = PrinterUtils.diffHighlight(
|
|
||||||
'-var myVar = 2;',
|
|
||||||
'+var myVariable = 3;',
|
|
||||||
{matching: 'words'}
|
|
||||||
);
|
|
||||||
|
|
||||||
assert.deepEqual({
|
|
||||||
first: {
|
|
||||||
prefix: '-',
|
|
||||||
line: 'var <del>myVar</del> = <del>2</del>;'
|
|
||||||
},
|
|
||||||
second: {
|
|
||||||
prefix: '+',
|
|
||||||
line: 'var <ins>myVariable</ins> = <ins>3</ins>;'
|
|
||||||
}
|
|
||||||
}, result);
|
|
||||||
});
|
|
||||||
it('should highlight two lines char by char', function() {
|
|
||||||
var result = PrinterUtils.diffHighlight(
|
|
||||||
'-var myVar = 2;',
|
|
||||||
'+var myVariable = 3;',
|
|
||||||
{ diffStyle: 'char' }
|
|
||||||
);
|
|
||||||
|
|
||||||
assert.deepEqual({
|
|
||||||
first: {
|
|
||||||
prefix: '-',
|
|
||||||
line: 'var myVar = <del>2</del>;'
|
|
||||||
},
|
|
||||||
second: {
|
|
||||||
prefix: '+',
|
|
||||||
line: 'var myVar<ins>iable</ins> = <ins>3</ins>;'
|
|
||||||
}
|
|
||||||
}, result);
|
|
||||||
});
|
|
||||||
it('should highlight combined diff lines', function() {
|
|
||||||
var result = PrinterUtils.diffHighlight(
|
|
||||||
' -var myVar = 2;',
|
|
||||||
' +var myVariable = 3;',
|
|
||||||
{
|
|
||||||
diffStyle: 'word',
|
|
||||||
isCombined: true,
|
|
||||||
matching: 'words',
|
|
||||||
matchWordsThreshold: 1.00
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
assert.deepEqual({
|
|
||||||
first: {
|
|
||||||
prefix: ' -',
|
|
||||||
line: 'var <del class="d2h-change">myVar</del> = <del class="d2h-change">2</del>;'
|
|
||||||
},
|
|
||||||
second: {
|
|
||||||
prefix: ' +',
|
|
||||||
line: 'var <ins class="d2h-change">myVariable</ins> = <ins class="d2h-change">3</ins>;'
|
|
||||||
}
|
|
||||||
}, result);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
var assert = require('assert');
|
|
||||||
|
|
||||||
var Utils = require('../src/utils.js').Utils;
|
|
||||||
|
|
||||||
describe('Utils', function() {
|
|
||||||
describe('escape', function() {
|
|
||||||
it('should escape & with &', function() {
|
|
||||||
var result = Utils.escape('&');
|
|
||||||
assert.equal('&', result);
|
|
||||||
});
|
|
||||||
it('should escape < with <', function() {
|
|
||||||
var result = Utils.escape('<');
|
|
||||||
assert.equal('<', result);
|
|
||||||
});
|
|
||||||
it('should escape > with >', function() {
|
|
||||||
var result = Utils.escape('>');
|
|
||||||
assert.equal('>', result);
|
|
||||||
});
|
|
||||||
it('should escape a string with multiple problematic characters', function() {
|
|
||||||
var result = Utils.escape('<a href="#">\tlink text</a>');
|
|
||||||
var expected = '<a href="#">\tlink text</a>';
|
|
||||||
assert.equal(expected, result);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
28
tsconfig.json
Normal file
28
tsconfig.json
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "./build/commonjs-node",
|
||||||
|
"target": "es5",
|
||||||
|
"module": "commonjs",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
// TODO: Change to true after migration to TS is complete
|
||||||
|
"allowJs": true,
|
||||||
|
"declaration": false,
|
||||||
|
"declarationMap": false,
|
||||||
|
/////////////////////////////////////////////////////////
|
||||||
|
"strictNullChecks": true,
|
||||||
|
"removeComments": true,
|
||||||
|
"preserveConstEnums": true,
|
||||||
|
"sourceMap": true,
|
||||||
|
"alwaysStrict": true,
|
||||||
|
"strict": true,
|
||||||
|
"noImplicitAny": true,
|
||||||
|
"noImplicitThis": true,
|
||||||
|
"noUnusedParameters": true,
|
||||||
|
"noUnusedLocals": true,
|
||||||
|
"noImplicitReturns": true,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"forceConsistentCasingInFileNames": true
|
||||||
|
},
|
||||||
|
"include": ["./src/**/*"],
|
||||||
|
"exclude": ["node_modules", "./src/__tests__/*"]
|
||||||
|
}
|
||||||
|
|
@ -15,20 +15,20 @@
|
||||||
|
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
// Improves browser compatibility
|
// Improves browser compatibility
|
||||||
require('whatwg-fetch');
|
require("whatwg-fetch");
|
||||||
|
|
||||||
var searchParam = 'diff';
|
const searchParam = "diff";
|
||||||
|
|
||||||
var $container = $('.container');
|
const $container = $(".container");
|
||||||
var $url = $('#url');
|
const $url = $("#url");
|
||||||
var $outputFormat = $('#diff-url-options-output-format');
|
const $outputFormat = $("#diff-url-options-output-format");
|
||||||
var $showFiles = $('#diff-url-options-show-files');
|
const $showFiles = $("#diff-url-options-show-files");
|
||||||
var $matching = $('#diff-url-options-matching');
|
const $matching = $("#diff-url-options-matching");
|
||||||
var $wordsThreshold = $('#diff-url-options-match-words-threshold');
|
const $wordsThreshold = $("#diff-url-options-match-words-threshold");
|
||||||
var $matchingMaxComparisons = $('#diff-url-options-matching-max-comparisons');
|
const $matchingMaxComparisons = $("#diff-url-options-matching-max-comparisons");
|
||||||
|
|
||||||
if (window.location.search) {
|
if (window.location.search) {
|
||||||
var url = getUrlFromSearch(window.location.search);
|
const url = getUrlFromSearch(window.location.search);
|
||||||
$url.val(url);
|
$url.val(url);
|
||||||
smartDraw(url);
|
smartDraw(url);
|
||||||
}
|
}
|
||||||
|
|
@ -41,99 +41,99 @@ $(document).ready(function() {
|
||||||
.add($wordsThreshold)
|
.add($wordsThreshold)
|
||||||
.add($matchingMaxComparisons)
|
.add($matchingMaxComparisons)
|
||||||
.change(function(e) {
|
.change(function(e) {
|
||||||
console.log('');
|
console.log("");
|
||||||
console.log(e);
|
console.log(e);
|
||||||
console.log('');
|
console.log("");
|
||||||
smartDraw(null, true);
|
smartDraw(null, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
function getUrlFromSearch(search) {
|
function getUrlFromSearch(search) {
|
||||||
try {
|
try {
|
||||||
return search
|
return search
|
||||||
.split('?')[1]
|
.split("?")[1]
|
||||||
.split(searchParam + '=')[1]
|
.split(searchParam + "=")[1]
|
||||||
.split('&')[0];
|
.split("&")[0];
|
||||||
} catch (_ignore) {
|
} catch (_ignore) {}
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getParamsFromSearch(search) {
|
function getParamsFromSearch(search) {
|
||||||
var map = {};
|
const map = {};
|
||||||
try {
|
try {
|
||||||
search
|
search
|
||||||
.split('?')[1]
|
.split("?")[1]
|
||||||
.split('&')
|
.split("&")
|
||||||
.map(function(e) {
|
.map(function(e) {
|
||||||
var values = e.split('=');
|
const values = e.split("=");
|
||||||
map[values[0]] = values[1];
|
map[values[0]] = values[1];
|
||||||
});
|
});
|
||||||
} catch (_ignore) {
|
} catch (_ignore) {}
|
||||||
}
|
|
||||||
|
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
function bind() {
|
function bind() {
|
||||||
$('#url-btn').click(function(e) {
|
$("#url-btn").click(function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
var url = $url.val();
|
const url = $url.val();
|
||||||
smartDraw(url);
|
smartDraw(url);
|
||||||
});
|
});
|
||||||
|
|
||||||
$url.on('paste', function(e) {
|
$url.on("paste", function(e) {
|
||||||
var url = e.originalEvent.clipboardData.getData('Text');
|
const url = e.originalEvent.clipboardData.getData("Text");
|
||||||
smartDraw(url);
|
smartDraw(url);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function prepareUrl(url) {
|
function prepareUrl(url) {
|
||||||
var fetchUrl;
|
let fetchUrl;
|
||||||
var headers = new Headers();
|
const headers = new Headers();
|
||||||
|
|
||||||
var githubCommitUrl = /^https?:\/\/(?:www\.)?github\.com\/(.*?)\/(.*?)\/commit\/(.*?)(?:\.diff)?(?:\.patch)?(?:\/.*)?$/;
|
const githubCommitUrl = /^https?:\/\/(?:www\.)?github\.com\/(.*?)\/(.*?)\/commit\/(.*?)(?:\.diff)?(?:\.patch)?(?:\/.*)?$/;
|
||||||
var githubPrUrl = /^https?:\/\/(?:www\.)?github\.com\/(.*?)\/(.*?)\/pull\/(.*?)(?:\.diff)?(?:\.patch)?(?:\/.*)?$/;
|
const githubPrUrl = /^https?:\/\/(?:www\.)?github\.com\/(.*?)\/(.*?)\/pull\/(.*?)(?:\.diff)?(?:\.patch)?(?:\/.*)?$/;
|
||||||
|
|
||||||
var gitlabCommitUrl = /^https?:\/\/(?:www\.)?gitlab\.com\/(.*?)\/(.*?)\/commit\/(.*?)(?:\.diff)?(?:\.patch)?(?:\/.*)?$/;
|
const gitlabCommitUrl = /^https?:\/\/(?:www\.)?gitlab\.com\/(.*?)\/(.*?)\/commit\/(.*?)(?:\.diff)?(?:\.patch)?(?:\/.*)?$/;
|
||||||
var gitlabPrUrl = /^https?:\/\/(?:www\.)?gitlab\.com\/(.*?)\/(.*?)\/merge_requests\/(.*?)(?:\.diff)?(?:\.patch)?(?:\/.*)?$/;
|
const gitlabPrUrl = /^https?:\/\/(?:www\.)?gitlab\.com\/(.*?)\/(.*?)\/merge_requests\/(.*?)(?:\.diff)?(?:\.patch)?(?:\/.*)?$/;
|
||||||
|
|
||||||
var bitbucketCommitUrl = /^https?:\/\/(?:www\.)?bitbucket\.org\/(.*?)\/(.*?)\/commits\/(.*?)(?:\/raw)?(?:\/.*)?$/;
|
const bitbucketCommitUrl = /^https?:\/\/(?:www\.)?bitbucket\.org\/(.*?)\/(.*?)\/commits\/(.*?)(?:\/raw)?(?:\/.*)?$/;
|
||||||
var bitbucketPrUrl = /^https?:\/\/(?:www\.)?bitbucket\.org\/(.*?)\/(.*?)\/pull-requests\/(.*?)(?:\/.*)?$/;
|
const bitbucketPrUrl = /^https?:\/\/(?:www\.)?bitbucket\.org\/(.*?)\/(.*?)\/pull-requests\/(.*?)(?:\/.*)?$/;
|
||||||
|
|
||||||
function gitLabUrlGen(userName, projectName, type, value) {
|
function gitLabUrlGen(userName, projectName, type, value) {
|
||||||
return 'https://crossorigin.me/https://gitlab.com/' + userName + '/' + projectName + '/' + type + '/' + value + '.diff';
|
return (
|
||||||
|
"https://crossorigin.me/https://gitlab.com/" + userName + "/" + projectName + "/" + type + "/" + value + ".diff"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function gitHubUrlGen(userName, projectName, type, value) {
|
function gitHubUrlGen(userName, projectName, type, value) {
|
||||||
headers.append('Accept', 'application/vnd.github.v3.diff');
|
headers.append("Accept", "application/vnd.github.v3.diff");
|
||||||
return 'https://api.github.com/repos/' + userName + '/' + projectName + '/' + type + '/' + value;
|
return "https://api.github.com/repos/" + userName + "/" + projectName + "/" + type + "/" + value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function bitbucketUrlGen(userName, projectName, type, value) {
|
function bitbucketUrlGen(userName, projectName, type, value) {
|
||||||
var baseUrl = 'https://bitbucket.org/api/2.0/repositories/';
|
const baseUrl = "https://bitbucket.org/api/2.0/repositories/";
|
||||||
if (type === 'pullrequests') {
|
if (type === "pullrequests") {
|
||||||
return baseUrl + userName + '/' + projectName + '/pullrequests/' + value + '/diff';
|
return baseUrl + userName + "/" + projectName + "/pullrequests/" + value + "/diff";
|
||||||
}
|
}
|
||||||
return baseUrl + userName + '/' + projectName + '/diff/' + value;
|
return baseUrl + userName + "/" + projectName + "/diff/" + value;
|
||||||
}
|
}
|
||||||
|
|
||||||
var values;
|
let values;
|
||||||
if ((values = githubCommitUrl.exec(url))) {
|
if ((values = githubCommitUrl.exec(url))) {
|
||||||
fetchUrl = gitHubUrlGen(values[1], values[2], 'commits', values[3]);
|
fetchUrl = gitHubUrlGen(values[1], values[2], "commits", values[3]);
|
||||||
} else if ((values = githubPrUrl.exec(url))) {
|
} else if ((values = githubPrUrl.exec(url))) {
|
||||||
fetchUrl = gitHubUrlGen(values[1], values[2], 'pulls', values[3]);
|
fetchUrl = gitHubUrlGen(values[1], values[2], "pulls", values[3]);
|
||||||
} else if ((values = gitlabCommitUrl.exec(url))) {
|
} else if ((values = gitlabCommitUrl.exec(url))) {
|
||||||
fetchUrl = gitLabUrlGen(values[1], values[2], 'commit', values[3]);
|
fetchUrl = gitLabUrlGen(values[1], values[2], "commit", values[3]);
|
||||||
} else if ((values = gitlabPrUrl.exec(url))) {
|
} else if ((values = gitlabPrUrl.exec(url))) {
|
||||||
fetchUrl = gitLabUrlGen(values[1], values[2], 'merge_requests', values[3]);
|
fetchUrl = gitLabUrlGen(values[1], values[2], "merge_requests", values[3]);
|
||||||
} else if ((values = bitbucketCommitUrl.exec(url))) {
|
} else if ((values = bitbucketCommitUrl.exec(url))) {
|
||||||
fetchUrl = bitbucketUrlGen(values[1], values[2], 'commit', values[3]);
|
fetchUrl = bitbucketUrlGen(values[1], values[2], "commit", values[3]);
|
||||||
} else if ((values = bitbucketPrUrl.exec(url))) {
|
} else if ((values = bitbucketPrUrl.exec(url))) {
|
||||||
fetchUrl = bitbucketUrlGen(values[1], values[2], 'pullrequests', values[3]);
|
fetchUrl = bitbucketUrlGen(values[1], values[2], "pullrequests", values[3]);
|
||||||
} else {
|
} else {
|
||||||
console.info('Could not parse url, using the provided url.');
|
console.info("Could not parse url, using the provided url.");
|
||||||
fetchUrl = 'https://crossorigin.me/' + url;
|
fetchUrl = "https://crossorigin.me/" + url;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
@ -144,90 +144,96 @@ $(document).ready(function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function smartDraw(urlOpt, forced) {
|
function smartDraw(urlOpt, forced) {
|
||||||
var url = urlOpt || $url.val();
|
const url = urlOpt || $url.val();
|
||||||
var req = prepareUrl(url);
|
const req = prepareUrl(url);
|
||||||
draw(req, forced);
|
draw(req, forced);
|
||||||
}
|
}
|
||||||
|
|
||||||
function draw(req, forced) {
|
function draw(req, forced) {
|
||||||
if (!validateUrl(req.url)) {
|
if (!validateUrl(req.url)) {
|
||||||
console.error('Invalid url provided!');
|
console.error("Invalid url provided!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (validateUrl(req.originalUrl)) updateUrl(req.originalUrl);
|
if (validateUrl(req.originalUrl)) updateUrl(req.originalUrl);
|
||||||
|
|
||||||
var outputFormat = $outputFormat.val();
|
const outputFormat = $outputFormat.val();
|
||||||
var showFiles = $showFiles.is(':checked');
|
const showFiles = $showFiles.is(":checked");
|
||||||
var matching = $matching.val();
|
const matching = $matching.val();
|
||||||
var wordsThreshold = $wordsThreshold.val();
|
const wordsThreshold = $wordsThreshold.val();
|
||||||
var matchingMaxComparisons = $matchingMaxComparisons.val();
|
const matchingMaxComparisons = $matchingMaxComparisons.val();
|
||||||
|
|
||||||
fetch(req.url, {
|
fetch(req.url, {
|
||||||
method: 'GET',
|
method: "GET",
|
||||||
headers: req.headers,
|
headers: req.headers,
|
||||||
mode: 'cors',
|
mode: "cors",
|
||||||
cache: 'default'
|
cache: "default"
|
||||||
})
|
})
|
||||||
.then(function(res) {
|
.then(function(res) {
|
||||||
return res.text();
|
return res.text();
|
||||||
})
|
})
|
||||||
.then(function(data) {
|
.then(function(data) {
|
||||||
var container = '#url-diff-container';
|
const container = "#url-diff-container";
|
||||||
var diff2htmlUi = new Diff2HtmlUI({diff: data});
|
const diff2htmlUi = new Diff2HtmlUI({ diff: data });
|
||||||
|
|
||||||
if (outputFormat === 'side-by-side') {
|
if (outputFormat === "side-by-side") {
|
||||||
$container.css({'width': '100%'});
|
$container.css({ width: "100%" });
|
||||||
} else {
|
} else {
|
||||||
$container.css({'width': ''});
|
$container.css({ width: "" });
|
||||||
}
|
}
|
||||||
|
|
||||||
var params = getParamsFromSearch(window.location.search);
|
const params = getParamsFromSearch(window.location.search);
|
||||||
delete params[searchParam];
|
delete params[searchParam];
|
||||||
|
|
||||||
if (forced) {
|
if (forced) {
|
||||||
params['outputFormat'] = outputFormat;
|
params.outputFormat = outputFormat;
|
||||||
params['showFiles'] = showFiles;
|
params.showFiles = showFiles;
|
||||||
params['matching'] = matching;
|
params.matching = matching;
|
||||||
params['wordsThreshold'] = wordsThreshold;
|
params.wordsThreshold = wordsThreshold;
|
||||||
params['matchingMaxComparisons'] = matchingMaxComparisons;
|
params.matchingMaxComparisons = matchingMaxComparisons;
|
||||||
} else {
|
} else {
|
||||||
params['outputFormat'] = params['outputFormat'] || outputFormat;
|
params.outputFormat = params.outputFormat || outputFormat;
|
||||||
params['showFiles'] = String(params['showFiles']) !== 'false' || (params['showFiles'] === null && showFiles);
|
params.showFiles = String(params.showFiles) !== "false" || (params.showFiles === null && showFiles);
|
||||||
params['matching'] = params['matching'] || matching;
|
params.matching = params.matching || matching;
|
||||||
params['wordsThreshold'] = params['wordsThreshold'] || wordsThreshold;
|
params.wordsThreshold = params.wordsThreshold || wordsThreshold;
|
||||||
params['matchingMaxComparisons'] = params['matchingMaxComparisons'] || matchingMaxComparisons;
|
params.matchingMaxComparisons = params.matchingMaxComparisons || matchingMaxComparisons;
|
||||||
|
|
||||||
$outputFormat.val(params['outputFormat']);
|
$outputFormat.val(params.outputFormat);
|
||||||
$showFiles.prop('checked', params['showFiles']);
|
$showFiles.prop("checked", params.showFiles);
|
||||||
$matching.val(params['matching']);
|
$matching.val(params.matching);
|
||||||
$wordsThreshold.val(params['wordsThreshold']);
|
$wordsThreshold.val(params.wordsThreshold);
|
||||||
$matchingMaxComparisons.val(params['matchingMaxComparisons']);
|
$matchingMaxComparisons.val(params.matchingMaxComparisons);
|
||||||
}
|
}
|
||||||
|
|
||||||
params['synchronisedScroll'] = params['synchronisedScroll'] || true;
|
params.synchronisedScroll = params.synchronisedScroll || true;
|
||||||
|
|
||||||
diff2htmlUi.draw(container, params);
|
diff2htmlUi.draw(container, params);
|
||||||
diff2htmlUi.fileListCloseable(container, params['fileListCloseable'] || false);
|
diff2htmlUi.fileListCloseable(container, params.fileListCloseable || false);
|
||||||
if (params['highlight'] === undefined || params['highlight']) {
|
if (params.highlight === undefined || params.highlight) {
|
||||||
diff2htmlUi.highlightCode(container);
|
diff2htmlUi.highlightCode(container);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function validateUrl(url) {
|
function validateUrl(url) {
|
||||||
return /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(url);
|
return /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(
|
||||||
|
url
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateUrl(url) {
|
function updateUrl(url) {
|
||||||
var params = getParamsFromSearch(window.location.search);
|
const params = getParamsFromSearch(window.location.search);
|
||||||
|
|
||||||
if (params[searchParam] === url) return;
|
if (params[searchParam] === url) return;
|
||||||
|
|
||||||
params[searchParam] = url;
|
params[searchParam] = url;
|
||||||
|
|
||||||
var paramString = Object.keys(params).map(function(k) { return k + '=' + params[k]; }).join('&');
|
const paramString = Object.keys(params)
|
||||||
|
.map(function(k) {
|
||||||
|
return k + "=" + params[k];
|
||||||
|
})
|
||||||
|
.join("&");
|
||||||
|
|
||||||
window.location = 'demo.html?' + paramString;
|
window.location = "demo.html?" + paramString;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue