{% extends "repo_master.html" %} {% from "_formhelper.html" import render_field_in_row, show_comment, render_bootstrap_field %} {% block title %} {%- if pull_request -%} PR#{{ requestid }}: {{ pull_request.title | noJS(ignore="img")}} {%- elif form and (g.repo_admin or remote_git) -%} Create new Pull Request for {{ branch_to }} {%- elif origin == 'compare_commits' -%} Diff from {{ commit1 }} to {{ commit2 }} {%- else -%} Diff from {{ branch_from }} to {{ branch_to }} {%- endif %} - {{ repo.namespace + '/' if repo.namespace }}{{ repo.name }} {% endblock %} {% set tag = "home" %} {% block header %} <link href="{{ url_for('static', filename='emoji/emojione.sprites.css') }}" rel="stylesheet" /> <link href="{{ url_for('static', filename='selectize.bootstrap3.css') }}" rel="stylesheet" /> <link href="{{ url_for('static', filename='atwho/jquery.atwho.css') }}" rel="stylesheet" /> {% endblock %} {% block repo %} <div class="row"> <div class="{% if pull_request %}col-md-8{% elif form and (g.repo_admin or remote_git) %}col-md-12{%endif%}"> {% if pull_request %} <h3><span class="label label-default">PR#{{requestid}}</span> {% if pull_request.status != 'Open'%} <span class="label {{'label-success' if pull_request.status == 'Merged' else 'label-danger'}}">{{pull_request.status}}</span> {% endif %} {{ pull_request.title | noJS(ignore="img") | safe}} {% if authenticated and (g.fas_user.username == pull_request.user.username or g.repo_admin) and pull_request.status == 'Open'%} <span class="pull-xs-right"> {% if pull_request.status == 'Open' and authenticated and (g.repo_admin or g.fas_user.username == pull_request.user.username) %} <form style="display:inline;" action="{{ url_for( 'cancel_request_pull', username=username, namespace=repo.namespace, repo=repo.name, requestid=requestid) }}" method="POST"> {% endif %} <div class="btn-group" role="group" aria-label="Basic example"> <a class="btn btn-sm btn-primary" href="{{ url_for( 'request_pull_edit', repo=repo.name, username=username, namespace=repo.namespace, requestid=requestid) }}" title="Update title"><span class="oi" data-glyph="pencil"></span></a> {% if pull_request.status == 'Open' and authenticated and (g.repo_admin or g.fas_user.username == pull_request.user.username) %} {{ mergeform.csrf_token }} <button type="submit" value="Close" id="cancel_pr" class="btn btn-danger btn-sm" title="Close PR without merging it"> <span class="oi" data-glyph="x"></span> </button> {% endif %} </div> {% if pull_request.status == 'Open' and authenticated and (g.repo_admin or g.fas_user.username == pull_request.user.username) %} </form> {% endif %} </span> {% endif %} </h3> <h5 class="text-muted"> Proposed <a href="#" data-toggle="tooltip" title="{{ pull_request.date_created.strftime('%b %d %Y %H:%M:%S') }}">{{ pull_request.date_created |humanize }}</a> by {{ pull_request.user.default_email | avatar(16) | safe }} {{ pull_request.user.user }} </h5> From <span class="pr-toplabel">{{ pull_request.project_from.fullname or pull_request.remote_git }}</span> <span class="pr-toplabel"> <span class="oi" data-glyph="random"> </span> <a href="{{ url_for('view_repo_branch', repo=pull_request.project_from.name, username=pull_request.project_from.user.user if pull_request.project_from.is_fork else None, namespace=repo.namespace, branchname=pull_request.branch_from) }}"> {{ pull_request.branch_from }} </a> </span> into <span class="pr-toplabel">{{ pull_request.project.fullname }}</span> <span class="pr-toplabel"><span class="oi" data-glyph="random"></span> <a href="{{ url_for('view_repo_branch', repo=pull_request.project.name, username=pull_request.project.user.user if pull_request.project.is_fork else None, namespace=repo.namespace, branchname=pull_request.branch) }}"> {{ pull_request.branch }} </a> </span> {%if pull_request and pull_request.initial_comment %} <section class="m-t-1" id="comment-0"> <div class="comment_body"> {{ pull_request.initial_comment | markdown | noJS | safe }} </div> </section> {%endif%} {% elif form and (g.repo_admin or remote_git) %} <h2>Create pull request</h2> {% else %} <h2>Diff (<a href="{{ url_for('view_tree', repo=repo.name, username=username, namespace=repo.namespace, identifier=commitid) }}" >tree</a>)</h2> {% if origin == 'compare_commits' %} <h5 class="text-muted">{{ commit1 }} .. {{ commit2 }}</h5> {% endif %} {% endif %} {% if form and (g.repo_admin or remote_git) %} <section class="new_project"> {% if remote_git %} <form action="{{ url_for('.new_remote_request_pull', repo=repo.name, username=username, namespace=repo.namespace, confirm=True) }}" method="post"> <input type="hidden" value="{{ branch_from }}" name="branch_from" /> <input type="hidden" value="{{ remote_git }}" name="git_repo" /> {% else %} <form action="{{ url_for('.new_request_pull', repo=repo.name, username=username, namespace=repo.namespace, commitid=commitid, branch_from=branch_from, branch_to=branch_to) }}" method="post"> {% endif %} <div class="p-b-1"> Pull from <span class="pr-toplabel">{% if remote_git -%}{{ remote_git }}{%- else -%} <span class="oi" data-glyph="fork"></span> {{ repo.fullname }} {%- endif -%} </span> <span class="pr-toplabel"> <span class="oi" data-glyph="random"></span> {{ branch_from }} </span> into <span class="pr-toplabel"> {% if repo.is_fork -%}{{ repo.parent.fullname }}{% else %}{{ repo.fullname }}{% endif %} </span> <select class="pr-toplabel-select" id="branch_select" name="branch_to"> <option value="{{ branch_to }}">{{ branch_to }}</option> {% for branch in g.branches |reverse %} {% if branch != branch_to %} <option value="{{ branch }}">{{ branch }}</option> {% endif %} {% endfor %} </select> </div> {% if contributing %} <div id="contributing"> {{ contributing | markdown | noJS | safe}} </div> {% endif %} {{ render_bootstrap_field(form.title) }} <fieldset class="form-group"> <label for="initial_comment"><strong>Inital Comment</strong></label> <small class="text-muted pull-xs-right"> <span class="btn btn-sm btn-secondary inactive" aria-pressed="false" id="previewinmarkdown">Preview</span> </small> {{ form.initial_comment(class_="form-control")|safe }} <div> {% if form.initial_comment.errors %} <span class="pull-xs-right text-danger"> <small> {% for error in form.initial_comment.errors %} {{ error }} {% endfor %} </small> </span> {% endif %} </div> <div id="preview" style="display:none;"> </div> </fieldset> <p class="buttons indent"> <input type="submit" class="btn btn-primary" value="Create"> {{ form.csrf_token }} <a class="btn btn-secondary" href="{{ url_for( 'view_repo', repo=repo.name, username=username, namespace=repo.namespace)}}"> Cancel </a> </p> </form> </section> {% endif %} <ul class="nav nav-tabs nav-small" role="tablist" id="pr-tabs"> {% if pull_request %} <li class="nav-item"> <a class="nav-link active" data-toggle="tab" role="tab" href="#comments"> Comments </a> </li> {%endif%} <li class="nav-item"> <a class="nav-link {% if not pull_request %}active{% endif %}" data-toggle="tab" role="tab" href="#request_diff"> <span class="hidden-sm-down">Files Changed </span> <span class="label label-default label-pill hidden-sm-down"> {{ diff|length if diff else 0}} </span> </a> </li> <li class="nav-item"> <a class="nav-link" data-toggle="tab" role="tab" href="#commit_list"> <span class="hidden-sm-down">Commits </span> <span class="label label-default label-pill hidden-sm-down"> {{ diff_commits|length }} </span> </a> </li> {% if pull_request %} <li class="nav-item pull-xs-right"> <a class="nav-link" href="{{ url_for( 'request_pull_patch', repo=repo.name, username=username, namespace=repo.namespace, requestid=requestid) }}"> <span class="hidden-sm-down">Patch</span> </a> </li> {% endif %} </ul> <div class="tab-content"> <div class="tab-pane" role="tabpanel" id="commit_list"> <div class="list-group"> {% for commit in diff_commits %} {% if pull_request and pull_request.status and pull_request.project_from.is_fork %} <a class="list-group-item" href="{{ url_for( 'view_commit', repo=pull_request.project_from.name, username=pull_request.project_from.user.user, namespace=repo.namespace, commitid=commit.oid.hex) }}"> {% elif pull_request and pull_request.remote %} <a> {% else %} <a class="list-group-item" href="{{ url_for('view_commit', repo=repo.name, username=username, namespace=repo.namespace, commitid=commit.oid.hex)}}"> {% endif %} <h5> <strong>{{ commit.message.strip().split('\n')[0] }}</strong> <div class="pull-xs-right"> <span class="commitdate" title="{{ commit.commit_time|format_ts }}"> {{ commit.commit_time|humanize }} </span> </div> </h5> {{ commit.author | author2avatar(20) | safe }} {{ commit.author.name }} <div class="pull-xs-right"> <span class="label label-default">{{ commit.hex|short }}</span> </div> </a> {% else %} <p class="error"> No commits found </p> {% endfor %} </div> </div> <div class="tab-pane {% if not pull_request %}active{% endif %}" role="tabpanel" id="request_diff"> {% if authenticated and pull_request %} <form action="{{ url_for('.pull_request_drop_comment', repo=repo.name, username=username, namespace=repo.namespace, requestid=requestid) }}" method="post" class="icon" onsubmit="return try_async_comment(this, null)" > {% endif %} {% if diff %} {% set count = 0 %} {% for patch in diff %} {% set count = count+1 %} {% if patch |hasattr('new_id') %} {% set patch_new_id = patch.new_id %} {% elif patch |hasattr('delta') %} {% set patch_new_id = patch.delta.new_file.id %} {% else %} {% set patch_new_id = patch.new_oid %} {% endif %} {% if patch |hasattr('old_id') %} {% set patch_old_id = patch.old_id %} {% elif patch |hasattr('delta') %} {% set patch_old_id = patch.delta.old_file.id %} {% else %} {% set patch_old_id = patch.old_oid %} {% endif %} {% if patch | hasattr('new_file_path') %} {% set patch_new_file_path = patch.new_file_path -%} {% if patch.new_file_path != patch.old_file_path %} {% set patch_old_file_path = patch.old_file_path %} {%- endif -%} {%- elif patch | hasattr('delta') -%} {% set patch_new_file_path = patch.delta.new_file.path -%} {%- if patch.delta.new_file.path != patch.delta.old_file.path -%} {% set patch_old_file_path = patch.delta.old_file.path %} {%- endif -%} {%- endif -%} <section class="commit_diff"> <div class="card clearfix" id="_{{count}}"> <div class="card-header"> <h5> {% if patch | hasattr('additions') %} {# Version of pygit2 -0.21.4 -- F21/EL7 #} {% set linesadded = patch.additions %} {% set linesremoved = patch.deletions %} {% else %} {# Version of pygit2 -0.23.0 -- F23 #} {% set linesadded = patch.line_stats[1] %} {% set linesremoved = patch.line_stats[2] %} {% endif %} {% macro lineschanged(added, removed) -%} {%if added%} <span class="label label-success pull-xs-right text-mono">+{{linesadded}}</span> {%endif%} {%if removed%} <span class="label label-danger pull-xs-right">-{{linesremoved}}</span> {%endif%} {%endmacro%} {% macro viewfilelink(filepath, identifier=False)%} {% if pull_request %} {% if not identifier %} {% set identifier = pull_request.branch_from %} {% endif %} <a href="{{ url_for( 'view_file', repo=pull_request.project_from.name, username=pull_request.project_from.user.username if pull_request.project_from.is_fork else None, namespace=pull_request.project_from.namespace, identifier=identifier, filename=filepath) }}" {% else %} {% if identifier == False %} {% set identifier = branch_from %} {% endif %} <a href="{{ url_for( 'view_file', repo=repo.name, username=username, namespace=repo.namespace, identifier=identifier, filename=filepath) }}" {% endif %} title="View file as of {{ patch_new_id|short }}">{{filepath | unicode}}</a> {% endmacro %} {% if patch | hasattr('new_file_path') %} {%- if patch.new_file_path == patch.old_file_path -%} {%- if patch.status == 'D' -%} {% set patchtype = "removed"%} <div class="clearfix"> {{ viewfilelink(patch.new_file_path) }} {{ lineschanged(False, True) }} </div> <div><small>file removed</small></div> {%-elif patch.status == 'A' -%} {% set patchtype = "added"%} <div class="clearfix"> {{ viewfilelink(patch.new_file_path) }} {{ lineschanged(True, False) }} </div> <div><small>file added</small></div> {%-elif patch.status == 'M' -%} {% set patchtype = "changed"%} <div class="clearfix"> {{ viewfilelink(patch.new_file_path) }} {{ lineschanged(True, True) }} </div> <div><small>file changed</small></div> {%-endif-%} {%- else -%} {% set patchtype = "moved"%} {{lineschanged(True, True)}} <div class="clearfix"> <strike>{{patch.old_file_path}}</strike><br/> {{viewfilelink(patch.new_file_path)}} </div> <div><small>file moved</small></div> {%- endif -%} {%- elif patch | hasattr('delta') -%} {%- if patch.delta.new_file.path == patch.delta.old_file.path -%} {%- if patch.delta.new_file.mode == 0 and patch.delta.old_file.mode == 33188 -%} {% set patchtype = "removed"%} <div class="clearfix">{{viewfilelink(patch.delta.new_file.path)}} {{lineschanged(False, True)}}</div> <div><small>file removed</small></div> {%-elif patch.delta.new_file.mode == 33188 and patch.delta.old_file.mode == 0 -%} {% set patchtype = "added"%} <div class="clearfix">{{viewfilelink(patch.delta.new_file.path)}} {{lineschanged(True, False)}}</div> <div><small>file added</small></div> {%-elif patch.delta.new_file.mode == 33188 and patch.delta.old_file.mode == 33188 -%} {% set patchtype = "changed"%} <div class="clearfix"> {{ viewfilelink(patch.delta.new_file.path)}} {{lineschanged(True, True)}} </div> <div><small>file changed</small></div> {%-endif-%} {%- else -%} {% set patchtype = "moved"%} {{lineschanged(True, True)}} <div class="clearfix"> <strike>{{patch.delta.old_file.path}}</strike><br/> {{viewfilelink(patch.delta.new_file.path)}} </div> <div><small>file moved</small></div> {%- endif -%} {%- endif -%} </h5> </div> {% if patchtype == "moved" and linesadded == 0 and linesremoved == 0%} <div class="card-block"> <div class="text-muted text-xs-center">file was moved with no change to the file</div> </div> {% elif patchtype == "added" and linesadded == 0 %} <div class="card-block"> <div class="text-muted text-xs-center">empty file added</div> </div> {% else %} {% if patchtype == "added" and linesadded > 1000 %} <div class="card-block"> <div class="text-muted text-xs-center"> The added file is too large to be shown here, see it at: {{ viewfilelink(patch_new_file_path) }} </div> </div> {% elif patchtype == "removed" %} <div class="card-block"> <div class="text-muted text-xs-center"> The removed file is too large to be shown here, see it at: {{ viewfilelink(patch_new_file_path, patch_old_id) }} </div> </div> {% else %} {% autoescape false %} {{ patch | patch_to_diff | html_diff | format_loc( filename=patch_new_file_path, commit=patch_new_id, prequest=pull_request, index=loop.index, tree_id=diff_commits[0].tree.id)}} {% endautoescape %} {% endif %} {% endif %} </div> </section> {% endfor %} {% endif %} {% if authenticated and pull_request %} {{ mergeform.csrf_token }} </form> {% endif %} </div> {% if pull_request %} <div class="tab-pane active" role="tabpanel" id="comments"> <section class="request_comment" id="request_comment"> {% if pull_request.comments %} <form action="{{ url_for('.pull_request_drop_comment', repo=repo.name, username=username, namespace=repo.namespace, requestid=requestid) }}" method="post" onsubmit="return try_async_comment(this, null)"> {% for comment in pull_request.comments %} {% if comment.commit_id %} <div class="card"> <div class="card-header"> <div> {{ comment.user.user }} commented on line <a href="#c-{{ comment.commit_id }}-{{ comment.line }}" onclick="showTab()">{{ comment.line }} of {{ comment.filename }}</a>. <div class="pull-xs-right text-muted"> <span title="{{ comment.date_created.strftime('%Y-%m-%d %H:%M:%S') }}">{{ comment.date_created | humanize }}</span></div> </div> (<a class="inline-btn small" data-id="{{ loop.index }}">Show</a>) <div class="inline-comments" id="inline-comment-{{ loop.index }}"> {{ comment.comment }} </div> </div> </div> {% elif comment.notification %} <div class="card"> <div class="card-header"> <div> <div class="pull-xs-right text-muted"> <span title="{{ comment.date_created.strftime('%Y-%m-%d %H:%M:%S') }}">{{ comment.date_created | humanize }}</span> </div> <small>{{ comment.comment | markdown | noJS | safe }}</small> </div> </div> </div> {% else %} {{ show_comment(comment, comment.id, repo, username, requestid, form) }} {% endif %} {% endfor %} {{ mergeform.csrf_token }} </form> {% endif %} </section> {% if authenticated and mergeform and pull_request %} <div class="card"> <div class="card-header"> <section class="request_comment add_comment"> {% if authenticated %} <form action="{{ url_for( 'pull_request_add_comment', repo=repo.name, username=username, namespace=repo.namespace, requestid=requestid) }}" method="post" onsubmit="return try_async_comment(this, false)"> {{ mergeform.csrf_token }} <fieldset class="form-group"> <label for="comment"><strong>Add new comment</strong></label> <small class="text-muted pull-xs-right"> <span class="btn btn-sm btn-secondary inactive" aria-pressed="false" id="previewinmarkdown">Preview </span> </small> <textarea class="form-control" rows=8 id="comment" name="comment" placeholder="Enter your comment here" tabindex=1></textarea> <div id="preview"> </div> </fieldset> <a href="http://daringfireball.net/projects/markdown/syntax" target="_blank" rel="noopener noreferrer">Markdown Syntax</a> <div> <input type="submit" class="btn btn-primary" value="Update Issue" tabindex=2 /> <input type="button" class="btn btn-secondary" value="Clear" id="clear_comment" tabindex=3 /> </div> </form> {% else %} <p> <a href="{{ url_for('auth_login', next=request.url) }}"> Login </a> to comment on this ticket. </p> {% endif %} </section> </div> </div> {% endif %} </div> {% endif %} </div> <!-- tab content--> </div> <div class="col-md-4"> {% if pull_request %} <section class="pr_info"> <div id="spinner" class="content-loading" style="display:none"></div> <div id="merge-alert" class="alert text-xs-center" style="display:none;" role="alert"> {% if pull_request.status == 'Open' and g.repo_admin %} <div> <form action="{{ url_for('merge_request_pull', repo=repo.name, username=username, namespace=repo.namespace, requestid=requestid) }}" method="POST"> {{ mergeform.csrf_token }} <button id="merge_btn" type="submit" class="btn btn-block">Merge</button> </form> </div> {% endif %} <small id="merge-alert-message"></small> </div> {% if pull_request.status != 'Open'%} <div class="alert {{'alert-success' if pull_request.status == 'Merged' else 'alert-danger'}} text-xs-center" role="alert"> <div>{{ pull_request.status }} by <a href="{{ url_for('view_user', username=pull_request.closed_by.user)}} "> {{ pull_request.closed_by.user if pull_request.closed_by else ''}} </a> {{pull_request.closed_at|humanize}} </div> </div> {% endif %} {% if pull_request.flags %} <div class="card" id="pr_flags"> <ul class="list-group list-group-flush"> {% for flag in pull_request.flags %} <li class="list-group-item"> <div> <span><a href="{{ flag.url }}">{{ flag.username }}</a></span> <div class="pull-xs-right"><span class="label {% if flag.percent <= 10 %}label-danger{% elif flag.percent <= 90 %}label-warning{% else %}label-success{% endif %}">{{ flag.percent }}%</label></div> </div> <small><div class="clearfix"> <span>{{ flag.comment }}</span> <div title="{{ flag.date_created }}" class="pull-xs-right"> {{ flag.date_created | humanize }}</div> </div> </small> </li> {% endfor %} </ul> </div> {% endif %} <div class="card"> <div class="card-block"> {% if authenticated and mergeform and pull_request.status == 'Open' and g.repo_admin %} <form method="POST" action="{{ url_for('.set_assignee_requests', repo=repo.name, username=username, namespace=repo.namespace, requestid=requestid) }}"> <fieldset class="form-group issue-metadata-form"> <label><strong>Assignee</strong></label> <div> <input value="{{ pull_request.assignee.username or '' }}" name="user" id="assignee" placeholder="username" > {{ mergeform.csrf_token }} </div> </fieldset> {% endif %} <fieldset class="form-group issue-metadata-display"> <label><strong>Assignee</strong></label> <div> {{ pull_request.assignee.username or 'Unassigned' }} </div> </fieldset> {% if authenticated and mergeform and pull_request.status == 'Open' and g.repo_admin %} <input type="submit" class="btn btn-primary issue-metadata-form" value="Update"> <a class="btn btn-secondary issue-metadata-form editmetadatatoggle" >cancel</a> </form> <a class="btn btn-secondary issue-metadata-display editmetadatatoggle" >Edit Metadata</a> {% endif %} </div> </div> </section> {% endif %} {% if diff and pull_request%} <div class="card clearfix"> <div class="card-header"> <h5><strong>Changes summary</strong></h5> </div> {% macro changeschangedfile(filepath, added, removed, diffanchor) -%} <div class="clearfix" style="margin-left:-4px;"> <div class="pull-xs-right"> <span class="label label-success">+{{added}}</span> <span class="label label-danger">-{{removed}}</span> </div> <div class="pull-xs-left pr-changes-description"> <strong>file <span class="text-muted">changed</span></strong> </div> </div> <div class="ellipsis pr-changes-description"> <a href="#_{{diffanchor}}">{{filepath}}</a> </div> {%- endmacro %} {% macro changesrenamedfile(oldfilepath, newfilepath, added, removed, diffanchor) -%} <div class="clearfix" style="margin-left:-4px;"> <div class="pull-xs-right"><span class="label label-success">+{{added}}</span> <span class="label label-danger">-{{removed}}</span></div> <div class="pull-xs-left pr-changes-description"><strong>file <span class="text-warning">renamed</span></strong></div> </div> <div class="ellipsis pr-changes-description"> <strike class="text-muted">{{oldfilepath}}</strike> <br/> <a href="#_{{diffanchor}}">{{newfilepath}}</a> </div> {%- endmacro %} {% macro changesdeletedfile(filepath, added, removed, diffanchor) -%} <div class="clearfix" style="margin-left:-4px;"> <div class="pull-xs-right"><span class="label label-danger">-{{removed}}</span></div> <div class="pull-xs-left pr-changes-description"><strong>file <span class="text-danger">removed</span></strong></div> </div> <div class="ellipsis pr-changes-description"> <a href="#_{{diffanchor}}">{{filepath}}</a> </div> {%- endmacro %} {% macro changesaddedfile(filepath, added, removed, diffanchor) -%} <div class="clearfix" style="margin-left:-4px;"> <div class="pull-xs-right"><span class="label label-success">+{{added}}</span></div> <div class="pull-xs-left pr-changes-description"><strong>file <span class="text-success">added</span></strong></div> </div> <div class="ellipsis pr-changes-description"> <a href="#_{{diffanchor}}">{{filepath}}</a> </div> {%- endmacro %} <div class="list-group list-group-flush"> {% set count = 0 %} {% for patch in diff %} {% set count = count+1 %} <div class="list-group-item"> {% if patch | hasattr('additions') %} {# Version of pygit2 -0.21.4 -- F21/EL7 #} {% set linesadded = patch.additions %} {% set linesremoved = patch.deletions %} {% else %} {# Version of pygit2 -0.23.0 -- F23 #} {% set linesadded = patch.line_stats[1] %} {% set linesremoved = patch.line_stats[2] %} {% endif %} {% if patch | hasattr('new_file_path') %} {%- if patch.new_file_path == patch.old_file_path -%} {%- if patch.status == 'D' -%} {{ changesdeletedfile(patch.new_file_path, linesadded, linesremoved, count) }} {%-elif patch.status == 'A' -%} {{ changesaddedfile(patch.new_file_path, linesadded, linesremoved, count) }} {%-elif patch.status == 'M' -%} {{ changeschangedfile(patch.new_file_path, linesadded, linesremoved, count) }} {%-endif-%} {%- else -%} {{changesrenamedfile(patch.old_file_path, patch.new_file_path, linesadded, linesremoved, count)}} {%- endif -%} {%- elif patch | hasattr('delta') -%} {%- if patch.delta.new_file.path == patch.delta.old_file.path -%} {%- if patch.delta.new_file.mode == 0 and patch.delta.old_file.mode == 33188 -%} {{ changesdeletedfile(patch.delta.new_file.path, linesadded, linesremoved, count) }} {%-elif patch.delta.new_file.mode == 33188 and patch.delta.old_file.mode == 0 -%} {{ changesaddedfile(patch.delta.new_file.path, linesadded, linesremoved, count) }} {%-elif patch.delta.new_file.mode == 33188 and patch.delta.old_file.mode == 33188 -%} {{ changeschangedfile(patch.delta.new_file.path, linesadded, linesremoved, count) }} {%-endif-%} {%- else -%} {{changesrenamedfile(patch.delta.old_file.path, patch.delta.new_file.path, linesadded, linesremoved, count)}} {%- endif -%} {%- endif -%} </div> {% endfor %} </div> </div> {% endif %} </div> </div> {% endblock %} {% block jscripts %} {{ super() }} <script type="text/javascript" src="{{ url_for('static', filename='emoji/jquery.textcomplete.min.js') }}"> </script> <script type="text/javascript" src="{{ url_for('static', filename='emoji/emojione.min.js') }}"> </script> <script type="text/javascript" src="{{ url_for('static', filename='emoji/emojicomplete.js') }}"> </script> <script src="{{ url_for('static', filename='selectize.min.js') }}" type="text/javascript"> </script> <script type="text/javascript" src="{{ url_for('static', filename='atwho/jquery.caret.min.js') }}"></script> <script type="text/javascript" src="{{ url_for('static', filename='atwho/jquery.atwho.min.js') }}"></script> <script type="text/javascript"> function cancel_edit_btn() { $(".cancel").unbind(); $( ".cancel" ).click( function() { item = $(this).closest('section'); $(item.parent().find('.issue_comment')).show(); $(item.parent().find('.issue_actions')).show(); $(item.parent().closest('.pr_comment_form')).remove(); return false; } ); }; function setup_edit_btns() { $(".edit_btn").unbind(); $(".edit_btn").click(function() { var commentid = $( this ).attr('data-comment'); var _url = '{{ request.base_url }}' + '/comment/' + commentid + '/edit'; $.ajax({ url: _url + '?js=1', type: 'GET', dataType: 'html', success: function(res) { var el = $('#comment-' + commentid); var sec = el.parent().find('.issue_comment'); $(sec).hide(); el.parent().find('.issue_actions').hide(); $(sec).after(res); cancel_edit_btn(); }, error: function() { alert('Could not make edit work'); } }); return false; }); }; function setup_reply_btns() { $(".reply").unbind(); $( ".reply" ).click( function() { var _section = $(this).closest('.card-block'); var _comment = _section.find('.comment_body'); var _text = _comment.text().split("\n"); var _output = new Array(); for (var cnt=0; cnt < _text.length; cnt++) { _output[cnt] = '> ' + _text[cnt]; } $( "#comment" ).val(_output.join("\n")); } ); }; function showTab(){ $('#pr-tabs a[href="#request_diff"]').tab('show') } $(document).ready(function() { $(".inline-comments").hide(); $( ".inline-btn" ).click(function() { var msgid = $( this ).attr('data-id'); if ($( this ).html() == 'Show') { $( this ).html('Hide'); } else { $( this ).html('Show'); } $( '#inline-comment-' + msgid).toggle(); }); $( ".commit_msg_txt" ).hide(); $( ".commit_msg_btn" ).click(function() { var msgid = $( this ).attr('data-id'); $( '#commit_msg_' + msgid).toggle(); }); var folder = '{{url_for("static", filename="emoji/png/") }}'; var json_url = '{{ url_for("static", filename="emoji/emoji_strategy.json") }}'; var branchselect = $('#branch_select').selectize({ create: false, sortField: 'text', allowEmptyOption: false, onChange: function(value) { if (value != ""){ var sel = $('#branch_select'); var final_url = "{{ url_for('.new_request_pull', username=username, namespace=repo.namespace, repo=repo.name, branch_from=branch_from, branch_to='--') }}"; final_url = final_url.replace('--', sel.val()); window.location.href = final_url; } } }); {% if pull_request %} {# These lines are only for existing pull-requests, not new ones #} emoji_complete(json_url, folder); $('#cancel_pr').click(function(){ return window.confirm("Are you sure you want to close this requested pull?"); }); $( ".code_table tr" ).hover( function() { $( this ).find( ".prc_img" ).show().width(13); }, function() { $( this ).find( ".prc_img" ).hide(); } ); $( ".prc" ).click( function() { var row = $( this ).attr('data-row'); var commit = $( this ).attr('data-commit'); var filename = $( this ).attr('data-filename'); var tree_id = $( this ).attr('data-tree'); var url = "{{ url_for( 'pull_request_add_comment', repo=repo.name, username=username, namespace=repo.namespace, requestid=requestid, commit='', filename='', row='') }}".slice(0, -2); url = url + commit + '/' + filename + '/' + row if (tree_id) { url += '?tree_id=' + tree_id; } var rowid = $(this).prev().find('a').attr('id'); var table = $( this ).parent().parent(); var nextid = rowid.replace('_' + row, '_' + (Number(row) + 1)); var next_row = table.find('#' + nextid).parent().parent(); {# If we're at the last row, we won't be able to find the next_row therefore we need to add it manually #} if (next_row.length == 0) { table.find("tr:last").after( '<tr><td><a id="' + nextid + '"></a></td></tr>'); next_row = table.find('#' + nextid).parent().parent(); } if (next_row.prev().find('.pr_comment_form').length == 0){ $.get( url , function( data ) { next_row.before( '<tr><td></td><td colspan="2" class="pr_comment_form"> \ <div class="card m-x-1"><div class="card-block">' + data + '</div></div></td></tr>' ); cancel_edit_btn(); emoji_complete(json_url, folder); }); } else { next_row.prev().find('.pr_comment_form').parent().remove(); } } ); $( "#clear_comment").click( function() { $( "#comment" ).val(""); } ); $( "#preview" ).hide(); $( "#previewinmarkdown" ).click( function(event, ui) { if ($( "#previewinmarkdown" ).hasClass("inactive")){ var _text = $( "#comment" ).val(); var _url = "{{ url_for('markdown_preview', repo=repo.name, user=repo.user.user if repo.is_fork, namespace=repo.namespace) | safe}}"; $.ajax({ url: _url , type: 'POST', data: { content: _text, csrf_token: "{{ mergeform.csrf_token.current_token }}", }, dataType: 'html', success: function(res) { var preview = emojione.toImage(res) $( "#preview" ).html(preview); $( "#previewinmarkdown" ).removeClass("inactive"); $( "#previewinmarkdown" ).addClass("active"); $( "#comment" ).hide(); $( "#preview" ).show(); }, error: function() { alert('Unable to generate preview!'); } }); return false; } else if ($( "#previewinmarkdown" ).hasClass("active")){ $( "#previewinmarkdown" ).addClass("inactive"); $( "#previewinmarkdown" ).removeClass("active"); $( "#comment" ).show(); $( "#preview" ).hide(); } } ); setup_edit_btns(); setup_reply_btns(); $(".comment_body").each(function(ind, obj) { var source = $(obj).html(); var preview = emojione.toImage(source); $(obj).html(preview); }); $(".pr_comment").each(function(ind, obj) { var source = $(obj).html(); var preview = emojione.toImage(source); $(obj).html(preview); }); {% if pull_request.status == 'Open' %} $(function(){ $('#spinner').show(); $.ajax({ url: '{{ url_for("internal_ns.mergeable_request_pull") }}' , type: 'POST', data: { requestid: "{{ pull_request.uid }}", csrf_token: "{{ mergeform.csrf_token.current_token }}", }, dataType: 'json', success: function(res) { $('#spinner').hide(); if (res.code == 'FFORWARD'){ $('#merge_btn').addClass("btn-success"); $('#merge-alert').addClass("alert-success"); $('#merge-alert-message').append(res.message); $('#merge-alert').show(); } else if (res.code == 'MERGE') { $('#merge_btn').addClass("btn-warning"); $('#merge-alert').addClass("alert-warning"); $('#merge-alert-message').append(res.message); $('#merge-alert').show(); } else if (res.code == 'CONFLICTS') { $('#merge_btn').hide(); $('#merge-alert').addClass("alert-danger"); $('#merge-alert-message').append(res.message); $('#merge-alert').show(); } else if (res.code == 'NO_CHANGE') { $('#merge_btn').hide(); $('#merge-alert').addClass("alert-info"); $('#merge-alert-message').append(res.message); $('#merge-alert').show(); } }, error: function(res) { $('#spinner').hide(); var _obj = $('#pr_flags').find('tbody'); if (res.responseJSON.message) { _obj.append( $('<tr><th>PR Status:</th><td><span class="'+ res.responseJSON.code +'" title="' + res.responseJSON.message +'"></span>'+ res.responseJSON.message +'</td></tr>')); } else { _obj.append( $('<tr><th>PR Status:</th><td><span class="'+ res.responseJSON.code +'"></span>' + res.responseJSON.message +'</td></tr>')); } $('#merge_btn').attr("disabled", "disabled"); } }); return false; }); {% endif %} {% endif %} }); {% if authenticated and pull_request %} $('#assignee').selectize({ valueField: 'user', labelField: 'user', searchField: 'user', maxItems: 1, create: false, load: function(query, callback) { if (!query.length) return callback(); $.getJSON( "{{ url_for('api_ns.api_users') }}", { pattern: query.term }, function( data ) { callback( data.users.map(function(x) { return { user: x }; }) ); } ); } }); $( ".editmetadatatoggle" ).click( function() { $( ".issue-metadata-form" ).toggle(); $( ".issue-metadata-display" ).toggle(); } ); function try_async_comment(form, inline) { $(form).off('submit'); $(form).find('input[type="submit"]').attr("disabled", "disabled"); var _data = $(form).serialize(); var btn = $(document.activeElement); if (btn[0].name == 'drop_comment'){ _data += '&drop_comment=' + btn[0].value; return true; } if (!sse) { console.log('no sse, submitting'); form.submit(); return false; } var _url = form.action; if (_url.indexOf('?') != -1){ _url += "&js=1"; } else { _url += "?js=1"; } $.post( _url, $(form).serialize() ) .done(function(data) { if(data == 'ok') { $('#comment').val(''); $('#preview').html(''); $('#previewinmarkdown').addClass('inactive'); $('#previewinmarkdown').removeClass('active'); $('#preview').hide(); $('#comment').show(); /* We have submitted the comment correctly */ var item = $('.pr_comment_form').closest('tr'); if (!$(item.parent().children()[1]).is(':visible')){ $(item.parent().children()[1]).show() } item.remove(); } else { // Make the browser submit the form sync form.submit(); } }) .fail(function() { // Make the browser submit the form sync form.submit(); }) $(form).on('submit'); $(form).find('input[type="submit"]').removeAttr("disabled"); return false; }; {% endif %} </script> <script type="text/javascript"> var cur_hash = null; function highlight_comment() { var _hash = window.location.hash; if (_hash != cur_hash) { $( cur_hash ).css( "background", "linear-gradient(to bottom, #ededed 0%, #fff 100%)" ); }; cur_hash = _hash; if ( _hash ) { $( _hash ).css( "background", "linear-gradient(to bottom, #eded98 0%, #fff 100%)" ); }; return false; }; function updateHighlight(onload) { var cls = "highlighted-line"; $('.' + cls).removeClass(cls) if (location.hash === '') { return } if (location.hash.indexOf("comment-") > -1) { highlight_comment(); } else { if (onload) { $('#request_diff').addClass('active'); $('#comments').removeClass('active'); $('[href="#request_diff"]').addClass('active'); $('[href="#comments"]').removeClass('active'); } var file = parseInt(location.hash.substr(2).split(',')[0], 10); var lines = location.hash.split(',')[1].split('-').map(function (x) { return parseInt(x, 10) }); for (var i = lines[lines.length - 1]; i >= lines[0]; i--) { $('#' + file + '_' + i).closest('tr').addClass(cls); } } } $(document).ready(function () { updateHighlight(true) {% if form %} $( "#previewinmarkdown" ).click( function(event, ui) { if ($( "#previewinmarkdown" ).hasClass("inactive")){ var _text = $( "#initial_comment" ).val(); var _url = "{{ url_for('markdown_preview') }}"; $.ajax({ url: _url , type: 'POST', data: { content: _text, csrf_token: "{{ form.csrf_token.current_token }}", }, dataType: 'html', success: function(res) { var preview = emojione.toImage(res); $( "#preview" ).html(preview); $( "#previewinmarkdown" ).removeClass("inactive"); $( "#previewinmarkdown" ).addClass("active"); $( "#initial_comment" ).hide(); $( "#preview" ).show(); }, error: function() { alert('Unable to generate preview!'+error); } }); return false; } else if ($( "#previewinmarkdown" ).hasClass("active")){ $( "#previewinmarkdown" ).addClass("inactive"); $( "#previewinmarkdown" ).removeClass("active"); $( "#initial_comment" ).show(); $( "#preview" ).hide(); } } ); {% endif %} $.get("{{ url_for('api_ns.api_users') }}", { pattern: '*' }).done(function(resp) { var userConfig = { at: '@', data: resp['mention'], insertTpl: '@${username}', displayTpl: "<li><img src=\"${image}\"> ${username} <small>${name}</small></li>", searchKey: "username" } $("#comment").atwho(userConfig); }); {% if config.get('ENABLE_TICKETS', True) %} $.when($.get("{{ url_for('api_ns.api_view_issues', repo=repo.name, username=username, namespace=repo.namespace, status='all') }}"), $.get("{{ url_for('api_ns.api_pull_request_views', repo=repo.name, username=username, namespace=repo.namespace, status='all') }}") ).done(function(issuesResp, prResp) { // 0 is the api response var issuesAndPrs = issuesResp[0]['issues'].concat(prResp[0]['requests']); var data = $.map(issuesAndPrs, function(ticket, idx) { return { name: ticket.id.toString(), title: $('<div>').text(ticket.title).html() } }); var issueAndPrConfig = { at: '#', data: data, insertTpl: '#${name}', displayTpl: "<li>#${name}<small> ${title}</small></li>", } $("#comment").atwho(issueAndPrConfig); }); {% else %} $.get("{{ url_for('api_ns.api_pull_request_views', repo=repo.name, username=username, namespace=repo.namespace, status='all') }}") .done(function(prResp) { var data = $.map(prResp['requests'], function(pr, idx) { return { name: pr.id.toString(), title: $('<div>').text(pr.title).html() } }); var conf = { at: '#', data: data, insertTpl: '#${name}', displayTpl: "<li>#${name}<small> ${title} </small></li>", } $("#comment").atwho(conf); }); {% endif %} } ); $(window).on('hashchange', updateHighlight); var selected = []; $("[data-line-number]").click(function (ev) { var line = $(this).attr('data-line-number'); var file = $(this).attr('id').split('_')[0]; if (ev.shiftKey) { selected = selected.slice(-1).concat(line); } else { selected = [line]; } var hash = '_' + file + ',' + selected[0]; if (selected.length === 2) { hash = '_' + file + ',' + Math.min(selected[0], selected[1]) + '-' + Math.max(selected[0], selected[1]); } window.location.hash = hash; return false; }); </script> {% if config['EVENTSOURCE_SOURCE'] and pull_request %} <script type="text/javascript" src="{{ url_for('static', filename='request_ev.js') }}"></script> <script type="text/javascript"> var source = null; var sse = true; if (!!window.EventSource) { source = new EventSource('{{ config["EVENTSOURCE_SOURCE"] + request.script_root + request.path }}'); source.addEventListener('error', function(e) { sse = false; }, false); } window.onbeforeunload = function() { source.close() }; source.addEventListener('message', function(e) { console.log(e.data); var data = $.parseJSON(e.data); process_event(data, "{{ request.uid }}", "{{ g.fas_user.username }}"); setup_edit_btns(); setup_reply_btns(); }, false); </script> {% endif %} {% endblock %}