Page MenuHomeSoftware Heritage

revision.html
No OneTemporary

revision.html

{% extends "browse.html" %}
{% load static %}
{% block header %}
{% include "includes/content-scripts.html" %}
<script src="{% static 'js/jquery-waypoints/jquery.waypoints.min.js' %}"></script>
{% endblock %}
{% block swh-browse-before-panels %}
{% if origin_context %}
{% include "includes/origin-visit-snapshot.html" %}
{% endif %}
{% endblock %}
{% block swh-browse-main-panel-content %}
<div style="height: 35px;margin: 4px;">
<i class="octicon octicon-git-commit fa-fw"></i>Revision <b>{{ swh_object_metadata.id }}</b>
authored by {{ swh_object_metadata.author }} on <b>{{ swh_object_metadata.date }}</b>
</div>
<div class="panel panel-default" style="overflow-x: auto;">
<div class="panel-heading" style="padding: 10px">
<a data-toggle="collapse" id="swh-collapse-revision-message" href="#swh-revision-message">
<div class="pull-left">
<pre style="white-space: pre-wrap; background-color: inherit; padding: 0px; margin: 0px; border: none;"><h2 style="padding-bottom: 0px;">{{ message_header }}</h2></pre>
</div>
<div class="clearfix"></div>
</a>
</div>
<div id="swh-revision-message" class="panel-collapse collapse">
<pre style="white-space: pre-wrap; margin: 0px; border: none; border-radius: 0px;">{{ message_body }}</pre>
</div>
</div>
<div style="margin: 4px; padding-bottom: 5px;">
{{ parents_links }}
</div>
<ul class="nav nav-tabs" style="padding-left: 5px;">
<li class="active"><a data-toggle="tab" href="#swh-revision-tree">Files</a></li>
<li><a data-toggle="tab" href="#swh-revision-changes">Changes</a></li>
</ul>
<div class="tab-content">
<div id="swh-revision-tree" class="tab-pane active">
{% include "includes/top-navigation.html" %}
{% if content_size %}
{% include "includes/content-display.html" %}
{% else %}
{% include "includes/directory-display.html" %}
{% endif %}
</div>
<div id="swh-revision-changes" class="tab-pane">
<div class="panel-group" style="padding: 5px;">
<div class="panel panel-default" style="overflow-x: auto;">
<div class="panel-heading">
<a data-toggle="collapse" href="#swh-revision-changes-list">
<div class="pull-left">
Showing <strong id="swh-revision-changed-files"></strong>
with <strong id="swh-revision-lines-added" style="color:green">0 additions</strong>
and <strong id="swh-revision-lines-deleted" style="color:red">0 deletions</strong>
(<span id="swh-nb-diffs-computed">0</span> / {{ changes|length }} diffs computed)
</div>
<div class="pull-right">
<button class="btn btn-md btn-swh" type="button" onclick="compute_all_diffs(event)" id="swh-compute-all-diffs"
title="By default, diffs will be computed as the view is scrolled.
Pushing that button will request the immediate computation of all diffs.">Compute all diffs</button>
</div>
<div class="clearfix"></div>
</a>
</div>
<div id="swh-revision-changes-list" class="panel-collapse collapse">
<pre style="background: none; border: none;">{{ changes_msg }}</pre>
</div>
</div>
{% for change in changes %}
<div id="panel_{{ change.id }}" class="panel panel-default swh-file-diff-panel" style="overflow-x: auto;">
<div class="panel-heading">
<a data-toggle="collapse" href="#panel_{{ change.id }}_content">
<div class="pull-left swh-title-color">
{% if change.type != 'rename' %}
<strong>{{ change.path }}</strong>
{% else %}
<strong>{{ change.from_path }} &rarr; {{ change.to_path }}</strong>
{% endif %}
</div>
</a>
<div class="pull-right">
{% if change.type != 'rename' %}
<div class="btn-group diff-styles" data-toggle="buttons" style="visibility: hidden;">
<button class="btn btn-md btn-swh active unified-diff-button" type="button" onclick="show_unified_diff(event, '{{ change.id }}')">Unified</button>
<button class="btn btn-md btn-swh splitted-diff-button" type="button" onclick="show_splitted_diff(event, '{{ change.id }}')">Side-by-side</button>
</div>
{% endif %}
<a href="{{ change.content_url }}" class="btn btn-md btn-swh" role="button">View file</a>
</div>
<div class="clearfix"></div>
</div>
<div id="panel_{{ change.id }}_content" class="panel-collapse collapse in">
<div class="swh-diff-loading" id="{{ change.id }}-loading" style="text-align: center;visibility: hidden;">
<img src="{% static 'img/swh-spinner.gif' %}"></img>
<p>Loading diff ...</p>
</div>
<div class="highlightjs swh-content" style="display: none;" id="{{ change.id }}-highlightjs">
<div id="{{ change.id }}-unified-diff">
<pre><code class="{{ change.id }}" id="{{ change.id }}"></code></pre>
</div>
<div style="width: 100%; display: none;" id="{{ change.id }}-splitted-diff">
<pre style="width: 50%; float: left;"><code class="{{ change.id }}" id="{{ change.id }}-from"></code></pre>
<pre style="width: 50%"><code class="{{ change.id }}" id="{{ change.id }}-to"></code></pre>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
<script>
// number of changed files in the revision
var nb_changed_files = {{ changes|length }};
// to track the number of already computed files diffs
var nb_diffs_computed = 0;
// the no newline at end of file marker from Github
var no_nl_marker = '<span class="no-nl-marker" title="No newline at end of file">' +
'<svg aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16">' +
' <path fill-rule="evenodd" d="M16 5v3c0 .55-.45 1-1 1h-3v2L9 8l3-3v2h2V5h2zM8 8c0 2.2-1.8 4-4 4s-4-1.8-4-4 1.8-4 4-4 4 1.8 4 4zM1.5 9.66L5.66 5.5C5.18 5.19 4.61 5 4 5 2.34 5 1 6.34 1 8c0 .61.19 1.17.5 1.66zM7 8c0-.61-.19-1.17-.5-1.66L2.34 10.5c.48.31 1.05.5 1.66.5 1.66 0 3-1.34 3-3z"></path>' +
'</svg>' +
'</span>';
// to track the total number of added lines in files diffs
var nb_additions = 0;
// to track the total number of deleted lines in files diffs
var nb_deletions = 0;
// to track the already computed diffs by id
var computed_diffs = {};
// map a diff id to its computation url
var diffs_urls = {};
// to check if a DOM element is in the viewport
function is_in_viewport(elt) {
var elementTop = $(elt).offset().top;
var elementBottom = elementTop + $(elt).outerHeight();
var viewportTop = $(window).scrollTop();
var viewportBottom = viewportTop + $(window).height();
return elementBottom > viewportTop && elementTop < viewportBottom;
}
// to format the diffs line numbers
function format_ln_diff(from_line, to_line, max_number_chars) {
var ret = '';
if (from_line != null) {
for (var i = 0 ; i < (max_number_chars - from_line.length); ++i) {
ret += ' ';
}
ret += from_line;
}
if (from_line != null && to_line != null) {
ret += ' ';
}
if (to_line != null) {
for (var i = 0 ; i < (max_number_chars - to_line.length); ++i) {
ret += ' ';
}
ret += to_line;
}
return ret;
}
// callback to switch from side-by-side diff to unified one
function show_unified_diff(event, diff_id) {
$('#' + diff_id + '-splitted-diff').css('display', 'none');
$('#' + diff_id + '-unified-diff').css('display', 'block');
$(event.target).parent().find('.splitted-diff-button').removeClass('active');
$(event.target).parent().find('.unified-diff-button').addClass('active');
}
// callback to switch from unified diff to side-by-side one
function show_splitted_diff(event, diff_id) {
$('#' + diff_id + '-unified-diff').css('display', 'none');
$('#' + diff_id + '-splitted-diff').css('display', 'block');
$(event.target).parent().find('.unified-diff-button').removeClass('active');
$(event.target).parent().find('.splitted-diff-button').addClass('active');
}
// to compute diff and process it for display
function compute_diff(diff_url, diff_id) {
// force diff computation ?
var force = diff_url.indexOf('force=true') != -1;
// it no forced computation and diff already computed, do nothing
if (!force && computed_diffs.hasOwnProperty(diff_id)) {
return;
}
// mark diff computation as already requested
computed_diffs[diff_id] = true;
$('#' + diff_id + '-loading').css('visibility', 'visible');
// set spinner visible while requesting diff
$('#' + diff_id + '-loading').css('display', 'block');
$('#' + diff_id + '-highlightjs').css('display', 'none');
// request diff computation and process it
$.ajax({
url: diff_url,
dataType: 'json',
success: function (data) {
// increment number of computed diffs
++nb_diffs_computed;
// toggle the 'Compute all diffs' button if all diffs have been computed
if (nb_diffs_computed == nb_changed_files) {
$('#swh-compute-all-diffs').addClass('active');
}
// Large diff (> threshold) are not automatically computed,
// add a button to force its computation
if (data.diff_str.indexOf('Large diff') == 0) {
$('#' + diff_id)[0].innerHTML = data.diff_str +
'<br/><button class="btn btn-md btn-swh" type="button" onclick="compute_diff(\'' +
diff_url + '&force=true\', \'' + diff_id + '\')">Request diff</button>'
} else {
// prepare code highlighting
$('.' + diff_id).removeClass('nohighlight-swh');
$('.' + diff_id).addClass(data.language);
// set unified diff text
$('#' + diff_id).text(data.diff_str);
// code highlighting for unified diff
$('#' + diff_id).each(function(i, block) {
hljs.highlightBlock(block);
hljs.lineNumbersBlock(block);
});
// process unified diff lines in order to generate side-by-side diffs text
// but also compute line numbers for unified and side-by-side difss
var lines_info_regexp = new RegExp(/@@ -(\d+),(\d+) \+(\d+),(\d+) @@/g);
var base_from_line = '';
var base_to_line = '';
var from_to_lines = [];
var from_lines = [];
var to_lines = [];
var max_number_chars = 0;
var diff_from_str = '';
var diff_to_str = '';
var lines_offset = 0;
$('#' + diff_id + ' .hljs-ln-numbers').each(function(i, ln_elt) {
var ln_text = ln_elt.nextSibling.innerText;
var lines_info = lines_info_regexp.exec(ln_text);
var from_line = '';
var to_line = '';
// parsed lines info from the diff output
if (lines_info) {
base_from_line = parseInt(lines_info[1]) - 1;
base_to_line = parseInt(lines_info[3]) - 1;
lines_offset = 0;
diff_from_str += (ln_text + '\n');
diff_to_str += (ln_text + '\n');
from_lines.push('');
to_lines.push('');
// line removed in the from file
} else if (ln_text.length > 0 && ln_text[0] == '-') {
base_from_line = base_from_line + 1;
from_line = base_from_line.toString();
from_lines.push(from_line);
++nb_deletions;
diff_from_str += (ln_text + '\n');
++lines_offset;
// line added in the from file
} else if (ln_text.length > 0 && ln_text[0] == '+') {
base_to_line = base_to_line + 1;
to_line = base_to_line.toString();
to_lines.push(to_line);
++nb_additions;
diff_to_str += (ln_text + '\n');
--lines_offset;
// line present in both files
} else {
base_from_line = base_from_line + 1;
base_to_line = base_to_line + 1;
from_line = base_from_line.toString();
to_line = base_to_line.toString();
for (var j = 0 ; j < Math.abs(lines_offset) ; ++j) {
if (lines_offset > 0) {
diff_to_str += '\n';
to_lines.push('');
} else {
diff_from_str += '\n';
from_lines.push('');
}
}
lines_offset = 0;
diff_from_str += (ln_text + '\n');
diff_to_str += (ln_text + '\n');
to_lines.push(to_line);
from_lines.push(from_line);
}
if (!base_from_line) {
from_line = '';
}
if (!base_to_line) {
to_line = '';
}
from_to_lines[i] = [from_line, to_line];
max_number_chars = Math.max(max_number_chars, from_line.length);
max_number_chars = Math.max(max_number_chars, to_line.length);
});
// set side-by-side diffs text
$('#' + diff_id + '-from').text(diff_from_str);
$('#' + diff_id + '-to').text(diff_to_str);
// code highlighting for side-by-side diffs
$('#' + diff_id + '-from, #' + diff_id + '-to').each(function(i, block) {
hljs.highlightBlock(block);
hljs.lineNumbersBlock(block);
});
// diff highlighting for added/removed lines on top of code highlighting
$('.' + diff_id + ' .hljs-ln-numbers').each(function(i, ln_elt) {
var ln_text = ln_elt.nextSibling.innerText;
var lines_info = lines_info_regexp.exec(ln_text);
if (lines_info) {
$(ln_elt).parent().addClass('swh-diff-lines-info');
} else if (ln_text.length > 0 && ln_text[0] == '-') {
$(ln_elt).parent().addClass('swh-diff-removed-line');
} else if (ln_text.length > 0 && ln_text[0] == '+') {
$(ln_elt).parent().addClass('swh-diff-added-line');
}
});
// set line numbers for unified diff
$('#' + diff_id + ' .hljs-ln-numbers').each(function(i, ln_elt) {
$(ln_elt).children().attr('data-line-number',
format_ln_diff(from_to_lines[i][0], from_to_lines[i][1],
max_number_chars));
});
// set line numbers for the from side-by-side diff
$('#' + diff_id + '-from .hljs-ln-numbers').each(function(i, ln_elt) {
$(ln_elt).children().attr('data-line-number',
format_ln_diff(from_lines[i], null,
max_number_chars));
});
// set line numbers for the to side-by-side diff
$('#' + diff_id + '-to .hljs-ln-numbers').each(function(i, ln_elt) {
$(ln_elt).children().attr('data-line-number',
format_ln_diff(null, to_lines[i],
max_number_chars));
});
// last processings:
// - remove the '+' and '-' at the beginning of the diff lines
// from code highlighting
// - add the "no new line at end of file marker" if needed
$('.' + diff_id + ' .hljs-ln-line').each(function(i, ln_elt) {
if (ln_elt.firstChild) {
if (ln_elt.firstChild.nodeName != "#text") {
var line_text = ln_elt.firstChild.innerHTML;
if (line_text[0] == '-' || line_text[0] == '+') {
ln_elt.firstChild.innerHTML = line_text.substr(1);
var new_text_node = document.createTextNode(line_text[0]);
$(ln_elt).prepend(new_text_node);
}
}
$(ln_elt).contents().filter(function() {
return this.nodeType === 3; //Node.TEXT_NODE
}).each(function(i, textNode) {
var swh_no_nl_marker = '[swh-no-nl-marker]';
if (textNode.textContent.indexOf(swh_no_nl_marker) != -1) {
textNode.textContent = textNode.textContent.replace(swh_no_nl_marker, '');
$(ln_elt).append($(no_nl_marker));
}
});
}
});
// remove empty last line added by highlight.js
$('#' + diff_id + ' tr:last').remove();
$('#' + diff_id + '-from tr:last').remove();
$('#' + diff_id + '-to tr:last').remove();
$('#' + diff_id + '-from tr:last').remove();
$('#' + diff_id + '-to tr:last').remove();
// hide the diff mode switch button in case of not generated diffs
if (data.diff_str.indexOf('Diffs are not generated for non textual content') != 0) {
$('#panel_' + diff_id + ' .diff-styles').css('visibility', 'visible');
}
}
// set the unified diff visible by default
$('#' + diff_id + '-loading').css('display', 'none');
$('#' + diff_id + '-highlightjs').css('display', 'block');
// update displayed counters
$('#swh-revision-lines-added').text(nb_additions + ' additions');
$('#swh-revision-lines-deleted').text(nb_deletions + ' deletions');
$('#swh-nb-diffs-computed').text(nb_diffs_computed);
// refresh the waypoints triggering diffs computation as
// the DOM layout has been updated
Waypoint.refreshAll();
}
});
}
// callback when the 'Changes' tab is activated
$(document).on('shown.bs.tab', 'a[data-toggle="tab"]', function (e) {
if (e.target.text == 'Changes') {
// iterate on list of file changes
{% for change in changes %}
// map diff id to diff computation url
diffs_urls['{{ change.id }}'] = '{{ change.diff_url }}';
// in order to not send too much diff computation requests
// (as the file changes list can be large),
// diffs computation will be requested on the fly
// as the view is scrolled
// create a waypoint that will trigger diff computation when
// the top of the diff panel hits the bottom of the viewport
$('#panel_{{ change.id }}').waypoint({
handler: function() {
if (is_in_viewport($('#panel_{{ change.id }}'))) {
compute_diff('{{ change.diff_url }}', '{{ change.id }}');
this.destroy();
}
},
offset: '100%'
});
// create a waypoint that will trigger diff computation when
// the bottom of the diff panel hits the top of the viewport
$('#panel_{{ change.id }}').waypoint({
handler: function() {
if (is_in_viewport($('#panel_{{ change.id }}'))) {
compute_diff('{{ change.diff_url }}', '{{ change.id }}');
this.destroy();
}
},
offset: function() {
return -$('#panel_{{ change.id }}').height();
}
});
{% endfor %}
// compute visible diffs when navigating to the 'Changes' tab
compute_visible_diffs();
$('#readme-panel').css('display', 'none');
} else if (e.target.text == 'Files') {
$('#readme-panel').css('display', 'block');
}
});
// to compute all visible diffs in the viewport
function compute_visible_diffs() {
$('.swh-file-diff-panel').each(function(i, elt) {
if (is_in_viewport(elt)) {
diff_id = elt.id.replace('panel_', '');
compute_diff(diffs_urls[diff_id], diff_id);
}
});
}
// callback when the user clicks on the 'Compute all diffs' button
function compute_all_diffs(event) {
$(event.target).addClass('active');
for (var diff_id in diffs_urls) {
if (diffs_urls.hasOwnProperty(diff_id)) {
compute_diff(diffs_urls[diff_id], diff_id);
}
}
event.stopPropagation();
}
$(document).ready(function() {
var changed_files_text = nb_changed_files + ' changed file';
if (nb_changed_files != 1) {
changed_files_text += 's';
}
$('#swh-revision-changed-files').text(changed_files_text);
{% if message_body|length > 0 %}
$('#swh-revision-message').addClass('in');
{% else %}
$('#swh-collapse-revision-message').attr('data-toggle', '');
{% endif %}
var $root = $('html, body');
// callback when the user requests to scroll on a specific diff or back to top
$('#swh-revision-changes-list a[href^="#"], #back-to-top a[href^="#"]').click(function() {
var href = $.attr(this, 'href');
// disable waypoints while scrolling as we do not want to
// launch computation of diffs the user is not interested in
// (file changes list can be large)
Waypoint.disableAll();
$root.animate(
{
scrollTop: $(href).offset().top
},
{
duration: 500,
complete: function () {
window.location.hash = href;
// enable waypoints back after scrolling
Waypoint.enableAll();
// compute diffs visible in the viewport
compute_visible_diffs();
}
});
return false;
});
});
</script>
{% endblock %}
{% block swh-browse-after-panels %}
{% include "includes/readme-display.html" %}
{% endblock %}

File Metadata

Mime Type
text/html
Expires
Fri, Jul 4, 2:52 PM (4 d, 1 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3417950

Event Timeline