Tom
2014-11-12 3e1336cc6d32511daf2acab9c45a517cd3b10058
Opacity adjustments for image diffs

* ImageDiffHandler adds the slider; styled in gitblit.css
* imgdiff.js is a little bottom-loaded Javascript that adjusts the
opacity on sliders' scroll events.
* The three diff pages add this bottom script to the page if needed
* GitBlitDiffFormatter: center image diffs.
1 files added
6 files modified
84 ■■■■■ changed files
src/main/java/com/gitblit/utils/GitBlitDiffFormatter.java 2 ●●● patch | view | raw | blame | history
src/main/java/com/gitblit/wicket/pages/BlobDiffPage.java 6 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/wicket/pages/CommitDiffPage.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/wicket/pages/ComparePage.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/wicket/pages/ImageDiffHandler.java 16 ●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/wicket/pages/scripts/imgdiff.js 23 ●●●●● patch | view | raw | blame | history
src/main/resources/gitblit.css 31 ●●●●● patch | view | raw | blame | history
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;
                }
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)));
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;
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;
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
src/main/java/com/gitblit/wicket/pages/scripts/imgdiff.js
New file
@@ -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);
    })
});
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 */