From 3e1336cc6d32511daf2acab9c45a517cd3b10058 Mon Sep 17 00:00:00 2001
From: Tom <tw201207@gmail.com>
Date: Wed, 12 Nov 2014 14:31:12 -0500
Subject: [PATCH] Opacity adjustments for image diffs

---
 src/main/java/com/gitblit/wicket/pages/ImageDiffHandler.java |   16 +++++++-
 src/main/resources/gitblit.css                               |   31 +++++++++++++++
 src/main/java/com/gitblit/wicket/pages/BlobDiffPage.java     |    6 +++
 src/main/java/com/gitblit/wicket/pages/scripts/imgdiff.js    |   23 +++++++++++
 src/main/java/com/gitblit/utils/GitBlitDiffFormatter.java    |    2 
 src/main/java/com/gitblit/wicket/pages/CommitDiffPage.java   |    3 +
 src/main/java/com/gitblit/wicket/pages/ComparePage.java      |    3 +
 7 files changed, 80 insertions(+), 4 deletions(-)

diff --git a/src/main/java/com/gitblit/utils/GitBlitDiffFormatter.java b/src/main/java/com/gitblit/utils/GitBlitDiffFormatter.java
index edaed70..3c65267 100644
--- a/src/main/java/com/gitblit/utils/GitBlitDiffFormatter.java
+++ b/src/main/java/com/gitblit/utils/GitBlitDiffFormatter.java
@@ -150,7 +150,7 @@
 			{
 				String binaryDiff = binaryDiffHandler.renderBinaryDiff(formatter.entry);
 				if (binaryDiff != null) {
-					byte[] bb = ("<tr><td colspan='4'>" + binaryDiff + "</td></tr>").getBytes(StandardCharsets.UTF_8);
+					byte[] bb = ("<tr><td colspan='4' align='center'>" + binaryDiff + "</td></tr>").getBytes(StandardCharsets.UTF_8);
 					super.write(bb, 0, bb.length);
 					return;
 				}
diff --git a/src/main/java/com/gitblit/wicket/pages/BlobDiffPage.java b/src/main/java/com/gitblit/wicket/pages/BlobDiffPage.java
index 517e80b..71516ec 100644
--- a/src/main/java/com/gitblit/wicket/pages/BlobDiffPage.java
+++ b/src/main/java/com/gitblit/wicket/pages/BlobDiffPage.java
@@ -55,6 +55,9 @@
 			ImageDiffHandler handler = new ImageDiffHandler(getContextUrl(), repositoryName,
 					parent.getName(), commit.getName(), imageExtensions);
 			diff = DiffUtils.getDiff(r, commit, blobPath, DiffOutputType.HTML, handler).content;
+			if (handler.getImgDiffCount() > 0) {
+				addBottomScript("scripts/imgdiff.js"); // Tiny support script for image diffs
+			}
 			add(new BookmarkablePageLink<Void>("patchLink", PatchPage.class,
 					WicketUtils.newPathParameter(repositoryName, objectId, blobPath)));
 		} else {
@@ -63,6 +66,9 @@
 			ImageDiffHandler handler = new ImageDiffHandler(getContextUrl(), repositoryName,
 					baseCommit.getName(), commit.getName(), imageExtensions);
 			diff = DiffUtils.getDiff(r, baseCommit, commit, blobPath, DiffOutputType.HTML, handler).content;
+			if (handler.getImgDiffCount() > 0) {
+				addBottomScript("scripts/imgdiff.js"); // Tiny support script for image diffs
+			}
 			add(new BookmarkablePageLink<Void>("patchLink", PatchPage.class,
 					WicketUtils.newBlobDiffParameter(repositoryName, baseObjectId, objectId,
 							blobPath)));
diff --git a/src/main/java/com/gitblit/wicket/pages/CommitDiffPage.java b/src/main/java/com/gitblit/wicket/pages/CommitDiffPage.java
index 77d5ccf..e40af51 100644
--- a/src/main/java/com/gitblit/wicket/pages/CommitDiffPage.java
+++ b/src/main/java/com/gitblit/wicket/pages/CommitDiffPage.java
@@ -85,6 +85,9 @@
 		final ImageDiffHandler handler = new ImageDiffHandler(getContextUrl(), repositoryName,
 				parents.isEmpty() ? null : parents.get(0), commit.getName(), imageExtensions);
 		final DiffOutput diff = DiffUtils.getCommitDiff(r, commit, DiffOutputType.HTML, handler);
+		if (handler.getImgDiffCount() > 0) {
+			addBottomScript("scripts/imgdiff.js"); // Tiny support script for image diffs
+		}
 
 		// add commit diffstat
 		int insertions = 0;
diff --git a/src/main/java/com/gitblit/wicket/pages/ComparePage.java b/src/main/java/com/gitblit/wicket/pages/ComparePage.java
index dae8d8e..c0141eb 100644
--- a/src/main/java/com/gitblit/wicket/pages/ComparePage.java
+++ b/src/main/java/com/gitblit/wicket/pages/ComparePage.java
@@ -117,6 +117,9 @@
 					fromCommit.getName(), toCommit.getName(), imageExtensions);
 
 			final DiffOutput diff = DiffUtils.getDiff(r, fromCommit, toCommit, DiffOutputType.HTML, handler);
+			if (handler.getImgDiffCount() > 0) {
+				addBottomScript("scripts/imgdiff.js"); // Tiny support script for image diffs
+			}
 
 			// add compare diffstat
 			int insertions = 0;
