Changeset - f78aa989c9ff
[Not reviewed]
default
1 5 0
Mads Kiilerich - 7 years ago 2018-12-11 00:25:21
mads@kiilerich.com
front-end: More clean-up after YUI is gone
6 files changed with 4 insertions and 75 deletions:
0 comments (0 inline, 0 general)
kallithea/lib/page.py
Show inline comments
 
# -*- coding: utf-8 -*-
 
# This program is free software: you can redistribute it and/or modify
 
# it under the terms of the GNU General Public License as published by
 
# the Free Software Foundation, either version 3 of the License, or
 
# (at your option) any later version.
 
#
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
"""
 
Custom paging classes
 
"""
 
import logging
 
import math
 
import re
 
from kallithea.config.routing import url
 
from webhelpers.html import literal, HTML
 
from webhelpers.paginate import Page as _Page
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
class Page(_Page):
 
    """
 
    Custom pager to match rendering style with YUI paginator emitting Bootstrap paginators
 
    Custom pager emitting Bootstrap paginators
 
    """
 

	
 
    def __init__(self, *args, **kwargs):
 
        kwargs.setdefault('url', url.current)
 
        _Page.__init__(self, *args, **kwargs)
 

	
 
    def _get_pos(self, cur_page, max_page, items):
 
        edge = (items / 2) + 1
 
        if (cur_page <= edge):
 
            radius = max(items / 2, items - cur_page)
 
        elif (max_page - cur_page) < edge:
 
            radius = (items - 1) - (max_page - cur_page)
 
        else:
 
            radius = items / 2
 

	
 
        left = max(1, (cur_page - (radius)))
 
        right = min(max_page, cur_page + (radius))
 
        return left, cur_page, right
 

	
 
    def _range(self, regexp_match):
 
        """
 
        Return range of linked pages (e.g. '1 2 [3] 4 5 6 7 8').
 

	
 
        Arguments:
 

	
 
        regexp_match
 
            A "re" (regular expressions) match object containing the
 
            radius of linked pages around the current page in
 
            regexp_match.group(1) as a string
 

	
 
        This function is supposed to be called as a callable in
 
        re.sub.
 

	
 
        """
 
        radius = int(regexp_match.group(1))
 

	
 
        # Compute the first and last page number within the radius
 
        # e.g. '1 .. 5 6 [7] 8 9 .. 12'
 
        # -> leftmost_page  = 5
 
        # -> rightmost_page = 9
 
        leftmost_page, _cur, rightmost_page = self._get_pos(self.page,
 
                                                            self.last_page,
 
                                                            (radius * 2) + 1)
 
        nav_items = []
 

	
 
        # Create a link to the first page (unless we are on the first page
 
        # or there would be no need to insert '..' spacers)
 
        if self.page != self.first_page and self.first_page < leftmost_page:
 
            nav_items.append(HTML.li(self._pagerlink(self.first_page, self.first_page)))
 

	
 
        # Insert dots if there are pages between the first page
 
        # and the currently displayed page range
 
        if leftmost_page - self.first_page > 1:
 
            # Wrap in a SPAN tag if nolink_attr is set
 
            text_ = '..'
 
            if self.dotdot_attr:
 
                text_ = HTML.span(c=text_, **self.dotdot_attr)
 
            nav_items.append(HTML.li(text_))
 

	
 
        for thispage in xrange(leftmost_page, rightmost_page + 1):
 
            # Highlight the current page number and do not use a link
 
            text_ = str(thispage)
 
            if thispage == self.page:
 
                # Wrap in a SPAN tag if nolink_attr is set
 
                if self.curpage_attr:
 
                    text_ = HTML.li(HTML.span(c=text_), **self.curpage_attr)
 
                nav_items.append(text_)
 
            # Otherwise create just a link to that page
 
            else:
 
                nav_items.append(HTML.li(self._pagerlink(thispage, text_)))
 

	
 
        # Insert dots if there are pages between the displayed
 
        # page numbers and the end of the page range
 
        if self.last_page - rightmost_page > 1:
 
            text_ = '..'
 
            # Wrap in a SPAN tag if nolink_attr is set
 
            if self.dotdot_attr:
 
                text_ = HTML.span(c=text_, **self.dotdot_attr)
 
            nav_items.append(HTML.li(text_))
 

	
 
        # Create a link to the very last page (unless we are on the last
 
        # page or there would be no need to insert '..' spacers)
 
        if self.page != self.last_page and rightmost_page < self.last_page:
 
            nav_items.append(HTML.li(self._pagerlink(self.last_page, self.last_page)))
 

	
 
        #_page_link = url.current()
 
        #nav_items.append(literal('<link rel="prerender" href="%s?page=%s">' % (_page_link, str(int(self.page)+1))))
 
        #nav_items.append(literal('<link rel="prefetch" href="%s?page=%s">' % (_page_link, str(int(self.page)+1))))
 
        return self.separator.join(nav_items)
 

	
 
    def pager(self, format='<ul class="pagination">$link_previous ~2~ $link_next</ul>', page_param='page', partial_param='partial',
 
        show_if_single_page=False, separator=' ', onclick=None,
 
        symbol_first='<<', symbol_last='>>',
 
        symbol_previous='<', symbol_next='>',
 
        link_attr=None,
 
        curpage_attr=None,
kallithea/public/less/main.less
Show inline comments
 
/*!
 
 * Don't edit the css file directly.
 
 *
 
 * Instead, edit the less file(s) and regenerate the css:
 
 *
 
 * npm install
 
 * npm run less
 
 *
 
 */
 

	
 
/* 3rd party styles */
 
@import "node_modules/bootstrap/less/bootstrap.less";
 
@import (inline) "node_modules/datatables.net-bs/css/dataTables.bootstrap.css";
 
@import (inline) "node_modules/at.js/dist/css/jquery.atwho.css";
 
@import (less) "node_modules/select2/select2.css";
 
@import (less) "node_modules/select2-bootstrap-css/select2-bootstrap.css";
 
@import (less) "tmp/pygments.css";
 
@import (less) "../fontello/css/kallithea.css";
 

	
 
/* kallithea styles */
 
@import "kallithea-variables.less";
 
@import "kallithea-labels.less";
 
@import "yui-ac.less";
 
@import "kallithea-select2.less";
 
@import "kallithea-diff.less";
 
@import "style.less";
 

	
 
/* finally, import the optional theme file with local customizations */
 
@import (optional) "theme.less";
kallithea/public/less/style.less
Show inline comments
 
@@ -366,194 +366,193 @@ table#changesets tr.out-of-range {
 
}
 
