Commit 68f964ad authored by Lin Jen-Shin's avatar Lin Jen-Shin

Merge remote-tracking branch 'upstream/master' into show-commit-status-from-source-project

* upstream/master: (409 commits)
  Update endpoint to username validator
  change border color to variable
  Add todo for deprecated user routes and more information about deprecation to changelog
  Provide better error message to the user
  Apply better hierarchy to markdown headers and issue/mr titles
  Swapped button text manipulation outcomes for the toggle query
  Fixed find file keyboard navigation
  Update CHANGELOG for 8.12.7
  Added download-button class and applied button margin
  Enable activerecord_sane_schema_dumper for test
  Updated logo from @luke
  Fix broken specs on MySQL after https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/6896
  Fix Test Env (proper error handling when gitlab-shell is not clonned)
  Fix randomly crashing spinach test for merge request
  [Great spinach fix] Replace gsub with delete
  Remove carriage returns from commit description as summary is on a newline and will always include carriage returns
  Convert due_date_select.js filetype to es6.
  Stop directly parsing due_date with Date.parse, prefer parsing implicitly.
  Improve spec for pipeline metrics worker
  Add Pipeline metrics worker
  ...
parents a04e9f9b 4e6af0c3
CHANGELOG merge=union CHANGELOG.md merge=union
*.js.es6 gitlab-language=javascript *.js.es6 gitlab-language=javascript
...@@ -19,12 +19,10 @@ variables: ...@@ -19,12 +19,10 @@ variables:
before_script: before_script:
- source ./scripts/prepare_build.sh - source ./scripts/prepare_build.sh
- cp config/gitlab.yml.example config/gitlab.yml - cp config/gitlab.yml.example config/gitlab.yml
- mkdir -p tmp/tests
- mount -t tmpfs tmpfs tmp/tests || echo "tmpfs mount failed, falling back to disc"
- bundle --version - bundle --version
- '[ "$USE_BUNDLE_INSTALL" != "true" ] || retry bundle install --without postgres production --jobs $(nproc) "${FLAGS[@]}"' - '[ "$USE_BUNDLE_INSTALL" != "true" ] || retry bundle install --without postgres production --jobs $(nproc) "${FLAGS[@]}"'
- retry gem install knapsack - retry gem install knapsack
- '[ "$SETUP_DB" != "true" ] || bundle exec rake db:drop db:create db:schema:load db:migrate' - '[ "$SETUP_DB" != "true" ] || bundle exec rake db:drop db:create db:schema:load db:migrate add_limits_mysql'
stages: stages:
- prepare - prepare
...@@ -101,7 +99,7 @@ update-knapsack: ...@@ -101,7 +99,7 @@ update-knapsack:
- export KNAPSACK_REPORT_PATH=knapsack/spinach_node_${CI_NODE_INDEX}_${CI_NODE_TOTAL}_report.json - export KNAPSACK_REPORT_PATH=knapsack/spinach_node_${CI_NODE_INDEX}_${CI_NODE_TOTAL}_report.json
- export KNAPSACK_GENERATE_REPORT=true - export KNAPSACK_GENERATE_REPORT=true
- cp knapsack/spinach_report.json ${KNAPSACK_REPORT_PATH} - cp knapsack/spinach_report.json ${KNAPSACK_REPORT_PATH}
- knapsack spinach "-r rerun" || retry '[ ! -e tmp/spinach-rerun.txt ] || bundle exec spinach -r rerun $(cat tmp/spinach-rerun.txt)' - knapsack spinach "-r rerun" || retry '[[ -e tmp/spinach-rerun.txt ]] && bundle exec spinach -r rerun $(cat tmp/spinach-rerun.txt)'
artifacts: artifacts:
expire_in: 31d expire_in: 31d
paths: paths:
...@@ -212,6 +210,13 @@ rake brakeman: *exec ...@@ -212,6 +210,13 @@ rake brakeman: *exec
rake flay: *exec rake flay: *exec
license_finder: *exec license_finder: *exec
rake downtime_check: *exec rake downtime_check: *exec
rake ce_to_ee_merge_check:
<<: *exec
only:
- branches
except:
- tags
allow_failure: yes
rake db:migrate:reset: rake db:migrate:reset:
stage: test stage: test
...@@ -257,6 +262,12 @@ lint-doc: ...@@ -257,6 +262,12 @@ lint-doc:
script: script:
- scripts/lint-doc.sh - scripts/lint-doc.sh
bundler:check:
stage: test
<<: *ruby-static-analysis
script:
- bundle check
bundler:audit: bundler:audit:
stage: test stage: test
<<: *ruby-static-analysis <<: *ruby-static-analysis
...@@ -295,6 +306,17 @@ coverage: ...@@ -295,6 +306,17 @@ coverage:
- coverage/index.html - coverage/index.html
- coverage/assets/ - coverage/assets/
# Trigger docs build
trigger_docs:
stage: post-test
before_script: []
cache: {}
artifacts: {}
script:
- "curl -X POST -F token=${DOCS_TRIGGER_TOKEN} -F ref=master https://gitlab.com/api/v3/projects/38069/trigger/builds"
only:
- master
# Notify slack in the end # Notify slack in the end
notify:slack: notify:slack:
...@@ -327,3 +349,16 @@ pages: ...@@ -327,3 +349,16 @@ pages:
- public - public
only: only:
- master - master
# Insurance in case a gem needed by one of our releases gets yanked from
# rubygems.org in the future.
cache gems:
only:
- tags
variables:
SETUP_DB: "false"
script:
- bundle package --all --all-platforms
artifacts:
paths:
- vendor/cache
See the general Documentation guidelines http://docs.gitlab.com/ce/development/doc_styleguide.html. See the general Documentation guidelines http://docs.gitlab.com/ce/development/doc_styleguide.html
## What does this MR do? ## What does this MR do?
......
...@@ -61,7 +61,7 @@ linters: ...@@ -61,7 +61,7 @@ linters:
# Separate rule, function, and mixin declarations with empty lines. # Separate rule, function, and mixin declarations with empty lines.
EmptyLineBetweenBlocks: EmptyLineBetweenBlocks:
enabled: false enabled: true
# Reports when you have an empty rule set. # Reports when you have an empty rule set.
EmptyRule: EmptyRule:
...@@ -219,7 +219,7 @@ linters: ...@@ -219,7 +219,7 @@ linters:
# Property values, @extend, @include, and @import directives, and variable # Property values, @extend, @include, and @import directives, and variable
# declarations should always end with a semicolon. # declarations should always end with a semicolon.
TrailingSemicolon: TrailingSemicolon:
enabled: false enabled: true
# Reports lines containing trailing whitespace. # Reports lines containing trailing whitespace.
TrailingWhitespace: TrailingWhitespace:
......
This diff is collapsed.
...@@ -247,7 +247,7 @@ request is as follows: ...@@ -247,7 +247,7 @@ request is as follows:
1. Fork the project into your personal space on GitLab.com 1. Fork the project into your personal space on GitLab.com
1. Create a feature branch, branch away from `master` 1. Create a feature branch, branch away from `master`
1. Write [tests](https://gitlab.com/gitlab-org/gitlab-development-kit#running-the-tests) and code 1. Write [tests](https://gitlab.com/gitlab-org/gitlab-development-kit#running-the-tests) and code
1. Add your changes to the [CHANGELOG](CHANGELOG): 1. Add your changes to the [CHANGELOG.md](CHANGELOG.md):
1. If you are fixing a ~regression issue, you can add your entry to the next 1. If you are fixing a ~regression issue, you can add your entry to the next
patch release (e.g. `8.12.5` if current version is `8.12.4`) patch release (e.g. `8.12.5` if current version is `8.12.4`)
1. Otherwise, add your entry to the next minor release (e.g. `8.13.0` if 1. Otherwise, add your entry to the next minor release (e.g. `8.13.0` if
......
...@@ -51,7 +51,7 @@ gem 'browser', '~> 2.2' ...@@ -51,7 +51,7 @@ gem 'browser', '~> 2.2'
# Extracting information from a git repository # Extracting information from a git repository
# Provide access to Gitlab::Git library # Provide access to Gitlab::Git library
gem 'gitlab_git', '~> 10.6.7' gem 'gitlab_git', '~> 10.6.8'
# LDAP Auth # LDAP Auth
# GitLab fork with several improvements to original library. For full list of changes # GitLab fork with several improvements to original library. For full list of changes
...@@ -101,7 +101,7 @@ gem 'seed-fu', '~> 2.3.5' ...@@ -101,7 +101,7 @@ gem 'seed-fu', '~> 2.3.5'
# Markdown and HTML processing # Markdown and HTML processing
gem 'html-pipeline', '~> 1.11.0' gem 'html-pipeline', '~> 1.11.0'
gem 'deckar01-task_list', '1.0.5', require: 'task_list/railtie' gem 'deckar01-task_list', '1.0.5', require: 'task_list/railtie'
gem 'github-markup', '~> 1.4' gem 'gitlab-markup', '~> 1.5.0'
gem 'redcarpet', '~> 3.3.3' gem 'redcarpet', '~> 3.3.3'
gem 'RedCloth', '~> 4.3.2' gem 'RedCloth', '~> 4.3.2'
gem 'rdoc', '~>3.6' gem 'rdoc', '~>3.6'
...@@ -225,7 +225,7 @@ gem 'gon', '~> 6.1.0' ...@@ -225,7 +225,7 @@ gem 'gon', '~> 6.1.0'
gem 'jquery-atwho-rails', '~> 1.3.2' gem 'jquery-atwho-rails', '~> 1.3.2'
gem 'jquery-rails', '~> 4.1.0' gem 'jquery-rails', '~> 4.1.0'
gem 'jquery-ui-rails', '~> 5.0.0' gem 'jquery-ui-rails', '~> 5.0.0'
gem 'request_store', '~> 1.3.0' gem 'request_store', '~> 1.3'
gem 'select2-rails', '~> 3.5.9' gem 'select2-rails', '~> 3.5.9'
gem 'virtus', '~> 1.0.1' gem 'virtus', '~> 1.0.1'
gem 'net-ssh', '~> 3.0.1' gem 'net-ssh', '~> 3.0.1'
...@@ -308,6 +308,8 @@ group :development, :test do ...@@ -308,6 +308,8 @@ group :development, :test do
gem 'license_finder', '~> 2.1.0', require: false gem 'license_finder', '~> 2.1.0', require: false
gem 'knapsack', '~> 1.11.0' gem 'knapsack', '~> 1.11.0'
gem 'activerecord_sane_schema_dumper', '0.2'
end end
group :test do group :test do
...@@ -324,7 +326,7 @@ gem 'newrelic_rpm', '~> 3.16' ...@@ -324,7 +326,7 @@ gem 'newrelic_rpm', '~> 3.16'
gem 'octokit', '~> 4.3.0' gem 'octokit', '~> 4.3.0'
gem 'mail_room', '~> 0.8' gem 'mail_room', '~> 0.8.1'
gem 'email_reply_parser', '~> 0.5.8' gem 'email_reply_parser', '~> 0.5.8'
...@@ -341,7 +343,7 @@ gem 'oauth2', '~> 1.2.0' ...@@ -341,7 +343,7 @@ gem 'oauth2', '~> 1.2.0'
gem 'paranoia', '~> 2.0' gem 'paranoia', '~> 2.0'
# Health check # Health check
gem 'health_check', '~> 2.1.0' gem 'health_check', '~> 2.2.0'
# System information # System information
gem 'vmstat', '~> 2.2' gem 'vmstat', '~> 2.2'
......
...@@ -38,6 +38,8 @@ GEM ...@@ -38,6 +38,8 @@ GEM
multi_json (~> 1.11, >= 1.11.2) multi_json (~> 1.11, >= 1.11.2)
rack (>= 1.5.2, < 3) rack (>= 1.5.2, < 3)
railties (>= 4.0, < 5.1) railties (>= 4.0, < 5.1)
activerecord_sane_schema_dumper (0.2)
rails (>= 4, < 5)
activesupport (4.2.7.1) activesupport (4.2.7.1)
i18n (~> 0.7) i18n (~> 0.7)
json (~> 1.7, >= 1.7.7) json (~> 1.7, >= 1.7.7)
...@@ -280,7 +282,8 @@ GEM ...@@ -280,7 +282,8 @@ GEM
diff-lcs (~> 1.1) diff-lcs (~> 1.1)
mime-types (>= 1.16, < 3) mime-types (>= 1.16, < 3)
posix-spawn (~> 0.3) posix-spawn (~> 0.3)
gitlab_git (10.6.7) gitlab-markup (1.5.0)
gitlab_git (10.6.8)
activesupport (~> 4.0) activesupport (~> 4.0)
charlock_holmes (~> 0.7.3) charlock_holmes (~> 0.7.3)
github-linguist (~> 4.7.0) github-linguist (~> 4.7.0)
...@@ -334,7 +337,7 @@ GEM ...@@ -334,7 +337,7 @@ GEM
thor thor
tilt tilt
hashie (3.4.4) hashie (3.4.4)
health_check (2.1.0) health_check (2.2.1)
rails (>= 4.0) rails (>= 4.0)
hipchat (1.5.2) hipchat (1.5.2)
httparty httparty
...@@ -399,7 +402,7 @@ GEM ...@@ -399,7 +402,7 @@ GEM
systemu (~> 2.6.2) systemu (~> 2.6.2)
mail (2.6.4) mail (2.6.4)
mime-types (>= 1.16, < 4) mime-types (>= 1.16, < 4)
mail_room (0.8.0) mail_room (0.8.1)
method_source (0.8.2) method_source (0.8.2)
mime-types (2.99.3) mime-types (2.99.3)
mimemagic (0.3.0) mimemagic (0.3.0)
...@@ -805,6 +808,7 @@ DEPENDENCIES ...@@ -805,6 +808,7 @@ DEPENDENCIES
RedCloth (~> 4.3.2) RedCloth (~> 4.3.2)
ace-rails-ap (~> 4.1.0) ace-rails-ap (~> 4.1.0)
activerecord-session_store (~> 1.0.0) activerecord-session_store (~> 1.0.0)
activerecord_sane_schema_dumper (= 0.2)
acts-as-taggable-on (~> 4.0) acts-as-taggable-on (~> 4.0)
addressable (~> 2.3.8) addressable (~> 2.3.8)
after_commit_queue (~> 1.3.0) after_commit_queue (~> 1.3.0)
...@@ -861,9 +865,9 @@ DEPENDENCIES ...@@ -861,9 +865,9 @@ DEPENDENCIES
gemnasium-gitlab-service (~> 0.2) gemnasium-gitlab-service (~> 0.2)
gemojione (~> 3.0) gemojione (~> 3.0)
github-linguist (~> 4.7.0) github-linguist (~> 4.7.0)
github-markup (~> 1.4)
gitlab-flowdock-git-hook (~> 1.0.1) gitlab-flowdock-git-hook (~> 1.0.1)
gitlab_git (~> 10.6.7) gitlab-markup (~> 1.5.0)
gitlab_git (~> 10.6.8)
gitlab_omniauth-ldap (~> 1.2.1) gitlab_omniauth-ldap (~> 1.2.1)
gollum-lib (~> 4.2) gollum-lib (~> 4.2)
gollum-rugged_adapter (~> 0.4.2) gollum-rugged_adapter (~> 0.4.2)
...@@ -872,7 +876,7 @@ DEPENDENCIES ...@@ -872,7 +876,7 @@ DEPENDENCIES
grape-entity (~> 0.4.2) grape-entity (~> 0.4.2)
haml_lint (~> 0.18.2) haml_lint (~> 0.18.2)
hamlit (~> 2.6.1) hamlit (~> 2.6.1)
health_check (~> 2.1.0) health_check (~> 2.2.0)
hipchat (~> 1.5.0) hipchat (~> 1.5.0)
html-pipeline (~> 1.11.0) html-pipeline (~> 1.11.0)
httparty (~> 0.13.3) httparty (~> 0.13.3)
...@@ -889,7 +893,7 @@ DEPENDENCIES ...@@ -889,7 +893,7 @@ DEPENDENCIES
license_finder (~> 2.1.0) license_finder (~> 2.1.0)
licensee (~> 8.0.0) licensee (~> 8.0.0)
loofah (~> 2.0.3) loofah (~> 2.0.3)
mail_room (~> 0.8) mail_room (~> 0.8.1)
method_source (~> 0.8) method_source (~> 0.8)
minitest (~> 5.7.0) minitest (~> 5.7.0)
mousetrap-rails (~> 1.4.6) mousetrap-rails (~> 1.4.6)
...@@ -934,7 +938,7 @@ DEPENDENCIES ...@@ -934,7 +938,7 @@ DEPENDENCIES
redis (~> 3.2) redis (~> 3.2)
redis-namespace (~> 1.5.2) redis-namespace (~> 1.5.2)
redis-rails (~> 4.0.0) redis-rails (~> 4.0.0)
request_store (~> 1.3.0) request_store (~> 1.3)
rerun (~> 0.11.0) rerun (~> 0.11.0)
responders (~> 2.0) responders (~> 2.0)
rouge (~> 2.0) rouge (~> 2.0)
......
...@@ -6,11 +6,10 @@ ...@@ -6,11 +6,10 @@
groupProjectsPath: "/api/:version/groups/:id/projects.json", groupProjectsPath: "/api/:version/groups/:id/projects.json",
projectsPath: "/api/:version/projects.json?simple=true", projectsPath: "/api/:version/projects.json?simple=true",
labelsPath: "/:namespace_path/:project_path/labels", labelsPath: "/:namespace_path/:project_path/labels",
licensePath: "/api/:version/licenses/:key", licensePath: "/api/:version/templates/licenses/:key",
gitignorePath: "/api/:version/gitignores/:key", gitignorePath: "/api/:version/templates/gitignores/:key",
gitlabCiYmlPath: "/api/:version/gitlab_ci_ymls/:key", gitlabCiYmlPath: "/api/:version/templates/gitlab_ci_ymls/:key",
issuableTemplatePath: "/:namespace_path/:project_path/templates/:type/:key", issuableTemplatePath: "/:namespace_path/:project_path/templates/:type/:key",
group: function(group_id, callback) { group: function(group_id, callback) {
var url = Api.buildUrl(Api.groupPath) var url = Api.buildUrl(Api.groupPath)
.replace(':id', group_id); .replace(':id', group_id);
......
...@@ -28,12 +28,13 @@ $(() => { ...@@ -28,12 +28,13 @@ $(() => {
state: Store.state, state: Store.state,
loading: true, loading: true,
endpoint: $boardApp.dataset.endpoint, endpoint: $boardApp.dataset.endpoint,
boardId: $boardApp.dataset.boardId,
disabled: $boardApp.dataset.disabled === 'true', disabled: $boardApp.dataset.disabled === 'true',
issueLinkBase: $boardApp.dataset.issueLinkBase issueLinkBase: $boardApp.dataset.issueLinkBase
}, },
init: Store.create.bind(Store), init: Store.create.bind(Store),
created () { created () {
gl.boardService = new BoardService(this.endpoint); gl.boardService = new BoardService(this.endpoint, this.boardId);
}, },
ready () { ready () {
Store.disabled = this.disabled; Store.disabled = this.disabled;
......
class BoardService { class BoardService {
constructor (root) { constructor (root, boardId) {
Vue.http.options.root = root; Vue.http.options.root = root;
this.lists = Vue.resource(`${root}/lists{/id}`, {}, { this.lists = Vue.resource(`${root}/${boardId}/lists{/id}`, {}, {
generate: { generate: {
method: 'POST', method: 'POST',
url: `${root}/lists/generate.json` url: `${root}/${boardId}/lists/generate.json`
} }
}); });
this.issue = Vue.resource(`${root}/issues{/id}`, {}); this.issue = Vue.resource(`${root}/${boardId}/issues{/id}`, {});
this.issues = Vue.resource(`${root}/lists{/id}/issues`, {}); this.issues = Vue.resource(`${root}/${boardId}/lists{/id}/issues`, {});
Vue.http.interceptors.push((request, next) => { Vue.http.interceptors.push((request, next) => {
request.headers['X-CSRF-Token'] = $.rails.csrfToken(); request.headers['X-CSRF-Token'] = $.rails.csrfToken();
......
...@@ -15,18 +15,17 @@ ...@@ -15,18 +15,17 @@
this.hideSidebar = bind(this.hideSidebar, this); this.hideSidebar = bind(this.hideSidebar, this);
this.toggleSidebar = bind(this.toggleSidebar, this); this.toggleSidebar = bind(this.toggleSidebar, this);
this.updateDropdown = bind(this.updateDropdown, this); this.updateDropdown = bind(this.updateDropdown, this);
this.$document = $(document);
clearInterval(Build.interval); clearInterval(Build.interval);
// Init breakpoint checker // Init breakpoint checker
this.bp = Breakpoints.get(); this.bp = Breakpoints.get();
$('.js-build-sidebar').niceScroll(); this.initSidebar();
this.populateJobs(this.build_stage); this.populateJobs(this.build_stage);
this.updateStageDropdownText(this.build_stage); this.updateStageDropdownText(this.build_stage);
this.hideSidebar();
$(document).off('click', '.js-sidebar-build-toggle').on('click', '.js-sidebar-build-toggle', this.toggleSidebar);
$(window).off('resize.build').on('resize.build', this.hideSidebar); $(window).off('resize.build').on('resize.build', this.hideSidebar);
$(document).off('click', '.stage-item').on('click', '.stage-item', this.updateDropdown); this.$document.off('click', '.stage-item').on('click', '.stage-item', this.updateDropdown);
$('#js-build-scroll > a').off('click').on('click', this.stepTrace); $('#js-build-scroll > a').off('click').on('click', this.stepTrace);
this.updateArtifactRemoveDate(); this.updateArtifactRemoveDate();
if ($('#build-trace').length) { if ($('#build-trace').length) {
...@@ -62,6 +61,21 @@ ...@@ -62,6 +61,21 @@
} }
} }
Build.prototype.initSidebar = function() {
this.$sidebar = $('.js-build-sidebar');
this.sidebarTranslationLimits = {
min: $('.navbar-gitlab').outerHeight() + $('.layout-nav').outerHeight()
}
this.sidebarTranslationLimits.max = this.sidebarTranslationLimits.min + $('.scrolling-tabs-container').outerHeight();
this.$sidebar.css({
top: this.sidebarTranslationLimits.max
});
this.$sidebar.niceScroll();
this.hideSidebar();
this.$document.off('click', '.js-sidebar-build-toggle').on('click', '.js-sidebar-build-toggle', this.toggleSidebar);
this.$document.off('scroll.translateSidebar').on('scroll.translateSidebar', this.translateSidebar.bind(this));
};
Build.prototype.getInitialBuildTrace = function() { Build.prototype.getInitialBuildTrace = function() {
var removeRefreshStatuses = ['success', 'failed', 'canceled', 'skipped'] var removeRefreshStatuses = ['success', 'failed', 'canceled', 'skipped']
...@@ -129,15 +143,23 @@ ...@@ -129,15 +143,23 @@
Build.prototype.toggleSidebar = function() { Build.prototype.toggleSidebar = function() {
if (this.shouldHideSidebar()) { if (this.shouldHideSidebar()) {
return $('.js-build-sidebar').toggleClass('right-sidebar-expanded right-sidebar-collapsed'); return this.$sidebar.toggleClass('right-sidebar-expanded right-sidebar-collapsed');
} }
}; };
Build.prototype.translateSidebar = function(e) {
var newPosition = this.sidebarTranslationLimits.max - document.body.scrollTop;
if (newPosition < this.sidebarTranslationLimits.min) newPosition = this.sidebarTranslationLimits.min;
this.$sidebar.css({
top: newPosition
});
};
Build.prototype.hideSidebar = function() { Build.prototype.hideSidebar = function() {
if (this.shouldHideSidebar()) { if (this.shouldHideSidebar()) {
return $('.js-build-sidebar').removeClass('right-sidebar-expanded').addClass('right-sidebar-collapsed'); return this.$sidebar.removeClass('right-sidebar-expanded').addClass('right-sidebar-collapsed');
} else { } else {
return $('.js-build-sidebar').removeClass('right-sidebar-collapsed').addClass('right-sidebar-expanded'); return this.$sidebar.removeClass('right-sidebar-collapsed').addClass('right-sidebar-expanded');
} }
}; };
......
...@@ -9,7 +9,10 @@ ...@@ -9,7 +9,10 @@
var $dropdown, selected; var $dropdown, selected;
$dropdown = $(this); $dropdown = $(this);
selected = $dropdown.data('selected'); selected = $dropdown.data('selected');
return $dropdown.glDropdown({ const $dropdownContainer = $dropdown.closest('.dropdown');
const $fieldInput = $(`input[name="${$dropdown.data('field-name')}"]`, $dropdownContainer);
const $filterInput = $('input[type="search"]', $dropdownContainer);
$dropdown.glDropdown({
data: function(term, callback) { data: function(term, callback) {
return $.ajax({ return $.ajax({
url: $dropdown.data('refs-url'), url: $dropdown.data('refs-url'),
...@@ -42,6 +45,14 @@ ...@@ -42,6 +45,14 @@
return $el.text().trim(); return $el.text().trim();
} }
}); });
$filterInput.on('keyup', (e) => {
const keyCode = e.keyCode || e.which;
if (keyCode !== 13) return;
const text = $filterInput.val();
$fieldInput.val(text);
$('.dropdown-toggle-text', $dropdown).text(text);
$dropdownContainer.removeClass('open');
});
}); });
}; };
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
Dispatcher = (function() { Dispatcher = (function() {
function Dispatcher() { function Dispatcher() {
this.initSearch(); this.initSearch();
this.initFieldErrors();
this.initPageScripts(); this.initPageScripts();
} }
...@@ -20,7 +21,11 @@ ...@@ -20,7 +21,11 @@
path = page.split(':'); path = page.split(':');
shortcut_handler = null; shortcut_handler = null;
switch (page) { switch (page) {
case 'sessions:new':
new UsernameValidator();
break;
case 'projects:boards:show': case 'projects:boards:show':
case 'projects:boards:index':
shortcut_handler = new ShortcutsNavigation(); shortcut_handler = new ShortcutsNavigation();
break; break;
case 'projects:merge_requests:index': case 'projects:merge_requests:index':
...@@ -45,7 +50,7 @@ ...@@ -45,7 +50,7 @@
case 'projects:milestones:new': case 'projects:milestones:new':
case 'projects:milestones:edit': case 'projects:milestones:edit':
new ZenMode(); new ZenMode();
new DueDateSelect(); new gl.DueDateSelectors();
new GLForm($('.milestone-form')); new GLForm($('.milestone-form'));
break; break;
case 'groups:milestones:new': case 'groups:milestones:new':
...@@ -96,9 +101,6 @@ ...@@ -96,9 +101,6 @@
new ZenMode(); new ZenMode();
new MergedButtons(); new MergedButtons();
break; break;
case "projects:merge_requests:conflicts":
window.mcui = new MergeConflictResolver()
break;
case 'projects:merge_requests:index': case 'projects:merge_requests:index':
shortcut_handler = new ShortcutsNavigation(); shortcut_handler = new ShortcutsNavigation();
Issuable.init(); Issuable.init();
...@@ -126,6 +128,9 @@ ...@@ -126,6 +128,9 @@
new TreeView(); new TreeView();
} }
break; break;
case 'projects:pipelines:show':
new gl.Pipelines();
break;
case 'groups:activity': case 'groups:activity':
new Activities(); new Activities();
break; break;
...@@ -136,12 +141,12 @@ ...@@ -136,12 +141,12 @@
break; break;
case 'groups:group_members:index': case 'groups:group_members:index':
new gl.MemberExpirationDate(); new gl.MemberExpirationDate();
new GroupMembers(); new gl.Members();
new UsersSelect(); new UsersSelect();
break; break;
case 'projects:project_members:index': case 'projects:project_members:index':
new gl.MemberExpirationDate(); new gl.MemberExpirationDate();
new ProjectMembers(); new gl.Members();
new UsersSelect(); new UsersSelect();
break; break;
case 'groups:new': case 'groups:new':
...@@ -287,6 +292,12 @@ ...@@ -287,6 +292,12 @@
} }
}; };
Dispatcher.prototype.initFieldErrors = function() {
$('.show-gl-field-errors').each((i, form) => {
new gl.GlFieldErrors(form);
});
};
return Dispatcher; return Dispatcher;
})(); })();
......
(function() {
this.DueDateSelect = (function() {
function DueDateSelect() {
var $datePicker, $dueDate, $loading;
// Milestone edit/new form
$datePicker = $('.datepicker');
if ($datePicker.length) {
$dueDate = $('#milestone_due_date');
$datePicker.datepicker({
dateFormat: 'yy-mm-dd',
onSelect: function(dateText, inst) {
return $dueDate.val(dateText);
}
}).datepicker('setDate', $.datepicker.parseDate('yy-mm-dd', $dueDate.val()));
}
$('.js-clear-due-date').on('click', function(e) {
e.preventDefault();
return $.datepicker._clearDate($datePicker);
});
// Issuable sidebar
$loading = $('.js-issuable-update .due_date').find('.block-loading').hide();
$('.js-due-date-select').each(function(i, dropdown) {
var $block, $dropdown, $dropdownParent, $selectbox, $sidebarValue, $value, $valueContent, abilityName, addDueDate, fieldName, issueUpdateURL;
$dropdown = $(dropdown);
$dropdownParent = $dropdown.closest('.dropdown');
$datePicker = $dropdownParent.find('.js-due-date-calendar');
$block = $dropdown.closest('.block');
$selectbox = $dropdown.closest('.selectbox');
$value = $block.find('.value');
$valueContent = $block.find('.value-content');
$sidebarValue = $('.js-due-date-sidebar-value', $block);
fieldName = $dropdown.data('field-name');
abilityName = $dropdown.data('ability-name');
issueUpdateURL = $dropdown.data('issue-update');
$dropdown.glDropdown({
hidden: function() {
$selectbox.hide();
return $value.css('display', '');
}
});
addDueDate = function(isDropdown) {
var data, date, mediumDate, value;
// Create the post date
value = $("input[name='" + fieldName + "']").val();
if (value !== '') {
date = new Date(value.replace(new RegExp('-', 'g'), ','));
mediumDate = $.datepicker.formatDate('M d, yy', date);
} else {
mediumDate = 'No due date';
}
data = {};
data[abilityName] = {};
data[abilityName].due_date = value;
return $.ajax({
type: 'PUT',
url: issueUpdateURL,
data: data,
dataType: 'json',
beforeSend: function() {
var cssClass;
$loading.fadeIn();
if (isDropdown) {
$dropdown.trigger('loading.gl.dropdown');
$selectbox.hide();
}
$value.css('display', '');
cssClass = Date.parse(mediumDate) ? 'bold' : 'no-value';
$valueContent.html("<span class='" + cssClass + "'>" + mediumDate + "</span>");
$sidebarValue.html(mediumDate);
if (value !== '') {
return $('.js-remove-due-date-holder').removeClass('hidden');
} else {
return $('.js-remove-due-date-holder').addClass('hidden');
}
}
}).done(function(data) {
if (isDropdown) {
$dropdown.trigger('loaded.gl.dropdown');
$dropdown.dropdown('toggle');
}
return $loading.fadeOut();
});
};
$block.on('click', '.js-remove-due-date', function(e) {
e.preventDefault();
$("input[name='" + fieldName + "']").val('');
return addDueDate(false);
});
return $datePicker.datepicker({
dateFormat: 'yy-mm-dd',
defaultDate: $("input[name='" + fieldName + "']").val(),
altField: "input[name='" + fieldName + "']",
onSelect: function() {
return addDueDate(true);
}
});
});
$(document).off('click', '.ui-datepicker-header a').on('click', '.ui-datepicker-header a', function(e) {
return e.stopImmediatePropagation();
});
}
return DueDateSelect;
})();
}).call(this);
(function(global) {
class DueDateSelect {
constructor({ $dropdown, $loading } = {}) {
const $dropdownParent = $dropdown.closest('.dropdown');
const $block = $dropdown.closest('.block');
this.$loading = $loading;
this.$dropdown = $dropdown;
this.$dropdownParent = $dropdownParent;
this.$datePicker = $dropdownParent.find('.js-due-date-calendar');
this.$block = $block;
this.$selectbox = $dropdown.closest('.selectbox');
this.$value = $block.find('.value');
this.$valueContent = $block.find('.value-content');
this.$sidebarValue = $('.js-due-date-sidebar-value', $block);
this.fieldName = $dropdown.data('field-name'),
this.abilityName = $dropdown.data('ability-name'),
this.issueUpdateURL = $dropdown.data('issue-update')
this.rawSelectedDate = null;
this.displayedDate = null;
this.datePayload = null;
this.initGlDropdown();
this.initRemoveDueDate();
this.initDatePicker();
this.initStopPropagation();
}
initGlDropdown() {
this.$dropdown.glDropdown({
hidden: () => {
this.$selectbox.hide();
this.$value.css('display', '');
}
});
}
initDatePicker() {
this.$datePicker.datepicker({
dateFormat: 'yy-mm-dd',
defaultDate: $("input[name='" + this.fieldName + "']").val(),
altField: "input[name='" + this.fieldName + "']",
onSelect: () => {
return this.saveDueDate(true);
}
});
}
initRemoveDueDate() {
this.$block.on('click', '.js-remove-due-date', (e) => {
e.preventDefault();
$("input[name='" + this.fieldName + "']").val('');
return this.saveDueDate(false);
});
}
initStopPropagation() {
$(document).off('click', '.ui-datepicker-header a').on('click', '.ui-datepicker-header a', (e) => {
return e.stopImmediatePropagation();
});
}
saveDueDate(isDropdown) {
this.parseSelectedDate();
this.prepSelectedDate();
this.submitSelectedDate(isDropdown);
}
parseSelectedDate() {
this.rawSelectedDate = $("input[name='" + this.fieldName + "']").val();
if (this.rawSelectedDate.length) {
let dateObj = new Date(this.rawSelectedDate);
this.displayedDate = $.datepicker.formatDate('M d, yy', dateObj);
} else {
this.displayedDate = 'No due date';
}
}
prepSelectedDate() {
const datePayload = {};
datePayload[this.abilityName] = {};
datePayload[this.abilityName].due_date = this.rawSelectedDate;
this.datePayload = datePayload;
}
submitSelectedDate(isDropdown) {
return $.ajax({
type: 'PUT',
url: this.issueUpdateURL,
data: this.datePayload,
dataType: 'json',
beforeSend: () => {
const selectedDateValue = this.datePayload[this.abilityName].due_date;
const displayedDateStyle = this.displayedDate !== 'No due date' ? 'bold' : 'no-value';
this.$loading.fadeIn();
if (isDropdown) {
this.$dropdown.trigger('loading.gl.dropdown');
this.$selectbox.hide();
}
this.$value.css('display', '');
this.$valueContent.html(`<span class='${displayedDateStyle}'>${this.displayedDate}</span>`);
this.$sidebarValue.html(this.displayedDate);
return selectedDateValue.length ?
$('.js-remove-due-date-holder').removeClass('hidden') :
$('.js-remove-due-date-holder').addClass('hidden');
}
}).done((data) => {
if (isDropdown) {
this.$dropdown.trigger('loaded.gl.dropdown');
this.$dropdown.dropdown('toggle');
}
return this.$loading.fadeOut();
});
}
}
class DueDateSelectors {
constructor() {
this.initMilestoneDueDate();
this.initIssuableSelect();
}
initMilestoneDueDate() {
const $datePicker = $('.datepicker');
if ($datePicker.length) {
const $dueDate = $('#milestone_due_date');
$datePicker.datepicker({
dateFormat: 'yy-mm-dd',
onSelect: (dateText, inst) => {
$dueDate.val(dateText);
}
}).datepicker('setDate', $.datepicker.parseDate('yy-mm-dd', $dueDate.val()));
}
$('.js-clear-due-date').on('click', (e) => {
e.preventDefault();
$.datepicker._clearDate($datePicker);
});
}
initIssuableSelect() {
const $loading = $('.js-issuable-update .due_date').find('.block-loading').hide();
$('.js-due-date-select').each((i, dropdown) => {
const $dropdown = $(dropdown);
new DueDateSelect({
$dropdown,
$loading
});
});
}
}
global.DueDateSelectors = DueDateSelectors;
})(window.gl || (window.gl = {}));
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
return function(e) { return function(e) {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
return _this.input.val('').trigger('keyup').focus(); return _this.input.val('').trigger('input').focus();
}; };
})(this)); })(this));
// Key events // Key events
...@@ -37,28 +37,16 @@ ...@@ -37,28 +37,16 @@
e.preventDefault() e.preventDefault()
} }
}) })
.on('keyup', function(e) { .on('input', function() {
var keyCode;
keyCode = e.which;
if (ARROW_KEY_CODES.indexOf(keyCode) >= 0) {
return;
}
if (this.input.val() !== "" && !$inputContainer.hasClass(HAS_VALUE_CLASS)) { if (this.input.val() !== "" && !$inputContainer.hasClass(HAS_VALUE_CLASS)) {
$inputContainer.addClass(HAS_VALUE_CLASS); $inputContainer.addClass(HAS_VALUE_CLASS);
} else if (this.input.val() === "" && $inputContainer.hasClass(HAS_VALUE_CLASS)) { } else if (this.input.val() === "" && $inputContainer.hasClass(HAS_VALUE_CLASS)) {
$inputContainer.removeClass(HAS_VALUE_CLASS); $inputContainer.removeClass(HAS_VALUE_CLASS);
} }
if (keyCode === 13 && !options.elIsInput) {
return false;
}
// Only filter asynchronously only if option remote is set // Only filter asynchronously only if option remote is set
if (this.options.remote) { if (this.options.remote) {
clearTimeout(timeout); clearTimeout(timeout);
return timeout = setTimeout(function() { return timeout = setTimeout(function() {
var blurField = this.shouldBlur(keyCode);
if (blurField && this.filterInputBlur) {
this.input.blur();
}
return this.options.query(this.input.val(), function(data) { return this.options.query(this.input.val(), function(data) {
return this.options.callback(data); return this.options.callback(data);
}.bind(this)); }.bind(this));
...@@ -255,7 +243,7 @@ ...@@ -255,7 +243,7 @@
_this.fullData = data; _this.fullData = data;
_this.parseData(_this.fullData); _this.parseData(_this.fullData);
if (_this.options.filterable && _this.filter && _this.filter.input) { if (_this.options.filterable && _this.filter && _this.filter.input) {
return _this.filter.input.trigger('keyup'); return _this.filter.input.trigger('input');
} }
}; };
// Remote data // Remote data
...@@ -487,7 +475,7 @@ ...@@ -487,7 +475,7 @@
// Triggering 'keyup' will re-render the dropdown which is not always required // Triggering 'keyup' will re-render the dropdown which is not always required
// specially if we want to keep the state of the dropdown needed for bulk-assignment // specially if we want to keep the state of the dropdown needed for bulk-assignment
if (!this.options.persistWhenHide) { if (!this.options.persistWhenHide) {
$input.trigger("keyup"); $input.trigger("input");
} }
if (this.dropdown.find(".dropdown-toggle-page").length) { if (this.dropdown.find(".dropdown-toggle-page").length) {
$('.dropdown-menu', this.dropdown).removeClass(PAGE_TWO_CLASS); $('.dropdown-menu', this.dropdown).removeClass(PAGE_TWO_CLASS);
...@@ -500,14 +488,27 @@ ...@@ -500,14 +488,27 @@
// Render the full menu // Render the full menu
GitLabDropdown.prototype.renderMenu = function(html) { GitLabDropdown.prototype.renderMenu = function(html) {
var menu_html;
menu_html = "";
if (this.options.renderMenu) { if (this.options.renderMenu) {
menu_html = this.options.renderMenu(html); return this.options.renderMenu(html);
} else { } else {
menu_html = $('<ul />').append(html); var ul = document.createElement('ul');
for (var i = 0; i < html.length; i++) {
var el = html[i];
if (el instanceof jQuery) {
el = el.get(0);
}
if (typeof el === 'string') {
ul.innerHTML += el;
} else {
ul.appendChild(el);
}
}
return ul;
} }
return menu_html;
}; };
// Append the menu into the dropdown // Append the menu into the dropdown
...@@ -521,7 +522,7 @@ ...@@ -521,7 +522,7 @@
}; };
GitLabDropdown.prototype.renderItem = function(data, group, index) { GitLabDropdown.prototype.renderItem = function(data, group, index) {
var cssClass, field, fieldName, groupAttrs, html, selected, text, url, value; var field, fieldName, html, selected, text, url, value;
if (group == null) { if (group == null) {
group = false; group = false;
} }
...@@ -529,18 +530,16 @@ ...@@ -529,18 +530,16 @@
// Render the row // Render the row
index = false; index = false;
} }
html = ""; html = document.createElement('li');
// Divider if (data === 'divider' || data === 'separator') {
if (data === "divider") { html.className = data;
return "<li class='divider'></li>"; return html;
}
// Separator is a full-width divider
if (data === "separator") {
return "<li class='separator'></li>";
} }
// Header // Header
if (data.header != null) { if (data.header != null) {
return _.template('<li class="dropdown-header"><%- header %></li>')({ header: data.header }); html.className = 'dropdown-header';
html.innerHTML = data.header;
return html;
} }
if (this.options.renderRow) { if (this.options.renderRow) {
// Call the render function // Call the render function
...@@ -567,24 +566,25 @@ ...@@ -567,24 +566,25 @@
} else { } else {
text = data.text != null ? data.text : ''; text = data.text != null ? data.text : '';
} }
cssClass = "";
if (selected) {
cssClass = "is-active";
}
if (this.highlight) { if (this.highlight) {
text = this.highlightTextMatches(text, this.filterInput.val()); text = this.highlightTextMatches(text, this.filterInput.val());
} }
// Create the list item & the link
var link = document.createElement('a');
link.href = url;
link.innerHTML = text;
if (selected) {
link.className = 'is-active';
}
if (group) { if (group) {
groupAttrs = 'data-group=' + group + ' data-index=' + index; link.dataset.group = group;
} else { link.dataset.index = index;
groupAttrs = '';
} }
html = _.template('<li><a href="<%- url %>" <%- groupAttrs %> class="<%- cssClass %>"><%= text %></a></li>')({
url: url, html.appendChild(link);
groupAttrs: groupAttrs,
cssClass: cssClass,
text: text
});
} }
return html; return html;
}; };
......
((global) => {
/*
* This class overrides the browser's validation error bubbles, displaying custom
* error messages for invalid fields instead. To begin validating any form, add the
* class `show-gl-field-errors` to the form element, and ensure error messages are
* declared in each inputs' title attribute.
*
* Example:
*
* <form class='show-gl-field-errors'>
* <input type='text' name='username' title='Username is required.'/>
*</form>
*
* */
const errorMessageClass = 'gl-field-error';
const inputErrorClass = 'gl-field-error-outline';
class GlFieldError {
constructor({ input, formErrors }) {
this.inputElement = $(input);
this.inputDomElement = this.inputElement.get(0);
this.form = formErrors;
this.errorMessage = this.inputElement.attr('title') || 'This field is required.';
this.fieldErrorElement = $(`<p class='${errorMessageClass} hide'>${ this.errorMessage }</p>`);
this.state = {
valid: false,
empty: true
};
this.initFieldValidation();
}
initFieldValidation() {
// hidden when injected into DOM
this.inputElement.after(this.fieldErrorElement);
this.inputElement.off('invalid').on('invalid', this.handleInvalidSubmit.bind(this));
this.scopedSiblings = this.safelySelectSiblings();
}
safelySelectSiblings() {
// Apply `ignoreSelector` in markup to siblings whose visibility should not be toggled with input validity
const ignoreSelector = '.validation-ignore';
const unignoredSiblings = this.inputElement.siblings(`p:not(${ignoreSelector})`);
const parentContainer = this.inputElement.parent('.form-group');
// Only select siblings when they're scoped within a form-group with one input
const safelyScoped = parentContainer.length && parentContainer.find('input').length === 1;
return safelyScoped ? unignoredSiblings : this.fieldErrorElement;
}
renderValidity() {
this.renderClear();
if (this.state.valid) {
return this.renderValid();
}
if (this.state.empty) {
return this.renderEmpty();
}
if (!this.state.valid) {
return this.renderInvalid();
}
}
handleInvalidSubmit(event) {
event.preventDefault();
const currentValue = this.accessCurrentValue();
this.state.valid = false;
this.state.empty = currentValue === '';
this.renderValidity();
this.form.focusOnFirstInvalid.apply(this.form);
// For UX, wait til after first invalid submission to check each keyup
this.inputElement.off('keyup.field_validator')
.on('keyup.field_validator', this.updateValidity.bind(this));
}
/* Get or set current input value */
accessCurrentValue(newVal) {
return newVal ? this.inputElement.val(newVal) : this.inputElement.val();
}
getInputValidity() {
return this.inputDomElement.validity.valid;
}
updateValidity() {
const inputVal = this.accessCurrentValue();
this.state.empty = !inputVal.length;
this.state.valid = this.getInputValidity();
this.renderValidity();
}
renderValid() {
return this.renderClear();
}
renderEmpty() {
return this.renderInvalid();
}
renderInvalid() {
this.inputElement.addClass(inputErrorClass);
this.scopedSiblings.hide();
return this.fieldErrorElement.show();
}
renderClear() {
const inputVal = this.accessCurrentValue();
if (!inputVal.split(' ').length) {
const trimmedInput = inputVal.trim();
this.accessCurrentValue(trimmedInput);
}
this.inputElement.removeClass(inputErrorClass);
this.scopedSiblings.hide();
this.fieldErrorElement.hide();
}
}
const customValidationFlag = 'no-gl-field-errors';
class GlFieldErrors {
constructor(form) {
this.form = $(form);
this.state = {
inputs: [],
valid: false
};
this.initValidators();
}
initValidators () {
// select all non-hidden inputs in form
this.state.inputs = this.form.find(':input:not([type=hidden])').toArray()
.filter((input) => !input.classList.contains(customValidationFlag))
.map((input) => new GlFieldError({ input, formErrors: this }));
this.form.on('submit', this.catchInvalidFormSubmit);
}
/* Neccessary to prevent intercept and override invalid form submit
* because Safari & iOS quietly allow form submission when form is invalid
* and prevents disabling of invalid submit button by application.js */
catchInvalidFormSubmit (event) {
if (!event.currentTarget.checkValidity()) {
event.preventDefault();
event.stopPropagation();
}
}
focusOnFirstInvalid () {
const firstInvalid = this.state.inputs.filter((input) => !input.inputDomElement.validity.valid)[0];
firstInvalid.inputElement.focus();
}
}
global.GlFieldErrors = GlFieldErrors;
})(window.gl || (window.gl = {}));
(function() {
this.GroupMembers = (function() {
function GroupMembers() {
$('li.group_member').bind('ajax:success', function() {
return $(this).fadeOut();
});
}
return GroupMembers;
})();
}).call(this);
...@@ -292,7 +292,7 @@ ...@@ -292,7 +292,7 @@
return; return;
} }
if (page === 'projects:boards:show') { if ($('html').hasClass('issue-boards-page')) {
return; return;
} }
if ($dropdown.hasClass('js-multiselect')) { if ($dropdown.hasClass('js-multiselect')) {
...@@ -334,7 +334,7 @@ ...@@ -334,7 +334,7 @@
page = $('body').data('page'); page = $('body').data('page');
isIssueIndex = page === 'projects:issues:index'; isIssueIndex = page === 'projects:issues:index';
isMRIndex = page === 'projects:merge_requests:index'; isMRIndex = page === 'projects:merge_requests:index';
if (page === 'projects:boards:show') { if ($('html').hasClass('issue-boards-page')) {
if (label.isAny) { if (label.isAny) {
gl.issueBoards.BoardsStore.state.filters['label_name'] = []; gl.issueBoards.BoardsStore.state.filters['label_name'] = [];
} }
......
...@@ -14,14 +14,18 @@ ...@@ -14,14 +14,18 @@
inputs.datepicker({ inputs.datepicker({
dateFormat: 'yy-mm-dd', dateFormat: 'yy-mm-dd',
minDate: 1, minDate: 1,
onSelect: toggleClearInput onSelect: function () {
$(this).trigger('change');
toggleClearInput.call(this);
}
}); });
inputs.next('.js-clear-input').on('click', function(event) { inputs.next('.js-clear-input').on('click', function(event) {
event.preventDefault(); event.preventDefault();
var input = $(this).closest('.clearable-input').find('.js-access-expiration-date'); var input = $(this).closest('.clearable-input').find('.js-access-expiration-date');
input.datepicker('setDate', null); input.datepicker('setDate', null)
.trigger('change');
toggleClearInput.call(input); toggleClearInput.call(input);
}); });
......
((w) => {
w.gl = w.gl || {};
class Members {
constructor() {
this.addListeners();
}
addListeners() {
$('.project_member, .group_member').off('ajax:success').on('ajax:success', this.removeRow);
$('.js-member-update-control').off('change').on('change', this.formSubmit);
$('.js-edit-member-form').off('ajax:success').on('ajax:success', this.formSuccess);
}
removeRow(e) {
const $target = $(e.target);
if ($target.hasClass('btn-remove')) {
$target.closest('.member')
.fadeOut(function () {
$(this).remove();
});
}
}
formSubmit() {
$(this).closest('form').trigger("submit.rails").end().disable();
}
formSuccess() {
$(this).find('.js-member-update-control').enable();
}
}
gl.Members = Members;
})(window);
const HEAD_HEADER_TEXT = 'HEAD//our changes';
const ORIGIN_HEADER_TEXT = 'origin//their changes';
const HEAD_BUTTON_TITLE = 'Use ours';
const ORIGIN_BUTTON_TITLE = 'Use theirs';
class MergeConflictDataProvider {
getInitialData() {
// TODO: remove reliance on jQuery and DOM state introspection
const diffViewType = $.cookie('diff_view');
const fixedLayout = $('.content-wrapper .container-fluid').hasClass('container-limited');
return {
isLoading : true,
hasError : false,
isParallel : diffViewType === 'parallel',
diffViewType : diffViewType,
fixedLayout : fixedLayout,
isSubmitting : false,
conflictsData : {},
resolutionData : {}
}
}
decorateData(vueInstance, data) {
this.vueInstance = vueInstance;
if (data.type === 'error') {
vueInstance.hasError = true;
data.errorMessage = data.message;
}
else {
data.shortCommitSha = data.commit_sha.slice(0, 7);
data.commitMessage = data.commit_message;
this.setParallelLines(data);
this.setInlineLines(data);
this.updateResolutionsData(data);
}
vueInstance.conflictsData = data;
vueInstance.isSubmitting = false;
const conflictsText = this.getConflictsCount() > 1 ? 'conflicts' : 'conflict';
vueInstance.conflictsData.conflictsText = conflictsText;
}
updateResolutionsData(data) {
const vi = this.vueInstance;
data.files.forEach( (file) => {
file.sections.forEach( (section) => {
if (section.conflict) {
vi.$set(`resolutionData['${section.id}']`, false);
}
});
});
}
setParallelLines(data) {
data.files.forEach( (file) => {
file.filePath = this.getFilePath(file);
file.iconClass = `fa-${file.blob_icon}`;
file.blobPath = file.blob_path;
file.parallelLines = [];
const linesObj = { left: [], right: [] };
file.sections.forEach( (section) => {
const { conflict, lines, id } = section;
if (conflict) {
linesObj.left.push(this.getOriginHeaderLine(id));
linesObj.right.push(this.getHeadHeaderLine(id));
}
lines.forEach( (line) => {
const { type } = line;
if (conflict) {
if (type === 'old') {
linesObj.left.push(this.getLineForParallelView(line, id, 'conflict'));
}
else if (type === 'new') {
linesObj.right.push(this.getLineForParallelView(line, id, 'conflict', true));
}
}
else {
const lineType = type || 'context';
linesObj.left.push (this.getLineForParallelView(line, id, lineType));
linesObj.right.push(this.getLineForParallelView(line, id, lineType, true));
}
});
this.checkLineLengths(linesObj);
});
for (let i = 0, len = linesObj.left.length; i < len; i++) {
file.parallelLines.push([
linesObj.right[i],
linesObj.left[i]
]);
}
});
}
checkLineLengths(linesObj) {
let { left, right } = linesObj;
if (left.length !== right.length) {
if (left.length > right.length) {
const diff = left.length - right.length;
for (let i = 0; i < diff; i++) {
right.push({ lineType: 'emptyLine', richText: '' });
}
}
else {
const diff = right.length - left.length;
for (let i = 0; i < diff; i++) {
left.push({ lineType: 'emptyLine', richText: '' });
}
}
}
}
setInlineLines(data) {
data.files.forEach( (file) => {
file.iconClass = `fa-${file.blob_icon}`;
file.blobPath = file.blob_path;
file.filePath = this.getFilePath(file);
file.inlineLines = []
file.sections.forEach( (section) => {
let currentLineType = 'new';
const { conflict, lines, id } = section;
if (conflict) {
file.inlineLines.push(this.getHeadHeaderLine(id));
}
lines.forEach( (line) => {
const { type } = line;
if ((type === 'new' || type === 'old') && currentLineType !== type) {
currentLineType = type;
file.inlineLines.push({ lineType: 'emptyLine', richText: '' });
}
this.decorateLineForInlineView(line, id, conflict);
file.inlineLines.push(line);
})
if (conflict) {
file.inlineLines.push(this.getOriginHeaderLine(id));
}
});
});
}
handleSelected(sectionId, selection) {
const vi = this.vueInstance;
vi.resolutionData[sectionId] = selection;
vi.conflictsData.files.forEach( (file) => {
file.inlineLines.forEach( (line) => {
if (line.id === sectionId && (line.hasConflict || line.isHeader)) {
this.markLine(line, selection);
}
});
file.parallelLines.forEach( (lines) => {
const left = lines[0];
const right = lines[1];
const hasSameId = right.id === sectionId || left.id === sectionId;
const isLeftMatch = left.hasConflict || left.isHeader;
const isRightMatch = right.hasConflict || right.isHeader;
if (hasSameId && (isLeftMatch || isRightMatch)) {
this.markLine(left, selection);
this.markLine(right, selection);
}
})
});
}
updateViewType(newType) {
const vi = this.vueInstance;
if (newType === vi.diffViewType || !(newType === 'parallel' || newType === 'inline')) {
return;
}
vi.diffViewType = newType;
vi.isParallel = newType === 'parallel';
$.cookie('diff_view', newType, {
path: (gon && gon.relative_url_root) || '/'
});
$('.content-wrapper .container-fluid')
.toggleClass('container-limited', !vi.isParallel && vi.fixedLayout);
}
markLine(line, selection) {
if (selection === 'head' && line.isHead) {
line.isSelected = true;
line.isUnselected = false;
}
else if (selection === 'origin' && line.isOrigin) {
line.isSelected = true;
line.isUnselected = false;
}
else {
line.isSelected = false;
line.isUnselected = true;
}
}
getConflictsCount() {
return Object.keys(this.vueInstance.resolutionData).length;
}
getResolvedCount() {
let count = 0;
const data = this.vueInstance.resolutionData;
for (const id in data) {
const resolution = data[id];
if (resolution) {
count++;
}
}
return count;
}
isReadyToCommit() {
const { conflictsData, isSubmitting } = this.vueInstance
const allResolved = this.getConflictsCount() === this.getResolvedCount();
const hasCommitMessage = $.trim(conflictsData.commitMessage).length;
return !isSubmitting && hasCommitMessage && allResolved;
}
getCommitButtonText() {
const initial = 'Commit conflict resolution';
const inProgress = 'Committing...';
const vue = this.vueInstance;
return vue ? vue.isSubmitting ? inProgress : initial : initial;
}
decorateLineForInlineView(line, id, conflict) {
const { type } = line;
line.id = id;
line.hasConflict = conflict;
line.isHead = type === 'new';
line.isOrigin = type === 'old';
line.hasMatch = type === 'match';
line.richText = line.rich_text;
line.isSelected = false;
line.isUnselected = false;
}
getLineForParallelView(line, id, lineType, isHead) {
const { old_line, new_line, rich_text } = line;
const hasConflict = lineType === 'conflict';
return {
id,
lineType,
hasConflict,
isHead : hasConflict && isHead,
isOrigin : hasConflict && !isHead,
hasMatch : lineType === 'match',
lineNumber : isHead ? new_line : old_line,
section : isHead ? 'head' : 'origin',
richText : rich_text,
isSelected : false,
isUnselected : false
}
}
getHeadHeaderLine(id) {
return {
id : id,
richText : HEAD_HEADER_TEXT,
buttonTitle : HEAD_BUTTON_TITLE,
type : 'new',
section : 'head',
isHeader : true,
isHead : true,
isSelected : false,
isUnselected: false
}
}
getOriginHeaderLine(id) {
return {
id : id,
richText : ORIGIN_HEADER_TEXT,
buttonTitle : ORIGIN_BUTTON_TITLE,
type : 'old',
section : 'origin',
isHeader : true,
isOrigin : true,
isSelected : false,
isUnselected: false
}
}
handleFailedRequest(vueInstance, data) {
vueInstance.hasError = true;
vueInstance.conflictsData.errorMessage = 'Something went wrong!';
}
getCommitData() {
return {
commit_message: this.vueInstance.conflictsData.commitMessage,
sections: this.vueInstance.resolutionData
}
}
getFilePath(file) {
const { old_path, new_path } = file;
return old_path === new_path ? new_path : `${old_path} → ${new_path}`;
}
}
//= require vue
class MergeConflictResolver {
constructor() {
this.dataProvider = new MergeConflictDataProvider()
this.initVue()
}
initVue() {
const that = this;
this.vue = new Vue({
el : '#conflicts',
name : 'MergeConflictResolver',
data : this.dataProvider.getInitialData(),
created : this.fetchData(),
computed : this.setComputedProperties(),
methods : {
handleSelected(sectionId, selection) {
that.dataProvider.handleSelected(sectionId, selection);
},
handleViewTypeChange(newType) {
that.dataProvider.updateViewType(newType);
},
commit() {
that.commit();
}
}
})
}
setComputedProperties() {
const dp = this.dataProvider;
return {
conflictsCount() { return dp.getConflictsCount() },
resolvedCount() { return dp.getResolvedCount() },
readyToCommit() { return dp.isReadyToCommit() },
commitButtonText() { return dp.getCommitButtonText() }
}
}
fetchData() {
const dp = this.dataProvider;
$.get($('#conflicts').data('conflictsPath'))
.done((data) => {
dp.decorateData(this.vue, data);
})
.error((data) => {
dp.handleFailedRequest(this.vue, data);
})
.always(() => {
this.vue.isLoading = false;
this.vue.$nextTick(() => {
$('#conflicts .js-syntax-highlight').syntaxHighlight();
});
$('.content-wrapper .container-fluid')
.toggleClass('container-limited', !this.vue.isParallel && this.vue.fixedLayout);
})
}
commit() {
this.vue.isSubmitting = true;
$.post($('#conflicts').data('resolveConflictsPath'), this.dataProvider.getCommitData())
.done((data) => {
window.location.href = data.redirect_to;
})
.error(() => {
this.vue.isSubmitting = false;
new Flash('Something went wrong!');
});
}
}
((global) => {
global.mergeConflicts = global.mergeConflicts || {};
global.mergeConflicts.diffFileEditor = Vue.extend({
props: {
file: Object,
onCancelDiscardConfirmation: Function,
onAcceptDiscardConfirmation: Function
},
data() {
return {
saved: false,
loading: false,
fileLoaded: false,
originalContent: '',
}
},
computed: {
classObject() {
return {
'saved': this.saved,
'is-loading': this.loading
};
}
},
watch: {
['file.showEditor'](val) {
this.resetEditorContent();
if (!val || this.fileLoaded || this.loading) {
return;
}
this.loadEditor();
}
},
ready() {
if (this.file.loadEditor) {
this.loadEditor();
}
},
methods: {
loadEditor() {
this.loading = true;
$.get(this.file.content_path)
.done((file) => {
let content = this.$el.querySelector('pre');
let fileContent = document.createTextNode(file.content);
content.textContent = fileContent.textContent;
this.originalContent = file.content;
this.fileLoaded = true;
this.editor = ace.edit(content);
this.editor.$blockScrolling = Infinity; // Turn off annoying warning
this.editor.getSession().setMode(`ace/mode/${file.blob_ace_mode}`);
this.editor.on('change', () => {
this.saveDiffResolution();
});
this.saveDiffResolution();
})
.fail(() => {
new Flash('Failed to load the file, please try again.');
})
.always(() => {
this.loading = false;
});
},
saveDiffResolution() {
this.saved = true;
// This probably be better placed in the data provider
this.file.content = this.editor.getValue();
this.file.resolveEditChanged = this.file.content !== this.originalContent;
this.file.promptDiscardConfirmation = false;
},
resetEditorContent() {
if (this.fileLoaded) {
this.editor.setValue(this.originalContent, -1);
}
},
cancelDiscardConfirmation(file) {
this.onCancelDiscardConfirmation(file);
},
acceptDiscardConfirmation(file) {
this.onAcceptDiscardConfirmation(file);
}
}
});
})(window.gl || (window.gl = {}));
((global) => {
global.mergeConflicts = global.mergeConflicts || {};
global.mergeConflicts.inlineConflictLines = Vue.extend({
props: {
file: Object
},
mixins: [global.mergeConflicts.utils, global.mergeConflicts.actions],
});
})(window.gl || (window.gl = {}));
((global) => {
global.mergeConflicts = global.mergeConflicts || {};
global.mergeConflicts.parallelConflictLine = Vue.extend({
props: {
file: Object,
line: Object
},
mixins: [global.mergeConflicts.utils, global.mergeConflicts.actions],
template: '#parallel-conflict-line'
});
})(window.gl || (window.gl = {}));
((global) => {
global.mergeConflicts = global.mergeConflicts || {};
global.mergeConflicts.parallelConflictLines = Vue.extend({
props: {
file: Object
},
mixins: [global.mergeConflicts.utils],
components: {
'parallel-conflict-line': gl.mergeConflicts.parallelConflictLine
}
});
})(window.gl || (window.gl = {}));
((global) => {
global.mergeConflicts = global.mergeConflicts || {};
class mergeConflictsService {
constructor(options) {
this.conflictsPath = options.conflictsPath;
this.resolveConflictsPath = options.resolveConflictsPath;
}
fetchConflictsData() {
return $.ajax({
dataType: 'json',
url: this.conflictsPath
});
}
submitResolveConflicts(data) {
return $.ajax({
url: this.resolveConflictsPath,
data: JSON.stringify(data),
contentType: 'application/json',
dataType: 'json',
method: 'POST'
});
}
};
global.mergeConflicts.mergeConflictsService = mergeConflictsService;
})(window.gl || (window.gl = {}));
//= require vue
//= require ./merge_conflict_store
//= require ./merge_conflict_service
//= require ./mixins/line_conflict_utils
//= require ./mixins/line_conflict_actions
//= require ./components/diff_file_editor
//= require ./components/inline_conflict_lines
//= require ./components/parallel_conflict_line
//= require ./components/parallel_conflict_lines
$(() => {
const INTERACTIVE_RESOLVE_MODE = 'interactive';
const conflictsEl = document.querySelector('#conflicts');
const mergeConflictsStore = gl.mergeConflicts.mergeConflictsStore;
const mergeConflictsService = new gl.mergeConflicts.mergeConflictsService({
conflictsPath: conflictsEl.dataset.conflictsPath,
resolveConflictsPath: conflictsEl.dataset.resolveConflictsPath
});
gl.MergeConflictsResolverApp = new Vue({
el: '#conflicts',
data: mergeConflictsStore.state,
components: {
'diff-file-editor': gl.mergeConflicts.diffFileEditor,
'inline-conflict-lines': gl.mergeConflicts.inlineConflictLines,
'parallel-conflict-lines': gl.mergeConflicts.parallelConflictLines
},
computed: {
conflictsCountText() { return mergeConflictsStore.getConflictsCountText() },
readyToCommit() { return mergeConflictsStore.isReadyToCommit() },
commitButtonText() { return mergeConflictsStore.getCommitButtonText() },
showDiffViewTypeSwitcher() { return mergeConflictsStore.fileTextTypePresent() }
},
created() {
mergeConflictsService
.fetchConflictsData()
.done((data) => {
if (data.type === 'error') {
mergeConflictsStore.setFailedRequest(data.message);
} else {
mergeConflictsStore.setConflictsData(data);
}
})
.error(() => {
mergeConflictsStore.setFailedRequest();
})
.always(() => {
mergeConflictsStore.setLoadingState(false);
this.$nextTick(() => {
$(conflictsEl.querySelectorAll('.js-syntax-highlight')).syntaxHighlight();
});
});
},
methods: {
handleViewTypeChange(viewType) {
mergeConflictsStore.setViewType(viewType);
},
onClickResolveModeButton(file, mode) {
if (mode === INTERACTIVE_RESOLVE_MODE && file.resolveEditChanged) {
mergeConflictsStore.setPromptConfirmationState(file, true);
return;
}
mergeConflictsStore.setFileResolveMode(file, mode);
},
acceptDiscardConfirmation(file) {
mergeConflictsStore.setPromptConfirmationState(file, false);
mergeConflictsStore.setFileResolveMode(file, INTERACTIVE_RESOLVE_MODE);
},
cancelDiscardConfirmation(file) {
mergeConflictsStore.setPromptConfirmationState(file, false);
},
commit() {
mergeConflictsStore.setSubmitState(true);
mergeConflictsService
.submitResolveConflicts(mergeConflictsStore.getCommitData())
.done((data) => {
window.location.href = data.redirect_to;
})
.error(() => {
mergeConflictsStore.setSubmitState(false);
new Flash('Failed to save merge conflicts resolutions. Please try again!');
});
}
}
})
});
((global) => {
global.mergeConflicts = global.mergeConflicts || {};
global.mergeConflicts.actions = {
methods: {
handleSelected(file, sectionId, selection) {
gl.mergeConflicts.mergeConflictsStore.handleSelected(file, sectionId, selection);
}
}
};
})(window.gl || (window.gl = {}));
((global) => {
global.mergeConflicts = global.mergeConflicts || {};
global.mergeConflicts.utils = {
methods: {
lineCssClass(line) {
return {
'head': line.isHead,
'origin': line.isOrigin,
'match': line.hasMatch,
'selected': line.isSelected,
'unselected': line.isUnselected
};
}
}
};
})(window.gl || (window.gl = {}));
...@@ -71,6 +71,7 @@ ...@@ -71,6 +71,7 @@
this._location = location; this._location = location;
this.bindEvents(); this.bindEvents();
this.activateTab(this.opts.action); this.activateTab(this.opts.action);
this.initAffix();
} }
MergeRequestTabs.prototype.bindEvents = function() { MergeRequestTabs.prototype.bindEvents = function() {
...@@ -380,6 +381,46 @@ ...@@ -380,6 +381,46 @@
// Only when sidebar is collapsed // Only when sidebar is collapsed
}; };
MergeRequestTabs.prototype.initAffix = function () {
var $tabs = $('.js-tabs-affix');
// Screen space on small screens is usually very sparse
// So we dont affix the tabs on these
if (Breakpoints.get().getBreakpointSize() === 'xs' || !$tabs.length) return;
var tabsWidth = $tabs.outerWidth(),
$diffTabs = $('#diff-notes-app'),
offsetTop = $tabs.offset().top - ($('.navbar-fixed-top').height() + $('.layout-nav').height());
$tabs.off('affix.bs.affix affix-top.bs.affix')
.affix({
offset: {
top: offsetTop
}
}).on('affix.bs.affix', function () {
$tabs.css({
left: $tabs.offset().left,
width: tabsWidth
});
$diffTabs.css({
marginTop: $tabs.height()
});
}).on('affix-top.bs.affix', function () {
$tabs.css({
left: '',
width: ''
});
$diffTabs.css({
marginTop: ''
});
});
// Fix bug when reloading the page already scrolling
if ($tabs.hasClass('affix')) {
$tabs.trigger('affix.bs.affix');
}
};
return MergeRequestTabs; return MergeRequestTabs;
})(); })();
......
(function() { ((global) => {
var indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; var indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
this.MergeRequestWidget = (function() { const DEPLOYMENT_TEMPLATE = `<div class="mr-widget-heading" id="<%- id %>">
<div class="ci_widget ci-success">
<%= ci_success_icon %>
<span>
Deployed to
<a href="<%- url %>" target="_blank" class="environment">
<%- name %>
</a>
<span class="js-environment-timeago" data-toggle="tooltip" data-placement="top" data-title="<%- deployed_at_formatted %>">
<%- deployed_at %>
</span>
<a class="js-environment-link" href="<%- external_url %>" target="_blank">
<i class="fa fa-external-link"></i>
View on <%- external_url_formatted %>
</a>
</span>
</div>
</div>`;
global.MergeRequestWidget = (function() {
function MergeRequestWidget(opts) { function MergeRequestWidget(opts) {
// Initialize MergeRequestWidget behavior // Initialize MergeRequestWidget behavior
// //
...@@ -10,17 +29,23 @@ ...@@ -10,17 +29,23 @@
// ci_status_url - String, URL to use to check CI status // ci_status_url - String, URL to use to check CI status
// //
this.opts = opts; this.opts = opts;
this.$widgetBody = $('.mr-widget-body');
$('#modal_merge_info').modal({ $('#modal_merge_info').modal({
show: false show: false
}); });
this.firstCICheck = true; this.firstCICheck = true;
this.readyForCICheck = false; this.readyForCICheck = false;
this.readyForCIEnvironmentCheck = false;
this.cancel = false; this.cancel = false;
clearInterval(this.fetchBuildStatusInterval); clearInterval(this.fetchBuildStatusInterval);
clearInterval(this.fetchBuildEnvironmentStatusInterval);
this.clearEventListeners(); this.clearEventListeners();
this.addEventListeners(); this.addEventListeners();
this.getCIStatus(false); this.getCIStatus(false);
this.getCIEnvironmentsStatus();
this.retrieveSuccessIcon();
this.pollCIStatus(); this.pollCIStatus();
this.pollCIEnvironmentsStatus();
notifyPermissions(); notifyPermissions();
} }
...@@ -41,6 +66,7 @@ ...@@ -41,6 +66,7 @@
page = $('body').data('page').split(':').last(); page = $('body').data('page').split(':').last();
if (allowedPages.indexOf(page) < 0) { if (allowedPages.indexOf(page) < 0) {
clearInterval(_this.fetchBuildStatusInterval); clearInterval(_this.fetchBuildStatusInterval);
clearInterval(_this.fetchBuildEnvironmentStatusInterval);
_this.cancelPolling(); _this.cancelPolling();
return _this.clearEventListeners(); return _this.clearEventListeners();
} }
...@@ -48,6 +74,12 @@ ...@@ -48,6 +74,12 @@
})(this)); })(this));
}; };
MergeRequestWidget.prototype.retrieveSuccessIcon = function() {
const $ciSuccessIcon = $('.js-success-icon');
this.$ciSuccessIcon = $ciSuccessIcon.html();
$ciSuccessIcon.remove();
}
MergeRequestWidget.prototype.mergeInProgress = function(deleteSourceBranch) { MergeRequestWidget.prototype.mergeInProgress = function(deleteSourceBranch) {
if (deleteSourceBranch == null) { if (deleteSourceBranch == null) {
deleteSourceBranch = false; deleteSourceBranch = false;
...@@ -62,7 +94,7 @@ ...@@ -62,7 +94,7 @@
urlSuffix = deleteSourceBranch ? '?deleted_source_branch=true' : ''; urlSuffix = deleteSourceBranch ? '?deleted_source_branch=true' : '';
return window.location.href = window.location.pathname + urlSuffix; return window.location.href = window.location.pathname + urlSuffix;
} else if (data.merge_error) { } else if (data.merge_error) {
return $('.mr-widget-body').html("<h4>" + data.merge_error + "</h4>"); return this.$widgetBody.html("<h4>" + data.merge_error + "</h4>");
} else { } else {
callback = function() { callback = function() {
return merge_request_widget.mergeInProgress(deleteSourceBranch); return merge_request_widget.mergeInProgress(deleteSourceBranch);
...@@ -118,6 +150,7 @@ ...@@ -118,6 +150,7 @@
if (data.status === '') { if (data.status === '') {
return; return;
} }
if (data.environments && data.environments.length) _this.renderEnvironments(data.environments);
if (_this.firstCICheck || data.status !== _this.opts.ci_status && (data.status != null)) { if (_this.firstCICheck || data.status !== _this.opts.ci_status && (data.status != null)) {
_this.opts.ci_status = data.status; _this.opts.ci_status = data.status;
_this.showCIStatus(data.status); _this.showCIStatus(data.status);
...@@ -150,6 +183,41 @@ ...@@ -150,6 +183,41 @@
})(this)); })(this));
}; };
MergeRequestWidget.prototype.pollCIEnvironmentsStatus = function() {
this.fetchBuildEnvironmentStatusInterval = setInterval(() => {
if (!this.readyForCIEnvironmentCheck) return;
this.getCIEnvironmentsStatus();
this.readyForCIEnvironmentCheck = false;
}, 300000);
};
MergeRequestWidget.prototype.getCIEnvironmentsStatus = function() {
$.getJSON(this.opts.ci_environments_status_url, (environments) => {
if (this.cancel) return;
this.readyForCIEnvironmentCheck = true;
if (environments && environments.length) this.renderEnvironments(environments);
});
};
MergeRequestWidget.prototype.renderEnvironments = function(environments) {
for (let i = 0; i < environments.length; i++) {
const environment = environments[i];
if ($(`.mr-state-widget #${ environment.id }`).length) return;
const $template = $(DEPLOYMENT_TEMPLATE);
if (!environment.external_url || !environment.external_url_formatted) $('.js-environment-link', $template).remove();
if (environment.deployed_at && environment.deployed_at_formatted) {
environment.deployed_at = $.timeago(environment.deployed_at) + '.';
} else {
$('.js-environment-timeago', $template).remove();
environment.name += '.';
}
environment.ci_success_icon = this.$ciSuccessIcon;
const templateString = _.unescape($template[0].outerHTML);
const template = _.template(templateString)(environment)
this.$widgetBody.before(template);
}
};
MergeRequestWidget.prototype.showCIStatus = function(state) { MergeRequestWidget.prototype.showCIStatus = function(state) {
var allowed_states; var allowed_states;
if (state == null) { if (state == null) {
...@@ -190,4 +258,4 @@ ...@@ -190,4 +258,4 @@
})(); })();
}).call(this); })(window.gl || (window.gl = {}));
...@@ -110,7 +110,7 @@ ...@@ -110,7 +110,7 @@
e.preventDefault(); e.preventDefault();
return; return;
} }
if (page === 'projects:boards:show') { if ($('html').hasClass('issue-boards-page')) {
gl.issueBoards.BoardsStore.state.filters[$dropdown.data('field-name')] = selected.name; gl.issueBoards.BoardsStore.state.filters[$dropdown.data('field-name')] = selected.name;
gl.issueBoards.BoardsStore.updateFiltersUrl(); gl.issueBoards.BoardsStore.updateFiltersUrl();
e.preventDefault(); e.preventDefault();
......
(function() {
function toggleGraph() {
const $pipelineBtn = $(this).closest('.toggle-pipeline-btn');
const $pipelineGraph = $(this).closest('.row-content-block').next('.pipeline-graph');
const $btnText = $(this).find('.toggle-btn-text');
const $icon = $(this).find('.fa');
$($pipelineBtn).add($pipelineGraph).toggleClass('graph-collapsed');
const graphCollapsed = $pipelineGraph.hasClass('graph-collapsed');
const expandIcon = 'fa-caret-down';
const hideIcon = 'fa-caret-up';
if(graphCollapsed) {
$btnText.text('Expand');
$icon.removeClass(hideIcon).addClass(expandIcon);
} else {
$btnText.text('Hide');
$icon.removeClass(expandIcon).addClass(hideIcon);
}
}
$(document).on('click', '.toggle-pipeline-btn', toggleGraph);
})();
((global) => {
class Pipelines {
constructor() {
$(document).off('click', '.toggle-pipeline-btn').on('click', '.toggle-pipeline-btn', this.toggleGraph);
this.addMarginToBuildColumns();
}
toggleGraph() {
const $pipelineBtn = $(this).closest('.toggle-pipeline-btn');
const $pipelineGraph = $(this).closest('.row-content-block').next('.pipeline-graph');
const $btnText = $(this).find('.toggle-btn-text');
const graphCollapsed = $pipelineGraph.hasClass('graph-collapsed');
$($pipelineBtn).add($pipelineGraph).toggleClass('graph-collapsed');
graphCollapsed ? $btnText.text('Hide') : $btnText.text('Expand')
}
addMarginToBuildColumns() {
const $secondChildBuildNode = $('.build:nth-child(2)');
if ($secondChildBuildNode.length) {
const $firstChildBuildNode = $secondChildBuildNode.prev('.build');
const $multiBuildColumn = $secondChildBuildNode.closest('.stage-column');
const $previousColumn = $multiBuildColumn.prev('.stage-column');
$multiBuildColumn.addClass('left-margin');
$firstChildBuildNode.addClass('left-connector');
$previousColumn.each(function() {
$this = $(this);
if ($('.build', $this).length === 1) $this.addClass('no-margin');
});
}
$('.pipeline-graph').removeClass('hidden');
}
}
global.Pipelines = Pipelines;
})(window.gl || (window.gl = {}));
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
function ProjectFindFile(element1, options) { function ProjectFindFile(element1, options) {
this.element = element1; this.element = element1;
this.options = options; this.options = options;
this.goToBlob = bind(this.goToBlob, this);
this.goToTree = bind(this.goToTree, this); this.goToTree = bind(this.goToTree, this);
this.selectRowDown = bind(this.selectRowDown, this); this.selectRowDown = bind(this.selectRowDown, this);
this.selectRowUp = bind(this.selectRowUp, this); this.selectRowUp = bind(this.selectRowUp, this);
...@@ -154,6 +155,14 @@ ...@@ -154,6 +155,14 @@
return location.href = this.options.treeUrl; return location.href = this.options.treeUrl;
}; };
ProjectFindFile.prototype.goToBlob = function() {
var $link = this.element.find(".tree-item.selected .tree-item-file-name a");
if ($link.length) {
$link.get(0).click();
}
};
return ProjectFindFile; return ProjectFindFile;
})(); })();
......
(function() {
this.ProjectMembers = (function() {
function ProjectMembers() {
$('li.project_member').bind('ajax:success', function() {
return $(this).fadeOut();
});
}
return ProjectMembers;
})();
}).call(this);
...@@ -4,7 +4,9 @@ ...@@ -4,7 +4,9 @@
this.ProjectNew = (function() { this.ProjectNew = (function() {
function ProjectNew() { function ProjectNew() {
this.toggleSettings = bind(this.toggleSettings, this); this.toggleSettings = bind(this.toggleSettings, this);
this.$selects = $('.features select'); this.$selects = $('.features select').filter(function () {
return $(this).data('field');
});
$('.project-edit-container').on('ajax:before', (function(_this) { $('.project-edit-container').on('ajax:before', (function(_this) {
return function() { return function() {
......
...@@ -16,7 +16,13 @@ ...@@ -16,7 +16,13 @@
if (initialQuery.name) this.requestFile(initialQuery); if (initialQuery.name) this.requestFile(initialQuery);
$('.reset-template', this.dropdown.parent()).on('click', () => { $('.reset-template', this.dropdown.parent()).on('click', () => {
if (this.currentTemplate) this.setInputValueToTemplateContent(false); this.setInputValueToTemplateContent();
});
$('.no-template', this.dropdown.parent()).on('click', () => {
this.currentTemplate = '';
this.setInputValueToTemplateContent();
$('.dropdown-toggle-text', this.dropdown).text('Choose a template');
}); });
} }
......
((global) => {
const debounceTimeoutDuration = 1000;
const invalidInputClass = 'gl-field-error-outline';
const successInputClass = 'gl-field-success-outline';
const unavailableMessageSelector = '.username .validation-error';
const successMessageSelector = '.username .validation-success';
const pendingMessageSelector = '.username .validation-pending';
const invalidMessageSelector = '.username .gl-field-error';
class UsernameValidator {
constructor() {
this.inputElement = $('#new_user_username');
this.inputDomElement = this.inputElement.get(0);
this.state = {
available: false,
valid: false,
pending: false,
empty: true
};
const debounceTimeout = _.debounce((username) => {
this.validateUsername(username);
}, debounceTimeoutDuration);
this.inputElement.on('keyup.username_check', () => {
const username = this.inputElement.val();
this.state.valid = this.inputDomElement.validity.valid;
this.state.empty = !username.length;
if (this.state.valid) {
return debounceTimeout(username);
}
this.renderState();
});
// Override generic field validation
this.inputElement.on('invalid', this.interceptInvalid.bind(this));
}
renderState() {
// Clear all state
this.clearFieldValidationState();
if (this.state.valid && this.state.available) {
return this.setSuccessState();
}
if (this.state.empty) {
return this.clearFieldValidationState();
}
if (this.state.pending) {
return this.setPendingState();
}
if (!this.state.available) {
return this.setUnavailableState();
}
if (!this.state.valid) {
return this.setInvalidState();
}
}
interceptInvalid(event) {
event.preventDefault();
event.stopPropagation();
}
validateUsername(username) {
if (this.state.valid) {
this.state.pending = true;
this.state.available = false;
this.renderState();
return $.ajax({
type: 'GET',
url: `/users/${username}/exists`,
dataType: 'json',
success: (res) => this.setAvailabilityState(res.exists)
});
}
}
setAvailabilityState(usernameTaken) {
if (usernameTaken) {
this.state.valid = false;
this.state.available = false;
} else {
this.state.available = true;
}
this.state.pending = false;
this.renderState();
}
clearFieldValidationState() {
this.inputElement.siblings('p').hide();
this.inputElement.removeClass(invalidInputClass)
.removeClass(successInputClass);
}
setUnavailableState() {
const $usernameUnavailableMessage = this.inputElement.siblings(unavailableMessageSelector);
this.inputElement.addClass(invalidInputClass).removeClass(successInputClass);
$usernameUnavailableMessage.show();
}
setSuccessState() {
const $usernameSuccessMessage = this.inputElement.siblings(successMessageSelector);
this.inputElement.addClass(successInputClass).removeClass(invalidInputClass);
$usernameSuccessMessage.show();
}
setPendingState() {
const $usernamePendingMessage = $(pendingMessageSelector);
if (this.state.pending) {
$usernamePendingMessage.show();
} else {
$usernamePendingMessage.hide();
}
}
setInvalidState() {
const $inputErrorMessage = $(invalidMessageSelector);
this.inputElement.addClass(invalidInputClass).removeClass(successInputClass);
$inputErrorMessage.show();
}
}
global.UsernameValidator = UsernameValidator;
})(window);
...@@ -160,7 +160,7 @@ ...@@ -160,7 +160,7 @@
selectedId = user.id; selectedId = user.id;
return; return;
} }
if (page === 'projects:boards:show') { if ($('html').hasClass('issue-boards-page')) {
selectedId = user.id; selectedId = user.id;
gl.issueBoards.BoardsStore.state.filters[$dropdown.data('field-name')] = user.id; gl.issueBoards.BoardsStore.state.filters[$dropdown.data('field-name')] = user.id;
gl.issueBoards.BoardsStore.updateFiltersUrl(); gl.issueBoards.BoardsStore.updateFiltersUrl();
...@@ -261,10 +261,11 @@ ...@@ -261,10 +261,11 @@
} }
} }
if (showEmailUser && data.results.length === 0 && query.term.match(/^[^@]+@[^@]+$/)) { if (showEmailUser && data.results.length === 0 && query.term.match(/^[^@]+@[^@]+$/)) {
var trimmed = query.term.trim();
emailUser = { emailUser = {
name: "Invite \"" + query.term + "\"", name: "Invite \"" + query.term + "\"",
username: query.term, username: trimmed,
id: query.term id: trimmed
}; };
data.results.unshift(emailUser); data.results.unshift(emailUser);
} }
...@@ -324,6 +325,10 @@ ...@@ -324,6 +325,10 @@
}; };
UsersSelect.prototype.user = function(user_id, callback) { UsersSelect.prototype.user = function(user_id, callback) {
if(!/^\d+$/.test(user_id)) {
return false;
}
var url; var url;
url = this.buildUrl(this.userPath); url = this.buildUrl(this.userPath);
url = url.replace(':id', user_id); url = url.replace(':id', user_id);
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
display: none; display: none;
&.hide { display: block; } &.hide { display: block; }
} }
&.open .content { &.open .content {
display: block; display: block;
&.hide { display: none; } &.hide { display: none; }
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
&.diff-collapsed { &.diff-collapsed {
padding: 5px; padding: 5px;
.click-to-expand { .click-to-expand {
cursor: pointer; cursor: pointer;
} }
...@@ -203,6 +204,7 @@ ...@@ -203,6 +204,7 @@
} }
} }
} }
&.user-cover-block { &.user-cover-block {
padding: 24px 0 0; padding: 24px 0 0;
} }
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
&:focus { &:focus {
background-color: $hover-background; background-color: $hover-background;
color: $hover-text; color: $hover-text;
border-color: $hover-border;; border-color: $hover-border;
} }
} }
...@@ -152,7 +152,8 @@ ...@@ -152,7 +152,8 @@
@include btn-blue-medium; @include btn-blue-medium;
} }
&.btn-info { &.btn-info,
&.btn-register {
@include btn-blue; @include btn-blue;
} }
...@@ -240,6 +241,7 @@ ...@@ -240,6 +241,7 @@
width: 100%; width: 100%;
margin: 0; margin: 0;
margin-bottom: 15px; margin-bottom: 15px;
&.btn { &.btn {
padding: 6px 0; padding: 6px 0;
} }
...@@ -321,6 +323,7 @@ ...@@ -321,6 +323,7 @@
.btn-build { .btn-build {
margin-left: 10px; margin-left: 10px;
i { i {
color: $gl-icon-color; color: $gl-icon-color;
} }
...@@ -328,6 +331,7 @@ ...@@ -328,6 +331,7 @@
.clone-dropdown-btn a { .clone-dropdown-btn a {
color: $dropdown-link-color; color: $dropdown-link-color;
&:hover { &:hover {
text-decoration: none; text-decoration: none;
} }
...@@ -337,6 +341,7 @@ ...@@ -337,6 +341,7 @@
background-color: $background-color !important; background-color: $background-color !important;
border: 1px solid lightgrey; border: 1px solid lightgrey;
cursor: default; cursor: default;
&:active { &:active {
-moz-box-shadow: inset 0 0 0 white; -moz-box-shadow: inset 0 0 0 white;
-webkit-box-shadow: inset 0 0 0 white; -webkit-box-shadow: inset 0 0 0 white;
......
...@@ -13,10 +13,12 @@ ...@@ -13,10 +13,12 @@
color: $text-color; color: $text-color;
background: $background-color; background: $background-color;
} }
.bs-callout h4 { .bs-callout h4 {
margin-top: 0; margin-top: 0;
margin-bottom: 5px; margin-bottom: 5px;
} }
.bs-callout p:last-child { .bs-callout p:last-child {
margin-bottom: 0; margin-bottom: 0;
} }
...@@ -27,16 +29,19 @@ ...@@ -27,16 +29,19 @@
border-color: #eed3d7; border-color: #eed3d7;
color: #b94a48; color: #b94a48;
} }
.bs-callout-warning { .bs-callout-warning {
background-color: #faf8f0; background-color: #faf8f0;
border-color: #faebcc; border-color: #faebcc;
color: #8a6d3b; color: #8a6d3b;
} }
.bs-callout-info { .bs-callout-info {
background-color: #f4f8fa; background-color: #f4f8fa;
border-color: #bce8f1; border-color: #bce8f1;
color: #34789a; color: #34789a;
} }
.bs-callout-success { .bs-callout-success {
background-color: #dff0d8; background-color: #dff0d8;
border-color: #5ca64d; border-color: #5ca64d;
......
/** COLORS **/ /** COLORS **/
.cgray { color: $gl-gray; } .cgray { color: $gl-gray; }
.clgray { color: #bbb } .clgray { color: #bbb; }
.cred { color: $gl-text-red; } .cred { color: $gl-text-red; }
.cgreen { color: $gl-text-green; } .cgreen { color: $gl-text-green; }
.cdark { color: #444 } .cdark { color: #444; }
/** COMMON CLASSES **/ /** COMMON CLASSES **/
.prepend-top-0 { margin-top: 0; } .prepend-top-0 { margin-top: 0; }
.prepend-top-5 { margin-top: 5px; } .prepend-top-5 { margin-top: 5px; }
.prepend-top-10 { margin-top: 10px } .prepend-top-10 { margin-top: 10px; }
.prepend-top-default { margin-top: $gl-padding !important; } .prepend-top-default { margin-top: $gl-padding !important; }
.prepend-top-20 { margin-top: 20px } .prepend-top-20 { margin-top: 20px; }
.prepend-left-5 { margin-left: 5px } .prepend-left-5 { margin-left: 5px; }
.prepend-left-10 { margin-left: 10px } .prepend-left-10 { margin-left: 10px; }
.prepend-left-default { margin-left: $gl-padding; } .prepend-left-default { margin-left: $gl-padding; }
.prepend-left-20 { margin-left: 20px } .prepend-left-20 { margin-left: 20px; }
.append-right-5 { margin-right: 5px } .append-right-5 { margin-right: 5px; }
.append-right-10 { margin-right: 10px } .append-right-10 { margin-right: 10px; }
.append-right-default { margin-right: $gl-padding; } .append-right-default { margin-right: $gl-padding; }
.append-right-20 { margin-right: 20px } .append-right-20 { margin-right: 20px; }
.append-bottom-0 { margin-bottom: 0 } .append-bottom-0 { margin-bottom: 0; }
.append-bottom-10 { margin-bottom: 10px } .append-bottom-10 { margin-bottom: 10px; }
.append-bottom-15 { margin-bottom: 15px } .append-bottom-15 { margin-bottom: 15px; }
.append-bottom-20 { margin-bottom: 20px } .append-bottom-20 { margin-bottom: 20px; }
.append-bottom-default { margin-bottom: $gl-padding; } .append-bottom-default { margin-bottom: $gl-padding; }
.inline { display: inline-block } .inline { display: inline-block; }
.center { text-align: center } .center { text-align: center; }
.underlined-link { text-decoration: underline; } .underlined-link { text-decoration: underline; }
.hint { font-style: italic; color: #999; } .hint { font-style: italic; color: #999; }
...@@ -97,6 +97,7 @@ span.update-author { ...@@ -97,6 +97,7 @@ span.update-author {
color: #999; color: #999;
font-weight: normal; font-weight: normal;
font-style: italic; font-style: italic;
strong { strong {
font-weight: bold; font-weight: bold;
font-style: normal; font-style: normal;
...@@ -128,7 +129,7 @@ p.time { ...@@ -128,7 +129,7 @@ p.time {
// Fix issue with notes & lists creating a bunch of bottom borders. // Fix issue with notes & lists creating a bunch of bottom borders.
li.note { li.note {
img { max-width: 100% } img { max-width: 100%; }
.note-title { .note-title {
li { li {
border-bottom: none !important; border-bottom: none !important;
...@@ -172,6 +173,7 @@ li.note { ...@@ -172,6 +173,7 @@ li.note {
@extend .col-md-6; @extend .col-md-6;
text-align: left; text-align: left;
margin-top: 40px; margin-top: 40px;
pre { pre {
background: white; background: white;
border: none; border: none;
...@@ -197,6 +199,7 @@ li.note { ...@@ -197,6 +199,7 @@ li.note {
background: #c67; background: #c67;
color: #fff; color: #fff;
font-weight: bold; font-weight: bold;
a { a {
color: #fff; color: #fff;
text-decoration: underline; text-decoration: underline;
...@@ -227,6 +230,7 @@ li.note { ...@@ -227,6 +230,7 @@ li.note {
&.milestone-closed { &.milestone-closed {
background: $gray-light; background: $gray-light;
} }
.progress { .progress {
margin-bottom: 0; margin-bottom: 0;
margin-top: 4px; margin-top: 4px;
...@@ -286,6 +290,7 @@ table { ...@@ -286,6 +290,7 @@ table {
.footer-links { .footer-links {
margin-bottom: 20px; margin-bottom: 20px;
a { a {
margin-right: 15px; margin-right: 15px;
} }
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
.dropdown-menu, .dropdown-menu,
.dropdown-menu-nav { .dropdown-menu-nav {
display: block; display: block;
@media (max-width: $screen-xs-max) { @media (max-width: $screen-xs-max) {
width: 100%; width: 100%;
} }
...@@ -48,6 +49,7 @@ ...@@ -48,6 +49,7 @@
margin-top: -6px; margin-top: -6px;
color: $dropdown-toggle-icon-color; color: $dropdown-toggle-icon-color;
font-size: 10px; font-size: 10px;
&.fa-spinner { &.fa-spinner {
font-size: 16px; font-size: 16px;
margin-top: -8px; margin-top: -8px;
......
...@@ -26,15 +26,6 @@ ...@@ -26,15 +26,6 @@
padding: 10px $gl-padding; padding: 10px $gl-padding;
word-wrap: break-word; word-wrap: break-word;
border-radius: 3px 3px 0 0; border-radius: 3px 3px 0 0;
cursor: pointer;
&:hover {
background-color: $dark-background-color;
}
.diff-toggle-caret {
padding-right: 6px;
}
&.file-title-clear { &.file-title-clear {
padding-left: 0; padding-left: 0;
...@@ -66,6 +57,7 @@ ...@@ -66,6 +57,7 @@
margin-top: -3px; margin-top: -3px;
} }
} }
.file-content { .file-content {
background: #fff; background: #fff;
...@@ -105,22 +97,27 @@ ...@@ -105,22 +97,27 @@
border: none; border: none;
margin: 0; margin: 0;
} }
tr { tr {
border-bottom: 1px solid #eee; border-bottom: 1px solid #eee;
} }
td { td {
&:first-child { &:first-child {
border-left: none; border-left: none;
} }
&:last-child { &:last-child {
border-right: none; border-right: none;
} }
} }
td.blame-commit { td.blame-commit {
padding: 0 10px; padding: 0 10px;
min-width: 400px; min-width: 400px;
background: $gray-light; background: $gray-light;
} }
td.line-numbers { td.line-numbers {
float: none; float: none;
border-left: 1px solid #ddd; border-left: 1px solid #ddd;
...@@ -130,6 +127,7 @@ ...@@ -130,6 +127,7 @@
margin-right: 0; margin-right: 0;
} }
} }
td.lines { td.lines {
padding: 0; padding: 0;
} }
...@@ -146,8 +144,10 @@ ...@@ -146,8 +144,10 @@
border-left: 1px solid $border-color; border-left: 1px solid $border-color;
margin-bottom: 0; margin-bottom: 0;
background: white; background: white;
li { li {
color: #888; color: #888;
p { p {
margin: 0; margin: 0;
color: #333; color: #333;
......
...@@ -9,7 +9,7 @@ input { ...@@ -9,7 +9,7 @@ input {
input[type='text'].danger { input[type='text'].danger {
background: #f2dede!important; background: #f2dede!important;
border-color: #d66; border-color: #d66;
text-shadow: 0 1px 1px #fff text-shadow: 0 1px 1px #fff;
} }
.datetime-controls { .datetime-controls {
...@@ -73,8 +73,8 @@ label { ...@@ -73,8 +73,8 @@ label {
} }
.form-control { .form-control {
box-shadow: none; @include box-shadow(none);
border-radius: 3px; border-radius: 2px;
padding: $gl-vert-padding $gl-input-padding; padding: $gl-vert-padding $gl-input-padding;
} }
...@@ -117,9 +117,11 @@ label { ...@@ -117,9 +117,11 @@ label {
display: table-cell; display: table-cell;
width: 200px !important; width: 200px !important;
} }
.input-group-addon { .input-group-addon {
background-color: #f7f8fa; background-color: #f7f8fa;
} }
.input-group-addon:not(:first-child):not(:last-child) { .input-group-addon:not(:first-child):not(:last-child) {
border-left: 0; border-left: 0;
border-right: 0; border-right: 0;
...@@ -129,3 +131,8 @@ label { ...@@ -129,3 +131,8 @@ label {
.help-block { .help-block {
margin-bottom: 0; margin-bottom: 0;
} }
.gl-field-error {
color: $red-normal;
}
...@@ -62,7 +62,7 @@ ...@@ -62,7 +62,7 @@
} }
i { i {
color: $white-light color: $white-light;
} }
path, path,
......
...@@ -168,6 +168,7 @@ header { ...@@ -168,6 +168,7 @@ header {
a { a {
color: $gl-text-color; color: $gl-text-color;
&:hover { &:hover {
text-decoration: underline; text-decoration: underline;
} }
......
...@@ -60,6 +60,7 @@ ...@@ -60,6 +60,7 @@
padding-top: 1px; padding-top: 1px;
margin: 0; margin: 0;
color: $gray-dark; color: $gray-dark;
img { img {
position: relative; position: relative;
top: 3px; top: 3px;
...@@ -128,6 +129,10 @@ ul.content-list { ...@@ -128,6 +129,10 @@ ul.content-list {
color: $gl-dark-link-color; color: $gl-dark-link-color;
} }
.member-group-link {
color: $blue-normal;
}
.description { .description {
p { p {
@include str-truncated; @include str-truncated;
...@@ -168,6 +173,14 @@ ul.content-list { ...@@ -168,6 +173,14 @@ ul.content-list {
} }
} }
.member-controls {
float: none;
@media (min-width: $screen-sm-min) {
float: right;
}
}
// When dragging a list item // When dragging a list item
&.ui-sortable-helper { &.ui-sortable-helper {
border-bottom: none; border-bottom: none;
......
@mixin unique-keyframes {
$animation-name: unique-id();
@include webkit-prefix(animation-name, $animation-name);
@-webkit-keyframes #{$animation-name} {
@content;
}
@keyframes #{$animation-name} {
@content;
}
}
@mixin tanuki-logo-colors($path-color) { @mixin tanuki-logo-colors($path-color) {
fill: $path-color; fill: $path-color;
transition: all 0.8s; transition: all 0.8s;
...@@ -20,28 +8,6 @@ ...@@ -20,28 +8,6 @@
} }
} }
@mixin tanuki-second-highlight-animations($tanuki-color) {
@include unique-keyframes {
10%, 80% {
fill: #{$tanuki-color}
}
20%, 90% {
fill: lighten($tanuki-color, 25%);
}
}
}
@mixin tanuki-forth-highlight-animations($tanuki-color) {
@include unique-keyframes {
30%, 60% {
fill: #{$tanuki-color};
}
40%, 70% {
fill: lighten($tanuki-color, 25%);
}
}
}
.tanuki-logo { .tanuki-logo {
.tanuki-left-ear, .tanuki-left-ear,
...@@ -67,10 +33,11 @@ ...@@ -67,10 +33,11 @@
} }
.tanuki-left-cheek { .tanuki-left-cheek {
@include unique-keyframes { @include include-keyframes(animate-tanuki-left-cheek) {
0%, 10%, 100% { 0%, 10%, 100% {
fill: lighten($tanuki-yellow, 25%); fill: lighten($tanuki-yellow, 25%);
} }
90% { 90% {
fill: $tanuki-yellow; fill: $tanuki-yellow;
} }
...@@ -78,18 +45,35 @@ ...@@ -78,18 +45,35 @@
} }
.tanuki-left-eye { .tanuki-left-eye {
@include tanuki-second-highlight-animations($tanuki-orange); @include include-keyframes(animate-tanuki-left-eye) {
10%, 80% {
fill: $tanuki-orange;
}
20%, 90% {
fill: lighten($tanuki-orange, 25%);
}
}
} }
.tanuki-left-ear { .tanuki-left-ear {
@include tanuki-second-highlight-animations($tanuki-red); @include include-keyframes(animate-tanuki-left-ear) {
10%, 80% {
fill: $tanuki-red;
}
20%, 90% {
fill: lighten($tanuki-red, 25%);
}
}
} }
.tanuki-nose { .tanuki-nose {
@include unique-keyframes { @include include-keyframes(animate-tanuki-nose) {
20%, 70% { 20%, 70% {
fill: $tanuki-red; fill: $tanuki-red;
} }
30%, 80% { 30%, 80% {
fill: lighten($tanuki-red, 25%); fill: lighten($tanuki-red, 25%);
} }
...@@ -97,22 +81,39 @@ ...@@ -97,22 +81,39 @@
} }
.tanuki-right-eye { .tanuki-right-eye {
@include tanuki-forth-highlight-animations($tanuki-orange); @include include-keyframes(animate-tanuki-right-eye) {
30%, 60% {
fill: $tanuki-orange;
}
40%, 70% {
fill: lighten($tanuki-orange, 25%);
}
}
} }
.tanuki-right-ear { .tanuki-right-ear {
@include tanuki-forth-highlight-animations($tanuki-red); @include include-keyframes(animate-tanuki-right-ear) {
30%, 60% {
fill: $tanuki-red;
}
40%, 70% {
fill: lighten($tanuki-red, 25%);
}
}
} }
.tanuki-right-cheek { .tanuki-right-cheek {
@include unique-keyframes { @include include-keyframes(animate-tanuki-right-cheek) {
40% { 40% {
fill: $tanuki-yellow; fill: $tanuki-yellow;
} }
60% { 60% {
fill: lighten($tanuki-yellow, 25%); fill: lighten($tanuki-yellow, 25%);
} }
} }
} }
} }
} }
\ No newline at end of file
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
&.active { &.active {
background: $gray-light; background: $gray-light;
a { a {
font-weight: 600; font-weight: 600;
} }
...@@ -84,3 +85,10 @@ ...@@ -84,3 +85,10 @@
@content; @content;
} }
} }
@mixin include-keyframes($animation-name) {
@include webkit-prefix(animation-name, $animation-name);
@include keyframes($animation-name) {
@content;
}
}
...@@ -210,6 +210,7 @@ ...@@ -210,6 +210,7 @@
@media (max-width: $screen-xs-max) { @media (max-width: $screen-xs-max) {
padding-bottom: 0; padding-bottom: 0;
width: 100%; width: 100%;
.btn, form, .dropdown, .dropdown-menu-toggle, .form-control { .btn, form, .dropdown, .dropdown-menu-toggle, .form-control {
margin: 0 0 10px; margin: 0 0 10px;
display: block; display: block;
......
...@@ -13,6 +13,11 @@ ...@@ -13,6 +13,11 @@
.dropdown-menu-toggle { .dropdown-menu-toggle {
line-height: 20px; line-height: 20px;
} }
.badge {
margin-top: -2px;
margin-left: 5px;
}
} }
.panel-body { .panel-body {
......
...@@ -93,7 +93,7 @@ ...@@ -93,7 +93,7 @@
background: none; background: none;
.select2-search-field input { .select2-search-field input {
padding: $gl-padding / 2; padding: 5px $gl-padding / 2;
font-size: 13px; font-size: 13px;
height: auto; height: auto;
font-family: inherit; font-family: inherit;
...@@ -101,7 +101,7 @@ ...@@ -101,7 +101,7 @@
} }
.select2-search-choice { .select2-search-choice {
margin: 8px 0 0 8px; margin: 5px 0 0 8px;
box-shadow: none; box-shadow: none;
border-color: $input-border; border-color: $input-border;
color: $gl-text-color; color: $gl-text-color;
...@@ -137,6 +137,7 @@ ...@@ -137,6 +137,7 @@
.select2-results { .select2-results {
max-height: 350px; max-height: 350px;
.select2-highlighted { .select2-highlighted {
background: $gl-primary; background: $gl-primary;
} }
...@@ -212,9 +213,11 @@ ...@@ -212,9 +213,11 @@
.group-image { .group-image {
float: left; float: left;
} }
.group-name { .group-name {
font-weight: bold; font-weight: bold;
} }
.group-path { .group-path {
color: #999; color: #999;
} }
...@@ -239,6 +242,7 @@ ...@@ -239,6 +242,7 @@
color: #aaa; color: #aaa;
font-weight: normal; font-weight: normal;
} }
.namespace-path { .namespace-path {
margin-left: 10px; margin-left: 10px;
font-weight: bolder; font-weight: bolder;
......
...@@ -48,6 +48,7 @@ ...@@ -48,6 +48,7 @@
&:before { &:before {
background: none; background: none;
} }
.timeline-entry .timeline-entry-inner { .timeline-entry .timeline-entry-inner {
.timeline-icon { .timeline-icon {
display: none; display: none;
......
...@@ -48,31 +48,40 @@ ...@@ -48,31 +48,40 @@
.clearfix { .clearfix {
@include clearfix(); @include clearfix();
} }
.center-block { .center-block {
@include center-block(); @include center-block();
} }
.pull-right { .pull-right {
float: right !important; float: right !important;
} }
.pull-left { .pull-left {
float: left !important; float: left !important;
} }
.hide { .hide {
display: none; display: none;
} }
.show { .show {
display: block !important; display: block !important;
} }
.invisible { .invisible {
visibility: hidden; visibility: hidden;
} }
.text-hide { .text-hide {
@include text-hide(); @include text-hide();
} }
.hidden { .hidden {
display: none !important; display: none !important;
visibility: hidden !important; visibility: hidden !important;
} }
.affix { .affix {
position: fixed; position: fixed;
} }
...@@ -146,6 +155,7 @@ ...@@ -146,6 +155,7 @@
padding: 6px 15px; padding: 6px 15px;
font-size: 13px; font-size: 13px;
font-weight: normal; font-weight: normal;
a { a {
color: #777; color: #777;
} }
......
...@@ -45,40 +45,38 @@ ...@@ -45,40 +45,38 @@
} }
h1 { h1 {
font-size: 2em; font-size: 1.75em;
font-weight: 600; font-weight: 600;
margin: 1em 0 10px; margin: 16px 0 10px;
padding: 0 0 0.3em; padding: 0 0 0.3em;
border-bottom: 1px solid $btn-default-border; border-bottom: 1px solid $white-dark;
color: $gl-gray-dark; color: $gl-gray-dark;
} }
h2 { h2 {
font-size: 1.6em; font-size: 1.5em;
font-weight: 600; font-weight: 600;
margin: 1em 0 10px; margin: 16px 0 10px;
padding-bottom: 0.3em;
border-bottom: 1px solid $btn-default-border;
color: $gl-gray-dark; color: $gl-gray-dark;
} }
h3 { h3 {
margin: 1em 0 10px; margin: 16px 0 10px;
font-size: 1.4em; font-size: 1.3em;
} }
h4 { h4 {
margin: 1em 0 10px; margin: 16px 0 10px;
font-size: 1.25em; font-size: 1.2em;
} }
h5 { h5 {
margin: 1em 0 10px; margin: 16px 0 10px;
font-size: 1em; font-size: 1em;
} }
h6 { h6 {
margin: 1em 0 10px; margin: 16px 0 10px;
font-size: 0.95em; font-size: 0.95em;
} }
...@@ -87,7 +85,12 @@ ...@@ -87,7 +85,12 @@
font-size: inherit; font-size: inherit;
padding: 8px 21px; padding: 8px 21px;
margin: 12px 0; margin: 12px 0;
border-left: 3px solid #e7e9ed; border-left: 3px solid $white-dark;
}
blockquote:dir(rtl) {
border-left: 0;
border-right: 3px solid $white-dark;
} }
blockquote p { blockquote p {
...@@ -106,11 +109,16 @@ ...@@ -106,11 +109,16 @@
@extend .table-bordered; @extend .table-bordered;
margin: 12px 0; margin: 12px 0;
color: #5c5d5e; color: #5c5d5e;
th { th {
background: #f8fafc; background: #f8fafc;
} }
} }
table:dir(rtl) th {
text-align: right;
}
pre { pre {
margin: 12px 0; margin: 12px 0;
font-size: 13px; font-size: 13px;
...@@ -128,6 +136,10 @@ ...@@ -128,6 +136,10 @@
margin: 3px 0 3px 28px !important; margin: 3px 0 3px 28px !important;
} }
ul:dir(rtl), ol:dir(rtl) {
margin: 3px 28px 3px 0 !important;
}
li { li {
line-height: 1.6em; line-height: 1.6em;
} }
......
...@@ -17,8 +17,10 @@ $white-normal: #ededed; ...@@ -17,8 +17,10 @@ $white-normal: #ededed;
$white-dark: #ececec; $white-dark: #ececec;
$gray-light: #fafafa; $gray-light: #fafafa;
$gray-lighter: #f9f9f9;
$gray-normal: #f5f5f5; $gray-normal: #f5f5f5;
$gray-dark: #ededed; $gray-dark: #ededed;
$gray-darker: #eee;
$gray-darkest: #c9c9c9; $gray-darkest: #c9c9c9;
$green-light: #38ae67; $green-light: #38ae67;
...@@ -33,6 +35,8 @@ $blue-medium-light: #3498cb; ...@@ -33,6 +35,8 @@ $blue-medium-light: #3498cb;
$blue-medium: #2f8ebf; $blue-medium: #2f8ebf;
$blue-medium-dark: #2d86b4; $blue-medium-dark: #2d86b4;
$blue-light-transparent: rgba(44, 159, 216, 0.05);
$orange-light: #fc8a51; $orange-light: #fc8a51;
$orange-normal: #e75e40; $orange-normal: #e75e40;
$orange-dark: #ce5237; $orange-dark: #ce5237;
...@@ -52,6 +56,7 @@ $border-gray-light: #dcdcdc; ...@@ -52,6 +56,7 @@ $border-gray-light: #dcdcdc;
$border-gray-normal: #d7d7d7; $border-gray-normal: #d7d7d7;
$border-gray-dark: #c6cacf; $border-gray-dark: #c6cacf;
$border-green-extra-light: #9adb84;
$border-green-light: #2faa60; $border-green-light: #2faa60;
$border-green-normal: #2ca05b; $border-green-normal: #2ca05b;
$border-green-dark: #279654; $border-green-dark: #279654;
...@@ -91,6 +96,7 @@ $table-text-gray: #8f8f8f; ...@@ -91,6 +96,7 @@ $table-text-gray: #8f8f8f;
$gl-font-size: 15px; $gl-font-size: 15px;
$gl-title-color: #333; $gl-title-color: #333;
$gl-text-color: #5c5c5c; $gl-text-color: #5c5c5c;
$gl-text-color-light: #8c8c8c;
$gl-text-green: #4a2; $gl-text-green: #4a2;
$gl-text-red: #d12f19; $gl-text-red: #d12f19;
$gl-text-orange: #d90; $gl-text-orange: #d90;
......
...@@ -55,68 +55,68 @@ ...@@ -55,68 +55,68 @@
color: #000 !important; color: #000 !important;
} }
.hll { background-color: #373b41 } .hll { background-color: #373b41; }
.c { color: #969896 } /* Comment */ .c { color: #969896; } /* Comment */
.err { color: #c66 } /* Error */ .err { color: #c66; } /* Error */
.k { color: #b294bb } /* Keyword */ .k { color: #b294bb; } /* Keyword */
.l { color: #de935f } /* Literal */ .l { color: #de935f; } /* Literal */
.n { color: #c5c8c6 } /* Name */ .n { color: #c5c8c6; } /* Name */
.o { color: #8abeb7 } /* Operator */ .o { color: #8abeb7; } /* Operator */
.p { color: #c5c8c6 } /* Punctuation */ .p { color: #c5c8c6; } /* Punctuation */
.cm { color: #969896 } /* Comment.Multiline */ .cm { color: #969896; } /* Comment.Multiline */
.cp { color: #969896 } /* Comment.Preproc */ .cp { color: #969896; } /* Comment.Preproc */
.c1 { color: #969896 } /* Comment.Single */ .c1 { color: #969896; } /* Comment.Single */
.cs { color: #969896 } /* Comment.Special */ .cs { color: #969896; } /* Comment.Special */
.gd { color: #c66 } /* Generic.Deleted */ .gd { color: #c66; } /* Generic.Deleted */
.ge { font-style: italic } /* Generic.Emph */ .ge { font-style: italic; } /* Generic.Emph */
.gh { color: #c5c8c6; font-weight: bold } /* Generic.Heading */ .gh { color: #c5c8c6; font-weight: bold; } /* Generic.Heading */
.gi { color: #b5bd68 } /* Generic.Inserted */ .gi { color: #b5bd68; } /* Generic.Inserted */
.gp { color: #969896; font-weight: bold } /* Generic.Prompt */ .gp { color: #969896; font-weight: bold; } /* Generic.Prompt */
.gs { font-weight: bold } /* Generic.Strong */ .gs { font-weight: bold; } /* Generic.Strong */
.gu { color: #8abeb7; font-weight: bold } /* Generic.Subheading */ .gu { color: #8abeb7; font-weight: bold; } /* Generic.Subheading */
.kc { color: #b294bb } /* Keyword.Constant */ .kc { color: #b294bb; } /* Keyword.Constant */
.kd { color: #b294bb } /* Keyword.Declaration */ .kd { color: #b294bb; } /* Keyword.Declaration */
.kn { color: #8abeb7 } /* Keyword.Namespace */ .kn { color: #8abeb7; } /* Keyword.Namespace */
.kp { color: #b294bb } /* Keyword.Pseudo */ .kp { color: #b294bb; } /* Keyword.Pseudo */
.kr { color: #b294bb } /* Keyword.Reserved */ .kr { color: #b294bb; } /* Keyword.Reserved */
.kt { color: #f0c674 } /* Keyword.Type */ .kt { color: #f0c674; } /* Keyword.Type */
.ld { color: #b5bd68 } /* Literal.Date */ .ld { color: #b5bd68; } /* Literal.Date */
.m { color: #de935f } /* Literal.Number */ .m { color: #de935f; } /* Literal.Number */
.s { color: #b5bd68 } /* Literal.String */ .s { color: #b5bd68; } /* Literal.String */
.na { color: #81a2be } /* Name.Attribute */ .na { color: #81a2be; } /* Name.Attribute */
.nb { color: #c5c8c6 } /* Name.Builtin */ .nb { color: #c5c8c6; } /* Name.Builtin */
.nc { color: #f0c674 } /* Name.Class */ .nc { color: #f0c674; } /* Name.Class */
.no { color: #c66 } /* Name.Constant */ .no { color: #c66; } /* Name.Constant */
.nd { color: #8abeb7 } /* Name.Decorator */ .nd { color: #8abeb7; } /* Name.Decorator */
.ni { color: #c5c8c6 } /* Name.Entity */ .ni { color: #c5c8c6; } /* Name.Entity */
.ne { color: #c66 } /* Name.Exception */ .ne { color: #c66; } /* Name.Exception */
.nf { color: #81a2be } /* Name.Function */ .nf { color: #81a2be; } /* Name.Function */
.nl { color: #c5c8c6 } /* Name.Label */ .nl { color: #c5c8c6; } /* Name.Label */
.nn { color: #f0c674 } /* Name.Namespace */ .nn { color: #f0c674; } /* Name.Namespace */
.nx { color: #81a2be } /* Name.Other */ .nx { color: #81a2be; } /* Name.Other */
.py { color: #c5c8c6 } /* Name.Property */ .py { color: #c5c8c6; } /* Name.Property */
.nt { color: #8abeb7 } /* Name.Tag */ .nt { color: #8abeb7; } /* Name.Tag */
.nv { color: #c66 } /* Name.Variable */ .nv { color: #c66; } /* Name.Variable */
.ow { color: #8abeb7 } /* Operator.Word */ .ow { color: #8abeb7; } /* Operator.Word */
.w { color: #c5c8c6 } /* Text.Whitespace */ .w { color: #c5c8c6; } /* Text.Whitespace */
.mf { color: #de935f } /* Literal.Number.Float */ .mf { color: #de935f; } /* Literal.Number.Float */
.mh { color: #de935f } /* Literal.Number.Hex */ .mh { color: #de935f; } /* Literal.Number.Hex */
.mi { color: #de935f } /* Literal.Number.Integer */ .mi { color: #de935f; } /* Literal.Number.Integer */
.mo { color: #de935f } /* Literal.Number.Oct */ .mo { color: #de935f; } /* Literal.Number.Oct */
.sb { color: #b5bd68 } /* Literal.String.Backtick */ .sb { color: #b5bd68; } /* Literal.String.Backtick */
.sc { color: #c5c8c6 } /* Literal.String.Char */ .sc { color: #c5c8c6; } /* Literal.String.Char */
.sd { color: #969896 } /* Literal.String.Doc */ .sd { color: #969896; } /* Literal.String.Doc */
.s2 { color: #b5bd68 } /* Literal.String.Double */ .s2 { color: #b5bd68; } /* Literal.String.Double */
.se { color: #de935f } /* Literal.String.Escape */ .se { color: #de935f; } /* Literal.String.Escape */
.sh { color: #b5bd68 } /* Literal.String.Heredoc */ .sh { color: #b5bd68; } /* Literal.String.Heredoc */
.si { color: #de935f } /* Literal.String.Interpol */ .si { color: #de935f; } /* Literal.String.Interpol */
.sx { color: #b5bd68 } /* Literal.String.Other */ .sx { color: #b5bd68; } /* Literal.String.Other */
.sr { color: #b5bd68 } /* Literal.String.Regex */ .sr { color: #b5bd68; } /* Literal.String.Regex */
.s1 { color: #b5bd68 } /* Literal.String.Single */ .s1 { color: #b5bd68; } /* Literal.String.Single */
.ss { color: #b5bd68 } /* Literal.String.Symbol */ .ss { color: #b5bd68; } /* Literal.String.Symbol */
.bp { color: #c5c8c6 } /* Name.Builtin.Pseudo */ .bp { color: #c5c8c6; } /* Name.Builtin.Pseudo */
.vc { color: #c66 } /* Name.Variable.Class */ .vc { color: #c66; } /* Name.Variable.Class */
.vg { color: #c66 } /* Name.Variable.Global */ .vg { color: #c66; } /* Name.Variable.Global */
.vi { color: #c66 } /* Name.Variable.Instance */ .vi { color: #c66; } /* Name.Variable.Instance */
.il { color: #de935f } /* Literal.Number.Integer.Long */ .il { color: #de935f; } /* Literal.Number.Integer.Long */
} }
...@@ -55,65 +55,65 @@ ...@@ -55,65 +55,65 @@
color: #000 !important; color: #000 !important;
} }
.hll { background-color: #49483e } .hll { background-color: #49483e; }
.c { color: #75715e } /* Comment */ .c { color: #75715e; } /* Comment */
.err { color: #960050; background-color: #1e0010 } /* Error */ .err { color: #960050; background-color: #1e0010; } /* Error */
.k { color: #66d9ef } /* Keyword */ .k { color: #66d9ef; } /* Keyword */
.l { color: #ae81ff } /* Literal */ .l { color: #ae81ff; } /* Literal */
.n { color: #f8f8f2 } /* Name */ .n { color: #f8f8f2; } /* Name */
.o { color: #f92672 } /* Operator */ .o { color: #f92672; } /* Operator */
.p { color: #f8f8f2 } /* Punctuation */ .p { color: #f8f8f2; } /* Punctuation */
.cm { color: #75715e } /* Comment.Multiline */ .cm { color: #75715e; } /* Comment.Multiline */
.cp { color: #75715e } /* Comment.Preproc */ .cp { color: #75715e; } /* Comment.Preproc */
.c1 { color: #75715e } /* Comment.Single */ .c1 { color: #75715e; } /* Comment.Single */
.cs { color: #75715e } /* Comment.Special */ .cs { color: #75715e; } /* Comment.Special */
.ge { font-style: italic } /* Generic.Emph */ .ge { font-style: italic; } /* Generic.Emph */
.gs { font-weight: bold } /* Generic.Strong */ .gs { font-weight: bold; } /* Generic.Strong */
.kc { color: #66d9ef } /* Keyword.Constant */ .kc { color: #66d9ef; } /* Keyword.Constant */
.kd { color: #66d9ef } /* Keyword.Declaration */ .kd { color: #66d9ef; } /* Keyword.Declaration */
.kn { color: #f92672 } /* Keyword.Namespace */ .kn { color: #f92672; } /* Keyword.Namespace */
.kp { color: #66d9ef } /* Keyword.Pseudo */ .kp { color: #66d9ef; } /* Keyword.Pseudo */
.kr { color: #66d9ef } /* Keyword.Reserved */ .kr { color: #66d9ef; } /* Keyword.Reserved */
.kt { color: #66d9ef } /* Keyword.Type */ .kt { color: #66d9ef; } /* Keyword.Type */
.ld { color: #e6db74 } /* Literal.Date */ .ld { color: #e6db74; } /* Literal.Date */
.m { color: #ae81ff } /* Literal.Number */ .m { color: #ae81ff; } /* Literal.Number */
.s { color: #e6db74 } /* Literal.String */ .s { color: #e6db74; } /* Literal.String */
.na { color: #a6e22e } /* Name.Attribute */ .na { color: #a6e22e; } /* Name.Attribute */
.nb { color: #f8f8f2 } /* Name.Builtin */ .nb { color: #f8f8f2; } /* Name.Builtin */
.nc { color: #a6e22e } /* Name.Class */ .nc { color: #a6e22e; } /* Name.Class */
.no { color: #66d9ef } /* Name.Constant */ .no { color: #66d9ef; } /* Name.Constant */
.nd { color: #a6e22e } /* Name.Decorator */ .nd { color: #a6e22e; } /* Name.Decorator */
.ni { color: #f8f8f2 } /* Name.Entity */ .ni { color: #f8f8f2; } /* Name.Entity */
.ne { color: #a6e22e } /* Name.Exception */ .ne { color: #a6e22e; } /* Name.Exception */
.nf { color: #a6e22e } /* Name.Function */ .nf { color: #a6e22e; } /* Name.Function */
.nl { color: #f8f8f2 } /* Name.Label */ .nl { color: #f8f8f2; } /* Name.Label */
.nn { color: #f8f8f2 } /* Name.Namespace */ .nn { color: #f8f8f2; } /* Name.Namespace */
.nx { color: #a6e22e } /* Name.Other */ .nx { color: #a6e22e; } /* Name.Other */
.py { color: #f8f8f2 } /* Name.Property */ .py { color: #f8f8f2; } /* Name.Property */
.nt { color: #f92672 } /* Name.Tag */ .nt { color: #f92672; } /* Name.Tag */
.nv { color: #f8f8f2 } /* Name.Variable */ .nv { color: #f8f8f2; } /* Name.Variable */
.ow { color: #f92672 } /* Operator.Word */ .ow { color: #f92672; } /* Operator.Word */
.w { color: #f8f8f2 } /* Text.Whitespace */ .w { color: #f8f8f2; } /* Text.Whitespace */
.mf { color: #ae81ff } /* Literal.Number.Float */ .mf { color: #ae81ff; } /* Literal.Number.Float */
.mh { color: #ae81ff } /* Literal.Number.Hex */ .mh { color: #ae81ff; } /* Literal.Number.Hex */
.mi { color: #ae81ff } /* Literal.Number.Integer */ .mi { color: #ae81ff; } /* Literal.Number.Integer */
.mo { color: #ae81ff } /* Literal.Number.Oct */ .mo { color: #ae81ff; } /* Literal.Number.Oct */
.sb { color: #e6db74 } /* Literal.String.Backtick */ .sb { color: #e6db74; } /* Literal.String.Backtick */
.sc { color: #e6db74 } /* Literal.String.Char */ .sc { color: #e6db74; } /* Literal.String.Char */
.sd { color: #e6db74 } /* Literal.String.Doc */ .sd { color: #e6db74; } /* Literal.String.Doc */
.s2 { color: #e6db74 } /* Literal.String.Double */ .s2 { color: #e6db74; } /* Literal.String.Double */
.se { color: #ae81ff } /* Literal.String.Escape */ .se { color: #ae81ff; } /* Literal.String.Escape */
.sh { color: #e6db74 } /* Literal.String.Heredoc */ .sh { color: #e6db74; } /* Literal.String.Heredoc */
.si { color: #e6db74 } /* Literal.String.Interpol */ .si { color: #e6db74; } /* Literal.String.Interpol */
.sx { color: #e6db74 } /* Literal.String.Other */ .sx { color: #e6db74; } /* Literal.String.Other */
.sr { color: #e6db74 } /* Literal.String.Regex */ .sr { color: #e6db74; } /* Literal.String.Regex */
.s1 { color: #e6db74 } /* Literal.String.Single */ .s1 { color: #e6db74; } /* Literal.String.Single */
.ss { color: #e6db74 } /* Literal.String.Symbol */ .ss { color: #e6db74; } /* Literal.String.Symbol */
.bp { color: #f8f8f2 } /* Name.Builtin.Pseudo */ .bp { color: #f8f8f2; } /* Name.Builtin.Pseudo */
.vc { color: #f8f8f2 } /* Name.Variable.Class */ .vc { color: #f8f8f2; } /* Name.Variable.Class */
.vg { color: #f8f8f2 } /* Name.Variable.Global */ .vg { color: #f8f8f2; } /* Name.Variable.Global */
.vi { color: #f8f8f2 } /* Name.Variable.Instance */ .vi { color: #f8f8f2; } /* Name.Variable.Instance */
.il { color: #ae81ff } /* Literal.Number.Integer.Long */ .il { color: #ae81ff; } /* Literal.Number.Integer.Long */
.gu { color: #75715e; } /* Generic.Subheading & Diff Unified/Comment? */ .gu { color: #75715e; } /* Generic.Subheading & Diff Unified/Comment? */
.gd { color: #f92672; } /* Generic.Deleted & Diff Deleted */ .gd { color: #f92672; } /* Generic.Deleted & Diff Deleted */
.gi { color: #a6e22e; } /* Generic.Inserted & Diff Inserted */ .gi { color: #a6e22e; } /* Generic.Inserted & Diff Inserted */
......
...@@ -72,72 +72,72 @@ ...@@ -72,72 +72,72 @@
green #859900 operators, other keywords green #859900 operators, other keywords
*/ */
.c { color: #586e75 } /* Comment */ .c { color: #586e75; } /* Comment */
.err { color: #93a1a1 } /* Error */ .err { color: #93a1a1; } /* Error */
.g { color: #93a1a1 } /* Generic */ .g { color: #93a1a1; } /* Generic */
.k { color: #859900 } /* Keyword */ .k { color: #859900; } /* Keyword */
.l { color: #93a1a1 } /* Literal */ .l { color: #93a1a1; } /* Literal */
.n { color: #93a1a1 } /* Name */ .n { color: #93a1a1; } /* Name */
.o { color: #859900 } /* Operator */ .o { color: #859900; } /* Operator */
.x { color: #cb4b16 } /* Other */ .x { color: #cb4b16; } /* Other */
.p { color: #93a1a1 } /* Punctuation */ .p { color: #93a1a1; } /* Punctuation */
.cm { color: #586e75 } /* Comment.Multiline */ .cm { color: #586e75; } /* Comment.Multiline */
.cp { color: #859900 } /* Comment.Preproc */ .cp { color: #859900; } /* Comment.Preproc */
.c1 { color: #586e75 } /* Comment.Single */ .c1 { color: #586e75; } /* Comment.Single */
.cs { color: #859900 } /* Comment.Special */ .cs { color: #859900; } /* Comment.Special */
.gd { color: #2aa198 } /* Generic.Deleted */ .gd { color: #2aa198; } /* Generic.Deleted */
.ge { color: #93a1a1; font-style: italic } /* Generic.Emph */ .ge { color: #93a1a1; font-style: italic; } /* Generic.Emph */
.gr { color: #dc322f } /* Generic.Error */ .gr { color: #dc322f; } /* Generic.Error */
.gh { color: #cb4b16 } /* Generic.Heading */ .gh { color: #cb4b16; } /* Generic.Heading */
.gi { color: #859900 } /* Generic.Inserted */ .gi { color: #859900; } /* Generic.Inserted */
.go { color: #93a1a1 } /* Generic.Output */ .go { color: #93a1a1; } /* Generic.Output */
.gp { color: #93a1a1 } /* Generic.Prompt */ .gp { color: #93a1a1; } /* Generic.Prompt */
.gs { color: #93a1a1; font-weight: bold } /* Generic.Strong */ .gs { color: #93a1a1; font-weight: bold; } /* Generic.Strong */
.gu { color: #cb4b16 } /* Generic.Subheading */ .gu { color: #cb4b16; } /* Generic.Subheading */
.gt { color: #93a1a1 } /* Generic.Traceback */ .gt { color: #93a1a1; } /* Generic.Traceback */
.kc { color: #cb4b16 } /* Keyword.Constant */ .kc { color: #cb4b16; } /* Keyword.Constant */
.kd { color: #268bd2 } /* Keyword.Declaration */ .kd { color: #268bd2; } /* Keyword.Declaration */
.kn { color: #859900 } /* Keyword.Namespace */ .kn { color: #859900; } /* Keyword.Namespace */
.kp { color: #859900 } /* Keyword.Pseudo */ .kp { color: #859900; } /* Keyword.Pseudo */
.kr { color: #268bd2 } /* Keyword.Reserved */ .kr { color: #268bd2; } /* Keyword.Reserved */
.kt { color: #dc322f } /* Keyword.Type */ .kt { color: #dc322f; } /* Keyword.Type */
.ld { color: #93a1a1 } /* Literal.Date */ .ld { color: #93a1a1; } /* Literal.Date */
.m { color: #2aa198 } /* Literal.Number */ .m { color: #2aa198; } /* Literal.Number */
.s { color: #2aa198 } /* Literal.String */ .s { color: #2aa198; } /* Literal.String */
.na { color: #93a1a1 } /* Name.Attribute */ .na { color: #93a1a1; } /* Name.Attribute */
.nb { color: #b58900 } /* Name.Builtin */ .nb { color: #b58900; } /* Name.Builtin */
.nc { color: #268bd2 } /* Name.Class */ .nc { color: #268bd2; } /* Name.Class */
.no { color: #cb4b16 } /* Name.Constant */ .no { color: #cb4b16; } /* Name.Constant */
.nd { color: #268bd2 } /* Name.Decorator */ .nd { color: #268bd2; } /* Name.Decorator */
.ni { color: #cb4b16 } /* Name.Entity */ .ni { color: #cb4b16; } /* Name.Entity */
.ne { color: #cb4b16 } /* Name.Exception */ .ne { color: #cb4b16; } /* Name.Exception */
.nf { color: #268bd2 } /* Name.Function */ .nf { color: #268bd2; } /* Name.Function */
.nl { color: #93a1a1 } /* Name.Label */ .nl { color: #93a1a1; } /* Name.Label */
.nn { color: #93a1a1 } /* Name.Namespace */ .nn { color: #93a1a1; } /* Name.Namespace */
.nx { color: #93a1a1 } /* Name.Other */ .nx { color: #93a1a1; } /* Name.Other */
.py { color: #93a1a1 } /* Name.Property */ .py { color: #93a1a1; } /* Name.Property */
.nt { color: #268bd2 } /* Name.Tag */ .nt { color: #268bd2; } /* Name.Tag */
.nv { color: #268bd2 } /* Name.Variable */ .nv { color: #268bd2; } /* Name.Variable */
.ow { color: #859900 } /* Operator.Word */ .ow { color: #859900; } /* Operator.Word */
.w { color: #93a1a1 } /* Text.Whitespace */ .w { color: #93a1a1; } /* Text.Whitespace */
.mf { color: #2aa198 } /* Literal.Number.Float */ .mf { color: #2aa198; } /* Literal.Number.Float */
.mh { color: #2aa198 } /* Literal.Number.Hex */ .mh { color: #2aa198; } /* Literal.Number.Hex */
.mi { color: #2aa198 } /* Literal.Number.Integer */ .mi { color: #2aa198; } /* Literal.Number.Integer */
.mo { color: #2aa198 } /* Literal.Number.Oct */ .mo { color: #2aa198; } /* Literal.Number.Oct */
.sb { color: #586e75 } /* Literal.String.Backtick */ .sb { color: #586e75; } /* Literal.String.Backtick */
.sc { color: #2aa198 } /* Literal.String.Char */ .sc { color: #2aa198; } /* Literal.String.Char */
.sd { color: #93a1a1 } /* Literal.String.Doc */ .sd { color: #93a1a1; } /* Literal.String.Doc */
.s2 { color: #2aa198 } /* Literal.String.Double */ .s2 { color: #2aa198; } /* Literal.String.Double */
.se { color: #cb4b16 } /* Literal.String.Escape */ .se { color: #cb4b16; } /* Literal.String.Escape */
.sh { color: #93a1a1 } /* Literal.String.Heredoc */ .sh { color: #93a1a1; } /* Literal.String.Heredoc */
.si { color: #2aa198 } /* Literal.String.Interpol */ .si { color: #2aa198; } /* Literal.String.Interpol */
.sx { color: #2aa198 } /* Literal.String.Other */ .sx { color: #2aa198; } /* Literal.String.Other */
.sr { color: #dc322f } /* Literal.String.Regex */ .sr { color: #dc322f; } /* Literal.String.Regex */
.s1 { color: #2aa198 } /* Literal.String.Single */ .s1 { color: #2aa198; } /* Literal.String.Single */
.ss { color: #2aa198 } /* Literal.String.Symbol */ .ss { color: #2aa198; } /* Literal.String.Symbol */
.bp { color: #268bd2 } /* Name.Builtin.Pseudo */ .bp { color: #268bd2; } /* Name.Builtin.Pseudo */
.vc { color: #268bd2 } /* Name.Variable.Class */ .vc { color: #268bd2; } /* Name.Variable.Class */
.vg { color: #268bd2 } /* Name.Variable.Global */ .vg { color: #268bd2; } /* Name.Variable.Global */
.vi { color: #268bd2 } /* Name.Variable.Instance */ .vi { color: #268bd2; } /* Name.Variable.Instance */
.il { color: #2aa198 } /* Literal.Number.Integer.Long */ .il { color: #2aa198; } /* Literal.Number.Integer.Long */
} }
...@@ -86,7 +86,7 @@ ...@@ -86,7 +86,7 @@
background-color: #fafe3d !important; background-color: #fafe3d !important;
} }
.hll { background-color: #f8f8f8 } .hll { background-color: #f8f8f8; }
.c { color: #998; font-style: italic; } .c { color: #998; font-style: italic; }
.err { color: #a61717; background-color: #e3d2d2; } .err { color: #a61717; background-color: #e3d2d2; }
.k { font-weight: bold; } .k { font-weight: bold; }
......
...@@ -78,7 +78,7 @@ span.highlight_word { ...@@ -78,7 +78,7 @@ span.highlight_word {
background-color: #fafe3d !important; background-color: #fafe3d !important;
} }
.hll { background-color: #f8f8f8 } .hll { background-color: #f8f8f8; }
.c { color: #998; font-style: italic; } .c { color: #998; font-style: italic; }
.err { color: #a61717; background-color: #e3d2d2; } .err { color: #a61717; background-color: #e3d2d2; }
.k { font-weight: bold; } .k { font-weight: bold; }
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -161,6 +161,7 @@ ...@@ -161,6 +161,7 @@
.branch-commit { .branch-commit {
color: $gl-gray; color: $gl-gray;
.commit-id, .commit-row-message { .commit-id, .commit-row-message {
color: $gl-gray; color: $gl-gray;
} }
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment