Add diff output options

This commit is contained in:
Rodrigo Fernandes 2016-10-12 22:52:59 +01:00
parent ba13de46a0
commit 259d3ef972
16 changed files with 3658 additions and 954 deletions

View file

@ -1,417 +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.css" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.6.0/styles/github.min.css">
<!-- diff2html -->
<link rel="stylesheet" type="text/css" href="assets/diff2html.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="swag-line template-index">
<div class="container-overflow-wrap">
<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">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>Line by Line</h1>
<div id="line-by-line" style="margin: 0 auto;">
</div>
<h1>Side by Side</h1>
<div id="side-by-side" style="margin: 0 auto;">
</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/highlight.js/9.6.0/highlight.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.6.0/languages/scala.min.js"></script>
<!-- diff2html -->
<script type="text/javascript" src="assets/diff2html.js"></script>
<script type="text/javascript" src="assets/diff2html-ui.js"></script>
<!-- -->
<script>
var lineDiffExample =
"--- a/src/my/really/big/path/sample.js\n" +
"+++ b/src/my/small/path/sample.js\n" +
"@@ -1 +1,2 @@\n" +
"-test\n" +
"+test1r\n" +
"+test2r\n" +
'diff --git a/src/core/init.java b/src/core/init.java\n' +
'index e49196a..50f310c 100644\n' +
'--- a/src/core/init.java\n' +
'+++ b/src/core/init.java\n' +
'@@ -101,7 +101,7 @@\n' +
' /**\n' +
' * Setter for property filesize.\n' +
' *\n' +
" * @param filesize value of property 'filesize'.\n" +
' */\n' +
' public void setFilesize(int filesize) {\n' +
'- this.filesizeOld = filesizeOld;\n' +
'+ this.filesizeNew = filesizeNew;\n' +
' }\n' +
'diff --git a/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/coverage.init b/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/coverage.init\n' +
'index fc56817..e8e7e49 100644\n' +
'--- a/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/coverage.init\n' +
'+++ b/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/coverage.init\n' +
'@@ -19,7 +19,7 @@\n' +
' -opt "\-nostart"\n' +
' \n' +
' # skip stopenv\n' +
'--do "runbvt,stopenv,getlogs,pullcoveragedata,stopenv,getlogs,pullcoveragedata,stopenv,getlogs,pullcoveragedata,stopenv,getlogs,pullcoveragedata,stopenv,getlogs,pullcoveragedata,stopenv,getlogs,pullcoveragedata,stopenv,getlogs,pullcoveragedata,stopenv,getlogs,pullcoveragedata,stopenv,getlogs,pullcoveragedata,stopenv,getlogs,pullcoveragedata"\n' +
'+-do "runbvt,getlogs,pullcoveragedata"\n' +
' \n' +
' ##########################################\n' +
' # logs files to bring back to base\n' +
'diff --git a/src/attributes/attr.js b/src/attributes/attr.js\n' +
'index facdd41..b627fe8 100644\n' +
'--- a/src/attributes/attr.js\n' +
'+++ b/src/attributes/attr.js\n' +
'@@ -1,11 +1,10 @@\n' +
' define([\n' +
' "../core",\n' +
' "../var/rnotwhite",\n' +
'- "../var/strundefined",\n' +
' "../core/access",\n' +
' "./support",\n' +
' "../selector"\n' +
'-], function( jQuery, rnotwhite, strundefined, access, support ) {\n' +
'+], function( jQuery, rnotwhite, access, support ) {\n' +
' \n' +
' var nodeHook, boolHook,\n' +
' attrHandle = jQuery.expr.attrHandle;\n' +
'@@ -33,7 +32,7 @@ jQuery.extend({\n' +
' }\n' +
' \n' +
' // Fallback to prop when attributes are not supported\n' +
'- if ( typeof elem.getAttribute === strundefined ) {\n' +
'+ if ( !elem.getAttribute ) {\n' +
' return jQuery.prop( elem, name, value );\n' +
' }\n' +
' \n' +
'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' +
'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' +
'@@ -10,7 +9,7 @@ define([\n' +
' "./core/init",\n' +
' "./data/accepts",\n' +
' "./selector"\n' +
'-], function( jQuery, strundefined, rnotwhite, hasOwn, slice, support, dataPriv ) {\n' +
'+], function( jQuery, rnotwhite, hasOwn, slice, support, dataPriv ) {\n' +
' \n' +
' var\n' +
' rkeyEvent = /^key/,\n' +
'@@ -72,7 +71,7 @@ jQuery.event = {\n' +
' eventHandle = elemData.handle = function( e ) {\n' +
' // Discard the second event of a jQuery.event.trigger() and\n' +
' // when an event is called after a page has unloaded\n' +
'- return typeof jQuery !== strundefined && jQuery.event.triggered !== e.type ?\n' +
'+ return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?\n' +
' jQuery.event.dispatch.apply( elem, arguments ) : undefined;\n' +
' };\n' +
' }\n' +
'diff --git a/src/exports/global.js b/src/exports/global.js\n' +
'index 6513287..1db4144 100644\n' +
'--- a/src/exports/global.js\n' +
'+++ b/src/exports/global.js\n' +
'@@ -1,7 +1,9 @@\n' +
' define([\n' +
'- "../core",\n' +
'- "../var/strundefined"\n' +
'-], function( jQuery, strundefined ) {\n' +
'+ "../core"\n' +
'+], function( jQuery ) {\n' +
'+\n' +
'+/* exported noGlobal */\n' +
'+/* global noGlobal: false */\n' +
' \n' +
' var\n' +
' // Map over jQuery in case of overwrite\n' +
'@@ -25,7 +27,7 @@ jQuery.noConflict = function( deep ) {\n' +
' // Expose jQuery and $ identifiers, even in AMD\n' +
' // (#7102#comment:10, https://github.com/jquery/jquery/pull/557)\n' +
' // and CommonJS for browser emulators (#13566)\n' +
'-if ( typeof noGlobal === strundefined ) {\n' +
'+if ( !noGlobal ) {\n' +
' window.jQuery = window.$ = jQuery;\n' +
' }\n' +
' \n' +
'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' +
' define([\n' +
' "./core",\n' +
'- "./var/strundefined",\n' +
' "./core/access",\n' +
' "./css/var/rnumnonpx",\n' +
' "./css/curCSS",\n' +
'@@ -10,7 +9,7 @@ define([\n' +
' "./core/init",\n' +
' "./css",\n' +
' "./selector" // contains\n' +
'-], function( jQuery, strundefined, access, rnumnonpx, curCSS, addGetHookIf, support ) {\n' +
'+], function( jQuery, access, rnumnonpx, curCSS, addGetHookIf, support ) {\n' +
' \n' +
' var docElem = window.document.documentElement;\n' +
' \n' +
'@@ -99,7 +98,7 @@ jQuery.fn.extend({\n' +
' \n' +
' // Support: BlackBerry 5, iOS 3 (original iPhone)\n' +
' // If we dont have gBCR, just use 0,0 rather than error\n' +
'- if ( typeof elem.getBoundingClientRect !== strundefined ) {\n' +
'+ if ( elem.getBoundingClientRect !== undefined ) {\n' +
' box = elem.getBoundingClientRect();\n' +
' }\n' +
' win = getWindow( doc );\n' +
'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' +
'diff --git a/components/textdiff/textdiff.html b/components/textdiff/textdiff.html\n' +
'index a3484bf..82209af 100644\n' +
'--- a/components/textdiff/textdiff.html\n' +
'+++ b/components/textdiff/textdiff.html\n' +
'@@ -1,6 +1,8 @@\n' +
' <!-- ko if: isShowingDiffs -->\n' +
' <div>\n' +
'- <div data-bind="event: { load: setDom($element) }"></div>\n' +
'+ <!-- ko if: isParsed -->\n' +
'+ <div data-bind="template: {nodes: ko.utils.parseHtmlFragment(htmlSrc())}"></div>\n' +
'+ <!-- /ko -->\n' +
' <div class="btn-load-more" data-bind="visible: loadMoreCount() > 0">\n' +
' </div>\n' +
'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,6 @@\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' +
"diff --git a/a.xml b/b.xml\n" +
"index e54317e..82a9a56 100644\n" +
"--- a/a.xml\n" +
"+++ b/b.xml\n" +
"@@ -242,4 +242,6 @@ need to create a new job for native server java api and move these tests to a ne\n" +
" </packages>\n" +
" </test>\n" +
" -->\n" +
"+\n" +
"+\n";
$(document).ready(function() {
var diff2htmlUi = new Diff2HtmlUI({diff: lineDiffExample});
diff2htmlUi.draw('#line-by-line', {
inputFormat: 'json',
showFiles: true,
matching: 'lines'
});
diff2htmlUi.fileListCloseable('#line-by-line', false);
diff2htmlUi.highlightCode('#line-by-line');
diff2htmlUi.draw('#side-by-side', {
inputFormat: 'json',
showFiles: true,
matching: 'lines',
outputFormat: 'side-by-side',
synchronisedScroll: true
});
diff2htmlUi.fileListCloseable('#side-by-side', false);
diff2htmlUi.highlightCode('#side-by-side');
});
</script>
</body>
</html>