.currently_following {
 
  padding-left: 10px;
 
  padding-bottom: 5px;
 
}
 
#switch_repos {
 
  position: absolute;
 
  height: 25px;
 
  z-index: 1;
 
}
 
#switch_repos select {
 
  min-width: 150px;
 
  max-height: 250px;
 
  z-index: 1;
 
}
 
table#permissions_manage span.private_repo_msg {
 
  font-size: 0.8em;
 
  opacity: 0.6;
 
}
 
table#permissions_manage td.private_repo_msg {
 
  font-size: 0.8em;
 
}
 
table#permissions_manage tr#add_perm_input td {
 
  vertical-align: middle;
 
}
 
div.gravatar {
 
  float: left;
 
  background-color: #FFF;
 
  margin-right: 0.7em;
 
  padding: 1px 1px 1px 1px;
 
  line-height: 0;
 
  border-radius: 3px;
 
}
 
div.gravatar img {
 
  border-radius: 2px;
 
}
 
.panel-body.settings .nav-pills > :not(.active) > a {
 
  color: inherit;
 
}
 
.panel-body.no-padding {
 
  padding: 0;
 
}
 
.panel-body ~ .panel-body {
 
  padding-top: 0;
 
}
 
.panel-body.no-padding ~ .panel-body {
 
  padding-top: 15px;
 
}
 
.panel-body > :last-child {
 
  margin-bottom: 0;
 
}
 
.panel-body.settings .text-muted {
 
  margin: 5px 0;
 
}
 
ins,
 
div.options a:hover {
 
  text-decoration: none;
 
}
 
img,
 
nav.navbar #quick li a:hover span.normal,
 
#clone_url,
 
#clone_url_id {
 
  border: none;
 
}
 
img.icon,
 
.right .merge img {
 
  vertical-align: bottom;
 
}
 
#content div.panel div.panel-heading ul.links,
 
#content div.panel div.message div.dismiss {
 
  float: right;
 
  margin: 0;
 
  padding: 0;
 
}
 
nav.navbar #home,
 
#content div.panel ul.left,
 
