mirror of
https://github.com/gitbucket/gitbucket.git
synced 2025-11-06 21:45:50 +01:00
Merge branch 'featuer/image-on-diff' of https://github.com/team-lab/gitbucket into team-lab-featuer/image-on-diff
# Conflicts: # src/main/webapp/assets/common/js/gitbucket.js
This commit is contained in:
@@ -474,12 +474,12 @@ function string_score_sort(word, strings, limit){
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
* hilight by result.
|
||||
* highlight by result.
|
||||
* @param score {string:"string target string", matchingPositions:"Array[Interger] matchng positions"}
|
||||
* @param hilight tag ex: '<b>'
|
||||
* @return array of hilighted html elements.
|
||||
* @param highlight tag ex: '<b>'
|
||||
* @return array of highlighted html elements.
|
||||
*/
|
||||
function string_score_hilight(result, tag){
|
||||
function string_score_highlight(result, tag){
|
||||
var str = result.string, msp=0;
|
||||
return hilight([], 0, result.matchingPositions[msp]);
|
||||
function hilight(html, c, mpos){
|
||||
@@ -493,3 +493,213 @@ function string_score_hilight(result, tag){
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* Diff */
|
||||
/****************************************************************************/
|
||||
// add naturalWidth and naturalHeight for ie 8
|
||||
function setNatural(img) {
|
||||
if(typeof img.naturalWidth == 'undefined'){
|
||||
var tmp = new Image();
|
||||
tmp.src = img.src;
|
||||
img.naturalWidth = tmp.width;
|
||||
img.naturalHeight = tmp.height;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* onload handler
|
||||
* @param img <img>
|
||||
*/
|
||||
function onLoadedDiffImages(img){
|
||||
setNatural(img);
|
||||
img = $(img);
|
||||
img.show();
|
||||
var tb = img.parents(".diff-image-render");
|
||||
// Find images. If the image has not loaded yet, value is undefined.
|
||||
var old = tb.find(".diff-old img.diff-image:visible")[0];
|
||||
var neo = tb.find(".diff-new img.diff-image:visible")[0];
|
||||
imageDiff.appendImageMeta(tb, old, neo);
|
||||
if(old && neo){
|
||||
imageDiff.createToolSelector(old, neo).appendTo(tb.parent());
|
||||
}
|
||||
}
|
||||
var imageDiff ={
|
||||
/** append image meta div after image nodes.
|
||||
* @param tb <div class="diff-image-2up">
|
||||
* @param old <img>||undefined
|
||||
* @param neo <img>||undefined
|
||||
*/
|
||||
appendImageMeta:function(tb, old, neo){
|
||||
old = old || {};
|
||||
neo = neo || {};
|
||||
tb.find(".diff-meta").remove();
|
||||
// before loaded, image is not visible.
|
||||
tb.find("img.diff-image:visible").each(function(){
|
||||
var div = $('<p class="diff-meta"><b>W:</b><span class="w"></span> | <b>W:</b><span class="h"></span></p>');
|
||||
div.find('.w').text(this.naturalWidth+"px").toggleClass("diff", old.naturalWidth != neo.naturalWidth);
|
||||
div.find('.h').text(this.naturalHeight+"px").toggleClass("diff", old.naturalHeight != neo.naturalHeight);
|
||||
div.appendTo(this.parentNode);
|
||||
});
|
||||
},
|
||||
/** check this browser can use canvas tag.
|
||||
*/
|
||||
hasCanvasSupport:function(){
|
||||
if(!this.hasCanvasSupport.hasOwnProperty('resultCache')){
|
||||
this.hasCanvasSupport.resultCache = (typeof $('<canvas>')[0].getContext)=='function';
|
||||
}
|
||||
return this.hasCanvasSupport.resultCache;
|
||||
},
|
||||
/** create toolbar
|
||||
* @param old <img>
|
||||
* @param neo <img>
|
||||
* @return jQuery(<ul class="image-diff-tools">)
|
||||
*/
|
||||
createToolSelector:function(old, neo){
|
||||
var self = this;
|
||||
return $('<ul class="image-diff-tools">'+
|
||||
'<li data-mode="diff2up" class="active">2-up</li>'+
|
||||
'<li data-mode="swipe">Swipe</li>'+
|
||||
'<li data-mode="onion">Onion Skin</li>'+
|
||||
'<li data-mode="difference" class="need-canvas">Difference</li>'+
|
||||
'<li data-mode="blink">Blink</li>'+
|
||||
'</ul>')
|
||||
.toggleClass('no-canvas', !this.hasCanvasSupport())
|
||||
.on('click', 'li', function(e){
|
||||
var td = $(this).parents("td");
|
||||
$(e.delegateTarget).find('li').each(function(){ $(this).toggleClass('active',this == e.target); });
|
||||
var mode = $(e.target).data('mode');
|
||||
td.find(".diff-image-render").hide();
|
||||
// create div if not created yet
|
||||
if(td.find(".diff-image-render."+mode).show().length===0){
|
||||
self[mode](old, neo).insertBefore(e.delegateTarget).addClass("diff-image-render");
|
||||
}
|
||||
return false;
|
||||
});
|
||||
},
|
||||
/** (private) calc size from images and css (const)
|
||||
* @param old <img>
|
||||
* @param neo <img>
|
||||
*/
|
||||
calcSizes:function(old, neo){
|
||||
var maxWidth = 869 - 20 - 20 - 4; // set by css
|
||||
var h = Math.min(Math.max(old.naturalHeight, neo.naturalHeight),maxWidth);
|
||||
var w = Math.min(Math.max(old.naturalWidth, neo.naturalWidth),maxWidth);
|
||||
var oldRate = Math.min(h/old.naturalHeight, w/old.naturalWidth);
|
||||
var neoRate = Math.min(h/neo.naturalHeight, w/neo.naturalWidth);
|
||||
var neoW = neo.naturalWidth*neoRate;
|
||||
var neoH = neo.naturalHeight*neoRate;
|
||||
var oldW = old.naturalWidth*oldRate;
|
||||
var oldH = old.naturalHeight*oldRate;
|
||||
var paddingLeft = (maxWidth/2)-Math.max(neoW,oldW)/2;
|
||||
return {
|
||||
height:Math.max(oldH, neoH),
|
||||
width:w,
|
||||
padding:paddingLeft,
|
||||
paddingTop:20, // set by css
|
||||
barWidth:200, // set by css
|
||||
old:{ rate:oldRate, width:oldW, height:oldH },
|
||||
neo:{ rate:neoRate, width:neoW, height:neoH }
|
||||
};
|
||||
},
|
||||
/** (private) create div
|
||||
* @param old <img>
|
||||
* @param neo <img>
|
||||
*/
|
||||
stack:function(old, neo){
|
||||
var size = this.calcSizes(old, neo);
|
||||
var diffNew = $('<div class="diff-new">')
|
||||
.append($("<img>").attr('src',neo.src).css({width:size.neo.width, height:size.neo.height}));
|
||||
var diffOld = $('<div class="diff-old">')
|
||||
.append($("<img>").attr('src',old.src).css({width:size.old.width, height:size.old.height}));
|
||||
var handle = $('<span class="diff-swipe-handle icon icon-resize-horizontal"></span>')
|
||||
.css({marginTop:size.height-5});
|
||||
var bar = $('<hr class="diff-silde-bar">').css({top:size.height+size.paddingTop});
|
||||
var div = $('<div class="diff-image-stack">')
|
||||
.css({height:size.height+size.paddingTop, paddingLeft:size.padding})
|
||||
.append(diffOld, diffNew, bar, handle);
|
||||
return {
|
||||
neo:diffNew,
|
||||
old:diffOld,
|
||||
size:size,
|
||||
handle:handle,
|
||||
bar:bar,
|
||||
div:div,
|
||||
/* add event listener 'on mousemove' */
|
||||
onMoveHandleOnBar:function(callback){
|
||||
div.on('mousemove',function(e){
|
||||
var x = Math.max(Math.min((e.pageX - bar.offset().left), size.barWidth), 0);
|
||||
handle.css({left:x});
|
||||
callback(x, e);
|
||||
});
|
||||
}
|
||||
};
|
||||
},
|
||||
/** create swipe box
|
||||
* @param old <img>
|
||||
* @param neo <img>
|
||||
* @return jQuery(<div class="diff-image-stack swipe">)
|
||||
*/
|
||||
swipe:function(old, neo){
|
||||
var stack = this.stack(old, neo);
|
||||
function setX(x){
|
||||
stack.neo.css({width:x});
|
||||
stack.handle.css({left:x+stack.size.padding});
|
||||
}
|
||||
setX(stack.size.neo.width/2);
|
||||
stack.div.on('mousemove',function(e){
|
||||
setX(Math.max(Math.min(e.pageX - stack.neo.offset().left, stack.size.neo.width),0));
|
||||
});
|
||||
return stack.div.addClass('swipe');
|
||||
},
|
||||
/** create blink box
|
||||
* @param old <img>
|
||||
* @param neo <img>
|
||||
* @return jQuery(<div class="diff-image-stack blink">)
|
||||
*/
|
||||
blink:function(old, neo){
|
||||
var stack = this.stack(old, neo);
|
||||
stack.onMoveHandleOnBar(function(x){
|
||||
stack.neo.toggle(Math.floor(x) % 2 === 0);
|
||||
});
|
||||
return stack.div.addClass('blink');
|
||||
},
|
||||
/** create onion skin box
|
||||
* @param old <img>
|
||||
* @param neo <img>
|
||||
* @return jQuery(<div class="diff-image-stack onion">)
|
||||
*/
|
||||
onion:function(old, neo){
|
||||
var stack = this.stack(old, neo);
|
||||
stack.neo.css({opacity:0.5});
|
||||
stack.onMoveHandleOnBar(function(x){
|
||||
stack.neo.css({opacity:x/stack.size.barWidth});
|
||||
});
|
||||
return stack.div.addClass('onion');
|
||||
},
|
||||
/** create difference box
|
||||
* @param old <img>
|
||||
* @param neo <img>
|
||||
* @return jQuery(<div class="diff-image-stack difference">)
|
||||
*/
|
||||
difference:function(old, neo){
|
||||
var size = this.calcSizes(old,neo);
|
||||
var canvas = $('<canvas>').attr({width:size.width, height:size.height})[0];
|
||||
var context = canvas.getContext('2d');
|
||||
|
||||
context.clearRect(0, 0, size.width, size.height);
|
||||
context.drawImage(neo, 0, 0, size.neo.width, size.neo.height);
|
||||
var neoData = context.getImageData(0, 0, size.neo.width, size.neo.height).data;
|
||||
context.clearRect(0, 0, size.width, size.height);
|
||||
|
||||
context.drawImage(old, 0, 0, size.old.width, size.old.height);
|
||||
var c = context.getImageData(0, 0, size.neo.width, size.neo.height);
|
||||
var cData = c.data;
|
||||
for (var i = cData.length -1; i>0; i --){
|
||||
cData[i] = (i%4===3) ? Math.max(cData[i], neoData[i]) : Math.abs(cData[i] - neoData[i]);
|
||||
}
|
||||
context.putImageData(c, 0, 0);
|
||||
|
||||
return $('<div class="diff-image-stack difference">').append(canvas);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user