aboutsummaryrefslogtreecommitdiffstats
path: root/testing-client/pom.xml
diff options
context:
space:
mode:
Diffstat (limited to 'testing-client/pom.xml')
-rw-r--r--testing-client/pom.xml2
1 files changed, 1 insertions, 1 deletions
diff --git a/testing-client/pom.xml b/testing-client/pom.xml
index 2e2ea723c..b64f920b4 100644
--- a/testing-client/pom.xml
+++ b/testing-client/pom.xml
@@ -6,7 +6,7 @@
<parent>
<groupId>org.aspectj</groupId>
<artifactId>aspectj-parent</artifactId>
- <version>1.9.19-SNAPSHOT</version>
+ <version>1.9.19</version>
</parent>
<artifactId>testing-client</artifactId>
ight .k { color: #008800; font-weight: bold } /* Keyword */ .highlight .ch { color: #888888 } /* Comment.Hashbang */ .highlight .cm { color: #888888 } /* Comment.Multiline */ .highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */ .highlight .cpf { color: #888888 } /* Comment.PreprocFile */ .highlight .c1 { color: #888888 } /* Comment.Single */ .highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */ .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .gr { color: #aa0000 } /* Generic.Error */ .highlight .gh { color: #333333 } /* Generic.Heading */ .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ .highlight .go { color: #888888 } /* Generic.Output */ .highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #666666 } /* Generic.Subheading */ .highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
/*
 * 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.
 */
package com.gitblit.wicket.pages;

import java.nio.charset.StandardCharsets;
import java.util.List;

import org.apache.wicket.protocol.http.WicketURLEncoder;
import org.eclipse.jgit.diff.DiffEntry;
import org.eclipse.jgit.diff.DiffEntry.Side;
import org.jsoup.nodes.Element;

import com.gitblit.servlet.RawServlet;
import com.gitblit.utils.DiffUtils;
import com.gitblit.utils.HtmlBuilder;

/**
 * A {@link DiffUtils.BinaryDiffHandler BinaryDiffHandler} for images.
 *
 * @author Tom <tw201207@gmail.com>
 */
public class ImageDiffHandler implements DiffUtils.BinaryDiffHandler {

	private final String oldCommitId;
	private final String newCommitId;
	private final String repositoryName;
	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;
		this.repositoryName = repositoryName;
		this.oldCommitId = oldCommitId;
		this.newCommitId = newCommitId;
		this.imageExtensions = imageExtensions;
	}

	/** {@inheritDoc} */
	@Override
	public String renderBinaryDiff(DiffEntry diffEntry) {
		switch (diffEntry.getChangeType()) {
		case MODIFY:
		case RENAME:
		case COPY:
			// TODO: for very small images such as icons, the slider doesn't really help. Two possible
			// approaches: either upscale them for display (may show blurry upscaled images), or show
			// them side by side (may still be too small to really make out the differences).
			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 wrapper = builder.root().attr("class", "imgdiff-container").attr("id", "imgdiff-" + id);
				Element container = wrapper.appendElement("div").attr("class", "imgdiff-ovr-slider").appendElement("div").attr("class", "imgdiff");
				Element old = 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,
				// which would scale the left image to the width of its resizeable container, which isn't what
				// we want here. Note that the max-width must be defined directly as inline style on the element,
				// otherwise browsers ignore it if the image is larger, and we end up with an image display that
				// is too wide.
				// XXX: Maybe add a max-height, too, to limit portrait-oriented images to some reasonable height?
				// (Like a 300x10000px image...)
				old.appendElement("img").attr("class", "imgdiff-old").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);
				wrapper.appendElement("br");
				wrapper.appendElement("div").attr("class", "imgdiff-opa-container").appendElement("div").attr("class", "imgdiff-opa-slider");
				return builder.toString();
			}
			break;
		case ADD:
			String url = getImageUrl(diffEntry, Side.NEW);
			if (url != null) {
				return new HtmlBuilder("img").root().attr("class", "diff-img").attr("src", url).toString();
			}
			break;
		default:
			break;
		}
		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
	 * must still be run through HTML escaping if it is to be used in HTML.
	 *
	 * @return the URL to the image, if the given {@link DiffEntry} and {@link Side} refers to an image, or {@code null} otherwise.
	 */
	protected String getImageUrl(DiffEntry entry, Side side) {
		String path = entry.getPath(side);
		int i = path.lastIndexOf('.');
		if (i > 0) {
			String extension = path.substring(i + 1);
			for (String ext : imageExtensions) {
				if (ext.equalsIgnoreCase(extension)) {
					String commitId = Side.NEW.equals(side) ? newCommitId : oldCommitId;
					if (commitId != null) {
						return RawServlet.asLink(baseUrl, urlencode(repositoryName), commitId, urlencode(path));
					} else {
						return null;
					}
				}
			}
		}
		return null;
	}

	/**
	 * Encode a URL component of a {@link RawServlet} URL in the special way that the servlet expects it. Note that
	 * the %-encoding used does not encode '&amp;' or '&lt;'. Slashes are not encoded in the result.
	 *
	 * @param component
	 *            to encode using %-encoding
	 * @return the encoded component
	 */
	protected String urlencode(final String component) {
		// RawServlet handles slashes itself. Note that only the PATH_INSTANCE fits the bill here: it encodes
		// spaces as %20, and we just have to correct for encoded slashes. Java's standard URLEncoder would
		// encode spaces as '+', and I don't know what effects that would have on other parts of GitBlit. It
		// would also be wrong for path components (but fine for a query part), so we'd have to correct it, too.
		//
		// Actually, this should be done in RawServlet.asLink(). As it is now, this may be incorrect if that
		// operation ever uses query parameters instead of paths, or if it is fixed to urlencode its path
		// components. But I don't want to touch that static method in RawServlet.
		return WicketURLEncoder.PATH_INSTANCE.encode(component, StandardCharsets.UTF_8.name()).replaceAll("%2[fF]", "/");
	}
}