|
|
## -*- coding: utf-8 -*-
|
|
|
<!DOCTYPE html>
|
|
|
|
|
|
<%
|
|
|
c.template_context['repo_name'] = getattr(c, 'repo_name', '')
|
|
|
|
|
|
if hasattr(c, 'rhodecode_db_repo'):
|
|
|
c.template_context['repo_type'] = c.rhodecode_db_repo.repo_type
|
|
|
c.template_context['repo_landing_commit'] = c.rhodecode_db_repo.landing_rev[1]
|
|
|
|
|
|
if getattr(c, 'rhodecode_user', None) and c.rhodecode_user.user_id:
|
|
|
c.template_context['rhodecode_user']['username'] = c.rhodecode_user.username
|
|
|
c.template_context['rhodecode_user']['email'] = c.rhodecode_user.email
|
|
|
c.template_context['rhodecode_user']['notification_status'] = c.rhodecode_user.get_instance().user_data.get('notification_status', True)
|
|
|
c.template_context['rhodecode_user']['first_name'] = c.rhodecode_user.name
|
|
|
c.template_context['rhodecode_user']['last_name'] = c.rhodecode_user.lastname
|
|
|
|
|
|
c.template_context['visual']['default_renderer'] = h.get_visual_attr(c, 'default_renderer')
|
|
|
%>
|
|
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
|
<head>
|
|
|
<script src="${h.asset('js/vendors/webcomponentsjs/webcomponents-lite.min.js', ver=c.rhodecode_version_hash)}"></script>
|
|
|
<link rel="import" href="${h.asset('js/rhodecode-components.html', ver=c.rhodecode_version_hash)}">
|
|
|
<title>${self.title()}</title>
|
|
|
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
|
|
|
<%def name="robots()">
|
|
|
<meta name="robots" content="index, nofollow"/>
|
|
|
</%def>
|
|
|
${self.robots()}
|
|
|
<link rel="icon" href="${h.asset('images/favicon.ico', ver=c.rhodecode_version_hash)}" sizes="16x16 32x32" type="image/png" />
|
|
|
|
|
|
## CSS definitions
|
|
|
<%def name="css()">
|
|
|
<link rel="stylesheet" type="text/css" href="${h.asset('css/style.css', ver=c.rhodecode_version_hash)}" media="screen"/>
|
|
|
<!--[if lt IE 9]>
|
|
|
<link rel="stylesheet" type="text/css" href="${h.asset('css/ie.css', ver=c.rhodecode_version_hash)}" media="screen"/>
|
|
|
<![endif]-->
|
|
|
## EXTRA FOR CSS
|
|
|
${self.css_extra()}
|
|
|
</%def>
|
|
|
## CSS EXTRA - optionally inject some extra CSS stuff needed for specific websites
|
|
|
<%def name="css_extra()">
|
|
|
</%def>
|
|
|
|
|
|
${self.css()}
|
|
|
|
|
|
## JAVASCRIPT
|
|
|
<%def name="js()">
|
|
|
<script>
|
|
|
// setup Polymer options
|
|
|
window.Polymer = {lazyRegister: true, dom: 'shadow'};
|
|
|
|
|
|
// Load webcomponentsjs polyfill if browser does not support native Web Components
|
|
|
(function() {
|
|
|
'use strict';
|
|
|
var onload = function() {
|
|
|
// For native Imports, manually fire WebComponentsReady so user code
|
|
|
// can use the same code path for native and polyfill'd imports.
|
|
|
if (!window.HTMLImports) {
|
|
|
document.dispatchEvent(
|
|
|
new CustomEvent('WebComponentsReady', {bubbles: true})
|
|
|
);
|
|
|
}
|
|
|
};
|
|
|
var webComponentsSupported = (
|
|
|
'registerElement' in document
|
|
|
&& 'import' in document.createElement('link')
|
|
|
&& 'content' in document.createElement('template')
|
|
|
);
|
|
|
if (!webComponentsSupported) {
|
|
|
} else {
|
|
|
onload();
|
|
|
}
|
|
|
})();
|
|
|
</script>
|
|
|
|
|
|
<script src="${h.asset('js/rhodecode/i18n/%s.js' % c.language, ver=c.rhodecode_version_hash)}"></script>
|
|
|
<script type="text/javascript">
|
|
|
// register templateContext to pass template variables to JS
|
|
|
var templateContext = ${h.json.dumps(c.template_context)|n};
|
|
|
|
|
|
var REPO_NAME = "${getattr(c, 'repo_name', '')}";
|
|
|
%if hasattr(c, 'rhodecode_db_repo'):
|
|
|
var REPO_LANDING_REV = '${c.rhodecode_db_repo.landing_rev[1]}';
|
|
|
var REPO_TYPE = '${c.rhodecode_db_repo.repo_type}';
|
|
|
%else:
|
|
|
var REPO_LANDING_REV = '';
|
|
|
var REPO_TYPE = '';
|
|
|
%endif
|
|
|
var APPLICATION_URL = "${h.url('home').rstrip('/')}";
|
|
|
var ASSET_URL = "${h.asset('')}";
|
|
|
var DEFAULT_RENDERER = "${h.get_visual_attr(c, 'default_renderer')}";
|
|
|
var CSRF_TOKEN = "${getattr(c, 'csrf_token', '')}";
|
|
|
% if getattr(c, 'rhodecode_user', None):
|
|
|
var USER = {name:'${c.rhodecode_user.username}'};
|
|
|
% else:
|
|
|
var USER = {name:null};
|
|
|
% endif
|
|
|
|
|
|
var APPENLIGHT = {
|
|
|
enabled: ${'true' if getattr(c, 'appenlight_enabled', False) else 'false'},
|
|
|
key: '${getattr(c, "appenlight_api_public_key", "")}',
|
|
|
% if getattr(c, 'appenlight_server_url', None):
|
|
|
serverUrl: '${getattr(c, "appenlight_server_url", "")}',
|
|
|
% endif
|
|
|
requestInfo: {
|
|
|
% if getattr(c, 'rhodecode_user', None):
|
|
|
ip: '${c.rhodecode_user.ip_addr}',
|
|
|
username: '${c.rhodecode_user.username}'
|
|
|
% endif
|
|
|
},
|
|
|
tags: {
|
|
|
rhodecode_version: '${c.rhodecode_version}',
|
|
|
rhodecode_edition: '${c.rhodecode_edition}'
|
|
|
}
|
|
|
};
|
|
|
|
|
|
|
|
|
Rhodecode = (function() {
|
|
|
function _Rhodecode() {
|
|
|
this.comments = new (function() { /* comments controller */
|
|
|
var self = this;
|
|
|
|
|
|
this.cancelComment = function(node) {
|
|
|
var $node = $(node);
|
|
|
var $td = $node.closest('td');
|
|
|
$node.closest('.comment-inline-form').removeClass('comment-inline-form-open');
|
|
|
return false;
|
|
|
}
|
|
|
this.getLineNumber = function(node) {
|
|
|
var $node = $(node);
|
|
|
return $node.closest('td').attr('data-line-number');
|
|
|
}
|
|
|
this.scrollToComment = function(node, offset) {
|
|
|
if (!node) {
|
|
|
node = $('.comment-selected');
|
|
|
if (!node.length) {
|
|
|
node = $('comment-current')
|
|
|
}
|
|
|
}
|
|
|
$comment = $(node).closest('.comment-current');
|
|
|
$comments = $('.comment-current');
|
|
|
|
|
|
$('.comment-selected').removeClass('comment-selected');
|
|
|
|
|
|
var nextIdx = $('.comment-current').index($comment) + offset;
|
|
|
if (nextIdx >= $comments.length) {
|
|
|
nextIdx = 0;
|
|
|
}
|
|
|
var $next = $('.comment-current').eq(nextIdx);
|
|
|
var $cb = $next.closest('.cb');
|
|
|
$cb.removeClass('cb-collapsed')
|
|
|
|
|
|
var $filediffCollapseState = $cb.closest('.filediff').prev();
|
|
|
$filediffCollapseState.prop('checked', false);
|
|
|
$next.addClass('comment-selected');
|
|
|
scrollToElement($next);
|
|
|
return false;
|
|
|
}
|
|
|
this.nextComment = function(node) {
|
|
|
return self.scrollToComment(node, 1);
|
|
|
}
|
|
|
this.prevComment = function(node) {
|
|
|
return self.scrollToComment(node, -1);
|
|
|
}
|
|
|
this.deleteComment = function(node) {
|
|
|
if (!confirm(_gettext('Delete this comment?'))) {
|
|
|
return false;
|
|
|
}
|
|
|
var $node = $(node);
|
|
|
var $td = $node.closest('td');
|
|
|
var $comment = $node.closest('.comment');
|
|
|
var comment_id = $comment.attr('data-comment-id');
|
|
|
var url = AJAX_COMMENT_DELETE_URL.replace('__COMMENT_ID__', comment_id);
|
|
|
var postData = {
|
|
|
'_method': 'delete',
|
|
|
'csrf_token': CSRF_TOKEN
|
|
|
};
|
|
|
|
|
|
$comment.addClass('comment-deleting');
|
|
|
$comment.hide('fast');
|
|
|
|
|
|
var success = function(response) {
|
|
|
$comment.remove();
|
|
|
return false;
|
|
|
};
|
|
|
var failure = function(data, textStatus, xhr) {
|
|
|
alert("error processing request: " + textStatus);
|
|
|
$comment.show('fast');
|
|
|
$comment.removeClass('comment-deleting');
|
|
|
return false;
|
|
|
};
|
|
|
ajaxPOST(url, postData, success, failure);
|
|
|
}
|
|
|
this.createComment = function(node) {
|
|
|
var $node = $(node);
|
|
|
var $td = $node.closest('td');
|
|
|
var $form = $td.find('.comment-inline-form');
|
|
|
|
|
|
if (!$form.length) {
|
|
|
var tmpl = $('#cb-comment-inline-form-template').html();
|
|
|
var f_path = $node.closest('.filediff').attr('data-f-path');
|
|
|
var lineno = self.getLineNumber(node);
|
|
|
tmpl = tmpl.format(f_path, lineno);
|
|
|
$form = $(tmpl);
|
|
|
|
|
|
var $comments = $td.find('.inline-comments');
|
|
|
if (!$comments.length) {
|
|
|
$comments = $(
|
|
|
$('#cb-comments-inline-container-template').html());
|
|
|
$td.append($comments);
|
|
|
}
|
|
|
|
|
|
$td.find('.cb-comment-add-button').before($form);
|
|
|
|
|
|
var pullRequestId = templateContext.pull_request_data.pull_request_id;
|
|
|
var commitId = templateContext.commit_data.commit_id;
|
|
|
var _form = $form[0];
|
|
|
var commentForm = new CommentForm(_form, commitId, pullRequestId, lineno, false);
|
|
|
var cm = commentForm.getCmInstance();
|
|
|
|
|
|
// set a CUSTOM submit handler for inline comments.
|
|
|
commentForm.setHandleFormSubmit(function(o) {
|
|
|
var text = commentForm.cm.getValue();
|
|
|
|
|
|
if (text === "") {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (lineno === undefined) {
|
|
|
alert('missing line !');
|
|
|
return;
|
|
|
}
|
|
|
if (f_path === undefined) {
|
|
|
alert('missing file path !');
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
var excludeCancelBtn = false;
|
|
|
var submitEvent = true;
|
|
|
commentForm.setActionButtonsDisabled(true, excludeCancelBtn, submitEvent);
|
|
|
commentForm.cm.setOption("readOnly", true);
|
|
|
var postData = {
|
|
|
'text': text,
|
|
|
'f_path': f_path,
|
|
|
'line': lineno,
|
|
|
'csrf_token': CSRF_TOKEN
|
|
|
};
|
|
|
var submitSuccessCallback = function(json_data) {
|
|
|
$form.remove();
|
|
|
console.log(json_data)
|
|
|
try {
|
|
|
var html = json_data.rendered_text;
|
|
|
var lineno = json_data.line_no;
|
|
|
var target_id = json_data.target_id;
|
|
|
|
|
|
$comments.find('.cb-comment-add-button').before(html);
|
|
|
console.log(lineno, target_id, $comments);
|
|
|
|
|
|
} catch (e) {
|
|
|
console.error(e);
|
|
|
}
|
|
|
|
|
|
|
|
|
// re trigger the linkification of next/prev navigation
|
|
|
linkifyComments($('.inline-comment-injected'));
|
|
|
timeagoActivate();
|
|
|
bindDeleteCommentButtons();
|
|
|
commentForm.setActionButtonsDisabled(false);
|
|
|
|
|
|
};
|
|
|
var submitFailCallback = function(){
|
|
|
commentForm.resetCommentFormState(text)
|
|
|
};
|
|
|
commentForm.submitAjaxPOST(
|
|
|
commentForm.submitUrl, postData, submitSuccessCallback, submitFailCallback);
|
|
|
});
|
|
|
|
|
|
setTimeout(function() {
|
|
|
// callbacks
|
|
|
if (cm !== undefined) {
|
|
|
cm.focus();
|
|
|
}
|
|
|
}, 10);
|
|
|
|
|
|
$.Topic('/ui/plugins/code/comment_form_built').prepareOrPublish({
|
|
|
form: _form,
|
|
|
parent: $td[0],
|
|
|
lineno: lineno,
|
|
|
f_path: f_path}
|
|
|
);
|
|
|
}
|
|
|
|
|
|
$form.addClass('comment-inline-form-open');
|
|
|
}
|
|
|
|
|
|
this.renderInlineComments = function(file_comments) {
|
|
|
show_add_button = typeof show_add_button !== 'undefined' ? show_add_button : true;
|
|
|
|
|
|
for (var i = 0; i < file_comments.length; i++) {
|
|
|
var box = file_comments[i];
|
|
|
|
|
|
var target_id = $(box).attr('target_id');
|
|
|
|
|
|
// actually comments with line numbers
|
|
|
var comments = box.children;
|
|
|
|
|
|
for (var j = 0; j < comments.length; j++) {
|
|
|
var data = {
|
|
|
'rendered_text': comments[j].outerHTML,
|
|
|
'line_no': $(comments[j]).attr('line'),
|
|
|
'target_id': target_id
|
|
|
};
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// since order of injection is random, we're now re-iterating
|
|
|
// from correct order and filling in links
|
|
|
linkifyComments($('.inline-comment-injected'));
|
|
|
bindDeleteCommentButtons();
|
|
|
firefoxAnchorFix();
|
|
|
};
|
|
|
|
|
|
})();
|
|
|
}
|
|
|
return new _Rhodecode();
|
|
|
})();
|
|
|
|
|
|
</script>
|
|
|
<%include file="/base/plugins_base.html"/>
|
|
|
<!--[if lt IE 9]>
|
|
|
<script language="javascript" type="text/javascript" src="${h.asset('js/excanvas.min.js')}"></script>
|
|
|
<![endif]-->
|
|
|
<script language="javascript" type="text/javascript" src="${h.asset('js/rhodecode/routes.js', ver=c.rhodecode_version_hash)}"></script>
|
|
|
<script> var alertMessagePayloads = ${h.flash.json_alerts()|n}; </script>
|
|
|
## avoide escaping the %N
|
|
|
<script language="javascript" type="text/javascript" src="${h.asset('js/rhodecode-components.js', ver=c.rhodecode_version_hash)}"></script>
|
|
|
<script>CodeMirror.modeURL = "${h.asset('') + 'js/mode/%N/%N.js?ver='+c.rhodecode_version_hash}";</script>
|
|
|
|
|
|
|
|
|
## JAVASCRIPT EXTRA - optionally inject some extra JS for specificed templates
|
|
|
${self.js_extra()}
|
|
|
|
|
|
<script type="text/javascript">
|
|
|
$(document).ready(function(){
|
|
|
show_more_event();
|
|
|
timeagoActivate();
|
|
|
})
|
|
|
</script>
|
|
|
|
|
|
</%def>
|
|
|
|
|
|
## JAVASCRIPT EXTRA - optionally inject some extra JS for specificed templates
|
|
|
<%def name="js_extra()"></%def>
|
|
|
${self.js()}
|
|
|
|
|
|
<%def name="head_extra()"></%def>
|
|
|
${self.head_extra()}
|
|
|
## extra stuff
|
|
|
%if c.pre_code:
|
|
|
${c.pre_code|n}
|
|
|
%endif
|
|
|
</head>
|
|
|
<body id="body">
|
|
|
<noscript>
|
|
|
<div class="noscript-error">
|
|
|
${_('Please enable JavaScript to use RhodeCode Enterprise')}
|
|
|
</div>
|
|
|
</noscript>
|
|
|
## IE hacks
|
|
|
<!--[if IE 7]>
|
|
|
<script>$(document.body).addClass('ie7')</script>
|
|
|
<![endif]-->
|
|
|
<!--[if IE 8]>
|
|
|
<script>$(document.body).addClass('ie8')</script>
|
|
|
<![endif]-->
|
|
|
<!--[if IE 9]>
|
|
|
<script>$(document.body).addClass('ie9')</script>
|
|
|
<![endif]-->
|
|
|
|
|
|
${next.body()}
|
|
|
%if c.post_code:
|
|
|
${c.post_code|n}
|
|
|
%endif
|
|
|
<rhodecode-app></rhodecode-app>
|
|
|
</body>
|
|
|
</html>
|
|
|
|