View file

@ -72,7 +72,7 @@
</li>
<li>
<a href="demo.html">Demo</a>
<a href="url.html?diff=https://github.com/rtfpessoa/diff2html/pull/106">Demo</a>
</li>
<li>
@ -101,11 +101,11 @@
<img class="screenshot hidden-xs" src="img/snapshot-2.png">
<a class="screenshot" href="demo.html#side-by-side">
<a class="screenshot" href="url.html?diff=https://github.com/rtfpessoa/diff2html/pull/106">
<img src="img/snapshot-3.png">
</a>
<a class="screenshot hidden-xs" href="demo.html#line-by-line">
<a class="screenshot hidden-xs" href="url.html?diff=https://github.com/rtfpessoa/diff2html/pull/106">
<img src="img/snapshot-1.png">
</a>

View file

@ -79,7 +79,7 @@
</li>
<li>
<a href="demo.html">Demo</a>
<a href="url.html?diff=https://github.com/rtfpessoa/diff2html/pull/106">Demo</a>
</li>
<li>
@ -100,15 +100,42 @@
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>
<h3>Options:</h3>
<div class="diff-url-options-container">
<h5>Output:</h5>
<label>Format
<select 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>
<label>Show Files
<input id="diff-url-options-show-files" type="checkbox" name="showFiles" checked/>
</label>
<h5>Matching:</h5>
<label>Type
<select 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>
<label>Words Threshold
<input id="diff-url-options-match-words-threshold" type="number" name="matchWordsThreshold" value="0.25" step="0.05"
min="0" max="1"/>
</label>
<label>Maximum Comparisons
<input id="diff-url-options-matching-max-comparisons" type="number" name="matchingMaxComparisons" value="2500"
step="100" min="0"/>
</label>
</div>
<br>
<div class="diff-url-wrapper">
<a id="url-btn" class="diff-url-btn btn btn-sm" href="#">Load</a>
<input id="url" class="diff-url-input" type="text" name="url" placeholder="URL"/>
</div>
<br>
<h2>Line by Line</h2>
<div id="line-by-line" style="margin: 0 auto;">
<div id="url-diff-container" style="margin: 0 auto;">
</div>
<br>
<h3 id="help">Help:</h3>
@ -128,14 +155,17 @@
</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="url.html?diff=https://github.com/rtfpessoa/diff2html/pull/106">https://diff2html.xyz/url?diff=https://github.com/rtfpessoa/diff2html/pull/106</a></p>
<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="url.html?diff=https://github.com/rtfpessoa/diff2html/pull/106">https://diff2html.xyz/url?diff=https://github.com/rtfpessoa/diff2html/pull/106</a>
</p>
<p>You can also use an hashtag (# or #! or #!/) in the end of the url.
This will be overridden if you click any href id and for that reason not advised.</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>
<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>
@ -203,128 +233,7 @@
<script type="text/javascript" src="assets/diff2html-ui.js"></script>
<!-- -->
<script>
/*
* Example URLs:
*
* github/rtfpessoa/diff2html/7d02e67f3b3386ac5d804f974d025cd7a1165839
* https://github.com/rtfpessoa/diff2html/commit/7d02e67f3b3386ac5d804f974d025cd7a1165839
* https://github.com/rtfpessoa/diff2html/pull/106
*
* gitlab/gitlab-org/gitlab-ce/4e963fed42ad518caa7353d361a38a1250c99c41
* https://gitlab.com/gitlab-org/gitlab-ce/commit/4e963fed42ad518caa7353d361a38a1250c99c41
* https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/6763
*
* bitbucket/atlassian/amps/52c38116f12475f75af4a147b7a7685478b83eca
* https://bitbucket.org/atlassian/amps/commits/52c38116f12475f75af4a147b7a7685478b83eca
* https://bitbucket.org/atlassian/amps/pull-requests/236
*/
$(document).ready(function() {
var hash = window.location.hash
.replace(/^(#!?\/?)/, "");
var search = window.location.search;
if (hash) {
$("#url").val(hash);
draw(prepareUrl(hash));
} else if (search) {
try {
var url = search
.split("?")[1]
.split("diff=")[1]
.split("&")[0];
$("#url").val(url);
draw(prepareUrl(url));
} catch (_ignore) {
}
}
bind(prepareUrl);
function bind() {
$("#url-btn").click(function(e) {
e.preventDefault();
var url = $("#url").val();
var preparedUrl = prepareUrl(url);
draw(preparedUrl);
});
}
function prepareUrl(url) {
var githubPath = /^github\/(.*?)\/(.*?)\/(.*?)$/;
var githubCommitUrl = /^https?:\/\/(?:www\.)?github\.com\/(.*?)\/(.*?)\/commit\/(.*?)(?:\.diff)?(?:\.patch)?(?:\/.*)?$/;
var githubPrUrl = /^https?:\/\/(?:www\.)?github\.com\/(.*?)\/(.*?)\/pull\/(.*?)(?:\.diff)?(?:\.patch)?(?:\/.*)?$/;
var gitlabPath = /^gitlab\/(.*?)\/(.*?)\/(.*?)$/;
var gitlabCommitUrl = /^https?:\/\/(?:www\.)?gitlab\.com\/(.*?)\/(.*?)\/commit\/(.*?)(?:\.diff)?(?:\.patch)?(?:\/.*)?$/;
var gitlabPrUrl = /^https?:\/\/(?:www\.)?gitlab\.com\/(.*?)\/(.*?)\/merge_requests\/(.*?)(?:\.diff)?(?:\.patch)?(?:\/.*)?$/;
var bitbucketPath = /^bitbucket\/(.*?)\/(.*?)\/(.*?)$/;
var bitbucketCommitUrl = /^https?:\/\/(?:www\.)?bitbucket\.org\/(.*?)\/(.*?)\/commits\/(.*?)(?:\/raw)?(?:\/.*)?$/;
var bitbucketPrUrl = /^https?:\/\/(?:www\.)?bitbucket\.org\/(.*?)\/(.*?)\/pull-requests\/(.*?)(?:\/.*)?$/;
function genericUrlGen(provider, userName, projectName, type, value) {
return "https://" + provider + ".com/" + userName + "/" + projectName + "/" + type + "/" + value + ".diff";
}
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;
var finalUrl;
if ((values = githubPath.exec(url))) {
finalUrl = genericUrlGen("github", values[1], values[2], "commit", values[3]);
} else if ((values = githubCommitUrl.exec(url))) {
finalUrl = genericUrlGen("github", values[1], values[2], "commit", values[3]);
} else if ((values = githubPrUrl.exec(url))) {
finalUrl = genericUrlGen("github", values[1], values[2], "pull", values[3]);
} else if ((values = gitlabPath.exec(url))) {
finalUrl = genericUrlGen("gitlab", values[1], values[2], "commit", values[3]);
} else if ((values = gitlabCommitUrl.exec(url))) {
finalUrl = genericUrlGen("gitlab", values[1], values[2], "commit", values[3]);
} else if ((values = gitlabPrUrl.exec(url))) {
finalUrl = genericUrlGen("gitlab", values[1], values[2], "merge_requests", values[3]);
} else if ((values = bitbucketPath.exec(url))) {
finalUrl = bitbucketUrlGen(values[1], values[2], "commit", values[3]);
} else if ((values = bitbucketCommitUrl.exec(url))) {
finalUrl = bitbucketUrlGen(values[1], values[2], "commit", values[3]);
} else if ((values = bitbucketPrUrl.exec(url))) {
finalUrl = bitbucketUrlGen(values[1], values[2], "pullrequests", values[3]);
} else {
console.info("Could not parse url, using the provided url.");
finalUrl = url;
}
return finalUrl;
}
function draw(url) {
var fullUrl = 'https://crossorigin.me/' + url;
fetch(fullUrl)
.then((res) => res.text())
.then((data) => {
var diff2htmlUi = new Diff2HtmlUI({diff: data});
diff2htmlUi.draw('#line-by-line', {
showFiles: true,
matching: 'lines'
});
diff2htmlUi.fileListCloseable('#line-by-line', false);
diff2htmlUi.highlightCode('#line-by-line');
});
}
});
</script>
<script type="text/javascript" src="url.js"></script>
</body>

561
docs/url.js Normal file
View file

@ -0,0 +1,561 @@
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
(function(self) {
'use strict';
if (self.fetch) {
return
}
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
}
function Headers(headers) {
this.map = {}
if (headers instanceof Headers) {
headers.forEach(function(value, name) {
this.append(name, value)
}, 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 list = this.map[name]
if (!list) {
list = []
this.map[name] = list
}
list.push(value)
}
Headers.prototype['delete'] = function(name) {
delete this.map[normalizeName(name)]
}
Headers.prototype.get = function(name) {
var values = this.map[normalizeName(name)]
return values ? values[0] : null
}
Headers.prototype.getAll = function(name) {
return this.map[normalizeName(name)] || []
}
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) {
Object.getOwnPropertyNames(this.map).forEach(function(name) {
this.map[name].forEach(function(value) {
callback.call(thisArg, value, name, this)
}, this)
}, this)
}
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()
reader.readAsArrayBuffer(blob)
return fileReaderReady(reader)
}
function readBlobAsText(blob) {
var reader = new FileReader()
reader.readAsText(blob)
return fileReaderReady(reader)
}
var support = {
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 Body() {
this.bodyUsed = false
this._initBody = function(body) {
this._bodyInit = body
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 (!body) {
this._bodyText = ''
} else if (support.arrayBuffer && ArrayBuffer.prototype.isPrototypeOf(body)) {
// Only support ArrayBuffers for POST method.
// Receiving ArrayBuffers happens via Blobs, instead.
} else {
throw new Error('unsupported BodyInit type')
}
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)
}
}
}
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._bodyFormData) {
throw new Error('could not read FormData body as blob')
} else {
return Promise.resolve(new Blob([this._bodyText]))
}
}
this.arrayBuffer = function() {
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._bodyFormData) {
throw new Error('could not read FormData body as text')
} else {
return Promise.resolve(this._bodyText)
}
}
} else {
this.text = function() {
var rejected = consumed(this)
return rejected ? rejected : 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 (Request.prototype.isPrototypeOf(input)) {
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
if (!body) {
body = input._bodyInit
input.bodyUsed = true
}
} else {
this.url = input
}
this.credentials = options.credentials || this.credentials || 'omit'
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.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)
}
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 headers(xhr) {
var head = new Headers()
var pairs = (xhr.getAllResponseHeaders() || '').trim().split('\n')
pairs.forEach(function(header) {
var split = header.trim().split(':')
var key = split.shift().trim()
var value = split.join(':').trim()
head.append(key, value)
})
return head
}
Body.call(Request.prototype)
function Response(bodyInit, options) {
if (!options) {
options = {}
}
this.type = 'default'
this.status = options.status
this.ok = this.status >= 200 && this.status < 300
this.statusText = options.statusText
this.headers = options.headers instanceof Headers ? options.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}})
}
self.Headers = Headers
self.Request = Request
self.Response = Response
self.fetch = function(input, init) {
return new Promise(function(resolve, reject) {
var request
if (Request.prototype.isPrototypeOf(input) && !init) {
request = input
} else {
request = new Request(input, init)
}
var xhr = new XMLHttpRequest()
function responseURL() {
if ('responseURL' in xhr) {
return xhr.responseURL
}
// Avoid security warnings on getResponseHeader when not allowed by CORS
if (/^X-Request-URL:/m.test(xhr.getAllResponseHeaders())) {
return xhr.getResponseHeader('X-Request-URL')
}
return
}
xhr.onload = function() {
var status = (xhr.status === 1223) ? 204 : xhr.status
if (status < 100 || status > 599) {
reject(new TypeError('Network request failed'))
return
}
var options = {
status: status,
statusText: xhr.statusText,
headers: headers(xhr),
url: responseURL()
}
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.open(request.method, request.url, true)
if (request.credentials === 'include') {
xhr.withCredentials = true
}
if ('responseType' in xhr && support.blob) {
xhr.responseType = 'blob'
}
request.headers.forEach(function(value, name) {
xhr.setRequestHeader(name, value)
})
xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit)
})
}
self.fetch.polyfill = true
})(typeof self !== 'undefined' ? self : this);
},{}],2:[function(require,module,exports){
/*
* Example URLs:
*
* github/rtfpessoa/diff2html/7d02e67f3b3386ac5d804f974d025cd7a1165839
* https://github.com/rtfpessoa/diff2html/commit/7d02e67f3b3386ac5d804f974d025cd7a1165839
* https://github.com/rtfpessoa/diff2html/pull/106
*
* gitlab/gitlab-org/gitlab-ce/4e963fed42ad518caa7353d361a38a1250c99c41
* https://gitlab.com/gitlab-org/gitlab-ce/commit/4e963fed42ad518caa7353d361a38a1250c99c41
* https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/6763
*
* bitbucket/atlassian/amps/52c38116f12475f75af4a147b7a7685478b83eca
* 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 $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 $wordThreshold = $("#diff-url-options-match-words-threshold");
var $matchingMaxComparisons = $("#diff-url-options-matching-max-comparisons");
var hash = window.location.hash
.replace(/^(#!?\/?)/, "");
var search = window.location.search;
if (hash) {
$url.val(hash);
draw(prepareUrl(hash));
} else if (search) {
try {
var url = search
.split("?")[1]
.split("diff=")[1]
.split("&")[0];
$url.val(url);
draw(prepareUrl(url));
} catch (_ignore) {
}
}
bind(prepareUrl);
$outputFormat
.add($showFiles)
.add($matching)
.add($wordThreshold)
.add($matchingMaxComparisons)
.change(function () {
fastDraw();
});
function fastDraw() {
var url = $url.val();
var preparedUrl = prepareUrl(url);
draw(preparedUrl);
}
function bind() {
$("#url-btn").click(function (e) {
e.preventDefault();
fastDraw();
});
}
function prepareUrl(url) {
var githubPath = /^github\/(.*?)\/(.*?)\/(.*?)$/;
var githubCommitUrl = /^https?:\/\/(?:www\.)?github\.com\/(.*?)\/(.*?)\/commit\/(.*?)(?:\.diff)?(?:\.patch)?(?:\/.*)?$/;
var githubPrUrl = /^https?:\/\/(?:www\.)?github\.com\/(.*?)\/(.*?)\/pull\/(.*?)(?:\.diff)?(?:\.patch)?(?:\/.*)?$/;
var gitlabPath = /^gitlab\/(.*?)\/(.*?)\/(.*?)$/;
var gitlabCommitUrl = /^https?:\/\/(?:www\.)?gitlab\.com\/(.*?)\/(.*?)\/commit\/(.*?)(?:\.diff)?(?:\.patch)?(?:\/.*)?$/;
var gitlabPrUrl = /^https?:\/\/(?:www\.)?gitlab\.com\/(.*?)\/(.*?)\/merge_requests\/(.*?)(?:\.diff)?(?:\.patch)?(?:\/.*)?$/;
var bitbucketPath = /^bitbucket\/(.*?)\/(.*?)\/(.*?)$/;
var bitbucketCommitUrl = /^https?:\/\/(?:www\.)?bitbucket\.org\/(.*?)\/(.*?)\/commits\/(.*?)(?:\/raw)?(?:\/.*)?$/;
var bitbucketPrUrl = /^https?:\/\/(?:www\.)?bitbucket\.org\/(.*?)\/(.*?)\/pull-requests\/(.*?)(?:\/.*)?$/;
function genericUrlGen(provider, userName, projectName, type, value) {
return "https://" + provider + ".com/" + userName + "/" + projectName + "/" + type + "/" + value + ".diff";
}
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;
var finalUrl;
if ((values = githubPath.exec(url))) {
finalUrl = genericUrlGen("github", values[1], values[2], "commit", values[3]);
} else if ((values = githubCommitUrl.exec(url))) {
finalUrl = genericUrlGen("github", values[1], values[2], "commit", values[3]);
} else if ((values = githubPrUrl.exec(url))) {
finalUrl = genericUrlGen("github", values[1], values[2], "pull", values[3]);
} else if ((values = gitlabPath.exec(url))) {
finalUrl = genericUrlGen("gitlab", values[1], values[2], "commit", values[3]);
} else if ((values = gitlabCommitUrl.exec(url))) {
finalUrl = genericUrlGen("gitlab", values[1], values[2], "commit", values[3]);
} else if ((values = gitlabPrUrl.exec(url))) {
finalUrl = genericUrlGen("gitlab", values[1], values[2], "merge_requests", values[3]);
} else if ((values = bitbucketPath.exec(url))) {
finalUrl = bitbucketUrlGen(values[1], values[2], "commit", values[3]);
} else if ((values = bitbucketCommitUrl.exec(url))) {
finalUrl = bitbucketUrlGen(values[1], values[2], "commit", values[3]);
} else if ((values = bitbucketPrUrl.exec(url))) {
finalUrl = bitbucketUrlGen(values[1], values[2], "pullrequests", values[3]);
} else {
console.info("Could not parse url, using the provided url.");
finalUrl = url;
}
return finalUrl;
}
function draw(url) {
var outputFormat = $outputFormat.val();
var showFiles = $showFiles.is(":checked");
var matching = $matching.val();
var wordThreshold = $wordThreshold.val();
var matchingMaxComparisons = $matchingMaxComparisons.val();
var fullUrl = 'https://crossorigin.me/' + url;
fetch(fullUrl)
.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": "1400px"});
} else {
$container.css({"width": ""});
}
diff2htmlUi.draw(container, {
outputFormat: outputFormat,
showFiles: showFiles,
matching: matching,
matchWordsThreshold: wordThreshold,
matchingMaxComparisons: matchingMaxComparisons
});
diff2htmlUi.fileListCloseable(container, false);
diff2htmlUi.highlightCode(container);
});
}
});
},{"whatwg-fetch":1}]},{},[2]);

1
docs/url.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View file

@ -37,7 +37,7 @@
"preferGlobal": true,
"scripts": {
"release": "./scripts/release.sh",
"release-website": "node ./scripts/release-website.js",
"release-website": "./scripts/release-website.sh",
"release-bower": "./scripts/update-bower-version.sh",
"templates": "./scripts/hulk.js --wrapper node --variable 'browserTemplates' ./src/templates/*.mustache > ./src/templates/diff2html-templates.js",
"style": "eslint .",
@ -55,7 +55,8 @@
},
"dependencies": {
"diff": "^3.0.0",
"hogan.js": "^3.0.2"
"hogan.js": "^3.0.2",
"whatwg-fetch": "0.11.1"
},
"devDependencies": {
"autoprefixer": "^6.5.0",

31
scripts/release-website.sh Executable file
View file

@ -0,0 +1,31 @@
#!/bin/bash
#
# diff2html website release script
# by rtfpessoa
#
set -e
INPUT_DIR=website
INPUT_URL_JS=${INPUT_DIR}/templates/pages/url/url.js
OUTPUT_DIR=docs
OUTPUT_URL_JS=${OUTPUT_DIR}/url.js
OUTPUT_URL_MIN_JS=${OUTPUT_DIR}/url.min.js
echo "Creating diff2html website release ..."
echo "Cleaning previous versions ..."
rm -rf ${OUTPUT_URL_JS}
echo "Generating website js aggregation file in ${OUTPUT_URL_JS}"
browserify -e ${INPUT_URL_JS} -o ${OUTPUT_URL_JS}
echo "Minifying ${OUTPUT_URL_JS} to ${OUTPUT_URL_MIN_JS}"
uglifyjs ${OUTPUT_URL_JS} -c -o ${OUTPUT_URL_MIN_JS}
echo "Generating HTMLs from templates ..."
node ./scripts/release-website.js
echo "diff2html website release created successfully!"

View file

@ -1,5 +0,0 @@
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.6.0/styles/github.min.css">
<!-- diff2html -->
<link rel="stylesheet" type="text/css" href="assets/diff2html.css">
<!-- -->

View file

@ -1,258 +0,0 @@
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.6.0/highlight.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.6.0/languages/scala.min.js"></script>
<!-- diff2html -->
<script type="text/javascript" src="assets/diff2html.js"></script>
<script type="text/javascript" src="assets/diff2html-ui.js"></script>
<!-- -->
<script>
var lineDiffExample =
"--- a/src/my/really/big/path/sample.js\n" +
"+++ b/src/my/small/path/sample.js\n" +
"@@ -1 +1,2 @@\n" +
"-test\n" +
"+test1r\n" +
"+test2r\n" +
'diff --git a/src/core/init.java b/src/core/init.java\n' +
'index e49196a..50f310c 100644\n' +
'--- a/src/core/init.java\n' +
'+++ b/src/core/init.java\n' +
'@@ -101,7 +101,7 @@\n' +
' /**\n' +
' * Setter for property filesize.\n' +
' *\n' +
" * @param filesize value of property 'filesize'.\n" +
' */\n' +
' public void setFilesize(int filesize) {\n' +
'- this.filesizeOld = filesizeOld;\n' +
'+ this.filesizeNew = filesizeNew;\n' +
' }\n' +
'diff --git a/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/coverage.init b/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/coverage.init\n' +
'index fc56817..e8e7e49 100644\n' +
'--- a/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/coverage.init\n' +
'+++ b/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/src/very/long/file/path/coverage.init\n' +
'@@ -19,7 +19,7 @@\n' +
' -opt "\-nostart"\n' +
' \n' +
' # skip stopenv\n' +
'--do "runbvt,stopenv,getlogs,pullcoveragedata,stopenv,getlogs,pullcoveragedata,stopenv,getlogs,pullcoveragedata,stopenv,getlogs,pullcoveragedata,stopenv,getlogs,pullcoveragedata,stopenv,getlogs,pullcoveragedata,stopenv,getlogs,pullcoveragedata,stopenv,getlogs,pullcoveragedata,stopenv,getlogs,pullcoveragedata,stopenv,getlogs,pullcoveragedata"\n' +
'+-do "runbvt,getlogs,pullcoveragedata"\n' +
' \n' +
' ##########################################\n' +
' # logs files to bring back to base\n' +
'diff --git a/src/attributes/attr.js b/src/attributes/attr.js\n' +
'index facdd41..b627fe8 100644\n' +
'--- a/src/attributes/attr.js\n' +
'+++ b/src/attributes/attr.js\n' +
'@@ -1,11 +1,10 @@\n' +
' define([\n' +
' "../core",\n' +
' "../var/rnotwhite",\n' +
'- "../var/strundefined",\n' +
' "../core/access",\n' +
' "./support",\n' +
' "../selector"\n' +
'-], function( jQuery, rnotwhite, strundefined, access, support ) {\n' +
'+], function( jQuery, rnotwhite, access, support ) {\n' +
' \n' +
' var nodeHook, boolHook,\n' +
' attrHandle = jQuery.expr.attrHandle;\n' +
'@@ -33,7 +32,7 @@ jQuery.extend({\n' +
' }\n' +
' \n' +
' // Fallback to prop when attributes are not supported\n' +
'- if ( typeof elem.getAttribute === strundefined ) {\n' +
'+ if ( !elem.getAttribute ) {\n' +
' return jQuery.prop( elem, name, value );\n' +
' }\n' +
' \n' +
'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' +
'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' +
'@@ -10,7 +9,7 @@ define([\n' +
' "./core/init",\n' +
' "./data/accepts",\n' +
' "./selector"\n' +
'-], function( jQuery, strundefined, rnotwhite, hasOwn, slice, support, dataPriv ) {\n' +
'+], function( jQuery, rnotwhite, hasOwn, slice, support, dataPriv ) {\n' +
' \n' +
' var\n' +
' rkeyEvent = /^key/,\n' +
'@@ -72,7 +71,7 @@ jQuery.event = {\n' +
' eventHandle = elemData.handle = function( e ) {\n' +
' // Discard the second event of a jQuery.event.trigger() and\n' +
' // when an event is called after a page has unloaded\n' +
'- return typeof jQuery !== strundefined && jQuery.event.triggered !== e.type ?\n' +
'+ return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?\n' +
' jQuery.event.dispatch.apply( elem, arguments ) : undefined;\n' +
' };\n' +
' }\n' +
'diff --git a/src/exports/global.js b/src/exports/global.js\n' +
'index 6513287..1db4144 100644\n' +
'--- a/src/exports/global.js\n' +
'+++ b/src/exports/global.js\n' +
'@@ -1,7 +1,9 @@\n' +
' define([\n' +
'- "../core",\n' +
'- "../var/strundefined"\n' +
'-], function( jQuery, strundefined ) {\n' +
'+ "../core"\n' +
'+], function( jQuery ) {\n' +
'+\n' +
'+/* exported noGlobal */\n' +
'+/* global noGlobal: false */\n' +
' \n' +
' var\n' +
' // Map over jQuery in case of overwrite\n' +
'@@ -25,7 +27,7 @@ jQuery.noConflict = function( deep ) {\n' +
' // Expose jQuery and $ identifiers, even in AMD\n' +
' // (#7102#comment:10, https://github.com/jquery/jquery/pull/557)\n' +
' // and CommonJS for browser emulators (#13566)\n' +
'-if ( typeof noGlobal === strundefined ) {\n' +
'+if ( !noGlobal ) {\n' +
' window.jQuery = window.$ = jQuery;\n' +
' }\n' +
' \n' +
'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' +
' define([\n' +
' "./core",\n' +
'- "./var/strundefined",\n' +
' "./core/access",\n' +
' "./css/var/rnumnonpx",\n' +
' "./css/curCSS",\n' +
'@@ -10,7 +9,7 @@ define([\n' +
' "./core/init",\n' +
' "./css",\n' +
' "./selector" // contains\n' +
'-], function( jQuery, strundefined, access, rnumnonpx, curCSS, addGetHookIf, support ) {\n' +
'+], function( jQuery, access, rnumnonpx, curCSS, addGetHookIf, support ) {\n' +
' \n' +
' var docElem = window.document.documentElement;\n' +
' \n' +
'@@ -99,7 +98,7 @@ jQuery.fn.extend({\n' +
' \n' +
' // Support: BlackBerry 5, iOS 3 (original iPhone)\n' +
' // If we dont have gBCR, just use 0,0 rather than error\n' +
'- if ( typeof elem.getBoundingClientRect !== strundefined ) {\n' +
'+ if ( elem.getBoundingClientRect !== undefined ) {\n' +
' box = elem.getBoundingClientRect();\n' +
' }\n' +
' win = getWindow( doc );\n' +
'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' +
'diff --git a/components/textdiff/textdiff.html b/components/textdiff/textdiff.html\n' +
'index a3484bf..82209af 100644\n' +
'--- a/components/textdiff/textdiff.html\n' +
'+++ b/components/textdiff/textdiff.html\n' +
'@@ -1,6 +1,8 @@\n' +
' <!-- ko if: isShowingDiffs -->\n' +
' <div>\n' +
'- <div data-bind="event: { load: setDom($element) }"></div>\n' +
'+ <!-- ko if: isParsed -->\n' +
'+ <div data-bind="template: {nodes: ko.utils.parseHtmlFragment(htmlSrc())}"></div>\n' +
'+ <!-- /ko -->\n' +
' <div class="btn-load-more" data-bind="visible: loadMoreCount() > 0">\n' +
' </div>\n' +
'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,6 @@\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' +
"diff --git a/a.xml b/b.xml\n" +
"index e54317e..82a9a56 100644\n" +
"--- a/a.xml\n" +
"+++ b/b.xml\n" +
"@@ -242,4 +242,6 @@ need to create a new job for native server java api and move these tests to a ne\n" +
" </packages>\n" +
" </test>\n" +
" -->\n" +
"+\n" +
"+\n";
$(document).ready(function() {
var diff2htmlUi = new Diff2HtmlUI({diff: lineDiffExample});
diff2htmlUi.draw('#line-by-line', {
inputFormat: 'json',
showFiles: true,
matching: 'lines'
});
diff2htmlUi.fileListCloseable('#line-by-line', false);
diff2htmlUi.highlightCode('#line-by-line');
diff2htmlUi.draw('#side-by-side', {
inputFormat: 'json',
showFiles: true,
matching: 'lines',
outputFormat: 'side-by-side',
synchronisedScroll: true
});
diff2htmlUi.fileListCloseable('#side-by-side', false);
diff2htmlUi.highlightCode('#side-by-side');
});
</script>

View file

@ -1,9 +0,0 @@
<h1>Line by Line</h1>
<div id="line-by-line" style="margin: 0 auto;">
</div>
<h1>Side by Side</h1>
<div id="side-by-side" style="margin: 0 auto;">
</div>

View file

@ -12,11 +12,11 @@
<img class="screenshot hidden-xs" src="img/snapshot-2.png">
<a class="screenshot" href="demo.html#side-by-side">
<a class="screenshot" href="url.html?diff=https://github.com/rtfpessoa/diff2html/pull/106">
<img src="img/snapshot-3.png">
</a>
<a class="screenshot hidden-xs" href="demo.html#line-by-line">
<a class="screenshot hidden-xs" href="url.html?diff=https://github.com/rtfpessoa/diff2html/pull/106">
<img src="img/snapshot-1.png">
</a>

View file

@ -6,125 +6,4 @@
<script type="text/javascript" src="assets/diff2html-ui.js"></script>
<!-- -->
<script>
/*
* Example URLs:
*
* github/rtfpessoa/diff2html/7d02e67f3b3386ac5d804f974d025cd7a1165839
* https://github.com/rtfpessoa/diff2html/commit/7d02e67f3b3386ac5d804f974d025cd7a1165839
* https://github.com/rtfpessoa/diff2html/pull/106
*
* gitlab/gitlab-org/gitlab-ce/4e963fed42ad518caa7353d361a38a1250c99c41
* https://gitlab.com/gitlab-org/gitlab-ce/commit/4e963fed42ad518caa7353d361a38a1250c99c41
* https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/6763
*
* bitbucket/atlassian/amps/52c38116f12475f75af4a147b7a7685478b83eca
* https://bitbucket.org/atlassian/amps/commits/52c38116f12475f75af4a147b7a7685478b83eca
* https://bitbucket.org/atlassian/amps/pull-requests/236
*/
$(document).ready(function() {
var hash = window.location.hash
.replace(/^(#!?\/?)/, "");
var search = window.location.search;
if (hash) {
$("#url").val(hash);
draw(prepareUrl(hash));
} else if (search) {
try {
var url = search
.split("?")[1]
.split("diff=")[1]
.split("&")[0];
$("#url").val(url);
draw(prepareUrl(url));
} catch (_ignore) {
}
}
bind(prepareUrl);
function bind() {
$("#url-btn").click(function(e) {
e.preventDefault();
var url = $("#url").val();
var preparedUrl = prepareUrl(url);
draw(preparedUrl);
});
}
function prepareUrl(url) {
var githubPath = /^github\/(.*?)\/(.*?)\/(.*?)$/;
var githubCommitUrl = /^https?:\/\/(?:www\.)?github\.com\/(.*?)\/(.*?)\/commit\/(.*?)(?:\.diff)?(?:\.patch)?(?:\/.*)?$/;
var githubPrUrl = /^https?:\/\/(?:www\.)?github\.com\/(.*?)\/(.*?)\/pull\/(.*?)(?:\.diff)?(?:\.patch)?(?:\/.*)?$/;
var gitlabPath = /^gitlab\/(.*?)\/(.*?)\/(.*?)$/;
var gitlabCommitUrl = /^https?:\/\/(?:www\.)?gitlab\.com\/(.*?)\/(.*?)\/commit\/(.*?)(?:\.diff)?(?:\.patch)?(?:\/.*)?$/;
var gitlabPrUrl = /^https?:\/\/(?:www\.)?gitlab\.com\/(.*?)\/(.*?)\/merge_requests\/(.*?)(?:\.diff)?(?:\.patch)?(?:\/.*)?$/;
var bitbucketPath = /^bitbucket\/(.*?)\/(.*?)\/(.*?)$/;
var bitbucketCommitUrl = /^https?:\/\/(?:www\.)?bitbucket\.org\/(.*?)\/(.*?)\/commits\/(.*?)(?:\/raw)?(?:\/.*)?$/;
var bitbucketPrUrl = /^https?:\/\/(?:www\.)?bitbucket\.org\/(.*?)\/(.*?)\/pull-requests\/(.*?)(?:\/.*)?$/;
function genericUrlGen(provider, userName, projectName, type, value) {
return "https://" + provider + ".com/" + userName + "/" + projectName + "/" + type + "/" + value + ".diff";
}
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;
var finalUrl;
if ((values = githubPath.exec(url))) {
finalUrl = genericUrlGen("github", values[1], values[2], "commit", values[3]);
} else if ((values = githubCommitUrl.exec(url))) {
finalUrl = genericUrlGen("github", values[1], values[2], "commit", values[3]);
} else if ((values = githubPrUrl.exec(url))) {
finalUrl = genericUrlGen("github", values[1], values[2], "pull", values[3]);
} else if ((values = gitlabPath.exec(url))) {
finalUrl = genericUrlGen("gitlab", values[1], values[2], "commit", values[3]);
} else if ((values = gitlabCommitUrl.exec(url))) {
finalUrl = genericUrlGen("gitlab", values[1], values[2], "commit", values[3]);
} else if ((values = gitlabPrUrl.exec(url))) {
finalUrl = genericUrlGen("gitlab", values[1], values[2], "merge_requests", values[3]);
} else if ((values = bitbucketPath.exec(url))) {
finalUrl = bitbucketUrlGen(values[1], values[2], "commit", values[3]);
} else if ((values = bitbucketCommitUrl.exec(url))) {
finalUrl = bitbucketUrlGen(values[1], values[2], "commit", values[3]);
} else if ((values = bitbucketPrUrl.exec(url))) {
finalUrl = bitbucketUrlGen(values[1], values[2], "pullrequests", values[3]);
} else {
console.info("Could not parse url, using the provided url.");
finalUrl = url;
}
return finalUrl;
}
function draw(url) {
var fullUrl = 'https://crossorigin.me/' + url;
fetch(fullUrl)
.then((res) => res.text())
.then((data) => {
var diff2htmlUi = new Diff2HtmlUI({diff: data});
diff2htmlUi.draw('#line-by-line', {
showFiles: true,
matching: 'lines'
});
diff2htmlUi.fileListCloseable('#line-by-line', false);
diff2htmlUi.highlightCode('#line-by-line');
});
}
});
</script>
<script type="text/javascript" src="url.js"></script>

View file

@ -0,0 +1,163 @@
/*
* Example URLs:
*
* github/rtfpessoa/diff2html/7d02e67f3b3386ac5d804f974d025cd7a1165839
* https://github.com/rtfpessoa/diff2html/commit/7d02e67f3b3386ac5d804f974d025cd7a1165839
* https://github.com/rtfpessoa/diff2html/pull/106
*
* gitlab/gitlab-org/gitlab-ce/4e963fed42ad518caa7353d361a38a1250c99c41
* https://gitlab.com/gitlab-org/gitlab-ce/commit/4e963fed42ad518caa7353d361a38a1250c99c41
* https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/6763
*
* bitbucket/atlassian/amps/52c38116f12475f75af4a147b7a7685478b83eca
* 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 $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 $wordThreshold = $("#diff-url-options-match-words-threshold");
var $matchingMaxComparisons = $("#diff-url-options-matching-max-comparisons");
var hash = window.location.hash
.replace(/^(#!?\/?)/, "");
var search = window.location.search;
if (hash) {
$url.val(hash);
draw(prepareUrl(hash));
} else if (search) {
try {
var url = search
.split("?")[1]
.split("diff=")[1]
.split("&")[0];
$url.val(url);
draw(prepareUrl(url));
} catch (_ignore) {
}
}
bind(prepareUrl);
$outputFormat
.add($showFiles)
.add($matching)
.add($wordThreshold)
.add($matchingMaxComparisons)
.change(function () {
fastDraw();
});
function fastDraw() {
var url = $url.val();
var preparedUrl = prepareUrl(url);
draw(preparedUrl);
}
function bind() {
$("#url-btn").click(function (e) {
e.preventDefault();
fastDraw();
});
}
function prepareUrl(url) {
var githubPath = /^github\/(.*?)\/(.*?)\/(.*?)$/;
var githubCommitUrl = /^https?:\/\/(?:www\.)?github\.com\/(.*?)\/(.*?)\/commit\/(.*?)(?:\.diff)?(?:\.patch)?(?:\/.*)?$/;
var githubPrUrl = /^https?:\/\/(?:www\.)?github\.com\/(.*?)\/(.*?)\/pull\/(.*?)(?:\.diff)?(?:\.patch)?(?:\/.*)?$/;
var gitlabPath = /^gitlab\/(.*?)\/(.*?)\/(.*?)$/;
var gitlabCommitUrl = /^https?:\/\/(?:www\.)?gitlab\.com\/(.*?)\/(.*?)\/commit\/(.*?)(?:\.diff)?(?:\.patch)?(?:\/.*)?$/;
var gitlabPrUrl = /^https?:\/\/(?:www\.)?gitlab\.com\/(.*?)\/(.*?)\/merge_requests\/(.*?)(?:\.diff)?(?:\.patch)?(?:\/.*)?$/;
var bitbucketPath = /^bitbucket\/(.*?)\/(.*?)\/(.*?)$/;
var bitbucketCommitUrl = /^https?:\/\/(?:www\.)?bitbucket\.org\/(.*?)\/(.*?)\/commits\/(.*?)(?:\/raw)?(?:\/.*)?$/;
var bitbucketPrUrl = /^https?:\/\/(?:www\.)?bitbucket\.org\/(.*?)\/(.*?)\/pull-requests\/(.*?)(?:\/.*)?$/;
function genericUrlGen(provider, userName, projectName, type, value) {
return "https://" + provider + ".com/" + userName + "/" + projectName + "/" + type + "/" + value + ".diff";
}
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;
var finalUrl;
if ((values = githubPath.exec(url))) {
finalUrl = genericUrlGen("github", values[1], values[2], "commit", values[3]);
} else if ((values = githubCommitUrl.exec(url))) {
finalUrl = genericUrlGen("github", values[1], values[2], "commit", values[3]);
} else if ((values = githubPrUrl.exec(url))) {
finalUrl = genericUrlGen("github", values[1], values[2], "pull", values[3]);
} else if ((values = gitlabPath.exec(url))) {
finalUrl = genericUrlGen("gitlab", values[1], values[2], "commit", values[3]);
} else if ((values = gitlabCommitUrl.exec(url))) {
finalUrl = genericUrlGen("gitlab", values[1], values[2], "commit", values[3]);
} else if ((values = gitlabPrUrl.exec(url))) {
finalUrl = genericUrlGen("gitlab", values[1], values[2], "merge_requests", values[3]);
} else if ((values = bitbucketPath.exec(url))) {
finalUrl = bitbucketUrlGen(values[1], values[2], "commit", values[3]);
} else if ((values = bitbucketCommitUrl.exec(url))) {
finalUrl = bitbucketUrlGen(values[1], values[2], "commit", values[3]);
} else if ((values = bitbucketPrUrl.exec(url))) {
finalUrl = bitbucketUrlGen(values[1], values[2], "pullrequests", values[3]);
} else {
console.info("Could not parse url, using the provided url.");
finalUrl = url;
}
return finalUrl;
}
function draw(url) {
var outputFormat = $outputFormat.val();
var showFiles = $showFiles.is(":checked");
var matching = $matching.val();
var wordThreshold = $wordThreshold.val();
var matchingMaxComparisons = $matchingMaxComparisons.val();
var fullUrl = 'https://crossorigin.me/' + url;
fetch(fullUrl)
.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": "1400px"});
} else {
$container.css({"width": ""});
}
diff2htmlUi.draw(container, {
outputFormat: outputFormat,
showFiles: showFiles,
matching: matching,
matchWordsThreshold: wordThreshold,
matchingMaxComparisons: matchingMaxComparisons
});
diff2htmlUi.fileListCloseable(container, false);
diff2htmlUi.highlightCode(container);
});
}
});

View file

@ -4,15 +4,42 @@
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>
<h3>Options:</h3>
<div class="diff-url-options-container">
<h5>Output:</h5>
<label>Format
<select 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>
<label>Show Files
<input id="diff-url-options-show-files" type="checkbox" name="showFiles" checked/>
</label>
<h5>Matching:</h5>
<label>Type
<select 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>
<label>Words Threshold
<input id="diff-url-options-match-words-threshold" type="number" name="matchWordsThreshold" value="0.25" step="0.05"
min="0" max="1"/>
</label>
<label>Maximum Comparisons
<input id="diff-url-options-matching-max-comparisons" type="number" name="matchingMaxComparisons" value="2500"
step="100" min="0"/>
</label>
</div>
<br>
<div class="diff-url-wrapper">
<a id="url-btn" class="diff-url-btn btn btn-sm" href="#">Load</a>
<input id="url" class="diff-url-input" type="text" name="url" placeholder="URL"/>
</div>
<br>
<h2>Line by Line</h2>
<div id="line-by-line" style="margin: 0 auto;">
<div id="url-diff-container" style="margin: 0 auto;">
</div>
<br>
<h3 id="help">Help:</h3>
@ -32,14 +59,17 @@
</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="url.html?diff=https://github.com/rtfpessoa/diff2html/pull/106">https://diff2html.xyz/url?diff=https://github.com/rtfpessoa/diff2html/pull/106</a></p>
<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="url.html?diff=https://github.com/rtfpessoa/diff2html/pull/106">https://diff2html.xyz/url?diff=https://github.com/rtfpessoa/diff2html/pull/106</a>
</p>
<p>You can also use an hashtag (# or #! or #!/) in the end of the url.
This will be overridden if you click any href id and for that reason not advised.</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>
<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>

View file

@ -76,7 +76,7 @@
</li>
<li>
<a href="demo.html">Demo</a>
<a href="url.html?diff=https://github.com/rtfpessoa/diff2html/pull/106">Demo</a>
</li>
<li>

2818
yarn.lock Normal file

File diff suppressed because it is too large Load diff