[ci skip] Merge branch 'master' into 42923-close-issue
* master: (25 commits) Addressed mr observations Clean new Flash() and stop disabling no-new (eslint) when possible Disable query limiting warnings for now on GitLab.com Revert "Merge branch 'rd-40552-gitlab-should-check-if-keys-are-valid-before-saving' into 'master'" Fix warning messages for promoting labels and milestones Fixed missing js selector for the realtime pipelines commit comp Honour workhorse provided file name Create an empty wiki when there is no wiki in the gitlab export bundle Revert and remove header_title line from labels issue Fixed bug with param config changed params passed to from a string to an object Move IssuableTimeTracker vue component Fix breadcrumb on labels page for groups Convert groups_select ajax to use axios Default CI variables to unprotected make sure there is a dependency on Gitlab::CurrentSettings is Make GITLAB_FEATURES in build_spec compatible with EE Update jquery.waitforimages & use npm version Fixed typo, updated test, and removed commented code Replaced use of $.get with axios.get and updated tests ...
This commit is contained in:
commit
d8d0f668a8
132 changed files with 340 additions and 10114 deletions
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import Flash from '../../flash';
|
import Flash from '../../flash';
|
||||||
|
import { __ } from '../../locale';
|
||||||
import Sidebar from '../../right_sidebar';
|
import Sidebar from '../../right_sidebar';
|
||||||
import eventHub from '../../sidebar/event_hub';
|
import eventHub from '../../sidebar/event_hub';
|
||||||
import assigneeTitle from '../../sidebar/components/assignees/assignee_title';
|
import assigneeTitle from '../../sidebar/components/assignees/assignee_title';
|
||||||
|
@ -95,7 +96,7 @@ gl.issueBoards.BoardSidebar = Vue.extend({
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
this.loadingAssignees = false;
|
this.loadingAssignees = false;
|
||||||
return new Flash('An error occurred while saving assignees');
|
Flash(__('An error occurred while saving assignees'));
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
/* eslint-disable no-new */
|
|
||||||
|
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import Flash from '../../../flash';
|
import Flash from '../../../flash';
|
||||||
|
import { __ } from '../../../locale';
|
||||||
import './lists_dropdown';
|
import './lists_dropdown';
|
||||||
import { pluralize } from '../../../lib/utils/text_utility';
|
import { pluralize } from '../../../lib/utils/text_utility';
|
||||||
|
|
||||||
|
@ -36,7 +35,7 @@ gl.issueBoards.ModalFooter = Vue.extend({
|
||||||
gl.boardService.bulkUpdate(issueIds, {
|
gl.boardService.bulkUpdate(issueIds, {
|
||||||
add_label_ids: [list.label.id],
|
add_label_ids: [list.label.id],
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
new Flash('Failed to update issues, please try again.', 'alert');
|
Flash(__('Failed to update issues, please try again.'));
|
||||||
|
|
||||||
selectedIssues.forEach((issue) => {
|
selectedIssues.forEach((issue) => {
|
||||||
list.removeIssue(issue);
|
list.removeIssue(issue);
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
/* eslint-disable no-new */
|
|
||||||
|
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import Flash from '../../../flash';
|
import Flash from '../../../flash';
|
||||||
|
import { __ } from '../../../locale';
|
||||||
|
|
||||||
const Store = gl.issueBoards.BoardsStore;
|
const Store = gl.issueBoards.BoardsStore;
|
||||||
|
|
||||||
|
@ -45,7 +44,7 @@ gl.issueBoards.RemoveIssueBtn = Vue.extend({
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
Vue.http.patch(this.updateUrl, data).catch(() => {
|
Vue.http.patch(this.updateUrl, data).catch(() => {
|
||||||
new Flash('Failed to remove issue from board, please try again.', 'alert');
|
Flash(__('Failed to remove issue from board, please try again.'));
|
||||||
|
|
||||||
lists.forEach((list) => {
|
lists.forEach((list) => {
|
||||||
list.addIssue(issue);
|
list.addIssue(issue);
|
||||||
|
|
|
@ -39,7 +39,7 @@ export default class VariableList {
|
||||||
},
|
},
|
||||||
protected: {
|
protected: {
|
||||||
selector: '.js-ci-variable-input-protected',
|
selector: '.js-ci-variable-input-protected',
|
||||||
default: 'true',
|
default: 'false',
|
||||||
},
|
},
|
||||||
environment_scope: {
|
environment_scope: {
|
||||||
// We can't use a `.js-` class here because
|
// We can't use a `.js-` class here because
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-var, no-use-before-define, prefer-arrow-callback, no-else-return, consistent-return, prefer-template, quotes, one-var, one-var-declaration-per-line, no-unused-vars, no-return-assign, comma-dangle, quote-props, no-unused-expressions, no-sequences, object-shorthand, max-len */
|
/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-var, no-use-before-define, prefer-arrow-callback, no-else-return, consistent-return, prefer-template, quotes, one-var, one-var-declaration-per-line, no-unused-vars, no-return-assign, comma-dangle, quote-props, no-unused-expressions, no-sequences, object-shorthand, max-len */
|
||||||
import 'vendor/jquery.waitforimages';
|
|
||||||
|
|
||||||
// Width where images must fits in, for 2-up this gets divided by 2
|
// Width where images must fits in, for 2-up this gets divided by 2
|
||||||
const availWidth = 900;
|
const availWidth = 900;
|
||||||
|
|
2
app/assets/javascripts/commons/jquery.js
vendored
2
app/assets/javascripts/commons/jquery.js
vendored
|
@ -6,5 +6,5 @@ import 'vendor/jquery.endless-scroll';
|
||||||
import 'vendor/jquery.caret';
|
import 'vendor/jquery.caret';
|
||||||
import 'vendor/jquery.atwho';
|
import 'vendor/jquery.atwho';
|
||||||
import 'vendor/jquery.scrollTo';
|
import 'vendor/jquery.scrollTo';
|
||||||
import 'vendor/jquery.waitforimages';
|
import 'jquery.waitforimages';
|
||||||
import 'select2/select2';
|
import 'select2/select2';
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
import axios from '~/lib/utils/axios_utils';
|
||||||
|
import flash from '~/flash';
|
||||||
|
import { __ } from '~/locale';
|
||||||
import { getLocationHash } from './lib/utils/url_utility';
|
import { getLocationHash } from './lib/utils/url_utility';
|
||||||
import FilesCommentButton from './files_comment_button';
|
import FilesCommentButton from './files_comment_button';
|
||||||
import SingleFileDiff from './single_file_diff';
|
import SingleFileDiff from './single_file_diff';
|
||||||
|
@ -69,7 +72,9 @@ export default class Diff {
|
||||||
const view = file.data('view');
|
const view = file.data('view');
|
||||||
|
|
||||||
const params = { since, to, bottom, offset, unfold, view };
|
const params = { since, to, bottom, offset, unfold, view };
|
||||||
$.get(link, params, response => $target.parent().replaceWith(response));
|
axios.get(link, { params })
|
||||||
|
.then(({ data }) => $target.parent().replaceWith(data))
|
||||||
|
.catch(() => flash(__('An error occurred while loading diff')));
|
||||||
}
|
}
|
||||||
|
|
||||||
openAnchoredDiff(cb) {
|
openAnchoredDiff(cb) {
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
import { parseQueryStringIntoObject } from '~/lib/utils/common_utils';
|
||||||
|
import axios from '~/lib/utils/axios_utils';
|
||||||
|
import flash from '~/flash';
|
||||||
|
import { __ } from '~/locale';
|
||||||
|
|
||||||
export default class GpgBadges {
|
export default class GpgBadges {
|
||||||
static fetch() {
|
static fetch() {
|
||||||
const badges = $('.js-loading-gpg-badge');
|
const badges = $('.js-loading-gpg-badge');
|
||||||
|
@ -5,13 +10,13 @@ export default class GpgBadges {
|
||||||
|
|
||||||
badges.html('<i class="fa fa-spinner fa-spin"></i>');
|
badges.html('<i class="fa fa-spinner fa-spin"></i>');
|
||||||
|
|
||||||
$.get({
|
const params = parseQueryStringIntoObject(form.serialize());
|
||||||
url: form.data('signatures-path'),
|
return axios.get(form.data('signatures-path'), { params })
|
||||||
data: form.serialize(),
|
.then(({ data }) => {
|
||||||
}).done((response) => {
|
data.signatures.forEach((signature) => {
|
||||||
response.signatures.forEach((signature) => {
|
|
||||||
badges.filter(`[data-commit-sha="${signature.commit_sha}"]`).replaceWith(signature.html);
|
badges.filter(`[data-commit-sha="${signature.commit_sha}"]`).replaceWith(signature.html);
|
||||||
});
|
});
|
||||||
});
|
})
|
||||||
|
.catch(() => flash(__('An error occurred while loading commits')));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
|
import axios from './lib/utils/axios_utils';
|
||||||
import Api from './api';
|
import Api from './api';
|
||||||
import { normalizeCRLFHeaders } from './lib/utils/common_utils';
|
import { normalizeHeaders } from './lib/utils/common_utils';
|
||||||
|
|
||||||
export default function groupsSelect() {
|
export default function groupsSelect() {
|
||||||
// Needs to be accessible in rspec
|
// Needs to be accessible in rspec
|
||||||
|
@ -17,24 +18,23 @@ export default function groupsSelect() {
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
quietMillis: 250,
|
quietMillis: 250,
|
||||||
transport(params) {
|
transport(params) {
|
||||||
return $.ajax(params)
|
axios[params.type.toLowerCase()](params.url, {
|
||||||
.then((data, status, xhr) => {
|
params: params.data,
|
||||||
const results = data || [];
|
})
|
||||||
|
.then((res) => {
|
||||||
const headers = normalizeCRLFHeaders(xhr.getAllResponseHeaders());
|
const results = res.data || [];
|
||||||
|
const headers = normalizeHeaders(res.headers);
|
||||||
const currentPage = parseInt(headers['X-PAGE'], 10) || 0;
|
const currentPage = parseInt(headers['X-PAGE'], 10) || 0;
|
||||||
const totalPages = parseInt(headers['X-TOTAL-PAGES'], 10) || 0;
|
const totalPages = parseInt(headers['X-TOTAL-PAGES'], 10) || 0;
|
||||||
const more = currentPage < totalPages;
|
const more = currentPage < totalPages;
|
||||||
|
|
||||||
return {
|
params.success({
|
||||||
results,
|
results,
|
||||||
pagination: {
|
pagination: {
|
||||||
more,
|
more,
|
||||||
},
|
},
|
||||||
};
|
});
|
||||||
})
|
}).catch(params.error);
|
||||||
.then(params.success)
|
|
||||||
.fail(params.error);
|
|
||||||
},
|
},
|
||||||
data(search, page) {
|
data(search, page) {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
/* eslint-disable func-names, space-before-function-paren, no-var, prefer-rest-params, wrap-iife, one-var, no-underscore-dangle, one-var-declaration-per-line, object-shorthand, no-unused-vars, no-new, comma-dangle, consistent-return, quotes, dot-notation, quote-props, prefer-arrow-callback, max-len */
|
/* eslint-disable func-names, space-before-function-paren, no-var, prefer-rest-params, wrap-iife, one-var, no-underscore-dangle, one-var-declaration-per-line, object-shorthand, no-unused-vars, no-new, comma-dangle, consistent-return, quotes, dot-notation, quote-props, prefer-arrow-callback, max-len */
|
||||||
import 'vendor/jquery.waitforimages';
|
|
||||||
import axios from './lib/utils/axios_utils';
|
import axios from './lib/utils/axios_utils';
|
||||||
import { addDelimiter } from './lib/utils/text_utility';
|
import { addDelimiter } from './lib/utils/text_utility';
|
||||||
import flash from './flash';
|
import flash from './flash';
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
/* eslint-disable func-names, space-before-function-paren, no-var, prefer-rest-params, wrap-iife, quotes, no-underscore-dangle, one-var, one-var-declaration-per-line, consistent-return, dot-notation, quote-props, comma-dangle, object-shorthand, max-len, prefer-arrow-callback */
|
/* eslint-disable func-names, space-before-function-paren, no-var, prefer-rest-params, wrap-iife, quotes, no-underscore-dangle, one-var, one-var-declaration-per-line, consistent-return, dot-notation, quote-props, comma-dangle, object-shorthand, max-len, prefer-arrow-callback */
|
||||||
|
|
||||||
import 'vendor/jquery.waitforimages';
|
|
||||||
import { __ } from '~/locale';
|
import { __ } from '~/locale';
|
||||||
import TaskList from './task_list';
|
import TaskList from './task_list';
|
||||||
import MergeRequestTabs from './merge_request_tabs';
|
import MergeRequestTabs from './merge_request_tabs';
|
||||||
|
|
|
@ -14,7 +14,7 @@ export default () => {
|
||||||
$('#tree-slider').waitForImages(() =>
|
$('#tree-slider').waitForImages(() =>
|
||||||
ajaxGet(document.querySelector('.js-tree-content').dataset.logsPath));
|
ajaxGet(document.querySelector('.js-tree-content').dataset.logsPath));
|
||||||
|
|
||||||
const commitPipelineStatusEl = document.getElementById('commit-pipeline-status');
|
const commitPipelineStatusEl = document.querySelector('.js-commit-pipeline-status');
|
||||||
const statusLink = document.querySelector('.commit-actions .ci-status-link');
|
const statusLink = document.querySelector('.commit-actions .ci-status-link');
|
||||||
if (statusLink != null) {
|
if (statusLink != null) {
|
||||||
statusLink.remove();
|
statusLink.remove();
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
/* global katex */
|
import { __ } from './locale';
|
||||||
|
import flash from './flash';
|
||||||
|
|
||||||
// Renders math using KaTeX in any element with the
|
// Renders math using KaTeX in any element with the
|
||||||
// `js-render-math` class
|
// `js-render-math` class
|
||||||
|
@ -8,15 +9,8 @@
|
||||||
// <code class="js-render-math"></div>
|
// <code class="js-render-math"></div>
|
||||||
//
|
//
|
||||||
|
|
||||||
import { __ } from './locale';
|
|
||||||
import axios from './lib/utils/axios_utils';
|
|
||||||
import flash from './flash';
|
|
||||||
|
|
||||||
// Only load once
|
|
||||||
let katexLoaded = false;
|
|
||||||
|
|
||||||
// Loop over all math elements and render math
|
// Loop over all math elements and render math
|
||||||
function renderWithKaTeX(elements) {
|
function renderWithKaTeX(elements, katex) {
|
||||||
elements.each(function katexElementsLoop() {
|
elements.each(function katexElementsLoop() {
|
||||||
const mathNode = $('<span></span>');
|
const mathNode = $('<span></span>');
|
||||||
const $this = $(this);
|
const $this = $(this);
|
||||||
|
@ -34,30 +28,10 @@ function renderWithKaTeX(elements) {
|
||||||
|
|
||||||
export default function renderMath($els) {
|
export default function renderMath($els) {
|
||||||
if (!$els.length) return;
|
if (!$els.length) return;
|
||||||
|
Promise.all([
|
||||||
if (katexLoaded) {
|
import(/* webpackChunkName: 'katex' */ 'katex'),
|
||||||
renderWithKaTeX($els);
|
import(/* webpackChunkName: 'katex' */ 'katex/dist/katex.css'),
|
||||||
} else {
|
]).then(([katex]) => {
|
||||||
axios.get(gon.katex_css_url)
|
renderWithKaTeX($els, katex);
|
||||||
.then(() => {
|
}).catch(() => flash(__('An error occurred while rendering KaTeX')));
|
||||||
const css = $('<link>', {
|
|
||||||
rel: 'stylesheet',
|
|
||||||
type: 'text/css',
|
|
||||||
href: gon.katex_css_url,
|
|
||||||
});
|
|
||||||
css.appendTo('head');
|
|
||||||
})
|
|
||||||
.then(() => axios.get(gon.katex_js_url, {
|
|
||||||
responseType: 'text',
|
|
||||||
}))
|
|
||||||
.then(({ data }) => {
|
|
||||||
// Add katex js to our document
|
|
||||||
$.globalEval(data);
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
katexLoaded = true;
|
|
||||||
renderWithKaTeX($els); // Run KaTeX
|
|
||||||
})
|
|
||||||
.catch(() => flash(__('An error occurred while rendering KaTeX')));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ import _ from 'underscore';
|
||||||
|
|
||||||
import '~/smart_interval';
|
import '~/smart_interval';
|
||||||
|
|
||||||
import timeTracker from './time_tracker';
|
import IssuableTimeTracker from './time_tracker.vue';
|
||||||
|
|
||||||
import Store from '../../stores/sidebar_store';
|
import Store from '../../stores/sidebar_store';
|
||||||
import Mediator from '../../sidebar_mediator';
|
import Mediator from '../../sidebar_mediator';
|
||||||
|
@ -16,7 +16,7 @@ export default {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
'issuable-time-tracker': timeTracker,
|
IssuableTimeTracker,
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
listenForQuickActions() {
|
listenForQuickActions() {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
<script>
|
||||||
import timeTrackingHelpState from './help_state';
|
import timeTrackingHelpState from './help_state';
|
||||||
import timeTrackingCollapsedState from './collapsed_state';
|
import timeTrackingCollapsedState from './collapsed_state';
|
||||||
import timeTrackingSpentOnlyPane from './spent_only_pane';
|
import timeTrackingSpentOnlyPane from './spent_only_pane';
|
||||||
|
@ -8,7 +9,15 @@ import timeTrackingComparisonPane from './comparison_pane';
|
||||||
import eventHub from '../../event_hub';
|
import eventHub from '../../event_hub';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'issuable-time-tracker',
|
name: 'IssuableTimeTracker',
|
||||||
|
components: {
|
||||||
|
'time-tracking-collapsed-state': timeTrackingCollapsedState,
|
||||||
|
'time-tracking-estimate-only-pane': timeTrackingEstimateOnlyPane,
|
||||||
|
'time-tracking-spent-only-pane': timeTrackingSpentOnlyPane,
|
||||||
|
'time-tracking-no-tracking-pane': timeTrackingNoTrackingPane,
|
||||||
|
'time-tracking-comparison-pane': timeTrackingComparisonPane,
|
||||||
|
'time-tracking-help-state': timeTrackingHelpState,
|
||||||
|
},
|
||||||
props: {
|
props: {
|
||||||
time_estimate: {
|
time_estimate: {
|
||||||
type: Number,
|
type: Number,
|
||||||
|
@ -38,14 +47,6 @@ export default {
|
||||||
showHelp: false,
|
showHelp: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
components: {
|
|
||||||
'time-tracking-collapsed-state': timeTrackingCollapsedState,
|
|
||||||
'time-tracking-estimate-only-pane': timeTrackingEstimateOnlyPane,
|
|
||||||
'time-tracking-spent-only-pane': timeTrackingSpentOnlyPane,
|
|
||||||
'time-tracking-no-tracking-pane': timeTrackingNoTrackingPane,
|
|
||||||
'time-tracking-comparison-pane': timeTrackingComparisonPane,
|
|
||||||
'time-tracking-help-state': timeTrackingHelpState,
|
|
||||||
},
|
|
||||||
computed: {
|
computed: {
|
||||||
timeSpent() {
|
timeSpent() {
|
||||||
return this.time_spent;
|
return this.time_spent;
|
||||||
|
@ -81,6 +82,9 @@ export default {
|
||||||
return !!this.showHelp;
|
return !!this.showHelp;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
created() {
|
||||||
|
eventHub.$on('timeTracker:updateData', this.update);
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
toggleHelpState(show) {
|
toggleHelpState(show) {
|
||||||
this.showHelp = show;
|
this.showHelp = show;
|
||||||
|
@ -92,10 +96,10 @@ export default {
|
||||||
this.human_time_spent = data.human_time_spent;
|
this.human_time_spent = data.human_time_spent;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
created() {
|
};
|
||||||
eventHub.$on('timeTracker:updateData', this.update);
|
</script>
|
||||||
},
|
|
||||||
template: `
|
<template>
|
||||||
<div
|
<div
|
||||||
class="time_tracker time-tracking-component-wrap"
|
class="time_tracker time-tracking-component-wrap"
|
||||||
v-cloak
|
v-cloak
|
||||||
|
@ -119,7 +123,8 @@ export default {
|
||||||
<i
|
<i
|
||||||
class="fa fa-question-circle"
|
class="fa fa-question-circle"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
/>
|
>
|
||||||
|
</i>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="close-help-button pull-right"
|
class="close-help-button pull-right"
|
||||||
|
@ -129,7 +134,8 @@ export default {
|
||||||
<i
|
<i
|
||||||
class="fa fa-close"
|
class="fa fa-close"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
/>
|
>
|
||||||
|
</i>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="time-tracking-content hide-collapsed">
|
<div class="time-tracking-content hide-collapsed">
|
||||||
|
@ -154,10 +160,9 @@ export default {
|
||||||
<transition name="help-state-toggle">
|
<transition name="help-state-toggle">
|
||||||
<time-tracking-help-state
|
<time-tracking-help-state
|
||||||
v-if="showHelpState"
|
v-if="showHelpState"
|
||||||
:rootPath="rootPath"
|
:root-path="rootPath"
|
||||||
/>
|
/>
|
||||||
</transition>
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`,
|
</template>
|
||||||
};
|
|
|
@ -33,8 +33,9 @@ class Key < ActiveRecord::Base
|
||||||
after_destroy :refresh_user_cache
|
after_destroy :refresh_user_cache
|
||||||
|
|
||||||
def key=(value)
|
def key=(value)
|
||||||
write_attribute(:key, value.present? ? Gitlab::SSHPublicKey.sanitize(value) : nil)
|
value&.delete!("\n\r")
|
||||||
|
value.strip! unless value.blank?
|
||||||
|
write_attribute(:key, value)
|
||||||
@public_key = nil
|
@public_key = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -96,7 +97,7 @@ class Key < ActiveRecord::Base
|
||||||
def generate_fingerprint
|
def generate_fingerprint
|
||||||
self.fingerprint = nil
|
self.fingerprint = nil
|
||||||
|
|
||||||
return unless public_key.valid?
|
return unless self.key.present?
|
||||||
|
|
||||||
self.fingerprint = public_key.fingerprint
|
self.fingerprint = public_key.fingerprint
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
- id = variable&.id
|
- id = variable&.id
|
||||||
- key = variable&.key
|
- key = variable&.key
|
||||||
- value = variable&.value
|
- value = variable&.value
|
||||||
- is_protected = variable && !only_key_value ? variable.protected : true
|
- is_protected = variable && !only_key_value ? variable.protected : false
|
||||||
|
|
||||||
- id_input_name = "#{form_field}[variables_attributes][][id]"
|
- id_input_name = "#{form_field}[variables_attributes][][id]"
|
||||||
- destroy_input_name = "#{form_field}[variables_attributes][][_destroy]"
|
- destroy_input_name = "#{form_field}[variables_attributes][][_destroy]"
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
- breadcrumb_title "Labels"
|
- breadcrumb_title "Labels"
|
||||||
- page_title 'New Label'
|
- page_title 'New Label'
|
||||||
- header_title group_title(@group, 'Labels', group_labels_path(@group))
|
|
||||||
|
|
||||||
%h3.page-title
|
%h3.page-title
|
||||||
New Label
|
New Label
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
- if commit.status(ref)
|
- if commit.status(ref)
|
||||||
= render_commit_status(commit, ref: ref)
|
= render_commit_status(commit, ref: ref)
|
||||||
|
|
||||||
#commit-pipeline-status{ data: { endpoint: pipelines_project_commit_path(project, commit.id) } }
|
.js-commit-pipeline-status{ data: { endpoint: pipelines_project_commit_path(project, commit.id) } }
|
||||||
= link_to commit.short_id, link, class: "commit-sha btn btn-transparent btn-link"
|
= link_to commit.short_id, link, class: "commit-sha btn btn-transparent btn-link"
|
||||||
= clipboard_button(text: commit.id, title: _("Copy commit SHA to clipboard"))
|
= clipboard_button(text: commit.id, title: _("Copy commit SHA to clipboard"))
|
||||||
= link_to_browse_code(project, commit)
|
= link_to_browse_code(project, commit)
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
Edit
|
Edit
|
||||||
|
|
||||||
- if @project.group
|
- if @project.group
|
||||||
= link_to promote_project_milestone_path(@milestone.project, @milestone), title: "Promote to Group Milestone", class: 'btn btn-grouped', data: { confirm: "You are about to promote #{@milestone.title} to a group level. This will make this milestone available to all projects inside #{@project.group.name}. The existing project milestone will be merged into the group level. This action cannot be reversed.", toggle: "tooltip" }, method: :post do
|
= link_to promote_project_milestone_path(@milestone.project, @milestone), title: "Promote to Group Milestone", class: 'btn btn-grouped', data: { confirm: "Promoting #{@milestone.title} will make it available for all projects inside #{@project.group.name}. Existing project milestones with the same name will be merged. This action cannot be reversed.", toggle: "tooltip" }, method: :post do
|
||||||
Promote
|
Promote
|
||||||
|
|
||||||
- if @milestone.active?
|
- if @milestone.active?
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
|
|
||||||
.pull-right.hidden-xs.hidden-sm
|
.pull-right.hidden-xs.hidden-sm
|
||||||
- if label.is_a?(ProjectLabel) && label.project.group && can?(current_user, :admin_label, label.project.group)
|
- if label.is_a?(ProjectLabel) && label.project.group && can?(current_user, :admin_label, label.project.group)
|
||||||
= link_to promote_project_label_path(label.project, label), title: "Promote to Group Label", class: 'btn btn-transparent btn-action', data: {confirm: "You are about to promote #{label.title} to a group level. This will make this milestone available to all projects inside #{label.project.group.name}. The existing project label will be merged into the group level. This action cannot be reversed.", toggle: "tooltip"}, method: :post do
|
= link_to promote_project_label_path(label.project, label), title: "Promote to Group Label", class: 'btn btn-transparent btn-action', data: {confirm: "Promoting #{label.title} will make it available for all projects inside #{label.project.group.name}. Existing project labels with the same name will be merged. This action cannot be reversed.", toggle: "tooltip"}, method: :post do
|
||||||
%span.sr-only Promote to Group
|
%span.sr-only Promote to Group
|
||||||
= sprite_icon('level-up')
|
= sprite_icon('level-up')
|
||||||
- if can?(current_user, :admin_label, label)
|
- if can?(current_user, :admin_label, label)
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
\
|
\
|
||||||
|
|
||||||
- if @project.group
|
- if @project.group
|
||||||
= link_to promote_project_milestone_path(milestone.project, milestone), title: "Promote to Group Milestone", class: 'btn btn-xs btn-grouped', data: { confirm: "You are about to promote #{milestone.title} to a group level. This will make this milestone available to all projects inside #{@project.group.name}. The existing project milestone will be merged into the group level. This action cannot be reversed.", toggle: "tooltip" }, method: :post do
|
= link_to promote_project_milestone_path(milestone.project, milestone), title: "Promote to Group Milestone", class: 'btn btn-xs btn-grouped', data: { confirm: "Promoting #{milestone.title} will make it available for all projects inside #{@project.group.name}. Existing project milestones with the same name will be merged. This action cannot be reversed.", toggle: "tooltip" }, method: :post do
|
||||||
Promote
|
Promote
|
||||||
|
|
||||||
= link_to 'Close Milestone', project_milestone_path(@project, milestone, milestone: {state_event: :close }), method: :put, remote: true, class: "btn btn-xs btn-close btn-grouped"
|
= link_to 'Close Milestone', project_milestone_path(@project, milestone, milestone: {state_event: :close }), method: :put, remote: true, class: "btn btn-xs btn-close btn-grouped"
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
---
|
|
||||||
title: Sanitize extra blank spaces used when uploading a SSH key
|
|
||||||
merge_request: 40552
|
|
||||||
author:
|
|
||||||
type: fixed
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Create empty wiki when import from GitLab and wiki is not there
|
||||||
|
merge_request:
|
||||||
|
author:
|
||||||
|
type: fixed
|
5
changelogs/unreleased/group-label-page-breadcrumb.yml
Normal file
5
changelogs/unreleased/group-label-page-breadcrumb.yml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Fix breadcrumb on labels page for groups
|
||||||
|
merge_request: 17045
|
||||||
|
author: Onuwa Nnachi Isaac
|
||||||
|
type: fixed
|
5
changelogs/unreleased/jivl-update-katex.yml
Normal file
5
changelogs/unreleased/jivl-update-katex.yml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Updated the katex library
|
||||||
|
merge_request: 15864
|
||||||
|
author:
|
||||||
|
type: other
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Move IssuableTimeTracker vue component
|
||||||
|
merge_request: 16948
|
||||||
|
author: George Tsiolis
|
||||||
|
type: performance
|
|
@ -11,6 +11,7 @@ module Gitlab
|
||||||
require_dependency Rails.root.join('lib/gitlab/redis/queues')
|
require_dependency Rails.root.join('lib/gitlab/redis/queues')
|
||||||
require_dependency Rails.root.join('lib/gitlab/redis/shared_state')
|
require_dependency Rails.root.join('lib/gitlab/redis/shared_state')
|
||||||
require_dependency Rails.root.join('lib/gitlab/request_context')
|
require_dependency Rails.root.join('lib/gitlab/request_context')
|
||||||
|
require_dependency Rails.root.join('lib/gitlab/current_settings')
|
||||||
|
|
||||||
# Settings in config/environments/* take precedence over those specified here.
|
# Settings in config/environments/* take precedence over those specified here.
|
||||||
# Application configuration should go into files in config/initializers
|
# Application configuration should go into files in config/initializers
|
||||||
|
@ -107,8 +108,6 @@ module Gitlab
|
||||||
config.assets.precompile << "print.css"
|
config.assets.precompile << "print.css"
|
||||||
config.assets.precompile << "notify.css"
|
config.assets.precompile << "notify.css"
|
||||||
config.assets.precompile << "mailers/*.css"
|
config.assets.precompile << "mailers/*.css"
|
||||||
config.assets.precompile << "katex.css"
|
|
||||||
config.assets.precompile << "katex.js"
|
|
||||||
config.assets.precompile << "xterm/xterm.css"
|
config.assets.precompile << "xterm/xterm.css"
|
||||||
config.assets.precompile << "performance_bar.css"
|
config.assets.precompile << "performance_bar.css"
|
||||||
config.assets.precompile << "lib/ace.js"
|
config.assets.precompile << "lib/ace.js"
|
||||||
|
|
|
@ -153,6 +153,27 @@ var config = {
|
||||||
name: '[name].[hash].[ext]',
|
name: '[name].[hash].[ext]',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
test: /katex.css$/,
|
||||||
|
include: /node_modules\/katex\/dist/,
|
||||||
|
use: [
|
||||||
|
{ loader: 'style-loader' },
|
||||||
|
{
|
||||||
|
loader: 'css-loader',
|
||||||
|
options: {
|
||||||
|
name: '[name].[hash].[ext]'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.(eot|ttf|woff|woff2)$/,
|
||||||
|
include: /node_modules\/katex\/dist\/fonts/,
|
||||||
|
loader: 'file-loader',
|
||||||
|
options: {
|
||||||
|
name: '[name].[hash].[ext]',
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
test: /monaco-editor\/\w+\/vs\/loader\.js$/,
|
test: /monaco-editor\/\w+\/vs\/loader\.js$/,
|
||||||
use: [
|
use: [
|
||||||
|
|
|
@ -13,8 +13,6 @@ module Gitlab
|
||||||
gon.relative_url_root = Gitlab.config.gitlab.relative_url_root
|
gon.relative_url_root = Gitlab.config.gitlab.relative_url_root
|
||||||
gon.shortcuts_path = help_page_path('shortcuts')
|
gon.shortcuts_path = help_page_path('shortcuts')
|
||||||
gon.user_color_scheme = Gitlab::ColorSchemes.for_user(current_user).css_class
|
gon.user_color_scheme = Gitlab::ColorSchemes.for_user(current_user).css_class
|
||||||
gon.katex_css_url = ActionController::Base.helpers.asset_path('katex.css')
|
|
||||||
gon.katex_js_url = ActionController::Base.helpers.asset_path('katex.js')
|
|
||||||
gon.sentry_dsn = Gitlab::CurrentSettings.clientside_sentry_dsn if Gitlab::CurrentSettings.clientside_sentry_enabled
|
gon.sentry_dsn = Gitlab::CurrentSettings.clientside_sentry_dsn if Gitlab::CurrentSettings.clientside_sentry_enabled
|
||||||
gon.gitlab_url = Gitlab.config.gitlab.url
|
gon.gitlab_url = Gitlab.config.gitlab.url
|
||||||
gon.revision = Gitlab::REVISION
|
gon.revision = Gitlab::REVISION
|
||||||
|
|
|
@ -50,9 +50,10 @@ module Gitlab
|
||||||
end
|
end
|
||||||
|
|
||||||
def wiki_restorer
|
def wiki_restorer
|
||||||
Gitlab::ImportExport::RepoRestorer.new(path_to_bundle: wiki_repo_path,
|
Gitlab::ImportExport::WikiRestorer.new(path_to_bundle: wiki_repo_path,
|
||||||
shared: @shared,
|
shared: @shared,
|
||||||
project: ProjectWiki.new(project_tree.restored_project))
|
project: ProjectWiki.new(project_tree.restored_project),
|
||||||
|
wiki_enabled: @project.wiki_enabled?)
|
||||||
end
|
end
|
||||||
|
|
||||||
def uploads_restorer
|
def uploads_restorer
|
||||||
|
|
23
lib/gitlab/import_export/wiki_restorer.rb
Normal file
23
lib/gitlab/import_export/wiki_restorer.rb
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
module Gitlab
|
||||||
|
module ImportExport
|
||||||
|
class WikiRestorer < RepoRestorer
|
||||||
|
def initialize(project:, shared:, path_to_bundle:, wiki_enabled:)
|
||||||
|
super(project: project, shared: shared, path_to_bundle: path_to_bundle)
|
||||||
|
|
||||||
|
@wiki_enabled = wiki_enabled
|
||||||
|
end
|
||||||
|
|
||||||
|
def restore
|
||||||
|
@project.wiki if create_empty_wiki?
|
||||||
|
|
||||||
|
super
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def create_empty_wiki?
|
||||||
|
!File.exist?(@path_to_bundle) && @wiki_enabled
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -42,7 +42,7 @@ module Gitlab
|
||||||
|
|
||||||
key, value = parsed_field.first
|
key, value = parsed_field.first
|
||||||
if value.nil?
|
if value.nil?
|
||||||
value = open_file(tmp_path)
|
value = open_file(tmp_path, @request.params["#{key}.name"])
|
||||||
@open_files << value
|
@open_files << value
|
||||||
else
|
else
|
||||||
value = decorate_params_value(value, @request.params[key], tmp_path)
|
value = decorate_params_value(value, @request.params[key], tmp_path)
|
||||||
|
@ -70,7 +70,7 @@ module Gitlab
|
||||||
|
|
||||||
case path_value
|
case path_value
|
||||||
when nil
|
when nil
|
||||||
value_hash[path_key] = open_file(tmp_path)
|
value_hash[path_key] = open_file(tmp_path, value_hash.dig(path_key, '.name'))
|
||||||
@open_files << value_hash[path_key]
|
@open_files << value_hash[path_key]
|
||||||
value_hash
|
value_hash
|
||||||
when Hash
|
when Hash
|
||||||
|
@ -81,8 +81,8 @@ module Gitlab
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def open_file(path)
|
def open_file(path, name)
|
||||||
::UploadedFile.new(path, File.basename(path), 'application/octet-stream')
|
::UploadedFile.new(path, name || File.basename(path), 'application/octet-stream')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ module Gitlab
|
||||||
# This ensures we don't produce any errors that users can't do anything
|
# This ensures we don't produce any errors that users can't do anything
|
||||||
# about themselves.
|
# about themselves.
|
||||||
def self.enable?
|
def self.enable?
|
||||||
Gitlab.com? || Rails.env.development? || Rails.env.test?
|
Rails.env.development? || Rails.env.test?
|
||||||
end
|
end
|
||||||
|
|
||||||
# Allows the current request to execute any number of SQL queries.
|
# Allows the current request to execute any number of SQL queries.
|
||||||
|
|
|
@ -21,22 +21,6 @@ module Gitlab
|
||||||
technology(name)&.supported_sizes
|
technology(name)&.supported_sizes
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.sanitize(key_content)
|
|
||||||
ssh_type, *parts = key_content.strip.split
|
|
||||||
|
|
||||||
return key_content if parts.empty?
|
|
||||||
|
|
||||||
parts.each_with_object("#{ssh_type} ").with_index do |(part, content), index|
|
|
||||||
content << part
|
|
||||||
|
|
||||||
if Gitlab::SSHPublicKey.new(content).valid?
|
|
||||||
break [content, parts[index + 1]].compact.join(' ') # Add the comment part if present
|
|
||||||
elsif parts.size == index + 1 # return original content if we've reached the last element
|
|
||||||
break key_content
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
attr_reader :key_text, :key
|
attr_reader :key_text, :key
|
||||||
|
|
||||||
# Unqualified MD5 fingerprint for compatibility
|
# Unqualified MD5 fingerprint for compatibility
|
||||||
|
@ -53,23 +37,23 @@ module Gitlab
|
||||||
end
|
end
|
||||||
|
|
||||||
def valid?
|
def valid?
|
||||||
key.present? && bits && technology.supported_sizes.include?(bits)
|
key.present?
|
||||||
end
|
end
|
||||||
|
|
||||||
def type
|
def type
|
||||||
technology.name if key.present?
|
technology.name if valid?
|
||||||
end
|
end
|
||||||
|
|
||||||
def bits
|
def bits
|
||||||
return if key.blank?
|
return unless valid?
|
||||||
|
|
||||||
case type
|
case type
|
||||||
when :rsa
|
when :rsa
|
||||||
key.n&.num_bits
|
key.n.num_bits
|
||||||
when :dsa
|
when :dsa
|
||||||
key.p&.num_bits
|
key.p.num_bits
|
||||||
when :ecdsa
|
when :ecdsa
|
||||||
key.group.order&.num_bits
|
key.group.order.num_bits
|
||||||
when :ed25519
|
when :ed25519
|
||||||
256
|
256
|
||||||
else
|
else
|
||||||
|
|
|
@ -52,9 +52,11 @@
|
||||||
"jed": "^1.1.1",
|
"jed": "^1.1.1",
|
||||||
"jquery": "^2.2.4",
|
"jquery": "^2.2.4",
|
||||||
"jquery-ujs": "1.2.2",
|
"jquery-ujs": "1.2.2",
|
||||||
|
"jquery.waitforimages": "^2.2.0",
|
||||||
"js-cookie": "^2.1.3",
|
"js-cookie": "^2.1.3",
|
||||||
"jszip": "^3.1.3",
|
"jszip": "^3.1.3",
|
||||||
"jszip-utils": "^0.0.2",
|
"jszip-utils": "^0.0.2",
|
||||||
|
"katex": "^0.8.3",
|
||||||
"marked": "^0.3.12",
|
"marked": "^0.3.12",
|
||||||
"monaco-editor": "0.10.0",
|
"monaco-editor": "0.10.0",
|
||||||
"mousetrap": "^1.4.6",
|
"mousetrap": "^1.4.6",
|
||||||
|
@ -68,6 +70,7 @@
|
||||||
"sanitize-html": "^1.16.1",
|
"sanitize-html": "^1.16.1",
|
||||||
"select2": "3.5.2-browserify",
|
"select2": "3.5.2-browserify",
|
||||||
"sql.js": "^0.4.0",
|
"sql.js": "^0.4.0",
|
||||||
|
"style-loader": "^0.19.1",
|
||||||
"svg4everybody": "2.1.9",
|
"svg4everybody": "2.1.9",
|
||||||
"three": "^0.84.0",
|
"three": "^0.84.0",
|
||||||
"three-orbit-controls": "^82.1.0",
|
"three-orbit-controls": "^82.1.0",
|
||||||
|
|
|
@ -5,10 +5,6 @@ FactoryBot.define do
|
||||||
title
|
title
|
||||||
key { Spec::Support::Helpers::KeyGeneratorHelper.new(1024).generate + ' dummy@gitlab.com' }
|
key { Spec::Support::Helpers::KeyGeneratorHelper.new(1024).generate + ' dummy@gitlab.com' }
|
||||||
|
|
||||||
factory :key_without_comment do
|
|
||||||
key { Spec::Support::Helpers::KeyGeneratorHelper.new(1024).generate }
|
|
||||||
end
|
|
||||||
|
|
||||||
factory :deploy_key, class: 'DeployKey'
|
factory :deploy_key, class: 'DeployKey'
|
||||||
|
|
||||||
factory :personal_key do
|
factory :personal_key do
|
||||||
|
|
|
@ -126,7 +126,7 @@ describe('VariableList', () => {
|
||||||
|
|
||||||
// Check for the correct default in the new row
|
// Check for the correct default in the new row
|
||||||
const $protectedInput = $wrapper.find('.js-row:last-child').find('.js-ci-variable-input-protected');
|
const $protectedInput = $wrapper.find('.js-row:last-child').find('.js-ci-variable-input-protected');
|
||||||
expect($protectedInput.val()).toBe('true');
|
expect($protectedInput.val()).toBe('false');
|
||||||
})
|
})
|
||||||
.then(done)
|
.then(done)
|
||||||
.catch(done.fail);
|
.catch(done.fail);
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
|
import MockAdapter from 'axios-mock-adapter';
|
||||||
|
import axios from '~/lib/utils/axios_utils';
|
||||||
import GpgBadges from '~/gpg_badges';
|
import GpgBadges from '~/gpg_badges';
|
||||||
|
|
||||||
describe('GpgBadges', () => {
|
describe('GpgBadges', () => {
|
||||||
|
let mock;
|
||||||
const dummyCommitSha = 'n0m0rec0ffee';
|
const dummyCommitSha = 'n0m0rec0ffee';
|
||||||
const dummyBadgeHtml = 'dummy html';
|
const dummyBadgeHtml = 'dummy html';
|
||||||
const dummyResponse = {
|
const dummyResponse = {
|
||||||
|
@ -11,38 +14,43 @@ describe('GpgBadges', () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
mock = new MockAdapter(axios);
|
||||||
setFixtures(`
|
setFixtures(`
|
||||||
|
<form
|
||||||
|
class="commits-search-form" data-signatures-path="/hello" action="/hello"
|
||||||
|
method="get">
|
||||||
|
<input name="utf8" type="hidden" value="✓">
|
||||||
|
<input type="search" name="search" id="commits-search"class="form-control search-text-input input-short">
|
||||||
|
</form>
|
||||||
<div class="parent-container">
|
<div class="parent-container">
|
||||||
<div class="js-loading-gpg-badge" data-commit-sha="${dummyCommitSha}"></div>
|
<div class="js-loading-gpg-badge" data-commit-sha="${dummyCommitSha}"></div>
|
||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('displays a loading spinner', () => {
|
afterEach(() => {
|
||||||
spyOn($, 'get').and.returnValue({
|
mock.restore();
|
||||||
done() {
|
|
||||||
// intentionally left blank
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
GpgBadges.fetch();
|
it('displays a loading spinner', (done) => {
|
||||||
|
mock.onGet('/hello').reply(200);
|
||||||
|
|
||||||
|
GpgBadges.fetch().then(() => {
|
||||||
expect(document.querySelector('.js-loading-gpg-badge:empty')).toBe(null);
|
expect(document.querySelector('.js-loading-gpg-badge:empty')).toBe(null);
|
||||||
const spinners = document.querySelectorAll('.js-loading-gpg-badge i.fa.fa-spinner.fa-spin');
|
const spinners = document.querySelectorAll('.js-loading-gpg-badge i.fa.fa-spinner.fa-spin');
|
||||||
expect(spinners.length).toBe(1);
|
expect(spinners.length).toBe(1);
|
||||||
|
done();
|
||||||
|
}).catch(done.fail);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('replaces the loading spinner', () => {
|
it('replaces the loading spinner', (done) => {
|
||||||
spyOn($, 'get').and.returnValue({
|
mock.onGet('/hello').reply(200, dummyResponse);
|
||||||
done(callback) {
|
|
||||||
callback(dummyResponse);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
GpgBadges.fetch();
|
|
||||||
|
|
||||||
|
GpgBadges.fetch().then(() => {
|
||||||
expect(document.querySelector('.js-loading-gpg-badge')).toBe(null);
|
expect(document.querySelector('.js-loading-gpg-badge')).toBe(null);
|
||||||
const parentContainer = document.querySelector('.parent-container');
|
const parentContainer = document.querySelector('.parent-container');
|
||||||
expect(parentContainer.innerHTML.trim()).toEqual(dummyBadgeHtml);
|
expect(parentContainer.innerHTML.trim()).toEqual(dummyBadgeHtml);
|
||||||
|
done();
|
||||||
|
}).catch(done.fail);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
|
|
||||||
import timeTracker from '~/sidebar/components/time_tracking/time_tracker';
|
import timeTracker from '~/sidebar/components/time_tracking/time_tracker.vue';
|
||||||
|
|
||||||
function initTimeTrackingComponent(opts) {
|
function initTimeTrackingComponent(opts) {
|
||||||
setFixtures(`
|
setFixtures(`
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import MarkdownComponent from '~/notebook/cells/markdown.vue';
|
import MarkdownComponent from '~/notebook/cells/markdown.vue';
|
||||||
import katex from 'vendor/katex';
|
import katex from 'katex';
|
||||||
|
|
||||||
const Component = Vue.extend(MarkdownComponent);
|
const Component = Vue.extend(MarkdownComponent);
|
||||||
|
|
||||||
|
|
45
spec/lib/gitlab/import_export/wiki_restorer_spec.rb
Normal file
45
spec/lib/gitlab/import_export/wiki_restorer_spec.rb
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Gitlab::ImportExport::WikiRestorer do
|
||||||
|
describe 'restore a wiki Git repo' do
|
||||||
|
let!(:project_with_wiki) { create(:project, :wiki_repo) }
|
||||||
|
let!(:project_without_wiki) { create(:project) }
|
||||||
|
let!(:project) { create(:project) }
|
||||||
|
let(:export_path) { "#{Dir.tmpdir}/project_tree_saver_spec" }
|
||||||
|
let(:shared) { Gitlab::ImportExport::Shared.new(relative_path: project.full_path) }
|
||||||
|
let(:bundler) { Gitlab::ImportExport::WikiRepoSaver.new(project: project_with_wiki, shared: shared) }
|
||||||
|
let(:bundle_path) { File.join(shared.export_path, Gitlab::ImportExport.project_bundle_filename) }
|
||||||
|
let(:restorer) do
|
||||||
|
described_class.new(path_to_bundle: bundle_path,
|
||||||
|
shared: shared,
|
||||||
|
project: project.wiki,
|
||||||
|
wiki_enabled: true)
|
||||||
|
end
|
||||||
|
|
||||||
|
before do
|
||||||
|
allow(Gitlab::ImportExport).to receive(:storage_path).and_return(export_path)
|
||||||
|
|
||||||
|
bundler.save
|
||||||
|
end
|
||||||
|
|
||||||
|
after do
|
||||||
|
FileUtils.rm_rf(export_path)
|
||||||
|
Gitlab::Shell.new.remove_repository(project_with_wiki.wiki.repository_storage_path, project_with_wiki.wiki.disk_path)
|
||||||
|
Gitlab::Shell.new.remove_repository(project.wiki.repository_storage_path, project.wiki.disk_path)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'restores the wiki repo successfully' do
|
||||||
|
expect(restorer.restore).to be true
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "no wiki in the bundle" do
|
||||||
|
let(:bundler) { Gitlab::ImportExport::WikiRepoSaver.new(project: project_without_wiki, shared: shared) }
|
||||||
|
|
||||||
|
it 'creates an empty wiki' do
|
||||||
|
expect(restorer.restore).to be true
|
||||||
|
|
||||||
|
expect(project.wiki_repository_exists?).to be true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -5,15 +5,17 @@ require 'tempfile'
|
||||||
describe Gitlab::Middleware::Multipart do
|
describe Gitlab::Middleware::Multipart do
|
||||||
let(:app) { double(:app) }
|
let(:app) { double(:app) }
|
||||||
let(:middleware) { described_class.new(app) }
|
let(:middleware) { described_class.new(app) }
|
||||||
|
let(:original_filename) { 'filename' }
|
||||||
|
|
||||||
it 'opens top-level files' do
|
it 'opens top-level files' do
|
||||||
Tempfile.open('top-level') do |tempfile|
|
Tempfile.open('top-level') do |tempfile|
|
||||||
env = post_env({ 'file' => tempfile.path }, { 'file.name' => 'filename' }, Gitlab::Workhorse.secret, 'gitlab-workhorse')
|
env = post_env({ 'file' => tempfile.path }, { 'file.name' => original_filename }, Gitlab::Workhorse.secret, 'gitlab-workhorse')
|
||||||
|
|
||||||
expect(app).to receive(:call) do |env|
|
expect(app).to receive(:call) do |env|
|
||||||
file = Rack::Request.new(env).params['file']
|
file = Rack::Request.new(env).params['file']
|
||||||
expect(file).to be_a(::UploadedFile)
|
expect(file).to be_a(::UploadedFile)
|
||||||
expect(file.path).to eq(tempfile.path)
|
expect(file.path).to eq(tempfile.path)
|
||||||
|
expect(file.original_filename).to eq(original_filename)
|
||||||
end
|
end
|
||||||
|
|
||||||
middleware.call(env)
|
middleware.call(env)
|
||||||
|
@ -34,13 +36,14 @@ describe Gitlab::Middleware::Multipart do
|
||||||
|
|
||||||
it 'opens files one level deep' do
|
it 'opens files one level deep' do
|
||||||
Tempfile.open('one-level') do |tempfile|
|
Tempfile.open('one-level') do |tempfile|
|
||||||
in_params = { 'user' => { 'avatar' => { '.name' => 'filename' } } }
|
in_params = { 'user' => { 'avatar' => { '.name' => original_filename } } }
|
||||||
env = post_env({ 'user[avatar]' => tempfile.path }, in_params, Gitlab::Workhorse.secret, 'gitlab-workhorse')
|
env = post_env({ 'user[avatar]' => tempfile.path }, in_params, Gitlab::Workhorse.secret, 'gitlab-workhorse')
|
||||||
|
|
||||||
expect(app).to receive(:call) do |env|
|
expect(app).to receive(:call) do |env|
|
||||||
file = Rack::Request.new(env).params['user']['avatar']
|
file = Rack::Request.new(env).params['user']['avatar']
|
||||||
expect(file).to be_a(::UploadedFile)
|
expect(file).to be_a(::UploadedFile)
|
||||||
expect(file.path).to eq(tempfile.path)
|
expect(file.path).to eq(tempfile.path)
|
||||||
|
expect(file.original_filename).to eq(original_filename)
|
||||||
end
|
end
|
||||||
|
|
||||||
middleware.call(env)
|
middleware.call(env)
|
||||||
|
@ -49,13 +52,14 @@ describe Gitlab::Middleware::Multipart do
|
||||||
|
|
||||||
it 'opens files two levels deep' do
|
it 'opens files two levels deep' do
|
||||||
Tempfile.open('two-levels') do |tempfile|
|
Tempfile.open('two-levels') do |tempfile|
|
||||||
in_params = { 'project' => { 'milestone' => { 'themesong' => { '.name' => 'filename' } } } }
|
in_params = { 'project' => { 'milestone' => { 'themesong' => { '.name' => original_filename } } } }
|
||||||
env = post_env({ 'project[milestone][themesong]' => tempfile.path }, in_params, Gitlab::Workhorse.secret, 'gitlab-workhorse')
|
env = post_env({ 'project[milestone][themesong]' => tempfile.path }, in_params, Gitlab::Workhorse.secret, 'gitlab-workhorse')
|
||||||
|
|
||||||
expect(app).to receive(:call) do |env|
|
expect(app).to receive(:call) do |env|
|
||||||
file = Rack::Request.new(env).params['project']['milestone']['themesong']
|
file = Rack::Request.new(env).params['project']['milestone']['themesong']
|
||||||
expect(file).to be_a(::UploadedFile)
|
expect(file).to be_a(::UploadedFile)
|
||||||
expect(file.path).to eq(tempfile.path)
|
expect(file.path).to eq(tempfile.path)
|
||||||
|
expect(file.original_filename).to eq(original_filename)
|
||||||
end
|
end
|
||||||
|
|
||||||
middleware.call(env)
|
middleware.call(env)
|
||||||
|
|
|
@ -12,14 +12,16 @@ describe Gitlab::QueryLimiting do
|
||||||
expect(described_class.enable?).to eq(true)
|
expect(described_class.enable?).to eq(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns true on GitLab.com' do
|
it 'returns false on GitLab.com' do
|
||||||
|
expect(Rails.env).to receive(:development?).and_return(false)
|
||||||
|
expect(Rails.env).to receive(:test?).and_return(false)
|
||||||
allow(Gitlab).to receive(:com?).and_return(true)
|
allow(Gitlab).to receive(:com?).and_return(true)
|
||||||
|
|
||||||
expect(described_class.enable?).to eq(true)
|
expect(described_class.enable?).to eq(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns true in a non GitLab.com' do
|
it 'returns false in a non GitLab.com' do
|
||||||
expect(Gitlab).to receive(:com?).and_return(false)
|
allow(Gitlab).to receive(:com?).and_return(false)
|
||||||
expect(Rails.env).to receive(:development?).and_return(false)
|
expect(Rails.env).to receive(:development?).and_return(false)
|
||||||
expect(Rails.env).to receive(:test?).and_return(false)
|
expect(Rails.env).to receive(:test?).and_return(false)
|
||||||
|
|
||||||
|
|
|
@ -37,41 +37,6 @@ describe Gitlab::SSHPublicKey, lib: true do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '.sanitize(key_content)' do
|
|
||||||
let(:content) { build(:key).key }
|
|
||||||
|
|
||||||
context 'when key has blank space characters' do
|
|
||||||
it 'removes the extra blank space characters' do
|
|
||||||
unsanitized = content.insert(100, "\n")
|
|
||||||
.insert(40, "\r\n")
|
|
||||||
.insert(30, ' ')
|
|
||||||
|
|
||||||
sanitized = described_class.sanitize(unsanitized)
|
|
||||||
_, body = sanitized.split
|
|
||||||
|
|
||||||
expect(sanitized).not_to eq(unsanitized)
|
|
||||||
expect(body).not_to match(/\s/)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context "when key doesn't have blank space characters" do
|
|
||||||
it "doesn't modify the content" do
|
|
||||||
sanitized = described_class.sanitize(content)
|
|
||||||
|
|
||||||
expect(sanitized).to eq(content)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context "when key is invalid" do
|
|
||||||
it 'returns the original content' do
|
|
||||||
unsanitized = "ssh-foo any content=="
|
|
||||||
sanitized = described_class.sanitize(unsanitized)
|
|
||||||
|
|
||||||
expect(sanitized).to eq(unsanitized)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '#valid?' do
|
describe '#valid?' do
|
||||||
subject { public_key }
|
subject { public_key }
|
||||||
|
|
||||||
|
|
|
@ -1413,7 +1413,7 @@ describe Ci::Build do
|
||||||
[
|
[
|
||||||
{ key: 'CI', value: 'true', public: true },
|
{ key: 'CI', value: 'true', public: true },
|
||||||
{ key: 'GITLAB_CI', value: 'true', public: true },
|
{ key: 'GITLAB_CI', value: 'true', public: true },
|
||||||
{ key: 'GITLAB_FEATURES', value: '', public: true },
|
{ key: 'GITLAB_FEATURES', value: project.namespace.features.join(','), public: true },
|
||||||
{ key: 'CI_SERVER_NAME', value: 'GitLab', public: true },
|
{ key: 'CI_SERVER_NAME', value: 'GitLab', public: true },
|
||||||
{ key: 'CI_SERVER_VERSION', value: Gitlab::VERSION, public: true },
|
{ key: 'CI_SERVER_VERSION', value: Gitlab::VERSION, public: true },
|
||||||
{ key: 'CI_SERVER_REVISION', value: Gitlab::REVISION, public: true },
|
{ key: 'CI_SERVER_REVISION', value: Gitlab::REVISION, public: true },
|
||||||
|
|
|
@ -72,53 +72,16 @@ describe Key, :mailer do
|
||||||
expect(build(:key)).to be_valid
|
expect(build(:key)).to be_valid
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'accepts a key with newline charecters after stripping them' do
|
||||||
|
key = build(:key)
|
||||||
|
key.key = key.key.insert(100, "\n")
|
||||||
|
key.key = key.key.insert(40, "\r\n")
|
||||||
|
expect(key).to be_valid
|
||||||
|
end
|
||||||
|
|
||||||
it 'rejects the unfingerprintable key (not a key)' do
|
it 'rejects the unfingerprintable key (not a key)' do
|
||||||
expect(build(:key, key: 'ssh-rsa an-invalid-key==')).not_to be_valid
|
expect(build(:key, key: 'ssh-rsa an-invalid-key==')).not_to be_valid
|
||||||
end
|
end
|
||||||
|
|
||||||
where(:factory, :chars, :expected_sections) do
|
|
||||||
[
|
|
||||||
[:key, ["\n", "\r\n"], 3],
|
|
||||||
[:key, [' ', ' '], 3],
|
|
||||||
[:key_without_comment, [' ', ' '], 2]
|
|
||||||
]
|
|
||||||
end
|
|
||||||
|
|
||||||
with_them do
|
|
||||||
let!(:key) { create(factory) }
|
|
||||||
let!(:original_fingerprint) { key.fingerprint }
|
|
||||||
|
|
||||||
it 'accepts a key with blank space characters after stripping them' do
|
|
||||||
modified_key = key.key.insert(100, chars.first).insert(40, chars.last)
|
|
||||||
_, content = modified_key.split
|
|
||||||
|
|
||||||
key.update!(key: modified_key)
|
|
||||||
|
|
||||||
expect(key).to be_valid
|
|
||||||
expect(key.key.split.size).to eq(expected_sections)
|
|
||||||
|
|
||||||
expect(content).not_to match(/\s/)
|
|
||||||
expect(original_fingerprint).to eq(key.fingerprint)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'validate size' do
|
|
||||||
where(:key_content, :result) do
|
|
||||||
[
|
|
||||||
[Spec::Support::Helpers::KeyGeneratorHelper.new(512).generate, false],
|
|
||||||
[Spec::Support::Helpers::KeyGeneratorHelper.new(8192).generate, false],
|
|
||||||
[Spec::Support::Helpers::KeyGeneratorHelper.new(1024).generate, true]
|
|
||||||
]
|
|
||||||
end
|
|
||||||
|
|
||||||
with_them do
|
|
||||||
it 'validates the size of the key' do
|
|
||||||
key = build(:key, key: key_content)
|
|
||||||
|
|
||||||
expect(key.valid?).to eq(result)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'validate it meets key restrictions' do
|
context 'validate it meets key restrictions' do
|
||||||
|
|
|
@ -41,13 +41,13 @@ shared_examples 'variable list' do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'adds new unprotected variable' do
|
it 'adds new protected variable' do
|
||||||
page.within('.js-ci-variable-list-section .js-row:last-child') do
|
page.within('.js-ci-variable-list-section .js-row:last-child') do
|
||||||
find('.js-ci-variable-input-key').set('key')
|
find('.js-ci-variable-input-key').set('key')
|
||||||
find('.js-ci-variable-input-value').set('key value')
|
find('.js-ci-variable-input-value').set('key value')
|
||||||
find('.ci-variable-protected-item .js-project-feature-toggle').click
|
find('.ci-variable-protected-item .js-project-feature-toggle').click
|
||||||
|
|
||||||
expect(find('.js-ci-variable-input-protected', visible: false).value).to eq('false')
|
expect(find('.js-ci-variable-input-protected', visible: false).value).to eq('true')
|
||||||
end
|
end
|
||||||
|
|
||||||
click_button('Save variables')
|
click_button('Save variables')
|
||||||
|
@ -59,7 +59,7 @@ shared_examples 'variable list' do
|
||||||
page.within('.js-ci-variable-list-section .js-row:nth-child(1)') do
|
page.within('.js-ci-variable-list-section .js-row:nth-child(1)') do
|
||||||
expect(find('.js-ci-variable-input-key').value).to eq('key')
|
expect(find('.js-ci-variable-input-key').value).to eq('key')
|
||||||
expect(find('.js-ci-variable-input-value', visible: false).value).to eq('key value')
|
expect(find('.js-ci-variable-input-value', visible: false).value).to eq('key value')
|
||||||
expect(find('.js-ci-variable-input-protected', visible: false).value).to eq('false')
|
expect(find('.js-ci-variable-input-protected', visible: false).value).to eq('true')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -143,7 +143,6 @@ shared_examples 'variable list' do
|
||||||
page.within('.js-ci-variable-list-section .js-row:last-child') do
|
page.within('.js-ci-variable-list-section .js-row:last-child') do
|
||||||
find('.js-ci-variable-input-key').set('unprotected_key')
|
find('.js-ci-variable-input-key').set('unprotected_key')
|
||||||
find('.js-ci-variable-input-value').set('unprotected_value')
|
find('.js-ci-variable-input-value').set('unprotected_value')
|
||||||
find('.ci-variable-protected-item .js-project-feature-toggle').click
|
|
||||||
|
|
||||||
expect(find('.js-ci-variable-input-protected', visible: false).value).to eq('false')
|
expect(find('.js-ci-variable-input-protected', visible: false).value).to eq('false')
|
||||||
end
|
end
|
||||||
|
@ -178,6 +177,7 @@ shared_examples 'variable list' do
|
||||||
page.within('.js-ci-variable-list-section .js-row:last-child') do
|
page.within('.js-ci-variable-list-section .js-row:last-child') do
|
||||||
find('.js-ci-variable-input-key').set('protected_key')
|
find('.js-ci-variable-input-key').set('protected_key')
|
||||||
find('.js-ci-variable-input-value').set('protected_value')
|
find('.js-ci-variable-input-value').set('protected_value')
|
||||||
|
find('.ci-variable-protected-item .js-project-feature-toggle').click
|
||||||
|
|
||||||
expect(find('.js-ci-variable-input-protected', visible: false).value).to eq('true')
|
expect(find('.js-ci-variable-input-protected', visible: false).value).to eq('true')
|
||||||
end
|
end
|
||||||
|
|
BIN
vendor/assets/fonts/KaTeX_AMS-Regular.eot
vendored
BIN
vendor/assets/fonts/KaTeX_AMS-Regular.eot
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_AMS-Regular.ttf
vendored
BIN
vendor/assets/fonts/KaTeX_AMS-Regular.ttf
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_AMS-Regular.woff
vendored
BIN
vendor/assets/fonts/KaTeX_AMS-Regular.woff
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_AMS-Regular.woff2
vendored
BIN
vendor/assets/fonts/KaTeX_AMS-Regular.woff2
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_Caligraphic-Bold.eot
vendored
BIN
vendor/assets/fonts/KaTeX_Caligraphic-Bold.eot
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_Caligraphic-Bold.ttf
vendored
BIN
vendor/assets/fonts/KaTeX_Caligraphic-Bold.ttf
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_Caligraphic-Bold.woff
vendored
BIN
vendor/assets/fonts/KaTeX_Caligraphic-Bold.woff
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_Caligraphic-Bold.woff2
vendored
BIN
vendor/assets/fonts/KaTeX_Caligraphic-Bold.woff2
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_Caligraphic-Regular.eot
vendored
BIN
vendor/assets/fonts/KaTeX_Caligraphic-Regular.eot
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_Caligraphic-Regular.ttf
vendored
BIN
vendor/assets/fonts/KaTeX_Caligraphic-Regular.ttf
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_Caligraphic-Regular.woff
vendored
BIN
vendor/assets/fonts/KaTeX_Caligraphic-Regular.woff
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_Caligraphic-Regular.woff2
vendored
BIN
vendor/assets/fonts/KaTeX_Caligraphic-Regular.woff2
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_Fraktur-Bold.eot
vendored
BIN
vendor/assets/fonts/KaTeX_Fraktur-Bold.eot
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_Fraktur-Bold.ttf
vendored
BIN
vendor/assets/fonts/KaTeX_Fraktur-Bold.ttf
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_Fraktur-Bold.woff
vendored
BIN
vendor/assets/fonts/KaTeX_Fraktur-Bold.woff
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_Fraktur-Bold.woff2
vendored
BIN
vendor/assets/fonts/KaTeX_Fraktur-Bold.woff2
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_Fraktur-Regular.eot
vendored
BIN
vendor/assets/fonts/KaTeX_Fraktur-Regular.eot
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_Fraktur-Regular.ttf
vendored
BIN
vendor/assets/fonts/KaTeX_Fraktur-Regular.ttf
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_Fraktur-Regular.woff
vendored
BIN
vendor/assets/fonts/KaTeX_Fraktur-Regular.woff
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_Fraktur-Regular.woff2
vendored
BIN
vendor/assets/fonts/KaTeX_Fraktur-Regular.woff2
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_Main-Bold.eot
vendored
BIN
vendor/assets/fonts/KaTeX_Main-Bold.eot
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_Main-Bold.ttf
vendored
BIN
vendor/assets/fonts/KaTeX_Main-Bold.ttf
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_Main-Bold.woff
vendored
BIN
vendor/assets/fonts/KaTeX_Main-Bold.woff
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_Main-Bold.woff2
vendored
BIN
vendor/assets/fonts/KaTeX_Main-Bold.woff2
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_Main-Italic.eot
vendored
BIN
vendor/assets/fonts/KaTeX_Main-Italic.eot
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_Main-Italic.ttf
vendored
BIN
vendor/assets/fonts/KaTeX_Main-Italic.ttf
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_Main-Italic.woff
vendored
BIN
vendor/assets/fonts/KaTeX_Main-Italic.woff
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_Main-Italic.woff2
vendored
BIN
vendor/assets/fonts/KaTeX_Main-Italic.woff2
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_Main-Regular.eot
vendored
BIN
vendor/assets/fonts/KaTeX_Main-Regular.eot
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_Main-Regular.ttf
vendored
BIN
vendor/assets/fonts/KaTeX_Main-Regular.ttf
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_Main-Regular.woff
vendored
BIN
vendor/assets/fonts/KaTeX_Main-Regular.woff
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_Main-Regular.woff2
vendored
BIN
vendor/assets/fonts/KaTeX_Main-Regular.woff2
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_Math-BoldItalic.eot
vendored
BIN
vendor/assets/fonts/KaTeX_Math-BoldItalic.eot
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_Math-BoldItalic.ttf
vendored
BIN
vendor/assets/fonts/KaTeX_Math-BoldItalic.ttf
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_Math-BoldItalic.woff
vendored
BIN
vendor/assets/fonts/KaTeX_Math-BoldItalic.woff
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_Math-BoldItalic.woff2
vendored
BIN
vendor/assets/fonts/KaTeX_Math-BoldItalic.woff2
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_Math-Italic.eot
vendored
BIN
vendor/assets/fonts/KaTeX_Math-Italic.eot
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_Math-Italic.ttf
vendored
BIN
vendor/assets/fonts/KaTeX_Math-Italic.ttf
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_Math-Italic.woff
vendored
BIN
vendor/assets/fonts/KaTeX_Math-Italic.woff
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_Math-Italic.woff2
vendored
BIN
vendor/assets/fonts/KaTeX_Math-Italic.woff2
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_Math-Regular.eot
vendored
BIN
vendor/assets/fonts/KaTeX_Math-Regular.eot
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_Math-Regular.ttf
vendored
BIN
vendor/assets/fonts/KaTeX_Math-Regular.ttf
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_Math-Regular.woff
vendored
BIN
vendor/assets/fonts/KaTeX_Math-Regular.woff
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_Math-Regular.woff2
vendored
BIN
vendor/assets/fonts/KaTeX_Math-Regular.woff2
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_SansSerif-Bold.eot
vendored
BIN
vendor/assets/fonts/KaTeX_SansSerif-Bold.eot
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_SansSerif-Bold.ttf
vendored
BIN
vendor/assets/fonts/KaTeX_SansSerif-Bold.ttf
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_SansSerif-Bold.woff
vendored
BIN
vendor/assets/fonts/KaTeX_SansSerif-Bold.woff
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_SansSerif-Bold.woff2
vendored
BIN
vendor/assets/fonts/KaTeX_SansSerif-Bold.woff2
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_SansSerif-Italic.eot
vendored
BIN
vendor/assets/fonts/KaTeX_SansSerif-Italic.eot
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_SansSerif-Italic.ttf
vendored
BIN
vendor/assets/fonts/KaTeX_SansSerif-Italic.ttf
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_SansSerif-Italic.woff
vendored
BIN
vendor/assets/fonts/KaTeX_SansSerif-Italic.woff
vendored
Binary file not shown.
BIN
vendor/assets/fonts/KaTeX_SansSerif-Italic.woff2
vendored
BIN
vendor/assets/fonts/KaTeX_SansSerif-Italic.woff2
vendored
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue