diff --git a/.tx/config b/.tx/config deleted file mode 100644 --- a/.tx/config +++ /dev/null @@ -1,16 +0,0 @@ -[main] -host = https://www.transifex.com - -[Kallithea.pot] -source_file = kallithea/i18n/kallithea.pot -source_lang = en - -trans.pl = kallithea/i18n/pl/LC_MESSAGES/kallithea.po -trans.ru = kallithea/i18n/ru/LC_MESSAGES/kallithea.po -trans.fr = kallithea/i18n/fr/LC_MESSAGES/kallithea.po -trans.ja = kallithea/i18n/ja/LC_MESSAGES/kallithea.po -trans.pt_BR = kallithea/i18n/pt_BR/LC_MESSAGES/kallithea.po -trans.zh_CN = kallithea/i18n/zh_CN/LC_MESSAGES/kallithea.po -trans.zh_TW = kallithea/i18n/zh_TW/LC_MESSAGES/kallithea.po -trans.de = kallithea/i18n/de/LC_MESSAGES/kallithea.po -type = PO diff --git a/LICENSE.md b/LICENSE.md --- a/LICENSE.md +++ b/LICENSE.md @@ -254,5 +254,21 @@ and licensed under the MIT-permissive li [included in this distribution](MIT-Permissive-License.txt). +Icon fonts +---------- + +Kallithea incorporates subsets of both +[Font Awesome](http://fontawesome.io) and +[GitHub Octicons](https://octicons.github.com) for icons. Font Awesome is: + +Copyright (c) 2012, Dave Gandy + +Octicons is: + +Copyright (c) 2012-2014 GitHub + +These two sets are distributed under [SIL OFL 1.1](http://scripts.sil.org/OFL) +and have been combined into one font called "kallithea." + EOF diff --git a/MANIFEST.in b/MANIFEST.in --- a/MANIFEST.in +++ b/MANIFEST.in @@ -17,5 +17,7 @@ recursive-include kallithea/public/image recursive-include kallithea/public/js * #codemirror recursive-include kallithea/public/codemirror * +#fontello +recursive-include kallithea/public/fontello * #templates recursive-include kallithea/templates * diff --git a/kallithea/config/middleware.py b/kallithea/config/middleware.py --- a/kallithea/config/middleware.py +++ b/kallithea/config/middleware.py @@ -79,24 +79,27 @@ def make_app(global_conf, full_stack=Tru # Handle Python exceptions app = ErrorHandler(app, global_conf, **config['pylons.errorware']) - # we want our low level middleware to get to the request ASAP. We don't - # need any pylons stack middleware in them - app = SimpleHg(app, config) - app = SimpleGit(app, config) - app = RequestWrapper(app, config) # Display error documents for 401, 403, 404 status codes (and # 500 when debug is disabled) + # Note: will buffer the output in memory! if asbool(config['debug']): app = StatusCodeRedirect(app) else: app = StatusCodeRedirect(app, [400, 401, 403, 404, 500]) - #enable https redirets based on HTTP_X_URL_SCHEME set by proxy - if any(asbool(config.get(x)) for x in ['https_fixup', 'force_https', 'use_htsts']): - app = HttpsFixup(app, config) + # Enable https redirects based on HTTP_X_URL_SCHEME set by proxy + if any(asbool(config.get(x)) for x in ['https_fixup', 'force_https', 'use_htsts']): + app = HttpsFixup(app, config) + + # we want our low level middleware to get to the request ASAP. We don't + # need any pylons stack middleware in them - especially no StatusCodeRedirect buffering + app = SimpleHg(app, config) + app = SimpleGit(app, config) + + app = RequestWrapper(app, config) # logging # Establish the Registry for this application - app = RegistryManager(app) + app = RegistryManager(app) # thread / request-local module globals / variables if asbool(static_files): # Serve static files diff --git a/kallithea/controllers/changeset.py b/kallithea/controllers/changeset.py --- a/kallithea/controllers/changeset.py +++ b/kallithea/controllers/changeset.py @@ -109,8 +109,8 @@ def _ignorews_url(GET, fileid=None): params[ctx_key] += [ctx_val] params['anchor'] = fileid - img = h.image(h.url('/images/icons/text_strikethrough.png'), lbl, class_='icon') - return h.link_to(img, h.url.current(**params), title=lbl, class_='tooltip') + icon = h.literal('') + return h.link_to(icon, h.url.current(**params), title=lbl, class_='tooltip') def get_line_ctx(fid, GET): @@ -169,8 +169,8 @@ def _context_url(GET, fileid=None): lbl = _('increase diff context to %(num)s lines') % {'num': ln_ctx} params['anchor'] = fileid - img = h.image(h.url('/images/icons/table_add.png'), lbl, class_='icon') - return h.link_to(img, h.url.current(**params), title=lbl, class_='tooltip') + icon = h.literal('') + return h.link_to(icon, h.url.current(**params), title=lbl, class_='tooltip') class ChangesetController(BaseRepoController): diff --git a/kallithea/controllers/files.py b/kallithea/controllers/files.py --- a/kallithea/controllers/files.py +++ b/kallithea/controllers/files.py @@ -563,20 +563,16 @@ class FilesController(BaseRepoController if not use_cached_archive: # generate new archive - temp_stream = None - try: - fd, archive = tempfile.mkstemp() - temp_stream = open(archive, 'wb') - log.debug('Creating new temp archive in %s' % archive) - cs.fill_archive(stream=temp_stream, kind=fileformat, subrepos=subrepos) - if not subrepos and archive_cache_enabled: - #if we generated the archive and use cache rename that - log.debug('Storing new archive in %s' % cached_archive_path) - shutil.move(archive, cached_archive_path) - archive = cached_archive_path - finally: - if temp_stream: - temp_stream.close() + fd, archive = tempfile.mkstemp() + temp_stream = open(archive, 'wb') + log.debug('Creating new temp archive in %s' % archive) + cs.fill_archive(stream=temp_stream, kind=fileformat, subrepos=subrepos) + temp_stream.close() + if not subrepos and archive_cache_enabled: + #if we generated the archive and use cache rename that + log.debug('Storing new archive in %s' % cached_archive_path) + shutil.move(archive, cached_archive_path) + archive = cached_archive_path def get_chunked_archive(archive): stream = open(archive, 'rb') diff --git a/kallithea/i18n/how_to b/kallithea/i18n/how_to --- a/kallithea/i18n/how_to +++ b/kallithea/i18n/how_to @@ -2,11 +2,11 @@ # to create new language # ########################## -Translations are available on transifex under:: +Translations are available on Hosted Weblate under:: - https://www.transifex.com/projects/p/Kallithea/ + https://hosted.weblate.org/projects/kallithea/kallithea/ -Preferred method is to register on transifex and request new language translation. +Preferred method is to register on Weblate and request new language translation. manual creation of new language +++++++++++++++++++++++++++++++ @@ -26,7 +26,6 @@ Create new language by executing followi python setup.py init_catalog -l This creates a new language under directory kallithea/i18n/ -Be sure to update transifex mapping under .tx/config for new language Edit the new PO file located in LC_MESSAGES directory with poedit or your favorite PO files editor. Do translations and at the end verify the translation diff --git a/kallithea/i18n/ja/LC_MESSAGES/kallithea.po b/kallithea/i18n/ja/LC_MESSAGES/kallithea.po --- a/kallithea/i18n/ja/LC_MESSAGES/kallithea.po +++ b/kallithea/i18n/ja/LC_MESSAGES/kallithea.po @@ -16,7 +16,7 @@ msgstr "" "PO-Revision-Date: 2014-02-13 14:34+0000\n" "Last-Translator: marcinkuzminski \n" "Language-Team: Japanese " -"(http://www.transifex.com/projects/p/Kallithea/language/ja/)\n" +"\n" "Plural-Forms: nplurals=1; plural=0\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/kallithea/i18n/pt_BR/LC_MESSAGES/kallithea.po b/kallithea/i18n/pt_BR/LC_MESSAGES/kallithea.po --- a/kallithea/i18n/pt_BR/LC_MESSAGES/kallithea.po +++ b/kallithea/i18n/pt_BR/LC_MESSAGES/kallithea.po @@ -12,7 +12,7 @@ msgstr "" "PO-Revision-Date: 2014-02-13 14:34+0000\n" "Last-Translator: marcinkuzminski \n" "Language-Team: Portuguese (Brazil) " -"(http://www.transifex.com/projects/p/Kallithea/language/pt_BR/)\n" +"\n" "Plural-Forms: nplurals=2; plural=(n > 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/kallithea/i18n/zh_TW/LC_MESSAGES/kallithea.po b/kallithea/i18n/zh_TW/LC_MESSAGES/kallithea.po --- a/kallithea/i18n/zh_TW/LC_MESSAGES/kallithea.po +++ b/kallithea/i18n/zh_TW/LC_MESSAGES/kallithea.po @@ -11,7 +11,7 @@ msgstr "" "PO-Revision-Date: 2014-02-13 14:34+0000\n" "Last-Translator: marcinkuzminski \n" "Language-Team: Chinese (Taiwan) " -"(http://www.transifex.com/projects/p/Kallithea/language/zh_TW/)\n" +"\n" "Plural-Forms: nplurals=1; plural=0\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" diff --git a/kallithea/lib/diffs.py b/kallithea/lib/diffs.py --- a/kallithea/lib/diffs.py +++ b/kallithea/lib/diffs.py @@ -157,11 +157,12 @@ class DiffProcessor(object): _chunk_re = re.compile(r'^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@(.*)') _newline_marker = re.compile(r'^\\ No newline at end of file') _git_header_re = re.compile(r""" - #^diff[ ]--git + # has already been split on this: + # ^diff[ ]--git [ ]a/(?P.+?)[ ]b/(?P.+?)\n (?:^similarity[ ]index[ ](?P\d+)%\n - ^rename[ ]from[ ](?P\S+)\n - ^rename[ ]to[ ](?P\S+)(?:\n|$))? + ^rename[ ]from[ ](?P.+)\n + ^rename[ ]to[ ](?P.+)(?:\n|$))? (?:^old[ ]mode[ ](?P\d+)\n ^new[ ]mode[ ](?P\d+)(?:\n|$))? (?:^new[ ]file[ ]mode[ ](?P.+)(?:\n|$))? @@ -169,32 +170,33 @@ class DiffProcessor(object): (?:^index[ ](?P[0-9A-Fa-f]+) \.\.(?P[0-9A-Fa-f]+)[ ]?(?P.+)?(?:\n|$))? (?:^(?PGIT[ ]binary[ ]patch)(?:\n|$))? - (?:^---[ ](a/(?P.+)|/dev/null)(?:\n|$))? - (?:^\+\+\+[ ](b/(?P.+)|/dev/null)(?:\n|$))? + (?:^---[ ](a/(?P.+?)|/dev/null)\t?(?:\n|$))? + (?:^\+\+\+[ ](b/(?P.+?)|/dev/null)\t?(?:\n|$))? """, re.VERBOSE | re.MULTILINE) _hg_header_re = re.compile(r""" - #^diff[ ]--git + # has already been split on this: + # ^diff[ ]--git [ ]a/(?P.+?)[ ]b/(?P.+?)\n (?:^old[ ]mode[ ](?P\d+)\n ^new[ ]mode[ ](?P\d+)(?:\n|$))? (?:^similarity[ ]index[ ](?P\d+)%(?:\n|$))? - (?:^rename[ ]from[ ](?P\S+)\n - ^rename[ ]to[ ](?P\S+)(?:\n|$))? - (?:^copy[ ]from[ ](?P\S+)\n - ^copy[ ]to[ ](?P\S+)(?:\n|$))? + (?:^rename[ ]from[ ](?P.+)\n + ^rename[ ]to[ ](?P.+)(?:\n|$))? + (?:^copy[ ]from[ ](?P.+)\n + ^copy[ ]to[ ](?P.+)(?:\n|$))? (?:^new[ ]file[ ]mode[ ](?P.+)(?:\n|$))? (?:^deleted[ ]file[ ]mode[ ](?P.+)(?:\n|$))? (?:^index[ ](?P[0-9A-Fa-f]+) \.\.(?P[0-9A-Fa-f]+)[ ]?(?P.+)?(?:\n|$))? (?:^(?PGIT[ ]binary[ ]patch)(?:\n|$))? - (?:^---[ ](a/(?P.+)|/dev/null)(?:\n|$))? - (?:^\+\+\+[ ](b/(?P.+)|/dev/null)(?:\n|$))? + (?:^---[ ](a/(?P.+?)|/dev/null)\t?(?:\n|$))? + (?:^\+\+\+[ ](b/(?P.+?)|/dev/null)\t?(?:\n|$))? """, re.VERBOSE | re.MULTILINE) #used for inline highlighter word split _token_re = re.compile(r'()(>|<|&|\t| |\W+?)') - _escape_re = re.compile(r'(&)|(<)|(>)|(\t)|( \n| $)') + _escape_re = re.compile(r'(&)|(<)|(>)|(\t)|(?<=.)( \n| $)') def __init__(self, diff, vcs='hg', format='gitdiff', diff_limit=None): @@ -261,8 +263,9 @@ class DiffProcessor(object): return '>' if groups[3]: return '\t' - if groups[4] and m.start(): # skip 1st column with +/- + if groups[4]: return ' ' + assert False return self._escape_re.sub(substitute, safe_unicode(string)) @@ -349,16 +352,19 @@ class DiffProcessor(object): :param diff_chunk: """ + match = None if self.vcs == 'git': match = self._git_header_re.match(diff_chunk) - diff = diff_chunk[match.end():] - return match.groupdict(), imap(self._escaper, diff.splitlines(1)) elif self.vcs == 'hg': match = self._hg_header_re.match(diff_chunk) - diff = diff_chunk[match.end():] - return match.groupdict(), imap(self._escaper, diff.splitlines(1)) - else: + if match is None: raise Exception('VCS type %s is not supported' % self.vcs) + groups = match.groupdict() + rest = diff_chunk[match.end():] + if rest and not rest.startswith('@') and not rest.startswith('literal '): + raise Exception('cannot parse diff header: %r followed by %r' % (diff_chunk[:match.end()], rest[:1000])) + difflines = imap(self._escaper, re.findall(r'.*\n|.+$', rest)) # don't split on \r as str.splitlines do + return groups, difflines def _clean_line(self, line, command): if command in ['+', '-', ' ']: @@ -401,7 +407,7 @@ class DiffProcessor(object): # RENAME if (head['rename_from'] and head['rename_to'] and head['rename_from'] != head['rename_to']): - op = 'M' + op = 'R' stats['binary'] = True stats['ops'][RENAMED_FILENODE] = ('file renamed from %s to %s' % (head['rename_from'], head['rename_to'])) @@ -499,24 +505,24 @@ class DiffProcessor(object): def _parse_lines(self, diff): """ - Parse the diff an return data for the template. + Parse the diff and return data for the template. """ - lineiter = iter(diff) stats = [0, 0] + (old_line, old_end, new_line, new_end) = (None, None, None, None) try: chunks = [] - line = lineiter.next() + line = diff.next() - while line: + while True: lines = [] chunks.append(lines) match = self._chunk_re.match(line) if not match: - break + raise Exception('error parsing diff @@ line %r' % line) gr = match.groups() (old_line, old_end, @@ -538,19 +544,16 @@ class DiffProcessor(object): 'line': line, }) - line = lineiter.next() + line = diff.next() while old_line < old_end or new_line < new_end: - command = ' ' - if line: - command = line[0] + if not line: + raise Exception('error parsing diff - empty line at -%s+%s' % (old_line, new_line)) affects_old = affects_new = False - # ignore those if we don't expect them - if command in '#@': - continue - elif command == '+': + command = line[0] + if command == '+': affects_new = True action = 'add' stats[0] += 1 @@ -558,9 +561,11 @@ class DiffProcessor(object): affects_old = True action = 'del' stats[1] += 1 - else: + elif command == ' ': affects_old = affects_new = True action = 'unmod' + else: + raise Exception('error parsing diff - unknown command in line %r at -%s+%s' % (line, old_line, new_line)) if not self._newline_marker.match(line): old_line += affects_old @@ -572,7 +577,7 @@ class DiffProcessor(object): 'line': self._clean_line(line, command) }) - line = lineiter.next() + line = diff.next() if self._newline_marker.match(line): # we need to append to lines, since this is not @@ -583,9 +588,16 @@ class DiffProcessor(object): 'action': 'context', 'line': self._clean_line(line, command) }) - + line = diff.next() + if old_line > old_end: + raise Exception('error parsing diff - more than %s "-" lines at -%s+%s' % (old_end, old_line, new_line)) + if new_line > new_end: + raise Exception('error parsing diff - more than %s "+" lines at -%s+%s' % (new_end, old_line, new_line)) except StopIteration: pass + if old_line != old_end or new_line != new_end: + raise Exception('diff processing broken when old %s<>%s or new %s<>%s line %r' % (old_line, old_end, new_line, new_end, line)) + return chunks, stats def _safe_id(self, idstring): diff --git a/kallithea/lib/helpers.py b/kallithea/lib/helpers.py --- a/kallithea/lib/helpers.py +++ b/kallithea/lib/helpers.py @@ -57,7 +57,7 @@ from kallithea.lib.utils import repo_nam from kallithea.lib.utils2 import str2bool, safe_unicode, safe_str, \ get_changeset_safe, datetime_to_time, time_to_datetime, AttributeDict,\ safe_int -from kallithea.lib.markup_renderer import MarkupRenderer +from kallithea.lib.markup_renderer import MarkupRenderer, url_re from kallithea.lib.vcs.exceptions import ChangesetDoesNotExistError from kallithea.lib.vcs.backends.base import BaseChangeset, EmptyChangeset from kallithea.config.conf import DATE_FORMAT, DATETIME_FORMAT @@ -588,9 +588,9 @@ def boolicon(value): """ if value: - return HTML.tag('i', class_="icon-ok-sign") + return HTML.tag('i', class_="icon-ok") else: - return HTML.tag('i', class_="icon-minus-sign") + return HTML.tag('i', class_="icon-minus-circled") def action_parser(user_log, feed=False, parse_cs=False): @@ -773,23 +773,23 @@ def action_parser(user_log, feed=False, # action : translated str, callback(extractor), icon action_map = { 'user_deleted_repo': (_('[deleted] repository'), - None, 'icon-trash'), + None, 'icon-trashcan'), 'user_created_repo': (_('[created] repository'), None, 'icon-plus icon-plus-colored'), 'user_created_fork': (_('[created] repository as fork'), - None, 'icon-code-fork'), + None, 'icon-fork'), 'user_forked_repo': (_('[forked] repository'), - get_fork_name, 'icon-code-fork'), + get_fork_name, 'icon-fork'), 'user_updated_repo': (_('[updated] repository'), None, 'icon-pencil icon-pencil-colored'), 'user_downloaded_archive': (_('[downloaded] archive from repository'), - get_archive_name, 'icon-download-alt'), + get_archive_name, 'icon-download-cloud'), 'admin_deleted_repo': (_('[delete] repository'), - None, 'icon-trash'), + None, 'icon-trashcan'), 'admin_created_repo': (_('[created] repository'), None, 'icon-plus icon-plus-colored'), 'admin_forked_repo': (_('[forked] repository'), - None, 'icon-code-fork icon-fork-colored'), + None, 'icon-fork icon-fork-colored'), 'admin_updated_repo': (_('[updated] repository'), None, 'icon-pencil icon-pencil-colored'), 'admin_created_user': (_('[created] user'), @@ -805,15 +805,15 @@ def action_parser(user_log, feed=False, 'user_commented_pull_request': (_('[commented] on pull request for'), get_pull_request, 'icon-comment icon-comment-colored'), 'user_closed_pull_request': (_('[closed] pull request for'), - get_pull_request, 'icon-check'), + get_pull_request, 'icon-ok'), 'push': (_('[pushed] into'), - get_cs_links, 'icon-arrow-up'), + get_cs_links, 'icon-move-up'), 'push_local': (_('[committed via Kallithea] into repository'), get_cs_links, 'icon-pencil icon-pencil-colored'), 'push_remote': (_('[pulled from remote] into repository'), - get_cs_links, 'icon-arrow-up'), + get_cs_links, 'icon-move-up'), 'pull': (_('[pulled] from'), - None, 'icon-arrow-down'), + None, 'icon-move-down'), 'started_following_repo': (_('[started following] repository'), None, 'icon-heart icon-heart-colored'), 'stopped_following_repo': (_('[stopped following] repository'), @@ -1256,13 +1256,10 @@ def urlify_text(text_, safe=True): :param text_: """ - url_pat = re.compile(r'''(http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+#]''' - '''|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+)''') - def url_func(match_obj): url_full = match_obj.groups()[0] return '%(url)s' % ({'url': url_full}) - _newtext = url_pat.sub(url_func, text_) + _newtext = url_re.sub(url_func, text_) if safe: return literal(_newtext) return _newtext diff --git a/kallithea/lib/markup_renderer.py b/kallithea/lib/markup_renderer.py --- a/kallithea/lib/markup_renderer.py +++ b/kallithea/lib/markup_renderer.py @@ -35,6 +35,9 @@ from kallithea.lib.utils2 import safe_un log = logging.getLogger(__name__) +url_re = re.compile(r'''(\bhttps?://(?:[\da-zA-Z0-9@:.-]+)''' + r'''(?:[/a-zA-Z0-9_=@#~&+%.,:?!*()-]*[/a-zA-Z0-9_=@#~])?)''') + class MarkupRenderer(object): RESTRUCTUREDTEXT_DISALLOWED_DIRECTIVES = ['include', 'meta', 'raw'] @@ -127,17 +130,11 @@ class MarkupRenderer(object): if universal_newline: newline = '\n' source = newline.join(source.splitlines()) - def urlify_text(text): - url_pat = re.compile(r'(http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+#]' - '|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+)') - def url_func(match_obj): - url_full = match_obj.groups()[0] - return '%(url)s' % ({'url': url_full}) - - return url_pat.sub(url_func, text) - - source = urlify_text(source) + def url_func(match_obj): + url_full = match_obj.groups()[0] + return '%(url)s' % ({'url': url_full}) + source = url_re.sub(url_func, source) return '
' + source.replace("\n", '
') @classmethod diff --git a/kallithea/model/db.py b/kallithea/model/db.py --- a/kallithea/model/db.py +++ b/kallithea/model/db.py @@ -2309,10 +2309,11 @@ class PullRequest(Base, BaseModel): def url(self, **kwargs): canonical = kwargs.pop('canonical', None) import kallithea.lib.helpers as h - s = '/' + self.title b = self.org_ref_parts[1] if b != self.other_ref_parts[1]: - s = '/_%s_%s' % (b, s) + s = '/_/' + b + else: + s = '/_/' + self.title kwargs['extra'] = urlreadable(s) if canonical: return h.canonical_url('pullrequest_show', repo_name=self.other_repo.repo_name, diff --git a/kallithea/public/css/bootstrap.css b/kallithea/public/css/bootstrap.css --- a/kallithea/public/css/bootstrap.css +++ b/kallithea/public/css/bootstrap.css @@ -2544,7 +2544,7 @@ input[type="button"].btn-block { content: "\e030"; } -.glyphicon-refresh:before { +.glyphicon-arrows-cw:before { content: "\e031"; } diff --git a/kallithea/public/css/contextbar.css b/kallithea/public/css/contextbar.css --- a/kallithea/public/css/contextbar.css +++ b/kallithea/public/css/contextbar.css @@ -2,69 +2,48 @@ * Stylesheets for the context bar */ -i.icon-archive { background-image: url("../images/icons/database_edit.png"); } -i.icon-arrow-right { background-image: url('../images/icons/arrow_right.png');} -i.icon-ban-circle { background-image: url("../images/icons/cancel.png"); } -i.icon-bar-chart { background-image: url("../images/icons/chart_bar.png"); } -i.icon-book { background-image: url("../images/icons/book.png"); } -i.icon-bookmark { background-image: url("../images/icons/tag_green.png"); } -i.icon-code-fork { background-image: url("../images/icons/arrow_branch.png"); } -i.icon-code-merge { background-image: url("../images/icons/arrow_merge.png"); } /* unused! */ -i.icon-cog { background-image: url("../images/icons/cog_edit.png"); } -i.icon-cog { background-image: url("../images/icons/cog.png"); } -i.icon-cogs { background-image: url("../images/icons/table_gear.png"); } i.icon-ellipsis-horizontal:after { content: ' ...';} -i.icon-eye-open { background-image: url("../images/icons/eye.png"); } -i.icon-file-2 { background-image: url("../images/icons/note.png"); } -i.icon-file-alt { background-image: url("../images/icons/note_add.png"); } -i.icon-file { background-image: url("../images/icons/file.png"); } -i.icon-file-text { background-image: url("../images/icons/clipboard_16.png"); } -i.icon-file-txt { background-image: url("../images/icons/note_error.png"); } -i.icon-folder-close { background-image: url("../images/icons/database_link.png"); } i.icon-git { background-image: url('../images/icons/giticon.png');} -i.icon-group { background-image: url("../images/icons/group_edit.png"); } -i.icon-heart { background-image: url("../images/icons/heart_delete.png"); } -i.icon-heart-empty { background-image: url("../images/icons/heart.png"); } i.icon-hg { background-image: url('../images/icons/hgicon.png');} -i.icon-key { background-image: url("../images/icons/server_key.png"); } -i.icon-lock { background-image: url('../images/icons/lock.png');} -i.icon-lock-alt { background-image: url('../images/icons/private_repo.png');} -i.icon-loop { background-image: url('../images/icons/arrow_inout.png');} -i.icon-loop-2 { background-image: url('../images/icons/arrow_inout.png');} -i.icon-private { background-image: url('../images/icons/private_repo.png');} -i.icon-public { background-image: url('../images/icons/public_repo.png');} -i.icon-random { background-image: url("../images/icons/arrow_switch.png"); } -i.icon-refresh { background-image: url('../images/icons/arrow_refresh.png');} -i.icon-search { background-image: url("../images/icons/search_16.png"); } -i.icon-tag { background-image: url("../images/icons/tag_blue.png"); } -i.icon-time { background-image: url("../images/icons/time.png"); } -i.icon-list-alt { background-image: url("../images/icons/time.png"); } -i.icon-unlock { background-image: url('../images/icons/lock_open.png');} -i.icon-unlock-alt { background-image: url('../images/icons/public_repo.png');} -i.icon-user { background-image: url("../images/icons/user_edit.png"); } -i.icon-wrench { background-image: url("../images/icons/wrench.png"); } -i.icon-rss-sign { background-image: url('../images/icons/rss_16.png');} -i.icon-plus-sign { background-image: url('../images/icons/add.png');} -i.icon-chevron-left:after { content: "\00AB";} -i.icon-chevron-right:after { content: "\00BB";} -i.icon-copy { background-image: url('../images/icons/note_add.png');} -i.icon-pencil { background-image: url('../images/icons/application_form_edit.png');} -i.icon-remove { background-image: url('../images/icons/delete.png');} -i.icon-remove-sign { background-image: url('../images/icons/delete.png');} -i.icon-plus { background-image: url('../images/icons/plus_16.png');} -i.icon-resize-vertical { background-image: url('../images/icons/text_align_left.png');} -i.icon-ok-sign { background-image: url('../images/icons/tick.png');} -i.icon-minus-sign { background-image: url('../images/icons/delete.png');} i.icon-disabled { background-image: url('../images/icons/shading.png');} /* todo: use instead of minus sign */ i[class^='icon-'] { background-repeat: no-repeat; background-position: center; display: inline-block; - width: 16px; - height: 16px; + min-width: 16px; + min-height: 16px; margin: -2px 0 -4px 0; /* background-color: red; /* for debugging */ + +} + +/* css classes for diff file status ... it'd be nice if css had a way to + inherit from another class but alas, we must make sure this content is the + same from the icon font file */ + +.icon-diff-M:before { + font-family: 'kallithea'; + content: '\e805'; + color: #d0b44c; +} + +.icon-diff-D:before { + font-family: 'kallithea'; + content: '\e807'; + color: #bd2c00; +} + +.icon-diff-A:before { + font-family: 'kallithea'; + content: '\e806'; + color: #6cc644; +} + +.icon-diff-R:before { + font-family: 'kallithea'; + content: '\e81f'; + color: #677a85; } #content #context-bar { diff --git a/kallithea/public/css/style.css b/kallithea/public/css/style.css --- a/kallithea/public/css/style.css +++ b/kallithea/public/css/style.css @@ -501,21 +501,6 @@ div.header img { margin: 0px 2px 0px 2px; } -#header #header-inner #quick li ul li a.journal, -#header #header-inner #quick li ul li a.journal:hover { - background-image: url("../images/icons/book.png"); -} - -#header #header-inner #quick li ul li a.private_repo, -#header #header-inner #quick li ul li a.private_repo:hover { - background-image: url("../images/icons/private_repo.png") -} - -#header #header-inner #quick li ul li a.public_repo, -#header #header-inner #quick li ul li a.public_repo:hover { - background-image: url("../images/icons/public_repo.png"); -} - #header #header-inner #quick li ul li a.hg, #header #header-inner #quick li ul li a.hg:hover { background-image: url("../images/icons/hgicon.png"); @@ -530,110 +515,6 @@ div.header img { background-position: 20px 9px; } -#header #header-inner #quick li ul li a.repos, -#header #header-inner #quick li ul li a.repos:hover { - background-image: url("../images/icons/database_edit.png"); -} - -#header #header-inner #quick li ul li a.repos_groups, -#header #header-inner #quick li ul li a.repos_groups:hover { - background-image: url("../images/icons/database_link.png"); -} - -#header #header-inner #quick li ul li a.users, -#header #header-inner #quick li ul li a.users:hover { - background-image: url("../images/icons/user_edit.png"); -} - -#header #header-inner #quick li ul li a.groups, -#header #header-inner #quick li ul li a.groups:hover { - background-image: url("../images/icons/group_edit.png"); -} - -#header #header-inner #quick li ul li a.defaults, -#header #header-inner #quick li ul li a.defaults:hover { - background-image: url("../images/icons/wrench.png"); -} - -#header #header-inner #quick li ul li a.settings, -#header #header-inner #quick li ul li a.settings:hover { - background-image: url("../images/icons/cog.png"); -} - -#header #header-inner #quick li ul li a.permissions, -#header #header-inner #quick li ul li a.permissions:hover { - background-image: url("../images/icons/key.png"); -} - -#header #header-inner #quick li ul li a.ldap, -#header #header-inner #quick li ul li a.ldap:hover { - background-image: url("../images/icons/server_key.png"); -} - -#header #header-inner #quick li ul li a.fork, -#header #header-inner #quick li ul li a.fork:hover { - background-image: url("../images/icons/arrow_divide.png"); -} - -#header #header-inner #quick li ul li a.locking_add, -#header #header-inner #quick li ul li a.locking_add:hover { - background-image: url("../images/icons/lock_add.png"); -} - -#header #header-inner #quick li ul li a.locking_del, -#header #header-inner #quick li ul li a.locking_del:hover { - background-image: url("../images/icons/lock_delete.png"); -} - -#header #header-inner #quick li ul li a.pull_request, -#header #header-inner #quick li ul li a.pull_request:hover { - background-image: url("../images/icons/arrow_join.png") ; -} - -#header #header-inner #quick li ul li a.compare_request, -#header #header-inner #quick li ul li a.compare_request:hover { - background-image: url("../images/icons/arrow_inout.png"); -} - -#header #header-inner #quick li ul li a.search, -#header #header-inner #quick li ul li a.search:hover { - background-image: url("../images/icons/search_16.png"); -} - -#header #header-inner #quick li ul li a.delete, -#header #header-inner #quick li ul li a.delete:hover { - background-image: url("../images/icons/delete.png"); -} - -#header #header-inner #quick li ul li a.branches, -#header #header-inner #quick li ul li a.branches:hover { - background-image: url("../images/icons/arrow_branch.png"); -} - -#header #header-inner #quick li ul li a.tags, -#header #header-inner #quick li ul li a.tags:hover { - background: #FFF url("../images/icons/tag_blue.png") no-repeat 4px 9px; - width: 167px; - margin: 0; - padding: 12px 9px 7px 24px; -} - -#header #header-inner #quick li ul li a.bookmarks, -#header #header-inner #quick li ul li a.bookmarks:hover { - background: #FFF url("../images/icons/tag_green.png") no-repeat 4px 9px; - width: 167px; - margin: 0; - padding: 12px 9px 7px 24px; -} - -#header #header-inner #quick li ul li a.admin, -#header #header-inner #quick li ul li a.admin:hover { - background: #FFF url("../images/icons/cog_edit.png") no-repeat 4px 9px; - width: 167px; - margin: 0; - padding: 12px 9px 7px 24px; -} - .groups_breadcrumbs a { color: #fff; } @@ -643,22 +524,34 @@ div.header img { text-decoration: none; } +td.quick_repo_menu:before { + font-family: "kallithea"; + content: "\e80f"; /* triangle-right */ + margin-left: 3px; + padding-right: 3px; +} + td.quick_repo_menu { - background: #FFF url("../images/vertical-indicator.png") 8px 50% no-repeat !important; cursor: pointer; width: 8px; border: 1px solid transparent; } +td.quick_repo_menu.active:before { + font-family: "kallithea"; + content: "\e80d"; /* triangle-down */ + margin-left: 1px; + padding-right: 0px; +} + td.quick_repo_menu.active { - background: url("../images/dt-arrow-dn.png") no-repeat scroll 5px 50% #FFFFFF !important; border: 1px solid #577632; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); cursor: pointer; } td.quick_repo_menu .menu_items { - margin-top: 10px; + margin-top: 5px; margin-left: -6px; width: 150px; position: absolute; @@ -778,7 +671,6 @@ th.yui-dt-hidden .yui-dt-resizer { displ padding: 1em 0; text-align: center; } -.yui-skin-sam .yui-dt th { background: #d8d8da url(../images/sprite.png) repeat-x 0 0 } .yui-skin-sam .yui-dt th, .yui-skin-sam .yui-dt th a { font-weight: normal; @@ -831,10 +723,18 @@ th.yui-dt-hidden .yui-dt-resizer { displ } .yui-skin-sam .yui-dt-scrollable .yui-dt-data tr.yui-dt-last td { border-bottom: 1px solid #7f7f7f } .yui-skin-sam th.yui-dt-asc, -.yui-skin-sam th.yui-dt-desc { background: url(../images/sprite.png) repeat-x 0 -100px } .yui-skin-sam th.yui-dt-sortable .yui-dt-label { margin-right: 10px } -.yui-skin-sam th.yui-dt-asc .yui-dt-liner { background: url(../images/dt-arrow-up.png) no-repeat right } -.yui-skin-sam th.yui-dt-desc .yui-dt-liner { background: url(../images/dt-arrow-dn.png) no-repeat right } + +.yui-skin-sam th.yui-dt-asc .yui-dt-liner:after { + font-family: "kallithea"; + content: "\e810"; /* triangle-up */ +} + +.yui-skin-sam th.yui-dt-desc .yui-dt-liner:after { + font-family: "kallithea"; + content: "\e80d"; /* triangle-down */ +} + tbody .yui-dt-editable { cursor: pointer } .yui-dt-editor { text-align: left; @@ -850,27 +750,6 @@ tbody .yui-dt-editable { cursor: pointer padding-top: 6px; text-align: right; } -.yui-dt-editor .yui-dt-button button { - background: url(../images/sprite.png) repeat-x 0 0; - border: 1px solid #999; - width: 4em; - height: 1.8em; - margin-left: 6px; -} -.yui-dt-editor .yui-dt-button button.yui-dt-default { - background: url(../images/sprite.png) repeat-x 0 -1400px; - background-color: #5584e0; - border: 1px solid #304369; - color: #FFF; -} -.yui-dt-editor .yui-dt-button button:hover { - background: url(../images/sprite.png) repeat-x 0 -1300px; - color: #000; -} -.yui-dt-editor .yui-dt-button button:active { - background: url(../images/sprite.png) repeat-x 0 -1700px; - color: #000; -} .yui-skin-sam tr.yui-dt-even { background-color: #FFF } .yui-skin-sam tr.yui-dt-odd { background-color: #edf5ff } .yui-skin-sam tr.yui-dt-even td.yui-dt-asc, @@ -1190,15 +1069,6 @@ tbody .yui-dt-editable { cursor: pointer padding: 9px 6px; } -#content div.box div.message div.dismiss a { - height: 16px; - width: 16px; - display: block; - background: url("../images/icons/cross.png") no-repeat; - margin: 15px 14px 0 0; - padding: 0; -} - #content div.box div.message div.text h1, #content div.box div.message div.text h2, #content div.box div.message div.text h3, @@ -1802,12 +1672,6 @@ div.form div.fields div.field div.button border-top: none; } -#summary-menu-stats a.followers { background-image: url('../images/icons/heart.png')} -#summary-menu-stats a.forks { background-image: url('../images/icons/arrow_divide.png')} -#summary-menu-stats a.settings { background-image: url('../images/icons/cog_edit.png')} -#summary-menu-stats a.feed { background-image: url('../images/icons/rss_16.png')} -#summary-menu-stats a.repo-size { background-image: url('../images/icons/server.png')} - #summary-menu-stats a { display: block; padding: 12px 10px; @@ -1981,8 +1845,13 @@ a.metatag[tag="license"]:hover { padding: 0; } +#login div.inner .icon-lock { + font-size: 80pt; + color: #DDD; +} + #login div.inner { - background: #FFF url("../images/login.png") no-repeat top left; + background: #FFF; border-top: none; border-bottom: none; margin: 0 auto; @@ -2548,30 +2417,28 @@ BIN_FILENODE = 6 .cs_files .cs_added, .cs_files .cs_A { - background: url("../images/icons/page_white_add.png") no-repeat scroll - 3px; height: 16px; - padding-left: 20px; margin-top: 7px; text-align: left; } .cs_files .cs_changed, .cs_files .cs_M { - background: url("../images/icons/page_white_edit.png") no-repeat scroll - 3px; height: 16px; - padding-left: 20px; margin-top: 7px; text-align: left; } .cs_files .cs_removed, .cs_files .cs_D { - background: url("../images/icons/page_white_delete.png") no-repeat - scroll 3px; height: 16px; - padding-left: 20px; + margin-top: 7px; + text-align: left; +} + +.cs_files .cs_renamed, +.cs_files .cs_R { + height: 16px; margin-top: 7px; text-align: left; } @@ -2816,6 +2683,20 @@ BIN_FILENODE = 6 float: left; } +/* changeset statuses (must be the same name as the status) */ +.changeset-status-not_reviewed { + color: #bababa; +} +.changeset-status-approved { + color: #81ba51; +} +.changeset-status-rejected { + color: #cc392e; +} +.changeset-status-under_review { + color: #ffc71e; +} + #graph_content .comments-cnt { color: rgb(136, 136, 136); padding: 5px 0; @@ -2826,16 +2707,6 @@ BIN_FILENODE = 6 padding: 3px 0; } -#pull_request_overview .comments-cnt a, -#changeset_compare_view_content .comments-cnt a, -#graph_content .comments-cnt a, -#shortlog_data .comments-cnt a { - background-image: url('../images/icons/comments.png'); - background-repeat: no-repeat; - background-position: 100% 50%; - padding: 5px 0; -} - .right .changes { clear: both; } @@ -3085,9 +2956,8 @@ table.code-browser tbody td { } table.code-browser .browser-file { - background: url("../images/icons/document_16.png") no-repeat scroll 3px; height: 16px; - padding-left: 20px; + padding-left: 5px; text-align: left; } .diffblock .changeset_header { @@ -3128,19 +2998,22 @@ table.code-browser .browser-file { background-color: #EEEEEE; } table.code-browser .browser-dir { - background: url("../images/icons/folder_16.png") no-repeat scroll 3px; height: 16px; - padding-left: 20px; + padding-left: 5px; text-align: left; } table.code-browser .submodule-dir { - background: url("../images/icons/disconnect.png") no-repeat scroll 3px; height: 16px; - padding-left: 20px; + padding-left: 5px; text-align: left; } +/* add some padding to the right of the file, folder, or submodule icon and +before the text */ +table.code-browser i[class^='icon-'] { + padding-right: .3em; +} .box .search { clear: both; @@ -3335,16 +3208,6 @@ table.code-browser .submodule-dir { z-index: 9050; } -.reposize { - background: url("../images/icons/server.png") no-repeat scroll 3px; - height: 16px; - width: 20px; - cursor: pointer; - display: block; - float: right; - margin-top: 2px; -} - #repo_size { display: block; margin-top: 4px; @@ -3352,111 +3215,11 @@ table.code-browser .submodule-dir { float: right; } -.locking_locked { - background: #FFF url("../images/icons/block_16.png") no-repeat scroll 3px; - height: 16px; - width: 20px; - cursor: pointer; - display: block; - float: right; - margin-top: 2px; -} - -.locking_unlocked { - background: #FFF url("../images/icons/accept.png") no-repeat scroll 3px; - height: 16px; - width: 20px; - cursor: pointer; - display: block; - float: right; - margin-top: 2px; -} - .currently_following { padding-left: 10px; padding-bottom: 5px; } -.add_icon { - background: url("../images/icons/add.png") no-repeat scroll 3px; - padding-left: 20px; - padding-top: 0px; - text-align: left; -} - -.accept_icon { - background: url("../images/icons/accept.png") no-repeat scroll 3px; - padding-left: 20px; - padding-top: 0px; - text-align: left; -} - -.edit_icon { - background: url("../images/icons/application_form_edit.png") no-repeat scroll 3px; - padding-left: 20px; - padding-top: 0px; - text-align: left; -} - -.delete_icon { - background: url("../images/icons/delete.png") no-repeat scroll 3px; - padding-left: 20px; - padding-top: 0px; - text-align: left; -} - -.refresh_icon { - background: url("../images/icons/arrow_refresh.png") no-repeat scroll - 3px; - padding-left: 20px; - padding-top: 0px; - text-align: left; -} - -.pull_icon { - background: url("../images/icons/connect.png") no-repeat scroll 3px; - padding-left: 20px; - padding-top: 0px; - text-align: left; -} - -.rss_icon { - background: url("../images/icons/rss_16.png") no-repeat scroll 3px; - padding-left: 20px; - padding-top: 4px; - text-align: left; - font-size: 8px -} - -.atom_icon { - background: url("../images/icons/rss_16.png") no-repeat scroll 3px; - padding-left: 20px; - padding-top: 4px; - text-align: left; - font-size: 8px -} - -.archive_icon { - background: url("../images/icons/compress.png") no-repeat scroll 3px; - padding-left: 20px; - text-align: left; - padding-top: 1px; -} - -.start_following_icon { - background: url("../images/icons/heart_add.png") no-repeat scroll 3px; - padding-left: 20px; - text-align: left; - padding-top: 0px; -} - -.stop_following_icon { - background: url("../images/icons/heart_delete.png") no-repeat scroll 3px; - padding-left: 20px; - text-align: left; - padding-top: 0px; -} - .action_button { border: 0; display: inline; @@ -3607,15 +3370,6 @@ table.code-browser .submodule-dir { box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25); } -#msg_close { - background: transparent url("../images/cross_grey_small.png") no-repeat scroll 0 0; - cursor: pointer; - height: 16px; - position: absolute; - right: 5px; - top: 5px; - width: 16px; -} div#legend_data { padding-left: 10px; } @@ -3732,19 +3486,6 @@ input.btn { padding: 0; } -/* make .btn inputs and buttons and divs look the same */ -button.btn, -input.btn { - font-family: inherit; - font-size: inherit; - line-height: inherit; -} - -.btn::-moz-focus-inner { - border: 0; - padding: 0; -} - .btn.badge { cursor: default !important; } @@ -4083,31 +3824,6 @@ div.form div.fields div.buttons input, margin: 0; } -input.ui-button { - background: #e5e3e3 url("../images/button.png") repeat-x; - border-top: 1px solid #DDD; - border-left: 1px solid #c6c6c6; - border-right: 1px solid #DDD; - border-bottom: 1px solid #c6c6c6; - color: #515151 !important; - outline: none; - margin: 0; - padding: 6px 12px; - -webkit-border-radius: 4px 4px 4px 4px; - -khtml-border-radius: 4px 4px 4px 4px; - border-radius: 4px 4px 4px 4px; - box-shadow: 0 1px 0 #ececec; - cursor: pointer; -} - -input.ui-button:hover { - background: #b4b4b4 url("../images/button_selected.png") repeat-x; - border-top: 1px solid #ccc; - border-left: 1px solid #bebebe; - border-right: 1px solid #b1b1b1; - border-bottom: 1px solid #afafaf; -} - div.form div.fields div.field div.highlight, #content div.box div.form div.fields div.buttons div.highlight { display: inline; @@ -4140,19 +3856,6 @@ div.box-right div.form div.fields div.bu padding: 0; } -#content div.box div.action div.button input.ui-state-hover, -#login div.form div.fields div.buttons input.ui-state-hover, -#register div.form div.fields div.buttons input.ui-state-hover { - background: #b4b4b4 url("../images/button_selected.png") repeat-x; - border-top: 1px solid #ccc; - border-left: 1px solid #bebebe; - border-right: 1px solid #b1b1b1; - border-bottom: 1px solid #afafaf; - color: #515151; - margin: 0; - padding: 6px 12px; -} - #content div.box div.pagination div.results, #content div.box div.pagination-wh div.results { text-align: left; @@ -5237,12 +4940,17 @@ tr.line.unmod td.code:hover .add-bubble position: relative; left: -32px; width: 32px; - top: -8px; height: 32px; - background: url("../images/icons/comment_add.png") no-repeat 100% 50%; cursor: pointer; } +.add-bubble div:before { + font-size: 14px; + color: #577632; + font-family: "kallithea"; + content: '\e80c'; +} + div.comment:target>.comment-wrapp { border: solid 2px #ee0 !important; } @@ -5291,3 +4999,7 @@ div.prev-next-comment div.next-comment { .repo-switcher-dropdown .select2-result-label span.repo-icons { margin-left: -12px; } + +.icon-only-links i { + color: white; +} diff --git a/kallithea/public/fontello/README-kallithea.txt b/kallithea/public/fontello/README-kallithea.txt new file mode 100644 --- /dev/null +++ b/kallithea/public/fontello/README-kallithea.txt @@ -0,0 +1,4 @@ +Files mentioned here might have been edited or removed. Re-run the export from +fontello by importing the config.json found in this same directory. + +Specifically, the ie7 and animation css files were not added to the repository. diff --git a/kallithea/public/fontello/README.txt b/kallithea/public/fontello/README.txt new file mode 100644 --- /dev/null +++ b/kallithea/public/fontello/README.txt @@ -0,0 +1,75 @@ +This webfont is generated by http://fontello.com open source project. + + +================================================================================ +Please, note, that you should obey original font licences, used to make this +webfont pack. Details available in LICENSE.txt file. + +- Usually, it's enough to publish content of LICENSE.txt file somewhere on your + site in "About" section. + +- If your project is open-source, usually, it will be ok to make LICENSE.txt + file publically available in your repository. + +- Fonts, used in Fontello, don't require to make clickable links on your site. + But any kind of additional authors crediting is welcome. +================================================================================ + + +Comments on archive content +--------------------------- + +- /font/* - fonts in different formats + +- /css/* - different kinds of css, for all situations. Should be ok with + twitter bootstrap. Also, you can skip style and assign icon classes + directly to text elements, if you don't mind about IE7. + +- demo.html - demo file, to show your webfont content + +- LICENSE.txt - license info about source fonts, used to build your one. + +- config.json - keeps your settings. You can import it back to fontello anytime, + to continue your work + + +Why so many CSS files ? +----------------------- + +Because we like to fit all your needs :) + +- basic file, .css - is usually enougth, in contains @font-face + and character codes definition + +- *-ie7.css - if you need IE7 support, but still don't wish to put char codes + directly into html + +- *-codes.css and *-ie7-codes.css - if you like to use your own @font-face + rules, but still wish to benefit of css generation. That can be very + convenient for automated assets build systems. When you need to update font - + no needs to manually edit files, just override old version with archive + content. See fontello source codes for example. + +- *-embedded.css - basic css file, but with embedded WOFF font, to avoid + CORS issues in Firefox and IE9+, when fonts are hosted on the separate domain. + We strongly recommend to resolve this issue by `Access-Control-Allow-Origin` + server headers. But if you ok with dirty hack - this file is for you. Note, + that data url moved to separate @font-face to avoid problems with YX>?r0mGG;2Yro#N*R8G9>TY#w>6YYfb+>GbmMqDZHyq&wBm+XSB-^rOOP1sX zf*1lx4)zC_Fxeo4*a=%^CX*Hp%fwD5AHxKOY$OAOgd`_3$w@>`!sH~Ld_l)*fA`jV zEy>0#XU_NU>(;CFR@JRrw{G2gU$vgt!EqP1a~$C)habv`JWD{yeFWppJ=|p}YH^Xh2d0m$eiZv}I|kz&8yg=Q{L#VZp5(apKSJR*4-6igAZ3;# z9JeM9`QX9910z$liH9NoGK}$)iSeoF3*Y@R)OY;@#|c+YOpZ+ad_Vs&j@y1az<-z{ z{0-zjPUIAN3q1!Vck40vCAWgmY0TRq)wF+V*F}+|#vCOw(sW?ZV(C4)g-bUmANoKMQ zgdF|CD*~~Eo+Fm$LRR6GFJM;W1-(GvCB0}d+;>DOC#a3vXC)1V3+;$RnE?pa2b7Wt=Za$*I|}m zZX{Gs0PQd!>#RyQ5HXx?&SX01mG7=lB0TR2BJ!6007I@tC4Hr)^HnfPU||ZTG`xGW@B@bd99da-fgV~oNlQsf;l;x7!VBl#*;diprc+M%nuxb5eQy3NKtszf6<&bFI!ap3 zo@J8e;uHLSptYT=_b+rDZErT zj$*cfy18$)YN;_Q4_otbK94#DwPhu6mJOg-K zeEZ@)eh${&$A#dKR-dVhl>4nb;-OWNY%Cj#`Z5hv_Ss2H(tH6T%0A5pqASxJbH|8} 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 + + +Copyright (C) 2014 by original authors @ fontello.com + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/kallithea/public/fontello/font/kallithea.ttf b/kallithea/public/fontello/font/kallithea.ttf new file mode 100644 index 0000000000000000000000000000000000000000..1b2dc07a238abe818bf8caa2686a437a2a10bbca GIT binary patch literal 21756 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 diff --git a/kallithea/public/fontello/font/kallithea.woff b/kallithea/public/fontello/font/kallithea.woff new file mode 100644 index 0000000000000000000000000000000000000000..ce8373840bbe8ca7ef9bf707733fc52217d826b6 GIT binary patch literal 12972 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\n'+ '
\n'+ '
\n'+ - ' \n'+ + ' \n'+ '
\n'+ '
gravatar
\n'+ '
{1}
\n'+ ' \n'+ '
\n'+ - ' \n'+ - '
*\n'+ + ' \n'+ + '
\n'+ ' \n'+ ' \n' ).format(gravatar_link, displayname, id); diff --git a/kallithea/templates/admin/gists/edit.html b/kallithea/templates/admin/gists/edit.html --- a/kallithea/templates/admin/gists/edit.html +++ b/kallithea/templates/admin/gists/edit.html @@ -35,7 +35,7 @@
- +
%if not notification.read:
- +
%endif
diff --git a/kallithea/templates/admin/notifications/show_notification.html b/kallithea/templates/admin/notifications/show_notification.html --- a/kallithea/templates/admin/notifications/show_notification.html +++ b/kallithea/templates/admin/notifications/show_notification.html @@ -34,7 +34,7 @@ ${c.notification.description}
- +
diff --git a/kallithea/templates/admin/permissions/permissions.html b/kallithea/templates/admin/permissions/permissions.html --- a/kallithea/templates/admin/permissions/permissions.html +++ b/kallithea/templates/admin/permissions/permissions.html @@ -31,7 +31,7 @@
  • - +
    ${_('Permissions')} diff --git a/kallithea/templates/admin/permissions/permissions_ips.html b/kallithea/templates/admin/permissions/permissions_ips.html --- a/kallithea/templates/admin/permissions/permissions_ips.html +++ b/kallithea/templates/admin/permissions/permissions_ips.html @@ -11,7 +11,7 @@ ${h.form(url('edit_user_ips', id=c.user.user_id),method='delete')} ${h.hidden('del_ip_id',ip.ip_id)} ${h.hidden('default_user', 'True')} - ${h.submit('remove_',_('delete'),id="remove_ip_%s" % ip.ip_id, + ${h.submit('remove_',_('delete'),id="remove_ip_%s" % ip.ip_id, class_="action_button", onclick="return confirm('"+_('Confirm to delete this ip: %s') % ip.ip_addr+"');")} ${h.end_form()} diff --git a/kallithea/templates/admin/repo_groups/repo_group_edit_advanced.html b/kallithea/templates/admin/repo_groups/repo_group_edit_advanced.html --- a/kallithea/templates/admin/repo_groups/repo_group_edit_advanced.html +++ b/kallithea/templates/admin/repo_groups/repo_group_edit_advanced.html @@ -21,7 +21,7 @@ ${h.form(h.url('repos_group', group_name onclick="return confirm('${ungettext('Confirm to delete this group: %s with %s repository', 'Confirm to delete this group: %s with %s repositories', c.repo_group.repositories_recursive_count) % (c.repo_group.group_name, c.repo_group.repositories_recursive_count)}');"> - + ${_('Delete this repository group')} ${h.end_form()} diff --git a/kallithea/templates/admin/repo_groups/repo_group_edit_perms.html b/kallithea/templates/admin/repo_groups/repo_group_edit_perms.html --- a/kallithea/templates/admin/repo_groups/repo_group_edit_perms.html +++ b/kallithea/templates/admin/repo_groups/repo_group_edit_perms.html @@ -31,7 +31,7 @@ ${h.form(url('edit_repo_group_perms', gr %if r2p.user.username !='default': - ${_('revoke')} + ${_('revoke')} %endif @@ -68,7 +68,7 @@ ${h.form(url('edit_repo_group_perms', gr - ${_('revoke')} + ${_('revoke')} diff --git a/kallithea/templates/admin/repos/repo_add_base.html b/kallithea/templates/admin/repos/repo_add_base.html --- a/kallithea/templates/admin/repos/repo_add_base.html +++ b/kallithea/templates/admin/repos/repo_add_base.html @@ -11,7 +11,7 @@ ${h.form(url('repos'))}
    ${h.text('repo_name',class_="small")} %if not c.authuser.is_admin: ${h.hidden('user_created',True)} diff --git a/kallithea/templates/admin/repos/repo_edit.html b/kallithea/templates/admin/repos/repo_edit.html --- a/kallithea/templates/admin/repos/repo_edit.html +++ b/kallithea/templates/admin/repos/repo_edit.html @@ -32,7 +32,7 @@ ${self.repo_context_bar('options')} - + diff --git a/kallithea/templates/admin/repos/repo_edit_advanced.html b/kallithea/templates/admin/repos/repo_edit_advanced.html --- a/kallithea/templates/admin/repos/repo_edit_advanced.html +++ b/kallithea/templates/admin/repos/repo_edit_advanced.html @@ -51,7 +51,7 @@ ${h.form(url('edit_repo_advanced_locking ${h.hidden('set_unlock', '1')} ${'Locked by %s on %s' % (h.person_by_id(c.repo_info.locked[0]),h.fmt_date(h.time_to_datetime(c.repo_info.locked[1])))} @@ -78,7 +78,7 @@ ${h.form(url('repo', repo_name=c.repo_na
    %if c.repo_info.forks.count(): diff --git a/kallithea/templates/admin/repos/repo_edit_fields.html b/kallithea/templates/admin/repos/repo_edit_fields.html --- a/kallithea/templates/admin/repos/repo_edit_fields.html +++ b/kallithea/templates/admin/repos/repo_edit_fields.html @@ -14,7 +14,7 @@ ${field.field_type} ${h.form(url('delete_repo_fields', repo_name=c.repo_info.repo_name, field_id=field.repo_field_id),method='delete')} - + ${h.submit('remove_%s' % field.repo_field_id, _('delete'), id="remove_field_%s" % field.repo_field_id, class_="action_button", onclick="return confirm('"+_('Confirm to delete this field: %s') % field.field_key+"');")} ${h.end_form()} diff --git a/kallithea/templates/admin/repos/repo_edit_permissions.html b/kallithea/templates/admin/repos/repo_edit_permissions.html --- a/kallithea/templates/admin/repos/repo_edit_permissions.html +++ b/kallithea/templates/admin/repos/repo_edit_permissions.html @@ -40,7 +40,7 @@ ${h.form(url('edit_repo_perms_update', r %if r2p.user.username !='default': - ${_('revoke')} + ${_('revoke')} %endif @@ -65,7 +65,7 @@ ${h.form(url('edit_repo_perms_update', r - ${_('revoke')} + ${_('revoke')} diff --git a/kallithea/templates/admin/settings/settings.html b/kallithea/templates/admin/settings/settings.html --- a/kallithea/templates/admin/settings/settings.html +++ b/kallithea/templates/admin/settings/settings.html @@ -30,7 +30,7 @@
  • - +
    ${_('Settings')} diff --git a/kallithea/templates/admin/settings/settings_hooks.html b/kallithea/templates/admin/settings/settings_hooks.html --- a/kallithea/templates/admin/settings/settings_hooks.html +++ b/kallithea/templates/admin/settings/settings_hooks.html @@ -32,7 +32,7 @@ ${h.form(url('admin_settings_hooks'), me ${h.text('hook_ui_value_new',hook.ui_value,size=60)} - + ${_('delete')}
    diff --git a/kallithea/templates/admin/settings/settings_vcs.html b/kallithea/templates/admin/settings/settings_vcs.html --- a/kallithea/templates/admin/settings/settings_vcs.html +++ b/kallithea/templates/admin/settings/settings_vcs.html @@ -88,7 +88,7 @@ ${h.form(url('admin_settings'), method=' $(document).ready(function(){ $('#path_unlock').on('click', function(e){ $('#path_unlock_icon').removeClass('icon-lock'); - $('#path_unlock_icon').addClass('icon-unlock'); + $('#path_unlock_icon').addClass('icon-lock-open-alt'); $('#paths_root_path').removeAttr('readonly'); $('#paths_root_path').removeClass('disabled'); }) diff --git a/kallithea/templates/admin/user_groups/user_group_edit.html b/kallithea/templates/admin/user_groups/user_group_edit.html --- a/kallithea/templates/admin/user_groups/user_group_edit.html +++ b/kallithea/templates/admin/user_groups/user_group_edit.html @@ -32,7 +32,7 @@
  • - +
    ${c.user_group.users_group_name} diff --git a/kallithea/templates/admin/user_groups/user_group_edit_advanced.html b/kallithea/templates/admin/user_groups/user_group_edit_advanced.html --- a/kallithea/templates/admin/user_groups/user_group_edit_advanced.html +++ b/kallithea/templates/admin/user_groups/user_group_edit_advanced.html @@ -17,7 +17,7 @@ ${h.form(h.url('users_group', id=c.user_group.users_group_id),method='delete')} ${h.end_form()} diff --git a/kallithea/templates/admin/user_groups/user_group_edit_perms.html b/kallithea/templates/admin/user_groups/user_group_edit_perms.html --- a/kallithea/templates/admin/user_groups/user_group_edit_perms.html +++ b/kallithea/templates/admin/user_groups/user_group_edit_perms.html @@ -31,7 +31,7 @@ ${h.form(url('edit_user_group_perms', id %if r2p.user.username !='default': - ${_('revoke')} + ${_('revoke')} %endif @@ -68,7 +68,7 @@ ${h.form(url('edit_user_group_perms', id - ${_('revoke')} + ${_('revoke')} diff --git a/kallithea/templates/admin/user_groups/user_group_edit_settings.html b/kallithea/templates/admin/user_groups/user_group_edit_settings.html --- a/kallithea/templates/admin/user_groups/user_group_edit_settings.html +++ b/kallithea/templates/admin/user_groups/user_group_edit_settings.html @@ -41,19 +41,19 @@ ${h.form(url('users_group', id=c.user_gr ${h.select('users_group_members',[x[0] for x in c.group_members],c.group_members,multiple=True,size=8,style="min-width:210px")}
    ${_('Remove all elements')} - +
    - +
    - +
    ${_('Available members')}
    ${h.select('available_members',[],c.available_members,multiple=True,size=8,style="min-width:210px")}
    - ${_('Add all elements')} + ${_('Add all elements')}
    diff --git a/kallithea/templates/admin/users/user_edit_advanced.html b/kallithea/templates/admin/users/user_edit_advanced.html --- a/kallithea/templates/admin/users/user_edit_advanced.html +++ b/kallithea/templates/admin/users/user_edit_advanced.html @@ -19,7 +19,7 @@ ${h.form(h.url('delete_user', id=c.user.user_id),method='delete')} ${h.end_form()} diff --git a/kallithea/templates/admin/users/user_edit_api_keys.html b/kallithea/templates/admin/users/user_edit_api_keys.html --- a/kallithea/templates/admin/users/user_edit_api_keys.html +++ b/kallithea/templates/admin/users/user_edit_api_keys.html @@ -38,7 +38,7 @@ ${h.hidden('del_api_key',api_key.api_key)} ${h.end_form()} diff --git a/kallithea/templates/admin/users/user_edit_emails.html b/kallithea/templates/admin/users/user_edit_emails.html --- a/kallithea/templates/admin/users/user_edit_emails.html +++ b/kallithea/templates/admin/users/user_edit_emails.html @@ -15,7 +15,7 @@ ${h.form(url('edit_user_emails', id=c.user.user_id),method='delete')} ${h.hidden('del_email_id',em.email_id)} - + ${h.submit('remove_',_('delete'),id="remove_email_%s" % em.email_id, class_="action_button", onclick="return confirm('"+_('Confirm to delete this email: %s') % em.email+"');")} ${h.end_form()} diff --git a/kallithea/templates/admin/users/user_edit_ips.html b/kallithea/templates/admin/users/user_edit_ips.html --- a/kallithea/templates/admin/users/user_edit_ips.html +++ b/kallithea/templates/admin/users/user_edit_ips.html @@ -18,7 +18,7 @@ ${h.form(url('edit_user_ips', id=c.user.user_id),method='delete')} ${h.hidden('del_ip_id',ip.ip_id)} - + ${h.submit('remove_',_('delete'),id="remove_ip_%s" % ip.ip_id, class_="action_button", onclick="return confirm('"+_('Confirm to delete this ip: %s') % ip.ip_addr+"');")} ${h.end_form()} diff --git a/kallithea/templates/base/base.html b/kallithea/templates/base/base.html --- a/kallithea/templates/base/base.html +++ b/kallithea/templates/base/base.html @@ -72,14 +72,14 @@ <%def name="admin_menu()"> @@ -89,13 +89,13 @@ <%def name="admin_menu_simple(repositories=None, repository_groups=None, user_groups=None)"> @@ -127,9 +127,9 @@ ## public/private %if c.db_repo.private: - + %else: - + %endif ${h.repo_link(c.db_repo.groups_and_repo)} @@ -147,32 +147,32 @@
  • @@ -108,17 +108,17 @@ <%def name="rss(name)"> %if c.authuser.username != 'default': - + %else: - + %endif <%def name="atom(name)"> %if c.authuser.username != 'default': - + %else: - + %endif @@ -135,7 +135,7 @@
    ${h.form(h.url('repo', repo_name=repo_name),method='delete')} - + ${h.submit('remove_%s' % repo_name,_('delete'),class_="action_button", onclick="return confirm('"+_('Confirm to delete this repository: %s') % repo_name+"');")} ${h.end_form()} @@ -163,7 +163,7 @@
    ${h.form(h.url('delete_user', id=user_id),method='delete')} - + ${h.submit('remove_',_('delete'),id="remove_user_%s" % user_id, class_="action_button", onclick="return confirm('"+_('Confirm to delete this user: %s') % username+"');")} ${h.end_form()} @@ -179,7 +179,7 @@
    ${h.form(h.url('users_group', id=user_group_id),method='delete')} - + ${h.submit('remove_',_('delete'),id="remove_group_%s" % user_group_id, class_="action_button", onclick="return confirm('"+_('Confirm to delete this user group: %s') % user_group_name+"');")} ${h.end_form()} @@ -195,7 +195,7 @@
    ${h.form(h.url('repos_group', group_name=repo_group_name),method='delete')} - + ${h.submit('remove_%s' % repo_group_name,_('delete'),class_="action_button", onclick="return confirm('"+ungettext('Confirm to delete this group: %s with %s repository','Confirm to delete this group: %s with %s repositories',gr_count) % (repo_group_name, gr_count)+"');")} ${h.end_form()} @@ -216,7 +216,7 @@ <%def name="user_group_name(user_group_id, user_group_name)">
    - ${user_group_name} + ${user_group_name}
    diff --git a/kallithea/templates/files/diff_2way.html b/kallithea/templates/files/diff_2way.html --- a/kallithea/templates/files/diff_2way.html +++ b/kallithea/templates/files/diff_2way.html @@ -44,16 +44,16 @@ ${self.repo_context_bar('changelog')}
    - + - + - + - + ${h.checkbox('ignorews', label=_('Ignore whitespace'))} ${h.checkbox('edit_mode', label=_('Edit'))} diff --git a/kallithea/templates/files/files_browser.html b/kallithea/templates/files/files_browser.html --- a/kallithea/templates/files/files_browser.html +++ b/kallithea/templates/files/files_browser.html @@ -1,19 +1,38 @@ <%def name="file_class(node)"> %if node.is_file(): <%return "browser-file" %> + %elif node.is_submodule(): + <%return "submodule-dir"%> %else: <%return "browser-dir"%> %endif +<%def name="file_url(node, c)"> + %if node.is_submodule(): + <%return node.url or '#'%> + %else: + <%return h.url('files_home', repo_name=c.repo_name, revision=c.changeset.raw_id, f_path=h.safe_unicode(node.path))%> + %endif + +<%def name="file_name(node)"> + <% + c = "icon-folder-open" + if node.is_file(): + c = "icon-doc" + elif node.is_submodule(): + c = "icon-file-submodule" + %> + <%return h.literal('%s' % (c, node.name))%> +
    ${h.form(h.url.current())}
    ${_('revision')}
    -
    +
    ${h.text('at_rev',value=c.changeset.revision,size=5)}
    -
    +
    ${h.end_form()}
    @@ -51,7 +70,7 @@ %if c.file.parent: - ${h.link_to('..',h.url('files_home',repo_name=c.repo_name,revision=c.changeset.raw_id,f_path=c.file.parent.path),class_="browser-dir ypjax-link")} + ${h.link_to(h.literal('..'),h.url('files_home',repo_name=c.repo_name,revision=c.changeset.raw_id,f_path=c.file.parent.path),class_="browser-dir ypjax-link")} @@ -64,11 +83,7 @@ %for cnt,node in enumerate(c.file): - %if node.is_submodule(): - ${h.link_to(node.name,node.url or '#',class_="submodule-dir ypjax-link")} - %else: - ${h.link_to(node.name, h.url('files_home',repo_name=c.repo_name,revision=c.changeset.raw_id,f_path=h.safe_unicode(node.path)),class_=file_class(node)+" ypjax-link")} - %endif: + ${h.link_to(file_name(node),file_url(node,c),class_=file_class(node)+" ypjax-link")} %if node.is_file(): diff --git a/kallithea/templates/files/files_edit.html b/kallithea/templates/files/files_edit.html --- a/kallithea/templates/files/files_edit.html +++ b/kallithea/templates/files/files_edit.html @@ -43,7 +43,7 @@ ${self.repo_context_bar('files')}
    -
    +
    ${h.link_to(h.show_id(c.file.changeset),h.url('changeset_home',repo_name=c.repo_name,revision=c.file.changeset.raw_id))}
    ${h.format_byte_size(c.file.size,binary=True)}
    ${c.file.mimetype}
    diff --git a/kallithea/templates/files/files_source.html b/kallithea/templates/files/files_source.html --- a/kallithea/templates/files/files_source.html +++ b/kallithea/templates/files/files_source.html @@ -21,7 +21,7 @@
    -
    +
    ${h.link_to(h.show_id(c.file_changeset),h.url('changeset_home',repo_name=c.repo_name,revision=c.file_changeset.raw_id))}
    ${h.format_byte_size(c.file.size,binary=True)}
    ${c.file.mimetype}
    diff --git a/kallithea/templates/files/files_ypjax.html b/kallithea/templates/files/files_ypjax.html --- a/kallithea/templates/files/files_ypjax.html +++ b/kallithea/templates/files/files_ypjax.html @@ -8,7 +8,7 @@ % if h.HasRepoPermissionAny('repository.write','repository.admin')(c.repo_name): / - + % endif %endif diff --git a/kallithea/templates/forks/forks_data.html b/kallithea/templates/forks/forks_data.html --- a/kallithea/templates/forks/forks_data.html +++ b/kallithea/templates/forks/forks_data.html @@ -18,7 +18,7 @@ ${h.age(f.created_on)} ${_('Compare Fork')} + class="btn btn-small"> ${_('Compare Fork')}
    diff --git a/kallithea/templates/journal/journal.html b/kallithea/templates/journal/journal.html --- a/kallithea/templates/journal/journal.html +++ b/kallithea/templates/journal/journal.html @@ -32,10 +32,10 @@ ${self.breadcrumbs()}
    @@ -51,10 +51,10 @@
    diff --git a/kallithea/templates/journal/public_journal.html b/kallithea/templates/journal/public_journal.html --- a/kallithea/templates/journal/public_journal.html +++ b/kallithea/templates/journal/public_journal.html @@ -25,7 +25,7 @@ diff --git a/kallithea/templates/login.html b/kallithea/templates/login.html --- a/kallithea/templates/login.html +++ b/kallithea/templates/login.html @@ -37,6 +37,7 @@
    ${h.form(h.url.current(came_from=c.came_from))}
    +
    diff --git a/kallithea/templates/pullrequests/pullrequest.html b/kallithea/templates/pullrequests/pullrequest.html --- a/kallithea/templates/pullrequests/pullrequest.html +++ b/kallithea/templates/pullrequests/pullrequest.html @@ -106,7 +106,7 @@ ${self.repo_context_bar('showpullrequest
    ${member.firstname} ${member.lastname} (${_('owner')})
    - +
    @@ -156,9 +156,8 @@ ${self.repo_context_bar('showpullrequest pendingajax = undefined; } pendingajax = ajaxGET(pyroutes.url('pullrequest_repo_info', {"repo_name": repo_name}), - function(o){ + function(data){ pendingajax = undefined; - var data = JSON.parse(o.responseText); $('#other_repo_desc').html(data.description); // replace options of other_ref with the ones for the current other_repo @@ -177,7 +176,7 @@ ${self.repo_context_bar('showpullrequest $other_ref.val(data.selected_ref); // reset && add the reviewer based on selected repo - YUD.get('review_members').innerHTML = ''; + $('#review_members').html(''); addReviewMember(data.user.user_id, data.user.firstname, data.user.lastname, data.user.username, data.user.gravatar_link); @@ -204,16 +203,15 @@ ${self.repo_context_bar('showpullrequest as_form=True, merge=True, )}"; - var org_repo = YUQ('#pull_request_form #org_repo')[0].value; - var org_ref = YUQ('#pull_request_form #org_ref')[0].value.split(':'); + var org_repo = $('#pull_request_form #org_repo').val(); + var org_ref = $('#pull_request_form #org_ref').val().split(':'); ## TODO: make nice link like link_to_ref() do - YUD.get('org_rev_span').innerHTML = org_ref[2].substr(0,12); + $('#org_rev_span').html(org_ref[2].substr(0,12)); - var other_repo = YUQ('#pull_request_form #other_repo')[0].value; - var other_ref = YUQ('#pull_request_form #other_ref')[0].value.split(':'); - YUD.get('other_rev_span').innerHTML = other_ref[2].substr(0,12); + var other_repo = $('#pull_request_form #other_repo').val(); + var other_ref = $('#pull_request_form #other_ref').val().split(':'); + $('#other_rev_span').html(other_ref[2].substr(0,12)); - var select_refs = YUQ('#pull_request_form select.refs') var rev_data = { '__org_repo__': org_repo, '__org_ref_name__': org_ref[2], diff --git a/kallithea/templates/pullrequests/pullrequest_data.html b/kallithea/templates/pullrequests/pullrequest_data.html --- a/kallithea/templates/pullrequests/pullrequest_data.html +++ b/kallithea/templates/pullrequests/pullrequest_data.html @@ -4,9 +4,9 @@
    %if pr.last_review_status: - + %else: - + %endif ${pr.title or _("(no title)")} diff --git a/kallithea/templates/pullrequests/pullrequest_show.html b/kallithea/templates/pullrequests/pullrequest_show.html --- a/kallithea/templates/pullrequests/pullrequest_show.html +++ b/kallithea/templates/pullrequests/pullrequest_show.html @@ -84,7 +84,7 @@ ${self.repo_context_bar('showpullrequest
    %if c.current_voting_result:
    -
    +
    %if c.pull_request.is_closed(): ${_('Closed')}, @@ -215,14 +215,14 @@ ${self.repo_context_bar('showpullrequest
  • - +
    gravatar
    ${member.full_name} (${_('owner') if c.pull_request.user_id == member.user_id else _('reviewer')})
    %if not c.pull_request.is_closed() and (h.HasPermissionAny('hg.admin')() or h.HasRepoPermissionAny('repository.admin')(c.repo_name) or c.pull_request.user_id == c.authuser.user_id):
    - +
    %endif
    @@ -251,12 +251,17 @@ ${self.repo_context_bar('showpullrequest
    - ${_('Compare View')} + ${_('Summary of Pull Request Content')}
    +
    + ${ungettext("%d comment", "%d comments", len(c.comments)) % len(c.comments)} ${ungettext("(%d inline)", "(%d inline)", c.inline_cnt) % c.inline_cnt} +
    ##CS -
    ${ungettext('Showing %s commit','Showing %s commits', len(c.cs_ranges)) % len(c.cs_ranges)}
    +
    + ${ungettext('Showing %s commit','Showing %s commits', len(c.cs_ranges)) % len(c.cs_ranges)} +
    <%include file="/compare/compare_cs.html" />
    @@ -280,12 +285,14 @@ ${self.repo_context_bar('showpullrequest %endif %for fid, change, f, stat in c.files:
    -
    ${h.link_to(h.safe_unicode(f),'#' + fid)}
    +
    + + ${h.link_to(h.safe_unicode(f),'#' + fid)} +
    ${h.fancy_file_stats(stat)}
    %endfor
    -
    ${ungettext("%d comment", "%d comments", len(c.comments)) % len(c.comments)} ${ungettext("(%d inline)", "(%d inline)", c.inline_cnt) % c.inline_cnt}
    % if c.limited_diff:
    ${_('Changeset was too big and was cut off...')} ${_('Show full diff anyway')}
    % endif @@ -333,37 +340,20 @@ ${self.repo_context_bar('showpullrequest $(document).ready(function(){ PullRequestAutoComplete('user', 'reviewers_container', _USERS_AC_DATA, _GROUPS_AC_DATA); - YUE.on(YUQ('.show-inline-comments'),'change',function(e){ - var show = 'none'; - var target = e.currentTarget; - if(target.checked){ - var show = '' - } - var boxid = YUD.getAttribute(target,'id_for'); - var comments = YUQ('#{0} .inline-comments'.format(boxid)); - for(c in comments){ - YUD.setStyle(comments[c],'display',show); - } - var btns = YUQ('#{0} .inline-comments-button'.format(boxid)); - for(c in btns){ - YUD.setStyle(btns[c],'display',show); - } - }) - - YUE.on(YUQ('.add-bubble'),'click',function(e){ + $('.add-bubble').click(function(e){ var tr = e.currentTarget; injectInlineForm(tr.parentNode.parentNode); }); // inject comments into they proper positions - var file_comments = YUQ('.inline-comment-placeholder'); + var file_comments = $('.inline-comment-placeholder').toArray(); renderInlineComments(file_comments); linkInlineComments(document.getElementsByClassName('firstlink'), document.getElementsByClassName("inline-comment")); - YUE.on(YUD.get('update_pull_request'),'click',function(e){ + $('#update_pull_request').click(function(e){ updateReviewers(undefined, "${c.repo_name}", "${c.pull_request.pull_request_id}"); - }) + }); // hack: re-navigate to target after JS is done ... if a target is set and setting href thus won't reload if (window.location.hash != "") { diff --git a/kallithea/templates/pullrequests/pullrequest_show_all.html b/kallithea/templates/pullrequests/pullrequest_show_all.html --- a/kallithea/templates/pullrequests/pullrequest_show_all.html +++ b/kallithea/templates/pullrequests/pullrequest_show_all.html @@ -35,9 +35,9 @@ ${self.repo_context_bar('showpullrequest %endif %if c.from_: - ${_('Show Pull Requests to %s') % c.repo_name} + ${_('Show Pull Requests to %s') % c.repo_name} %else: - ${_("Show Pull Requests from '%s'") % c.repo_name} + ${_("Show Pull Requests from '%s'") % c.repo_name} %endif
  • diff --git a/kallithea/templates/pullrequests/pullrequest_show_my_data.html b/kallithea/templates/pullrequests/pullrequest_show_my_data.html --- a/kallithea/templates/pullrequests/pullrequest_show_my_data.html +++ b/kallithea/templates/pullrequests/pullrequest_show_my_data.html @@ -6,9 +6,9 @@ ${h.checkbox('show_closed',checked="chec
  • @@ -39,9 +45,9 @@ ${h.checkbox('show_closed',checked="chec
  • %if pull_request.last_review_status: - + %else: - + %endif ${pull_request.title or _("(no title)")} diff --git a/kallithea/templates/summary/summary.html b/kallithea/templates/summary/summary.html --- a/kallithea/templates/summary/summary.html +++ b/kallithea/templates/summary/summary.html @@ -13,23 +13,23 @@ ## locking icon %if c.db_repo.enable_locking: %if c.db_repo.locked[0]: - + %else: - + %endif %endif ##FORK %if c.db_repo.fork: - - ${_('Fork of')} "${c.db_repo.fork.repo_name}" + - ${_('Fork of')} "${c.db_repo.fork.repo_name}" %endif ##REMOTE %if c.db_repo.clone_uri: - - ${_('Clone from')} "${h.hide_credentials(c.db_repo.clone_uri)}" + - ${_('Clone from')} "${h.hide_credentials(c.db_repo.clone_uri)}" %endif @@ -124,7 +124,7 @@ summary = lambda n:{False:'summary-short %endif %else: - ${_('Download as zip')} + ${_('Download as zip')} ${h.hidden('download_options')} @@ -153,30 +153,30 @@ summary = lambda n:{False:'summary-short
  • - ${_('Forks')} + ${_('Forks')} ${c.repository_forks}
  • %if c.authuser.username != 'default':
  • - ${_('Repository Size')} + ${_('Repository Size')}
  • %endif
  • %if c.authuser.username != 'default': - ${_('Feed')} + ${_('Feed')} %else: - ${_('Feed')} + ${_('Feed')} %endif
  • %if c.show_stats:
  • - ${_('Statistics')} + ${_('Statistics')}
  • %endif @@ -300,7 +300,7 @@ $(document).ready(function(){ var title_tmpl = "${_('Download %s as %s') % ('__CS_NAME__','__CS_EXT__')}"; title_tmpl= title_tmpl.replace('__CS_NAME__',new_cs.text); title_tmpl = title_tmpl.replace('__CS_EXT__',k); - title_tmpl = ' '+ title_tmpl; + title_tmpl = ' '+ title_tmpl; var url = tmpl_links[k].replace('__CS__',new_cs.id); var subrepos = $('#archive_subrepos').is(':checked'); url = url.replace('__SUB__',subrepos); diff --git a/kallithea/templates/switch_to_list.html b/kallithea/templates/switch_to_list.html --- a/kallithea/templates/switch_to_list.html +++ b/kallithea/templates/switch_to_list.html @@ -1,6 +1,6 @@ ## -*- coding: utf-8 -*-
  • - ${'%s (%s)' % (_('Branches'),len(c.db_repo_scm_instance.branches.values()))} + ${'%s (%s)' % (_('Branches'),len(c.db_repo_scm_instance.branches.values()))}
      %if c.db_repo_scm_instance.branches.values(): %for cnt,branch in enumerate(c.db_repo_scm_instance.branches.items()): @@ -13,7 +13,7 @@ %if c.db_repo_scm_instance.closed_branches.values():
    • - ${'%s (%s)' % (_('Closed Branches'),len(c.db_repo_scm_instance.closed_branches.values()))} + ${'%s (%s)' % (_('Closed Branches'),len(c.db_repo_scm_instance.closed_branches.values()))}
        %for cnt,branch in enumerate(c.db_repo_scm_instance.closed_branches.items()):
      • ${h.link_to('%s - %s' % (branch[0],h.short_id(branch[1])),h.url('files_home',repo_name=c.repo_name,revision=(branch[0] if '/' not in branch[0] else branch[1]), at=branch[0]))}
      • diff --git a/kallithea/templates/tags/tags.html b/kallithea/templates/tags/tags.html --- a/kallithea/templates/tags/tags.html +++ b/kallithea/templates/tags/tags.html @@ -91,7 +91,7 @@ myDataTable.subscribe('postRenderEvent', var func = function(node){ return node.parentNode.parentNode.parentNode.parentNode.parentNode; } - q_filter('q_filter_tags',YUQ('div.table tr td .logtags .tagtag a'),func); + q_filter('q_filter_tags',$('div.table tr td .logtags .tagtag a'),func); }); diff --git a/kallithea/tests/__init__.py b/kallithea/tests/__init__.py --- a/kallithea/tests/__init__.py +++ b/kallithea/tests/__init__.py @@ -208,7 +208,9 @@ class TestController(BaseTestCase): def checkSessionFlash(self, response, msg): self.assertTrue('flash' in response.session, msg='Response session have no flash key' % response.session) - if not msg in response.session['flash'][0][1]: - msg = u'msg `%s` not found in session flash: got `%s` instead' % ( - msg, response.session['flash'][0][1]) + if not any(msg in m for level, m in response.session['flash']): + for level, m in response.session['flash']: + msg = u'msg `%s` not found in session flash: got `%s` instead' % (msg, m) + self.fail(safe_str(msg)) + msg = u'msg `%s` not found in empty session flash' % (msg) self.fail(safe_str(msg)) diff --git a/kallithea/tests/fixtures/diff_with_diff_data.diff b/kallithea/tests/fixtures/diff_with_diff_data.diff --- a/kallithea/tests/fixtures/diff_with_diff_data.diff +++ b/kallithea/tests/fixtures/diff_with_diff_data.diff @@ -414,3 +414,4 @@ index e34033e29fa9b3d3366b723beab129cee7 - if __name__ == '__main__': unittest.main() + diff --git a/kallithea/tests/fixtures/hg_diff_mod_single_file_and_rename_and_chmod.diff b/kallithea/tests/fixtures/hg_diff_mod_single_file_and_rename_and_chmod.diff --- a/kallithea/tests/fixtures/hg_diff_mod_single_file_and_rename_and_chmod.diff +++ b/kallithea/tests/fixtures/hg_diff_mod_single_file_and_rename_and_chmod.diff @@ -9,7 +9,7 @@ rename to README readme2 line 1 line2 - + +line 1 + line2 -+ \ No newline at end of file ++ diff --git a/kallithea/tests/fixtures/hg_diff_rename_space_cr.diff b/kallithea/tests/fixtures/hg_diff_rename_space_cr.diff new file mode 100644 --- /dev/null +++ b/kallithea/tests/fixtures/hg_diff_rename_space_cr.diff @@ -0,0 +1,17 @@ +diff --git a/oh no b/oh yes +rename from oh no +rename to oh yes +--- a/oh no ++++ b/oh yes +@@ -1,4 +1,4 @@ + 1 +-2 + 2 +-3 ++2 ++3 + 4 +@@ -5,3 +6,4 @@ + 5 + 6 + 7 ++8 diff --git a/kallithea/tests/functional/test_compare.py b/kallithea/tests/functional/test_compare.py --- a/kallithea/tests/functional/test_compare.py +++ b/kallithea/tests/functional/test_compare.py @@ -105,7 +105,7 @@ class TestCompareController(TestControll ## files response.mustcontain("""file1""") #swap - response.mustcontain(""" Swap""" % (repo2.repo_name, rev1, rev2, repo1.repo_name)) + response.mustcontain(""" Swap""" % (repo2.repo_name, rev1, rev2, repo1.repo_name)) def test_compare_forks_on_branch_extra_commits_git(self): self.log_user() @@ -153,7 +153,7 @@ class TestCompareController(TestControll ## files response.mustcontain("""file1""") #swap - response.mustcontain(""" Swap""" % (repo2.repo_name, rev1, rev2, repo1.repo_name)) + response.mustcontain(""" Swap""" % (repo2.repo_name, rev1, rev2, repo1.repo_name)) def test_compare_forks_on_branch_extra_commits_origin_has_incomming_hg(self): self.log_user() @@ -208,7 +208,7 @@ class TestCompareController(TestControll ## files response.mustcontain("""file1""") #swap - response.mustcontain(""" Swap""" % (repo2.repo_name, rev1, rev2, repo1.repo_name)) + response.mustcontain(""" Swap""" % (repo2.repo_name, rev1, rev2, repo1.repo_name)) def test_compare_forks_on_branch_extra_commits_origin_has_incomming_git(self): self.log_user() @@ -263,7 +263,7 @@ class TestCompareController(TestControll ## files response.mustcontain("""file1""") #swap - response.mustcontain(""" Swap""" % (repo2.repo_name, rev1, rev2, repo1.repo_name)) + response.mustcontain(""" Swap""" % (repo2.repo_name, rev1, rev2, repo1.repo_name)) def test_compare_cherry_pick_changesets_from_bottom(self): diff --git a/kallithea/tests/functional/test_compare_local.py b/kallithea/tests/functional/test_compare_local.py --- a/kallithea/tests/functional/test_compare_local.py +++ b/kallithea/tests/functional/test_compare_local.py @@ -29,17 +29,39 @@ class TestCompareController(TestControll response.mustcontain('11 files changed with 94 insertions and 64 deletions') ## files diff - response.mustcontain('''''') - response.mustcontain('''''') - response.mustcontain('''''') - response.mustcontain('''''') - response.mustcontain('''''') - response.mustcontain('''''') - response.mustcontain('''''') - response.mustcontain('''''') - response.mustcontain('''''') - response.mustcontain('''''') - response.mustcontain('''''') + response.mustcontain('''
        + + docs/api/utils/index.rst''') + response.mustcontain('''
        + + test_and_report.sh''') + response.mustcontain('''
        + + .hgignore''') + response.mustcontain('''
        + + .hgtags''') + response.mustcontain('''
        + + docs/api/index.rst''') + response.mustcontain('''
        + + vcs/__init__.py''') + response.mustcontain('''
        + + vcs/backends/hg.py''') + response.mustcontain('''
        + + vcs/utils/__init__.py''') + response.mustcontain('''
        + + vcs/utils/annotate.py''') + response.mustcontain('''
        + + vcs/utils/diffs.py''') + response.mustcontain('''
        + + vcs/utils/lazy.py''') def test_compare_tag_git(self): self.log_user() diff --git a/kallithea/tests/functional/test_files.py b/kallithea/tests/functional/test_files.py --- a/kallithea/tests/functional/test_files.py +++ b/kallithea/tests/functional/test_files.py @@ -33,19 +33,19 @@ class TestFilesController(TestController revision='tip', f_path='/')) # Test response... - response.mustcontain('docs') - response.mustcontain('vcs') - response.mustcontain('.gitignore') - response.mustcontain('.hgignore') - response.mustcontain('.hgtags') - response.mustcontain('.travis.yml') - response.mustcontain('MANIFEST.in') - response.mustcontain('README.rst') - response.mustcontain('run_test_and_report.sh') - response.mustcontain('setup.cfg') - response.mustcontain('setup.py') - response.mustcontain('test_and_report.sh') - response.mustcontain('tox.ini') + response.mustcontain('docs') + response.mustcontain('vcs') + response.mustcontain('.gitignore') + response.mustcontain('.hgignore') + response.mustcontain('.hgtags') + response.mustcontain('.travis.yml') + response.mustcontain('MANIFEST.in') + response.mustcontain('README.rst') + response.mustcontain('run_test_and_report.sh') + response.mustcontain('setup.cfg') + response.mustcontain('setup.py') + response.mustcontain('test_and_report.sh') + response.mustcontain('tox.ini') def test_index_revision(self): self.log_user() @@ -59,9 +59,9 @@ class TestFilesController(TestController #Test response... - response.mustcontain('docs') - response.mustcontain('tests') - response.mustcontain('README.rst') + response.mustcontain('docs') + response.mustcontain('tests') + response.mustcontain('README.rst') response.mustcontain('1.1 KiB') response.mustcontain('text/x-python') diff --git a/kallithea/tests/functional/test_home.py b/kallithea/tests/functional/test_home.py --- a/kallithea/tests/functional/test_home.py +++ b/kallithea/tests/functional/test_home.py @@ -21,7 +21,7 @@ class TestHomeController(TestController) response.mustcontain(r'href=\"/%s\"' % HG_REPO) response.mustcontain(r'""" + """""" ) # clone url... @@ -57,7 +57,7 @@ class TestSummaryController(TestControll ) #public/private response.mustcontain( - """""" + """""" ) # clone url... @@ -77,7 +77,7 @@ class TestSummaryController(TestControll ) #public/private response.mustcontain( - """""" + """""" ) def test_index_by_repo_having_id_path_in_name_hg(self): @@ -106,7 +106,7 @@ class TestSummaryController(TestControll ) #public/private response.mustcontain( - """""" + """""" ) def _enable_stats(self, repo): diff --git a/kallithea/tests/models/test_diff_parsers.py b/kallithea/tests/models/test_diff_parsers.py --- a/kallithea/tests/models/test_diff_parsers.py +++ b/kallithea/tests/models/test_diff_parsers.py @@ -26,21 +26,19 @@ DIFF_FIXTURES = { ], 'hg_diff_mod_single_file_and_rename_and_chmod.diff': [ - ('README', 'M', + ('README', 'R', {'added': 3, 'deleted': 0, 'binary': False, - 'ops': {MOD_FILENODE: 'modified file', - RENAMED_FILENODE: 'file renamed from README.rst to README', + 'ops': {RENAMED_FILENODE: 'file renamed from README.rst to README', CHMOD_FILENODE: 'modified file chmod 100755 => 100644'}}), ], 'hg_diff_mod_file_and_rename.diff': [ - ('README.rst', 'M', + ('README.rst', 'R', {'added': 3, 'deleted': 0, 'binary': False, - 'ops': {MOD_FILENODE: 'modified file', - RENAMED_FILENODE: 'file renamed from README to README.rst'}}), + 'ops': {RENAMED_FILENODE: 'file renamed from README to README.rst'}}), ], 'hg_diff_del_single_binary_file.diff': [ ('US Warszawa.jpg', 'D', @@ -66,14 +64,14 @@ DIFF_FIXTURES = { 'ops': {CHMOD_FILENODE: 'modified file chmod 100755 => 100644'}}), ], 'hg_diff_rename_file.diff': [ - ('file_renamed', 'M', + ('file_renamed', 'R', {'added': 0, 'deleted': 0, 'binary': True, 'ops': {RENAMED_FILENODE: 'file renamed from file to file_renamed'}}), ], 'hg_diff_rename_and_chmod_file.diff': [ - ('README', 'M', + ('README', 'R', {'added': 0, 'deleted': 0, 'binary': True, @@ -132,7 +130,7 @@ DIFF_FIXTURES = { 'ops': {CHMOD_FILENODE: 'modified file chmod 100644 => 100755'}}) ], 'git_diff_rename_file.diff': [ - ('file.xls', 'M', + ('file.xls', 'R', {'added': 0, 'deleted': 0, 'binary': True, @@ -248,7 +246,14 @@ DIFF_FIXTURES = { 'ops': {COPIED_FILENODE: 'file copied from file4 to file5', CHMOD_FILENODE: 'modified file chmod 100755 => 100644', MOD_FILENODE: 'modified file'}}), - ] + ], + 'hg_diff_rename_space_cr.diff': [ + ('oh yes', 'R', + {'added': 3, + 'deleted': 2, + 'binary': False, + 'ops': {RENAMED_FILENODE: 'file renamed from oh no to oh yes'}}), + ], } @@ -257,7 +262,7 @@ class DiffLibTest(BaseTestCase): @parameterized.expand([(x,) for x in DIFF_FIXTURES]) def test_diff(self, diff_fixture): - diff = fixture.load_resource(diff_fixture) + diff = fixture.load_resource(diff_fixture, strip=False) diff_proc = DiffProcessor(diff) diff_proc_d = diff_proc.prepare()