#content div.panel ol.left,
 
div#commit_history,
 
div#legend_data,
 
div#legend_container,
 
div#legend_choices {
 
  float: left;
 
}
 

	
 
/* set size for statistics charts */
 
#commit_history {
 
  width: 450px;
 
  height: 300px;
 
}
 
#overview {
 
  clear: both;
 
  width: 450px;
 
  height: 100px;
 
}
 

	
 
#content #left #menu ul.closed,
 
#content #left #menu li ul.collapsed,
 
.yui-tt-shadow {
 
#content #left #menu li ul.collapsed {
 
  display: none;
 
}
 
#content #left #menu ul.opened,
 
#content #left #menu li ul.expanded {
 
  display: block !important;
 
}
 

	
 
#content div.panel ol.lower-roman,
 
#content div.panel ol.upper-roman,
 
#content div.panel ol.lower-alpha,
 
#content div.panel ol.upper-alpha,
 
#content div.panel ol.decimal {
 
  margin: 10px 24px 10px 44px;
 
}
 

	
 
div.form div.form-group div.button input,
 
#content div.panel div.form div.buttons input,
 
div.form div.buttons input,
 
#content div.panel div.action div.button input {
 
  font-size: 11px;
 
  font-weight: 700;
 
  margin: 0;
 
}
 
div.form div.form-group div.highlight,
 
#content div.panel div.form div.buttons div.highlight {
 
  display: inline;
 
}
 
#content div.panel table td.user,
 
#content div.panel table td.address {
 
  width: 10%;
 
  text-align: center;
 
}
 
#content div.panel div.action div.button {
 
  text-align: right;
 
  margin: 6px 0 0;
 
  padding: 0;
 
}
 
.ac .match {
 
  font-weight: 700;
 
  padding-top: 5px;
 
  padding-bottom: 5px;
 
}
 
.q_filter_box {
 
  border-radius: 4px;
 
  border: 0 none;
 
  margin-bottom: -4px;
 
  margin-top: -4px;
 
  padding-left: 3px;
 
}
 
#node_filter {
 
  border: 0px solid #545454;
 
  color: #AAAAAA;
 
  padding-left: 3px;
 
}
 
/** comment main **/
 
.comment .panel,
 
.comment-inline-form {
 
  max-width: 978px;
 
}
 
.comment .panel-body {
 
  background-color: #FAFAFA;
 
}
 
.comments-number {
 
  padding: 10px 0;
 
  color: #666;
 
}
 
.automatic-comment {
 
  font-style: italic;
 
}
 
/** comment form **/
 
.status-block {
 
  margin: 5px;
 
  clear: both;
 
}
 
.panel-heading .pull-left input[type=checkbox],
 
.panel-heading .pull-right input[type=checkbox] {
 
  position: relative;
 
  top: 4px;
 
  margin: -10px 2px 0;
 
}
 
/** comment inline **/
 
.inline-comments {
 
  padding: 5px;
 
}
 
.inline-comments .comments-number {
 
  padding: 0px 0px 10px 0px;
 
}
 
input.status_change_checkbox,
 
input.status_change_radio {
 
  margin: 0 0 5px 15px;
 
}
 