diff --git a/src/main/java/com/gitblit/wicket/pages/ImageDiffHandler.java b/src/main/java/com/gitblit/wicket/pages/ImageDiffHandler.java
index 69d84f4..4278f23 100644
--- a/src/main/java/com/gitblit/wicket/pages/ImageDiffHandler.java
+++ b/src/main/java/com/gitblit/wicket/pages/ImageDiffHandler.java
@@ -40,6 +40,8 @@
 	private final String baseUrl;
 	private final List<String> imageExtensions;
 
+	private int imgDiffCount = 0;
+
 	public ImageDiffHandler(final String baseUrl, final String repositoryName, final String oldCommitId,
 			final String newCommitId, final List<String> imageExtensions) {
 		this.baseUrl = baseUrl;
@@ -62,8 +64,10 @@
 			String oldUrl = getImageUrl(diffEntry, Side.OLD);
 			String newUrl = getImageUrl(diffEntry, Side.NEW);
 			if (oldUrl != null && newUrl != null) {
+				imgDiffCount++;
+				String id = "imgdiff" + imgDiffCount;
 				HtmlBuilder builder = new HtmlBuilder("div");
-				Element container = builder.root().appendElement("div").attr("class", "imgdiff");
+				Element container = builder.root().attr("align", "center").appendElement("div").attr("class", "imgdiff");
 				Element resizeable = container.appendElement("div").attr("class", "imgdiff-left");
 				// style='max-width:640px;' is necessary for ensuring that the browser limits large images
 				// to some reasonable width, and to override the "img { max-width: 100%; }" from bootstrap.css,
@@ -73,8 +77,11 @@
 				// is too wide.
 				// XXX: Maybe add a max-height, too, to limit portrait-oriented images to some reasonable height?
 				// (Like a 300x10000px image...)
-				resizeable.appendElement("img").attr("class", "imgdiff imgdiff-left").attr("style", "max-width:640px;").attr("src", oldUrl);
+				resizeable.appendElement("img").attr("class", "imgdiff-left").attr("id", id).attr("style", "max-width:640px;").attr("src", oldUrl);
 				container.appendElement("img").attr("class", "imgdiff").attr("style", "max-width:640px;").attr("src", newUrl);
+				builder.root().appendElement("br");
+				Element slider = builder.root().appendElement("div").attr("class", "imgdiff-slider").attr("id", "slider-" + id);
+				slider.appendElement("div").attr("class", "imgdiff-slider-inner");
 				return builder.toString();
 			}
 			break;
@@ -90,6 +97,11 @@
 		return null;
 	}
 
+	/** Returns the number of image diffs generated so far by this {@link ImageDiffHandler}. */
+	public int getImgDiffCount() {
+		return imgDiffCount;
+	}
+
 	/**
 	 * Constructs a URL that will fetch the designated resource in the git repository. The returned string will
 	 * contain the URL fully URL-escaped, but note that it may still contain unescaped ampersands, so the result
diff --git a/src/main/java/com/gitblit/wicket/pages/scripts/imgdiff.js b/src/main/java/com/gitblit/wicket/pages/scripts/imgdiff.js
new file mode 100644
index 0000000..faa2f33
--- /dev/null
+++ b/src/main/java/com/gitblit/wicket/pages/scripts/imgdiff.js
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2014 Tom <tw201207@gmail.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+jQuery(function () {
+	// Runs on jQuery's document.ready and sets up the scroll event handlers for all image diffs.
+	jQuery(".imgdiff-slider").scroll(function() {
+		var w = 1.0 - (this.scrollLeft / (this.scrollWidth - (this.clientWidth || this.offsetWidth)));
+		// We encode the target img id in the slider's id: slider-imgdiffNNN.
+		jQuery('#' + this.id.substr(this.id.indexOf('-') + 1)).css("opacity", w);
+	})
+});
diff --git a/src/main/resources/gitblit.css b/src/main/resources/gitblit.css
index f6d6b24..bdab205 100644
--- a/src/main/resources/gitblit.css
+++ b/src/main/resources/gitblit.css
@@ -1486,14 +1486,43 @@
 
 img.imgdiff-left {
 	margin-left: 18px; /* Compensate for padding on outer div. */
+	user-select: none;
 }
 
 img.imagediff {
 	user-select: none;
+	/* Checkerboard background */
+    background-color: white;
+    background-image: linear-gradient(45deg, #DDD 25%, transparent 25%, transparent 75%, #DDD 75%, #DDD), linear-gradient(45deg, #DDD 25%, transparent 25%, transparent 75%, #DDD 75%, #DDD);
+    background-size: 16px 16px;
+    background-position: 0 0, 8px 8px;
 }
 
 .diff-img {
-	margin: 2px 2px;
+	margin: 2px;
+}
+
+div.imgdiff-slider {
+	display: inline-block;
+	position: relative;
+	margin: 0px 2px;
+	width: 420px;
+	max-width: 420px;
+	height: 24px;
+	min-height: 18px;
+	overflow-x: scroll;
+	background: linear-gradient(to right, #F00, #0F0);
+}
+
+div.imgdiff-slider-inner {
+	position: absolute;
+	bottom: 0;
+	margin: 0;
+	padding: 0;
+	width : 1000%;
+	height: 1px;
+	border: none;
+	background: transparent;
 }
 
 /* End image diffs */

--
Gitblit v1.9.1