@keyframes animated-comment-background {
 
  0% {
 
    background-position: 0 0;
 
  }
 
  100% {
kallithea/public/less/yui-ac.less
Show inline comments
 
deleted file
kallithea/templates/changeset/changeset_file_comment.html
Show inline comments
 
## -*- coding: utf-8 -*-
 
## usage:
 
## <%namespace name="comment" file="/changeset/changeset_file_comment.html"/>
 
## ${comment.comment_block(co)}
 
##
 
<%def name="comment_block(co)">
 
  <div class="comment" id="comment-${co.comment_id}">
 
    <div class="comment-prev-next-links"></div>
 
    <div class="panel panel-default">
 
      <div class="panel-heading">
 
          ${h.gravatar_div(co.author.email, size=20)}
 
          <span class="user">
 
              ${co.author.full_name_and_username}
 
          </span>
 

	
 
          <span data-toggle="tooltip" title="${h.fmt_date(co.modified_at)}">
 
              ${h.age(co.modified_at)}
 
              %if co.pull_request:
 
                ${_('on pull request')}
 
                <a href="${co.url()}">"${co.pull_request.title or _("No title")}"</a>
 
              %else:
 
                ${_('on this changeset')}
 
              %endif
 
              <a class="permalink" href="${co.url()}">&para;</a>
 
          </span>
 

	
 
          %if co.author_id == request.authuser.user_id or h.HasRepoPermissionLevel('admin')(c.repo_name):
 
            %if co.deletable():
 
              <button type="button" onClick="confirm('${_('Delete comment?')}') && deleteComment(${co.comment_id})" class="pull-right buttons delete-comment btn btn-default btn-xs">${_('Delete')}</button>
 
            %endif
 
          %endif
 
      </div>
 
      <div class="panel-body">
 
        %if co.status_change:
 
           <div class="automatic-comment">
 
             <p>
 
               ${_("Status change")}: <span class="comment-status-label">${co.status_change[0].status_lbl}</span>
 
               <i class="icon-circle changeset-status-${co.status_change[0].status}"></i>
 
             </p>
 
           </div>
 
        %endif
 
        <div class="comment-text">
 
        %if co.text:
 
          ${h.render_w_mentions(co.text, c.repo_name)|n}
 
        %endif
 
        </div>
 
      </div>
 
    </div>
 
  </div>
 
</%def>
 

	
 

	
 
<%def name="comment_inline_form()">
 
<div id='comment-inline-form-template' style="display: none;">
 
  <div class="comment comment-preview submitting" style="display: none;">
 
    <div class="panel panel-default">
 
      <div class="panel-heading">
 
          ${h.gravatar_div(request.authuser.email, size=20)}
 
          <span class="user">
 
              ${request.authuser.full_name_or_username}
 
          </span>
 

	
 
          <span class="comment-submission-status">
 
              ${_('Submitting ...')}
 
          </span>
 
      </div>
 
      <div class="panel-body">
 
           <div class="automatic-comment" style="display: none;">
 
             <p>
 
               ${_("Status change")}: <span class="comment-status-label"></span>
 
               <i class="icon-circle"></i>
 
             </p>
 
           </div>
 
           <div class="comment-text">
 
             <div class="formatted-fixed">
 
             </div>
 
           </div>
 
      </div>
 
    </div>
 
  </div>
 
  <div class="ac">
 
  %if request.authuser.username != 'default':
 
    ${h.form('#', class_='inline-form')}
 
      <div class="well well-sm clearfix">
 
        <div class="comment-help">
 
          <span class="text-muted">${_('Comments are in plain text. Use @username to notify another user.')|n}</span>
 
        </div>
 
        <textarea name="text" class="form-control comment-block-ta yui-ac-input"></textarea>
 
        <textarea name="text" class="form-control"></textarea>
 

	
 
        <div id="status_block_container" class="status-block general-only hidden">
 
                %if c.pull_request is None:
 
                  ${_('Set changeset status')}:
 
                %else:
 
                  ${_('Vote for pull request status')}:
 
                %endif
 
                <span class="general-only cs-only">
 
                </span>
 
                <label class="radio-inline">
 
                    <input type="radio" class="status_change_radio" name="changeset_status" id="changeset_status_unchanged" value="" checked="checked" />
 
                    ${_('No change')}
 
                </label>
 
                %for status, lbl in c.changeset_statuses:
 
                    <label class="radio-inline">
 
                        <input type="radio" class="status_change_radio" name="changeset_status" id="${status}" value="${status}">
 
                        ${lbl}<i class="icon-circle changeset-status-${status}"></i>
 
                    </label>
 
                %endfor
 

	
 
                %if c.pull_request is not None and ( \
 
                    h.HasPermissionAny('hg.admin')() or h.HasRepoPermissionLevel('admin')(c.repo_name) \
 
                    or c.pull_request.owner_id == request.authuser.user_id):
 
                <div>
 
                  ${_('Finish pull request')}:
 
                  <label class="checkbox-inline">
 
                    <input id="save_close" type="checkbox" name="save_close" class="status_change_checkbox">
 
                    ${_("Close")}
 
                  </label>
 
                  <label class="checkbox-inline">
 
                    <input id="save_delete" type="checkbox" name="save_delete" value="delete" class="status_change_checkbox">
 
                    ${_("Delete")}
 
                  </label>
 
                </div>
 
                %endif
 
        </div>
 

	
 
      </div>
 
      <div class="comment-button">
 
        ${h.submit('save', _('Comment'), class_='btn btn-default btn-sm save-inline-form')}
 
        ${h.reset('hide-inline-form', _('Cancel'), class_='btn btn-default btn-sm hide-inline-form')}
 
      </div>
 
    ${h.end_form()}
 
  %else:
 
      ${h.form('')}
 
      <div class="clearfix">
 
          <div class="comment-help">
 
            ${_('You need to be logged in to comment.')} <a href="${h.url('login_home', came_from=request.path_qs)}">${_('Login now')}</a>
 
          </div>
 
      </div>
 
      <div class="comment-button">
 
      ${h.reset('hide-inline-form', _('Hide'), class_='btn btn-default btn-sm hide-inline-form')}
 
      </div>
 
      ${h.end_form()}
 
  %endif
 
  </div>
 
</div>
 
</%def>
 

	
 

	
 
## show comment count as "x comments (y inline, z general)"
 
<%def name="comment_count(inline_cnt, general_cnt)">
 
    ${'%s (%s, %s)' % (
 
        ungettext("%d comment", "%d comments", inline_cnt + general_cnt) % (inline_cnt + general_cnt),
 
        ungettext("%d inline", "%d inline", inline_cnt) % inline_cnt,
 
        ungettext("%d general", "%d general", general_cnt) % general_cnt
 
    )}
 
    <span class="firstlink"></span>
 
</%def>
 

	
 

	
 
## generate inline comments and the main ones
 
<%def name="generate_comments()">
 
## original location of comments ... but the ones outside diff context remains here
 
<div class="comments inline-comments">
 
  %for f_path, lines in c.inline_comments:
 
    %for line_no, comments in lines.iteritems():
 
      <div class="comments-list-chunk" data-f_path="${f_path}" data-line_no="${line_no}" data-target-id="${h.safeid(h.safe_unicode(f_path))}_${line_no}">
 
        %for co in comments:
 
            ${comment_block(co)}
 
        %endfor
 
      </div>
 
    %endfor
 
  %endfor
 

	
 
      <div class="comments-list-chunk" data-f_path="" data-line_no="" data-target-id="general-comments">
 
        %for co in c.comments:
 
            ${comment_block(co)}
 
        %endfor
 
      </div>
 
</div>
 
<div class="comments-number">
 
    ${comment_count(c.inline_cnt, len(c.comments))}
 
</div>
 
</%def>
 

	
scripts/whitespacecleanup.sh
Show inline comments
 
#!/bin/bash -x
 

	
 
# Enforce some consistency in whitespace - just to avoid spurious whitespaces changes
 

	
 
files=`hg mani | egrep -v '/fontello/|/email_templates/|(/lockfiles.py|^LICENSE-MERGELY.html|^docs/Makefile|^scripts/whitespacecleanup.sh|/(graph|mergely|native.history|yui.2.9)\.js|/test_dump_html_mails.ref.html|\.png|\.gif|\.ico|\.pot|\.po|\.mo|\.tar\.gz|\.diff)$'`
 
files=`hg mani | egrep -v '/fontello/|/email_templates/|(/lockfiles.py|^LICENSE-MERGELY.html|^docs/Makefile|^scripts/whitespacecleanup.sh|/(graph|mergely|native.history)\.js|/test_dump_html_mails.ref.html|\.png|\.gif|\.ico|\.pot|\.po|\.mo|\.tar\.gz|\.diff)$'`
 

	
 
sed -i "s/`printf '\r'`//g" $files
 
sed -i -e "s,`printf '\t'`,    ,g" $files
 
sed -i -e "s,  *$,,g" $files
 
sed -i -e 's,\([^ ]\)\\$,\1 \\,g' -e 's,\(["'"'"']["'"'"']["'"'"']\) \\$,\1\\,g' $files
 
# ensure one trailing newline - remove empty last line and make last line include trailing newline:
 
sed -i -e '$,${/^$/d}' -e '$a\' $files
 

	
 
sed -i -e 's,\([^ /]\){,\1 {,g' `hg loc '*.css'`
 
sed -i -e 's|^\([^ /].*,\)\([^ ]\)|\1 \2|g' `hg loc '*.css'`
 

	
 
hg mani | xargs chmod -x
 
hg loc 'set:!binary()&grep("^#!")&!(**_tmpl.py)&!(**/template**)' | xargs chmod +x
 

	
 
hg diff
0 comments (0 inline, 0 general)