Update upstream source from tag 'upstream/10.6.5+dfsg'
Update to upstream version '10.6.5+dfsg'
with Debian dir c26cf4dd8a
This commit is contained in:
commit
e7a9c8bfb9
56 changed files with 51909 additions and 71 deletions
|
@ -75,7 +75,7 @@ stages:
|
||||||
|
|
||||||
.use-mysql: &use-mysql
|
.use-mysql: &use-mysql
|
||||||
services:
|
services:
|
||||||
- mysql:latest
|
- mysql:5.7
|
||||||
- redis:alpine
|
- redis:alpine
|
||||||
|
|
||||||
# Skip all jobs except the ones that begin with 'docs/'.
|
# Skip all jobs except the ones that begin with 'docs/'.
|
||||||
|
|
25
CHANGELOG.md
25
CHANGELOG.md
|
@ -2,6 +2,31 @@
|
||||||
documentation](doc/development/changelog.md) for instructions on adding your own
|
documentation](doc/development/changelog.md) for instructions on adding your own
|
||||||
entry.
|
entry.
|
||||||
|
|
||||||
|
## 10.6.5 (2018-04-24)
|
||||||
|
|
||||||
|
### Security (1 change)
|
||||||
|
|
||||||
|
- Sanitizes user name to avoid XSS attacks.
|
||||||
|
|
||||||
|
|
||||||
|
## 10.6.4 (2018-04-09)
|
||||||
|
|
||||||
|
### Fixed (8 changes, 1 of them is from the community)
|
||||||
|
|
||||||
|
- Correct copy text for the promote milestone and label modals. !17726
|
||||||
|
- Avoid validation errors when running the Pages domain verification service. !17992
|
||||||
|
- Fix autolinking URLs containing ampersands. !18045
|
||||||
|
- Fix exceptions raised when migrating pipeline stages in the background. !18076
|
||||||
|
- Work around Prometheus Helm chart name changes to fix integration. !18206 (joshlambert)
|
||||||
|
- Don't show Jump to Discussion button on Issues.
|
||||||
|
- Fix listing commit branch/tags that contain special characters.
|
||||||
|
- Fix 404 in group boards when moving issue between lists.
|
||||||
|
|
||||||
|
### Performance (1 change)
|
||||||
|
|
||||||
|
- Free open file descriptors and libgit2 buffers in UpdatePagesService.
|
||||||
|
|
||||||
|
|
||||||
## 10.6.3 (2018-04-03)
|
## 10.6.3 (2018-04-03)
|
||||||
|
|
||||||
### Security (2 changes)
|
### Security (2 changes)
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
10.6.3
|
10.6.5
|
||||||
|
|
|
@ -19,7 +19,7 @@ export default class BoardService {
|
||||||
}
|
}
|
||||||
|
|
||||||
static generateIssuePath(boardId, id) {
|
static generateIssuePath(boardId, id) {
|
||||||
return `${gon.relative_url_root}/-/boards/${boardId ? `/${boardId}` : ''}/issues${id ? `/${id}` : ''}`;
|
return `${gon.relative_url_root}/-/boards/${boardId ? `${boardId}` : ''}/issues${id ? `/${id}` : ''}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
all() {
|
all() {
|
||||||
|
|
|
@ -292,10 +292,12 @@ Please check your network connection and try again.`;
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
v-if="note.resolvable"
|
||||||
class="btn-group discussion-actions"
|
class="btn-group discussion-actions"
|
||||||
role="group">
|
role="group"
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
v-if="note.resolvable && !discussionResolved"
|
v-if="!discussionResolved"
|
||||||
class="btn-group"
|
class="btn-group"
|
||||||
role="group">
|
role="group">
|
||||||
<a
|
<a
|
||||||
|
|
|
@ -19,15 +19,19 @@
|
||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
groupName: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
title() {
|
title() {
|
||||||
return sprintf(s__('Milestones|Promote %{milestoneTitle} to group milestone?'), { milestoneTitle: this.milestoneTitle });
|
return sprintf(s__('Milestones|Promote %{milestoneTitle} to group milestone?'), { milestoneTitle: this.milestoneTitle });
|
||||||
},
|
},
|
||||||
text() {
|
text() {
|
||||||
return s__(`Milestones|Promoting this milestone will make it available for all projects inside the group.
|
return sprintf(s__(`Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}.
|
||||||
Existing project milestones with the same title will be merged.
|
Existing project milestones with the same title will be merged.
|
||||||
This action cannot be reversed.`);
|
This action cannot be reversed.`), { milestoneTitle: this.milestoneTitle, groupName: this.groupName });
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
|
@ -25,6 +25,7 @@ export default () => {
|
||||||
const modalProps = {
|
const modalProps = {
|
||||||
milestoneTitle: button.dataset.milestoneTitle,
|
milestoneTitle: button.dataset.milestoneTitle,
|
||||||
url: button.dataset.url,
|
url: button.dataset.url,
|
||||||
|
groupName: button.dataset.groupName,
|
||||||
};
|
};
|
||||||
eventHub.$once('promoteMilestoneModal.requestStarted', onRequestStarted);
|
eventHub.$once('promoteMilestoneModal.requestStarted', onRequestStarted);
|
||||||
eventHub.$emit('promoteMilestoneModal.props', modalProps);
|
eventHub.$emit('promoteMilestoneModal.props', modalProps);
|
||||||
|
@ -54,6 +55,7 @@ export default () => {
|
||||||
return {
|
return {
|
||||||
modalProps: {
|
modalProps: {
|
||||||
milestoneTitle: '',
|
milestoneTitle: '',
|
||||||
|
groupName: '',
|
||||||
url: '',
|
url: '',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
<script>
|
<script>
|
||||||
|
import _ from 'underscore';
|
||||||
import axios from '~/lib/utils/axios_utils';
|
import axios from '~/lib/utils/axios_utils';
|
||||||
import createFlash from '~/flash';
|
import createFlash from '~/flash';
|
||||||
import GlModal from '~/vue_shared/components/gl_modal.vue';
|
import GlModal from '~/vue_shared/components/gl_modal.vue';
|
||||||
|
@ -27,19 +28,26 @@
|
||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
groupName: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
text() {
|
text() {
|
||||||
return s__(`Milestones|Promoting this label will make it available for all projects inside the group.
|
return sprintf(s__(`Labels|Promoting %{labelTitle} will make it available for all projects inside %{groupName}.
|
||||||
Existing project labels with the same title will be merged. This action cannot be reversed.`);
|
Existing project labels with the same title will be merged. This action cannot be reversed.`), {
|
||||||
|
labelTitle: this.labelTitle,
|
||||||
|
groupName: this.groupName,
|
||||||
|
});
|
||||||
},
|
},
|
||||||
title() {
|
title() {
|
||||||
const label = `<span
|
const label = `<span
|
||||||
class="label color-label"
|
class="label color-label"
|
||||||
style="background-color: ${this.labelColor}; color: ${this.labelTextColor};"
|
style="background-color: ${this.labelColor}; color: ${this.labelTextColor};"
|
||||||
>${this.labelTitle}</span>`;
|
>${_.escape(this.labelTitle)}</span>`;
|
||||||
|
|
||||||
return sprintf(s__('Labels|Promote label %{labelTitle} to Group Label?'), {
|
return sprintf(s__('Labels|<span>Promote label</span> %{labelTitle} <span>to Group Label?</span>'), {
|
||||||
labelTitle: label,
|
labelTitle: label,
|
||||||
}, false);
|
}, false);
|
||||||
},
|
},
|
||||||
|
@ -69,6 +77,7 @@
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
slot="title"
|
slot="title"
|
||||||
|
class="modal-title-with-label"
|
||||||
v-html="title"
|
v-html="title"
|
||||||
>
|
>
|
||||||
{{ title }}
|
{{ title }}
|
||||||
|
|
|
@ -30,6 +30,7 @@ const initLabelIndex = () => {
|
||||||
labelColor: button.dataset.labelColor,
|
labelColor: button.dataset.labelColor,
|
||||||
labelTextColor: button.dataset.labelTextColor,
|
labelTextColor: button.dataset.labelTextColor,
|
||||||
url: button.dataset.url,
|
url: button.dataset.url,
|
||||||
|
groupName: button.dataset.groupName,
|
||||||
};
|
};
|
||||||
eventHub.$once('promoteLabelModal.requestStarted', onRequestStarted);
|
eventHub.$once('promoteLabelModal.requestStarted', onRequestStarted);
|
||||||
eventHub.$emit('promoteLabelModal.props', modalProps);
|
eventHub.$emit('promoteLabelModal.props', modalProps);
|
||||||
|
@ -62,6 +63,7 @@ const initLabelIndex = () => {
|
||||||
labelColor: '',
|
labelColor: '',
|
||||||
labelTextColor: '',
|
labelTextColor: '',
|
||||||
url: '',
|
url: '',
|
||||||
|
groupName: '',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import _ from 'underscore';
|
||||||
|
|
||||||
function isValidProjectId(id) {
|
function isValidProjectId(id) {
|
||||||
return id > 0;
|
return id > 0;
|
||||||
}
|
}
|
||||||
|
@ -41,7 +43,7 @@ class SidebarMoveIssue {
|
||||||
renderRow: project => `
|
renderRow: project => `
|
||||||
<li>
|
<li>
|
||||||
<a href="#" class="js-move-issue-dropdown-item">
|
<a href="#" class="js-move-issue-dropdown-item">
|
||||||
${project.name_with_namespace}
|
${_.escape(project.name_with_namespace)}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
`,
|
`,
|
||||||
|
|
|
@ -4,9 +4,15 @@
|
||||||
|
|
||||||
.page-title,
|
.page-title,
|
||||||
.modal-title {
|
.modal-title {
|
||||||
|
.modal-title-with-label span {
|
||||||
|
vertical-align: middle;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
.color-label {
|
.color-label {
|
||||||
font-size: $gl-font-size;
|
font-size: $gl-font-size;
|
||||||
padding: $gl-vert-padding $label-padding-modal;
|
padding: $gl-vert-padding $label-padding-modal;
|
||||||
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -112,7 +112,7 @@ class Projects::LabelsController < Projects::ApplicationController
|
||||||
begin
|
begin
|
||||||
return render_404 unless promote_service.execute(@label)
|
return render_404 unless promote_service.execute(@label)
|
||||||
|
|
||||||
flash[:notice] = "#{@label.title} promoted to group label."
|
flash[:notice] = "#{@label.title} promoted to <a href=\"#{group_labels_path(@project.group)}\">group label</a>.".html_safe
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html do
|
format.html do
|
||||||
redirect_to(project_labels_path(@project), status: 303)
|
redirect_to(project_labels_path(@project), status: 303)
|
||||||
|
|
|
@ -70,9 +70,9 @@ class Projects::MilestonesController < Projects::ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def promote
|
def promote
|
||||||
Milestones::PromoteService.new(project, current_user).execute(milestone)
|
promoted_milestone = Milestones::PromoteService.new(project, current_user).execute(milestone)
|
||||||
|
|
||||||
flash[:notice] = "#{milestone.title} promoted to group milestone"
|
flash[:notice] = "#{milestone.title} promoted to <a href=\"#{group_milestone_path(project.group, promoted_milestone.iid)}\">group milestone</a>.".html_safe
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html do
|
format.html do
|
||||||
redirect_to project_milestones_path(project)
|
redirect_to project_milestones_path(project)
|
||||||
|
|
|
@ -10,6 +10,7 @@ module Clusters
|
||||||
Applications::Prometheus.application_name => Applications::Prometheus,
|
Applications::Prometheus.application_name => Applications::Prometheus,
|
||||||
Applications::Runner.application_name => Applications::Runner
|
Applications::Runner.application_name => Applications::Runner
|
||||||
}.freeze
|
}.freeze
|
||||||
|
DEFAULT_ENVIRONMENT = '*'.freeze
|
||||||
|
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
|
|
||||||
|
@ -50,6 +51,7 @@ module Clusters
|
||||||
|
|
||||||
scope :enabled, -> { where(enabled: true) }
|
scope :enabled, -> { where(enabled: true) }
|
||||||
scope :disabled, -> { where(enabled: false) }
|
scope :disabled, -> { where(enabled: false) }
|
||||||
|
scope :default_environment, -> { where(environment_scope: DEFAULT_ENVIRONMENT) }
|
||||||
|
|
||||||
def status_name
|
def status_name
|
||||||
if provider
|
if provider
|
||||||
|
|
|
@ -1,16 +1,24 @@
|
||||||
module DeploymentPlatform
|
module DeploymentPlatform
|
||||||
# EE would override this and utilize the extra argument
|
# EE would override this and utilize environment argument
|
||||||
|
# rubocop:disable Gitlab/ModuleWithInstanceVariables
|
||||||
def deployment_platform(environment: nil)
|
def deployment_platform(environment: nil)
|
||||||
@deployment_platform ||=
|
@deployment_platform ||= {}
|
||||||
find_cluster_platform_kubernetes ||
|
|
||||||
find_kubernetes_service_integration ||
|
@deployment_platform[environment] ||= find_deployment_platform(environment)
|
||||||
build_cluster_and_deployment_platform
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def find_cluster_platform_kubernetes
|
def find_deployment_platform(environment)
|
||||||
clusters.find_by(enabled: true)&.platform_kubernetes
|
find_cluster_platform_kubernetes(environment: environment) ||
|
||||||
|
find_kubernetes_service_integration ||
|
||||||
|
build_cluster_and_deployment_platform
|
||||||
|
end
|
||||||
|
|
||||||
|
# EE would override this and utilize environment argument
|
||||||
|
def find_cluster_platform_kubernetes(environment: nil)
|
||||||
|
clusters.enabled.default_environment
|
||||||
|
.last&.platform_kubernetes
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_kubernetes_service_integration
|
def find_kubernetes_service_integration
|
||||||
|
|
|
@ -42,7 +42,10 @@ module Boards
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
attrs[:move_between_ids] = move_between_ids if move_between_ids
|
if move_between_ids
|
||||||
|
attrs[:move_between_ids] = move_between_ids
|
||||||
|
attrs[:board_group_id] = board.group&.id
|
||||||
|
end
|
||||||
|
|
||||||
attrs
|
attrs
|
||||||
end
|
end
|
||||||
|
|
|
@ -55,9 +55,10 @@ module Issues
|
||||||
return unless params[:move_between_ids]
|
return unless params[:move_between_ids]
|
||||||
|
|
||||||
after_id, before_id = params.delete(:move_between_ids)
|
after_id, before_id = params.delete(:move_between_ids)
|
||||||
|
board_group_id = params.delete(:board_group_id)
|
||||||
|
|
||||||
issue_before = get_issue_if_allowed(issue.project, before_id) if before_id
|
issue_before = get_issue_if_allowed(before_id, board_group_id)
|
||||||
issue_after = get_issue_if_allowed(issue.project, after_id) if after_id
|
issue_after = get_issue_if_allowed(after_id, board_group_id)
|
||||||
|
|
||||||
issue.move_between(issue_before, issue_after)
|
issue.move_between(issue_before, issue_after)
|
||||||
end
|
end
|
||||||
|
@ -84,8 +85,16 @@ module Issues
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def get_issue_if_allowed(project, id)
|
def get_issue_if_allowed(id, board_group_id = nil)
|
||||||
issue = project.issues.find(id)
|
return unless id
|
||||||
|
|
||||||
|
issue =
|
||||||
|
if board_group_id
|
||||||
|
IssuesFinder.new(current_user, group_id: board_group_id).find_by(id: id)
|
||||||
|
else
|
||||||
|
project.issues.find(id)
|
||||||
|
end
|
||||||
|
|
||||||
issue if can?(current_user, :update_issue, issue)
|
issue if can?(current_user, :update_issue, issue)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -31,15 +31,17 @@ module Projects
|
||||||
|
|
||||||
# Check if we did extract public directory
|
# Check if we did extract public directory
|
||||||
archive_public_path = File.join(archive_path, 'public')
|
archive_public_path = File.join(archive_path, 'public')
|
||||||
raise FailedToExtractError, 'pages miss the public folder' unless Dir.exist?(archive_public_path)
|
raise InvaildStateError, 'pages miss the public folder' unless Dir.exist?(archive_public_path)
|
||||||
raise InvaildStateError, 'pages are outdated' unless latest?
|
raise InvaildStateError, 'pages are outdated' unless latest?
|
||||||
|
|
||||||
deploy_page!(archive_public_path)
|
deploy_page!(archive_public_path)
|
||||||
success
|
success
|
||||||
end
|
end
|
||||||
rescue InvaildStateError, FailedToExtractError => e
|
rescue InvaildStateError => e
|
||||||
register_failure
|
|
||||||
error(e.message)
|
error(e.message)
|
||||||
|
rescue => e
|
||||||
|
error(e.message, false)
|
||||||
|
raise e
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -50,12 +52,13 @@ module Projects
|
||||||
super
|
super
|
||||||
end
|
end
|
||||||
|
|
||||||
def error(message, http_status = nil)
|
def error(message, allow_delete_artifact = true)
|
||||||
|
register_failure
|
||||||
log_error("Projects::UpdatePagesService: #{message}")
|
log_error("Projects::UpdatePagesService: #{message}")
|
||||||
@status.allow_failure = !latest?
|
@status.allow_failure = !latest?
|
||||||
@status.description = message
|
@status.description = message
|
||||||
@status.drop(:script_failure)
|
@status.drop(:script_failure)
|
||||||
delete_artifact!
|
delete_artifact! if allow_delete_artifact
|
||||||
super
|
super
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -76,7 +79,7 @@ module Projects
|
||||||
elsif artifacts.ends_with?('.zip')
|
elsif artifacts.ends_with?('.zip')
|
||||||
extract_zip_archive!(temp_path)
|
extract_zip_archive!(temp_path)
|
||||||
else
|
else
|
||||||
raise FailedToExtractError, 'unsupported artifacts format'
|
raise InvaildStateError, 'unsupported artifacts format'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -89,13 +92,13 @@ module Projects
|
||||||
end
|
end
|
||||||
|
|
||||||
def extract_zip_archive!(temp_path)
|
def extract_zip_archive!(temp_path)
|
||||||
raise FailedToExtractError, 'missing artifacts metadata' unless build.artifacts_metadata?
|
raise InvaildStateError, 'missing artifacts metadata' unless build.artifacts_metadata?
|
||||||
|
|
||||||
# Calculate page size after extract
|
# Calculate page size after extract
|
||||||
public_entry = build.artifacts_metadata_entry(SITE_PATH, recursive: true)
|
public_entry = build.artifacts_metadata_entry(SITE_PATH, recursive: true)
|
||||||
|
|
||||||
if public_entry.total_size > max_size
|
if public_entry.total_size > max_size
|
||||||
raise FailedToExtractError, "artifacts for pages are too large: #{public_entry.total_size}"
|
raise InvaildStateError, "artifacts for pages are too large: #{public_entry.total_size}"
|
||||||
end
|
end
|
||||||
|
|
||||||
# Requires UnZip at least 6.00 Info-ZIP.
|
# Requires UnZip at least 6.00 Info-ZIP.
|
||||||
|
@ -174,6 +177,9 @@ module Projects
|
||||||
|
|
||||||
def latest_sha
|
def latest_sha
|
||||||
project.commit(build.ref).try(:sha).to_s
|
project.commit(build.ref).try(:sha).to_s
|
||||||
|
ensure
|
||||||
|
# Close any file descriptors that were opened and free libgit2 buffers
|
||||||
|
project.cleanup
|
||||||
end
|
end
|
||||||
|
|
||||||
def sha
|
def sha
|
||||||
|
|
|
@ -34,7 +34,8 @@ class VerifyPagesDomainService < BaseService
|
||||||
# Prevent any pre-existing grace period from being truncated
|
# Prevent any pre-existing grace period from being truncated
|
||||||
reverify = [domain.enabled_until, VERIFICATION_PERIOD.from_now].compact.max
|
reverify = [domain.enabled_until, VERIFICATION_PERIOD.from_now].compact.max
|
||||||
|
|
||||||
domain.update!(verified_at: Time.now, enabled_until: reverify)
|
domain.assign_attributes(verified_at: Time.now, enabled_until: reverify)
|
||||||
|
domain.save!(validate: false)
|
||||||
|
|
||||||
if was_disabled
|
if was_disabled
|
||||||
notify(:enabled)
|
notify(:enabled)
|
||||||
|
@ -47,7 +48,9 @@ class VerifyPagesDomainService < BaseService
|
||||||
|
|
||||||
def unverify_domain!
|
def unverify_domain!
|
||||||
if domain.verified?
|
if domain.verified?
|
||||||
domain.update!(verified_at: nil)
|
domain.assign_attributes(verified_at: nil)
|
||||||
|
domain.save!(validate: false)
|
||||||
|
|
||||||
notify(:verification_failed)
|
notify(:verification_failed)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -55,7 +58,8 @@ class VerifyPagesDomainService < BaseService
|
||||||
end
|
end
|
||||||
|
|
||||||
def disable_domain!
|
def disable_domain!
|
||||||
domain.update!(verified_at: nil, enabled_until: nil)
|
domain.assign_attributes(verified_at: nil, enabled_until: nil)
|
||||||
|
domain.save!(validate: false)
|
||||||
|
|
||||||
notify(:disabled)
|
notify(:disabled)
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
%button.js-promote-project-milestone-button.btn.btn-grouped{ data: { toggle: 'modal',
|
%button.js-promote-project-milestone-button.btn.btn-grouped{ data: { toggle: 'modal',
|
||||||
target: '#promote-milestone-modal',
|
target: '#promote-milestone-modal',
|
||||||
milestone_title: @milestone.title,
|
milestone_title: @milestone.title,
|
||||||
|
group_name: @project.group.name,
|
||||||
url: promote_project_milestone_path(@milestone.project, @milestone),
|
url: promote_project_milestone_path(@milestone.project, @milestone),
|
||||||
container: 'body' },
|
container: 'body' },
|
||||||
disabled: true,
|
disabled: true,
|
||||||
|
|
|
@ -55,6 +55,7 @@
|
||||||
label_title: label.title,
|
label_title: label.title,
|
||||||
label_color: label.color,
|
label_color: label.color,
|
||||||
label_text_color: label.text_color,
|
label_text_color: label.text_color,
|
||||||
|
group_name: label.project.group.name,
|
||||||
target: '#promote-label-modal',
|
target: '#promote-label-modal',
|
||||||
container: 'body',
|
container: 'body',
|
||||||
toggle: 'modal' } }
|
toggle: 'modal' } }
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
= hidden_field(resource_name, field, value: value)
|
= hidden_field(resource_name, field, value: value)
|
||||||
= hidden_field_tag(:spam_log_id, spammable.spam_log.id)
|
= hidden_field_tag(:spam_log_id, spammable.spam_log.id)
|
||||||
= hidden_field_tag(:recaptcha_verification, true)
|
= hidden_field_tag(:recaptcha_verification, true)
|
||||||
= recaptcha_tags script: script, callback: 'recaptchaDialogCallback'
|
= recaptcha_tags script: script, callback: 'recaptchaDialogCallback' unless Rails.env.test?
|
||||||
|
|
||||||
-# Yields a block with given extra params.
|
-# Yields a block with given extra params.
|
||||||
= yield
|
= yield
|
||||||
|
|
|
@ -56,6 +56,7 @@
|
||||||
type: 'button',
|
type: 'button',
|
||||||
data: { url: promote_project_milestone_path(milestone.project, milestone),
|
data: { url: promote_project_milestone_path(milestone.project, milestone),
|
||||||
milestone_title: milestone.title,
|
milestone_title: milestone.title,
|
||||||
|
group_name: @project.group.name,
|
||||||
target: '#promote-milestone-modal',
|
target: '#promote-milestone-modal',
|
||||||
container: 'body',
|
container: 'body',
|
||||||
toggle: 'modal' } }
|
toggle: 'modal' } }
|
||||||
|
|
|
@ -15,13 +15,8 @@ codequality:
|
||||||
services:
|
services:
|
||||||
- docker:dind
|
- docker:dind
|
||||||
script:
|
script:
|
||||||
- docker pull codeclimate/codeclimate
|
|
||||||
- export SP_VERSION=$(echo "$CI_SERVER_VERSION" | sed 's/^\([0-9]*\)\.\([0-9]*\).*/\1-\2-stable/')
|
- export SP_VERSION=$(echo "$CI_SERVER_VERSION" | sed 's/^\([0-9]*\)\.\([0-9]*\).*/\1-\2-stable/')
|
||||||
- docker run
|
- docker run --env SOURCE_CODE="$PWD" --volume "$PWD":/code --volume /var/run/docker.sock:/var/run/docker.sock "registry.gitlab.com/gitlab-org/security-products/codequality:$SP_VERSION" /code
|
||||||
--env SOURCE_CODE="$PWD" \
|
|
||||||
--volume "$PWD":/code \
|
|
||||||
--volume /var/run/docker.sock:/var/run/docker.sock \
|
|
||||||
"registry.gitlab.com/gitlab-org/security-products/codequality:$SP_VERSION" /code
|
|
||||||
artifacts:
|
artifacts:
|
||||||
paths: [codeclimate.json]
|
paths: [codeclimate.json]
|
||||||
```
|
```
|
||||||
|
|
|
@ -105,8 +105,12 @@ module Banzai
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
options = link_options.merge(href: match)
|
# match has come from node.to_html above, so we know it's encoded
|
||||||
content_tag(:a, match.html_safe, options) + dropped
|
# correctly.
|
||||||
|
html_safe_match = match.html_safe
|
||||||
|
options = link_options.merge(href: html_safe_match)
|
||||||
|
|
||||||
|
content_tag(:a, html_safe_match, options) + dropped
|
||||||
end
|
end
|
||||||
|
|
||||||
def autolink_filter(text)
|
def autolink_filter(text)
|
||||||
|
|
|
@ -12,6 +12,7 @@ module Gitlab
|
||||||
|
|
||||||
class Build < ActiveRecord::Base
|
class Build < ActiveRecord::Base
|
||||||
self.table_name = 'ci_builds'
|
self.table_name = 'ci_builds'
|
||||||
|
self.inheritance_column = :_type_disabled
|
||||||
|
|
||||||
def ensure_stage!(attempts: 2)
|
def ensure_stage!(attempts: 2)
|
||||||
find_stage || create_stage!
|
find_stage || create_stage!
|
||||||
|
|
|
@ -8,6 +8,7 @@ module Gitlab
|
||||||
class Repository
|
class Repository
|
||||||
include Gitlab::Git::RepositoryMirroring
|
include Gitlab::Git::RepositoryMirroring
|
||||||
include Gitlab::Git::Popen
|
include Gitlab::Git::Popen
|
||||||
|
include Gitlab::EncodingHelper
|
||||||
|
|
||||||
ALLOWED_OBJECT_DIRECTORIES_VARIABLES = %w[
|
ALLOWED_OBJECT_DIRECTORIES_VARIABLES = %w[
|
||||||
GIT_OBJECT_DIRECTORY
|
GIT_OBJECT_DIRECTORY
|
||||||
|
@ -1498,7 +1499,7 @@ module Gitlab
|
||||||
names.lines.each do |line|
|
names.lines.each do |line|
|
||||||
next unless line.start_with?(refs_prefix)
|
next unless line.start_with?(refs_prefix)
|
||||||
|
|
||||||
refs << line.rstrip[left_slice_count..-1]
|
refs << encode_utf8(line.rstrip[left_slice_count..-1])
|
||||||
end
|
end
|
||||||
|
|
||||||
refs
|
refs
|
||||||
|
|
|
@ -18,7 +18,7 @@ describe Projects::ClustersController do
|
||||||
context 'when project has one or more clusters' do
|
context 'when project has one or more clusters' do
|
||||||
let(:project) { create(:project) }
|
let(:project) { create(:project) }
|
||||||
let!(:enabled_cluster) { create(:cluster, :provided_by_gcp, projects: [project]) }
|
let!(:enabled_cluster) { create(:cluster, :provided_by_gcp, projects: [project]) }
|
||||||
let!(:disabled_cluster) { create(:cluster, :disabled, :provided_by_gcp, projects: [project]) }
|
let!(:disabled_cluster) { create(:cluster, :disabled, :provided_by_gcp, :production_environment, projects: [project]) }
|
||||||
it 'lists available clusters' do
|
it 'lists available clusters' do
|
||||||
go
|
go
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ describe Projects::ClustersController do
|
||||||
|
|
||||||
before do
|
before do
|
||||||
allow(Clusters::Cluster).to receive(:paginates_per).and_return(1)
|
allow(Clusters::Cluster).to receive(:paginates_per).and_return(1)
|
||||||
create_list(:cluster, 2, :provided_by_gcp, projects: [project])
|
create_list(:cluster, 2, :provided_by_gcp, :production_environment, projects: [project])
|
||||||
get :index, namespace_id: project.namespace, project_id: project, page: last_page
|
get :index, namespace_id: project.namespace, project_id: project, page: last_page
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -98,7 +98,7 @@ describe Projects::MilestonesController do
|
||||||
it 'shows group milestone' do
|
it 'shows group milestone' do
|
||||||
post :promote, namespace_id: project.namespace.id, project_id: project.id, id: milestone.iid
|
post :promote, namespace_id: project.namespace.id, project_id: project.id, id: milestone.iid
|
||||||
|
|
||||||
expect(flash[:notice]).to eq("#{milestone.title} promoted to group milestone")
|
expect(flash[:notice]).to eq("#{milestone.title} promoted to <a href=\"#{group_milestone_path(project.group, milestone.iid)}\">group milestone</a>.")
|
||||||
expect(response).to redirect_to(project_milestones_path(project))
|
expect(response).to redirect_to(project_milestones_path(project))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -32,5 +32,9 @@ FactoryBot.define do
|
||||||
trait :disabled do
|
trait :disabled do
|
||||||
enabled false
|
enabled false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
trait :production_environment do
|
||||||
|
sequence(:environment_scope) { |n| "production#{n}/*" }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -34,9 +34,6 @@ describe 'New issue', :js do
|
||||||
|
|
||||||
click_button 'Submit issue'
|
click_button 'Submit issue'
|
||||||
|
|
||||||
# reCAPTCHA alerts when it can't contact the server, so just accept it and move on
|
|
||||||
page.driver.browser.switch_to.alert.accept
|
|
||||||
|
|
||||||
# it is impossible to test recaptcha automatically and there is no possibility to fill in recaptcha
|
# it is impossible to test recaptcha automatically and there is no possibility to fill in recaptcha
|
||||||
# recaptcha verification is skipped in test environment and it always returns true
|
# recaptcha verification is skipped in test environment and it always returns true
|
||||||
expect(page).not_to have_content('issue title')
|
expect(page).not_to have_content('issue title')
|
||||||
|
|
|
@ -6,7 +6,7 @@ describe ClustersFinder do
|
||||||
|
|
||||||
describe '#execute' do
|
describe '#execute' do
|
||||||
let(:enabled_cluster) { create(:cluster, :provided_by_gcp, projects: [project]) }
|
let(:enabled_cluster) { create(:cluster, :provided_by_gcp, projects: [project]) }
|
||||||
let(:disabled_cluster) { create(:cluster, :disabled, :provided_by_gcp, projects: [project]) }
|
let(:disabled_cluster) { create(:cluster, :disabled, :provided_by_gcp, :production_environment, projects: [project]) }
|
||||||
|
|
||||||
subject { described_class.new(project, user, scope).execute }
|
subject { described_class.new(project, user, scope).execute }
|
||||||
|
|
||||||
|
|
|
@ -25,26 +25,34 @@ describe('issue_discussion component', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render user avatar', () => {
|
it('should render user avatar', () => {
|
||||||
expect(vm.$el.querySelector('.user-avatar-link')).toBeDefined();
|
expect(vm.$el.querySelector('.user-avatar-link')).not.toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render discussion header', () => {
|
it('should render discussion header', () => {
|
||||||
expect(vm.$el.querySelector('.discussion-header')).toBeDefined();
|
expect(vm.$el.querySelector('.discussion-header')).not.toBeNull();
|
||||||
expect(vm.$el.querySelector('.notes').children.length).toEqual(discussionMock.notes.length);
|
expect(vm.$el.querySelector('.notes').children.length).toEqual(discussionMock.notes.length);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('actions', () => {
|
describe('actions', () => {
|
||||||
it('should render reply button', () => {
|
it('should render reply button', () => {
|
||||||
expect(vm.$el.querySelector('.js-vue-discussion-reply').textContent.trim()).toEqual('Reply...');
|
expect(vm.$el.querySelector('.js-vue-discussion-reply').textContent.trim()).toEqual(
|
||||||
|
'Reply...',
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should toggle reply form', (done) => {
|
it('should toggle reply form', (done) => {
|
||||||
vm.$el.querySelector('.js-vue-discussion-reply').click();
|
vm.$el.querySelector('.js-vue-discussion-reply').click();
|
||||||
Vue.nextTick(() => {
|
Vue.nextTick(() => {
|
||||||
expect(vm.$refs.noteForm).toBeDefined();
|
expect(vm.$refs.noteForm).not.toBeNull();
|
||||||
expect(vm.isReplying).toEqual(true);
|
expect(vm.isReplying).toEqual(true);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('does not render jump to discussion button', () => {
|
||||||
|
expect(
|
||||||
|
vm.$el.querySelector('*[data-original-title="Jump to next unresolved discussion"]'),
|
||||||
|
).toBeNull();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -12,6 +12,7 @@ describe('Promote label modal', () => {
|
||||||
labelColor: '#5cb85c',
|
labelColor: '#5cb85c',
|
||||||
labelTextColor: '#ffffff',
|
labelTextColor: '#ffffff',
|
||||||
url: `${gl.TEST_HOST}/dummy/promote/labels`,
|
url: `${gl.TEST_HOST}/dummy/promote/labels`,
|
||||||
|
groupName: 'group',
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('Modal title and description', () => {
|
describe('Modal title and description', () => {
|
||||||
|
@ -24,7 +25,7 @@ describe('Promote label modal', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('contains the proper description', () => {
|
it('contains the proper description', () => {
|
||||||
expect(vm.text).toContain('Promoting this label will make it available for all projects inside the group');
|
expect(vm.text).toContain(`Promoting ${labelMockData.labelTitle} will make it available for all projects inside ${labelMockData.groupName}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('contains a label span with the color', () => {
|
it('contains a label span with the color', () => {
|
||||||
|
|
|
@ -10,6 +10,7 @@ describe('Promote milestone modal', () => {
|
||||||
const milestoneMockData = {
|
const milestoneMockData = {
|
||||||
milestoneTitle: 'v1.0',
|
milestoneTitle: 'v1.0',
|
||||||
url: `${gl.TEST_HOST}/dummy/promote/milestones`,
|
url: `${gl.TEST_HOST}/dummy/promote/milestones`,
|
||||||
|
groupName: 'group',
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('Modal title and description', () => {
|
describe('Modal title and description', () => {
|
||||||
|
@ -22,7 +23,7 @@ describe('Promote milestone modal', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('contains the proper description', () => {
|
it('contains the proper description', () => {
|
||||||
expect(vm.text).toContain('Promoting this milestone will make it available for all projects inside the group.');
|
expect(vm.text).toContain(`Promoting ${milestoneMockData.milestoneTitle} will make it available for all projects inside ${milestoneMockData.groupName}.`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('contains the correct title', () => {
|
it('contains the correct title', () => {
|
||||||
|
|
|
@ -130,7 +130,7 @@ const RESPONSE_MAP = {
|
||||||
'name_with_namespace': 'No project',
|
'name_with_namespace': 'No project',
|
||||||
}, {
|
}, {
|
||||||
'id': 20,
|
'id': 20,
|
||||||
'name_with_namespace': 'foo / bar',
|
'name_with_namespace': '<img src=x onerror=alert(document.domain)> foo / bar',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
|
@ -68,6 +68,15 @@ describe('SidebarMoveIssue', () => {
|
||||||
|
|
||||||
expect($.fn.glDropdown).toHaveBeenCalled();
|
expect($.fn.glDropdown).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('escapes html from project name', (done) => {
|
||||||
|
this.$toggleButton.dropdown('toggle');
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
expect(this.$content.find('.js-move-issue-dropdown-item')[1].innerHTML.trim()).toEqual('<img src=x onerror=alert(document.domain)> foo / bar');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('onConfirmClicked', () => {
|
describe('onConfirmClicked', () => {
|
||||||
|
|
|
@ -167,6 +167,15 @@ describe Banzai::Filter::AutolinkFilter do
|
||||||
expect(actual).to eq(expected_complicated_link)
|
expect(actual).to eq(expected_complicated_link)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'does not double-encode HTML entities' do
|
||||||
|
encoded_link = "#{link}?foo=bar&baz=quux"
|
||||||
|
expected_encoded_link = %Q{<a href="#{encoded_link}">#{encoded_link}</a>}
|
||||||
|
actual = unescape(filter(encoded_link).to_html)
|
||||||
|
|
||||||
|
expect(actual).to eq(Rinku.auto_link(encoded_link))
|
||||||
|
expect(actual).to eq(expected_encoded_link)
|
||||||
|
end
|
||||||
|
|
||||||
it 'does not include trailing HTML entities' do
|
it 'does not include trailing HTML entities' do
|
||||||
doc = filter("See <<<#{link}>>>")
|
doc = filter("See <<<#{link}>>>")
|
||||||
|
|
||||||
|
|
|
@ -51,4 +51,20 @@ describe Gitlab::BackgroundMigration::MigrateBuildStage, :migration, schema: 201
|
||||||
expect { described_class.new.perform(1, 6) }
|
expect { described_class.new.perform(1, 6) }
|
||||||
.to raise_error ActiveRecord::RecordNotUnique
|
.to raise_error ActiveRecord::RecordNotUnique
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when invalid class can be loaded due to single table inheritance' do
|
||||||
|
let(:commit_status) do
|
||||||
|
jobs.create!(id: 7, commit_id: 1, project_id: 123, stage_idx: 4,
|
||||||
|
stage: 'post-deploy', status: :failed)
|
||||||
|
end
|
||||||
|
|
||||||
|
before do
|
||||||
|
commit_status.update_column(:type, 'SomeClass')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does ignore single table inheritance type' do
|
||||||
|
expect { described_class.new.perform(1, 7) }.not_to raise_error
|
||||||
|
expect(jobs.find(7)).to have_attributes(stage_id: (a_value > 0))
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -604,17 +604,20 @@ describe Gitlab::Git::Repository, seed_helper: true do
|
||||||
shared_examples 'returning the right branches' do
|
shared_examples 'returning the right branches' do
|
||||||
let(:head_id) { repository.rugged.head.target.oid }
|
let(:head_id) { repository.rugged.head.target.oid }
|
||||||
let(:new_branch) { head_id }
|
let(:new_branch) { head_id }
|
||||||
|
let(:utf8_branch) { 'branch-é' }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
repository.create_branch(new_branch, 'master')
|
repository.create_branch(new_branch, 'master')
|
||||||
|
repository.create_branch(utf8_branch, 'master')
|
||||||
end
|
end
|
||||||
|
|
||||||
after do
|
after do
|
||||||
repository.delete_branch(new_branch)
|
repository.delete_branch(new_branch)
|
||||||
|
repository.delete_branch(utf8_branch)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'displays that branch' do
|
it 'displays that branch' do
|
||||||
expect(repository.branch_names_contains_sha(head_id)).to include('master', new_branch)
|
expect(repository.branch_names_contains_sha(head_id)).to include('master', new_branch, utf8_branch)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -339,7 +339,7 @@ describe ProjectPresenter do
|
||||||
|
|
||||||
it 'returns link to clusters page if more than one exists' do
|
it 'returns link to clusters page if more than one exists' do
|
||||||
project.add_master(user)
|
project.add_master(user)
|
||||||
create(:cluster, projects: [project])
|
create(:cluster, :production_environment, projects: [project])
|
||||||
create(:cluster, projects: [project])
|
create(:cluster, projects: [project])
|
||||||
|
|
||||||
expect(presenter.kubernetes_cluster_anchor_data).to eq(OpenStruct.new(enabled: true,
|
expect(presenter.kubernetes_cluster_anchor_data).to eq(OpenStruct.new(enabled: true,
|
||||||
|
|
|
@ -48,7 +48,7 @@ describe Boards::Issues::MoveService do
|
||||||
parent.add_developer(user)
|
parent.add_developer(user)
|
||||||
end
|
end
|
||||||
|
|
||||||
it_behaves_like 'issues move service'
|
it_behaves_like 'issues move service', true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -82,7 +82,7 @@ describe Clusters::CreateService do
|
||||||
|
|
||||||
context 'when project has a cluster' do
|
context 'when project has a cluster' do
|
||||||
include_context 'valid params'
|
include_context 'valid params'
|
||||||
let!(:cluster) { create(:cluster, :provided_by_gcp, projects: [project]) }
|
let!(:cluster) { create(:cluster, :provided_by_gcp, :production_environment, projects: [project]) }
|
||||||
|
|
||||||
it 'does not create a cluster' do
|
it 'does not create a cluster' do
|
||||||
expect(ClusterProvisionWorker).not_to receive(:perform_async)
|
expect(ClusterProvisionWorker).not_to receive(:perform_async)
|
||||||
|
|
|
@ -97,6 +97,37 @@ describe Issues::UpdateService, :mailer do
|
||||||
expect(issue.relative_position).to be_between(issue1.relative_position, issue2.relative_position)
|
expect(issue.relative_position).to be_between(issue1.relative_position, issue2.relative_position)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when moving issue between issues from different projects' do
|
||||||
|
let(:group) { create(:group) }
|
||||||
|
let(:project_1) { create(:project, namespace: group) }
|
||||||
|
let(:project_2) { create(:project, namespace: group) }
|
||||||
|
let(:project_3) { create(:project, namespace: group) }
|
||||||
|
|
||||||
|
let(:issue_1) { create(:issue, project: project_1) }
|
||||||
|
let(:issue_2) { create(:issue, project: project_2) }
|
||||||
|
let(:issue_3) { create(:issue, project: project_3) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
group.add_developer(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'sorts issues as specified by parameters' do
|
||||||
|
# Moving all issues to end here like the last example won't work since
|
||||||
|
# all projects only have the same issue count
|
||||||
|
# so their relative_position will be the same.
|
||||||
|
issue_1.move_to_end
|
||||||
|
issue_2.move_after(issue_1)
|
||||||
|
issue_3.move_after(issue_2)
|
||||||
|
[issue_1, issue_2, issue_3].map(&:save)
|
||||||
|
|
||||||
|
opts[:move_between_ids] = [issue_1.id, issue_2.id]
|
||||||
|
opts[:board_group_id] = group.id
|
||||||
|
|
||||||
|
described_class.new(issue_3.project, user, opts).execute(issue_3)
|
||||||
|
expect(issue_2.relative_position).to be_between(issue_1.relative_position, issue_2.relative_position)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context 'when current user cannot admin issues in the project' do
|
context 'when current user cannot admin issues in the project' do
|
||||||
let(:guest) { create(:user) }
|
let(:guest) { create(:user) }
|
||||||
before do
|
before do
|
||||||
|
|
|
@ -87,7 +87,8 @@ describe Projects::UpdatePagesService do
|
||||||
it 'fails for empty file fails' do
|
it 'fails for empty file fails' do
|
||||||
build.update_attributes(legacy_artifacts_file: empty_file)
|
build.update_attributes(legacy_artifacts_file: empty_file)
|
||||||
|
|
||||||
expect(execute).not_to eq(:success)
|
expect { execute }
|
||||||
|
.to raise_error(Projects::UpdatePagesService::FailedToExtractError)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -159,7 +160,8 @@ describe Projects::UpdatePagesService do
|
||||||
it 'fails for empty file fails' do
|
it 'fails for empty file fails' do
|
||||||
build.job_artifacts_archive.update_attributes(file: empty_file)
|
build.job_artifacts_archive.update_attributes(file: empty_file)
|
||||||
|
|
||||||
expect(execute).not_to eq(:success)
|
expect { execute }
|
||||||
|
.to raise_error(Projects::UpdatePagesService::FailedToExtractError)
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when timeout happens by DNS error' do
|
context 'when timeout happens by DNS error' do
|
||||||
|
@ -172,7 +174,39 @@ describe Projects::UpdatePagesService do
|
||||||
expect { execute }.to raise_error(SocketError)
|
expect { execute }.to raise_error(SocketError)
|
||||||
|
|
||||||
build.reload
|
build.reload
|
||||||
expect(build.artifacts?).to eq(true)
|
expect(deploy_status).to be_failed
|
||||||
|
expect(build.artifacts?).to be_truthy
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when failed to extract zip artifacts' do
|
||||||
|
before do
|
||||||
|
allow_any_instance_of(described_class)
|
||||||
|
.to receive(:extract_zip_archive!)
|
||||||
|
.and_raise(Projects::UpdatePagesService::FailedToExtractError)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'raises an error' do
|
||||||
|
expect { execute }
|
||||||
|
.to raise_error(Projects::UpdatePagesService::FailedToExtractError)
|
||||||
|
|
||||||
|
build.reload
|
||||||
|
expect(deploy_status).to be_failed
|
||||||
|
expect(build.artifacts?).to be_truthy
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when missing artifacts metadata' do
|
||||||
|
before do
|
||||||
|
allow(build).to receive(:artifacts_metadata?).and_return(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does not raise an error and remove artifacts as failed job' do
|
||||||
|
execute
|
||||||
|
|
||||||
|
build.reload
|
||||||
|
expect(deploy_status).to be_failed
|
||||||
|
expect(build.artifacts?).to be_falsey
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -93,6 +93,25 @@ describe VerifyPagesDomainService do
|
||||||
expect(domain).not_to be_enabled
|
expect(domain).not_to be_enabled
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'invalid domain' do
|
||||||
|
let(:domain) { build(:pages_domain, :expired, :with_missing_chain) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
domain.save(validate: false)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'can be disabled' do
|
||||||
|
error_status[:message] += '. It is now disabled.'
|
||||||
|
|
||||||
|
stub_resolver
|
||||||
|
|
||||||
|
expect(service.execute).to eq(error_status)
|
||||||
|
|
||||||
|
expect(domain).not_to be_verified
|
||||||
|
expect(domain).not_to be_enabled
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'timeout behaviour' do
|
context 'timeout behaviour' do
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
module MigrationsHelpers
|
module MigrationsHelpers
|
||||||
def table(name)
|
def table(name)
|
||||||
Class.new(ActiveRecord::Base) { self.table_name = name }
|
Class.new(ActiveRecord::Base) do
|
||||||
|
self.table_name = name
|
||||||
|
self.inheritance_column = :_type_disabled
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def migrations_paths
|
def migrations_paths
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
shared_examples 'issues move service' do
|
shared_examples 'issues move service' do |group|
|
||||||
context 'when moving an issue between lists' do
|
context 'when moving an issue between lists' do
|
||||||
let(:issue) { create(:labeled_issue, project: project, labels: [bug, development]) }
|
let(:issue) { create(:labeled_issue, project: project, labels: [bug, development]) }
|
||||||
let(:params) { { board_id: board1.id, from_list_id: list1.id, to_list_id: list2.id } }
|
let(:params) { { board_id: board1.id, from_list_id: list1.id, to_list_id: list2.id } }
|
||||||
|
@ -83,5 +83,18 @@ shared_examples 'issues move service' do
|
||||||
|
|
||||||
expect(issue.relative_position).to be_between(issue1.relative_position, issue2.relative_position)
|
expect(issue.relative_position).to be_between(issue1.relative_position, issue2.relative_position)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if group
|
||||||
|
context 'when on a group board' do
|
||||||
|
it 'sends the board_group_id parameter' do
|
||||||
|
params.merge!(move_after_id: issue1.id, move_before_id: issue2.id)
|
||||||
|
|
||||||
|
match_params = { move_between_ids: [issue1.id, issue2.id], board_group_id: parent.id }
|
||||||
|
expect(Issues::UpdateService).to receive(:new).with(issue.project, user, match_params).and_return(double(execute: build(:issue)))
|
||||||
|
|
||||||
|
described_class.new(parent, user, params).execute(issue)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
1202
vendor/assets/javascripts/jquery.atwho.js
vendored
Normal file
1202
vendor/assets/javascripts/jquery.atwho.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
436
vendor/assets/javascripts/jquery.caret.js
vendored
Normal file
436
vendor/assets/javascripts/jquery.caret.js
vendored
Normal file
|
@ -0,0 +1,436 @@
|
||||||
|
(function (root, factory) {
|
||||||
|
if (typeof define === 'function' && define.amd) {
|
||||||
|
// AMD. Register as an anonymous module.
|
||||||
|
define(["jquery"], function ($) {
|
||||||
|
return (root.returnExportsGlobal = factory($));
|
||||||
|
});
|
||||||
|
} else if (typeof exports === 'object') {
|
||||||
|
// Node. Does not work with strict CommonJS, but
|
||||||
|
// only CommonJS-like enviroments that support module.exports,
|
||||||
|
// like Node.
|
||||||
|
module.exports = factory(require("jquery"));
|
||||||
|
} else {
|
||||||
|
factory(jQuery);
|
||||||
|
}
|
||||||
|
}(this, function ($) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
Implement Github like autocomplete mentions
|
||||||
|
http://ichord.github.com/At.js
|
||||||
|
|
||||||
|
Copyright (c) 2013 chord.luo@gmail.com
|
||||||
|
Licensed under the MIT license.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
本插件操作 textarea 或者 input 内的插入符
|
||||||
|
只实现了获得插入符在文本框中的位置,我设置
|
||||||
|
插入符的位置.
|
||||||
|
*/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
var EditableCaret, InputCaret, Mirror, Utils, discoveryIframeOf, methods, oDocument, oFrame, oWindow, pluginName, setContextBy;
|
||||||
|
|
||||||
|
pluginName = 'caret';
|
||||||
|
|
||||||
|
EditableCaret = (function() {
|
||||||
|
function EditableCaret($inputor) {
|
||||||
|
this.$inputor = $inputor;
|
||||||
|
this.domInputor = this.$inputor[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
EditableCaret.prototype.setPos = function(pos) {
|
||||||
|
var fn, found, offset, sel;
|
||||||
|
if (sel = oWindow.getSelection()) {
|
||||||
|
offset = 0;
|
||||||
|
found = false;
|
||||||
|
(fn = function(pos, parent) {
|
||||||
|
var node, range, _i, _len, _ref, _results;
|
||||||
|
_ref = parent.childNodes;
|
||||||
|
_results = [];
|
||||||
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
|
node = _ref[_i];
|
||||||
|
if (found) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (node.nodeType === 3) {
|
||||||
|
if (offset + node.length >= pos) {
|
||||||
|
found = true;
|
||||||
|
range = oDocument.createRange();
|
||||||
|
range.setStart(node, pos - offset);
|
||||||
|
sel.removeAllRanges();
|
||||||
|
sel.addRange(range);
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
_results.push(offset += node.length);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_results.push(fn(pos, node));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _results;
|
||||||
|
})(pos, this.domInputor);
|
||||||
|
}
|
||||||
|
return this.domInputor;
|
||||||
|
};
|
||||||
|
|
||||||
|
EditableCaret.prototype.getIEPosition = function() {
|
||||||
|
return this.getPosition();
|
||||||
|
};
|
||||||
|
|
||||||
|
EditableCaret.prototype.getPosition = function() {
|
||||||
|
var inputor_offset, offset;
|
||||||
|
offset = this.getOffset();
|
||||||
|
inputor_offset = this.$inputor.offset();
|
||||||
|
offset.left -= inputor_offset.left;
|
||||||
|
offset.top -= inputor_offset.top;
|
||||||
|
return offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
EditableCaret.prototype.getOldIEPos = function() {
|
||||||
|
var preCaretTextRange, textRange;
|
||||||
|
textRange = oDocument.selection.createRange();
|
||||||
|
preCaretTextRange = oDocument.body.createTextRange();
|
||||||
|
preCaretTextRange.moveToElementText(this.domInputor);
|
||||||
|
preCaretTextRange.setEndPoint("EndToEnd", textRange);
|
||||||
|
return preCaretTextRange.text.length;
|
||||||
|
};
|
||||||
|
|
||||||
|
EditableCaret.prototype.getPos = function() {
|
||||||
|
var clonedRange, pos, range;
|
||||||
|
if (range = this.range()) {
|
||||||
|
clonedRange = range.cloneRange();
|
||||||
|
clonedRange.selectNodeContents(this.domInputor);
|
||||||
|
clonedRange.setEnd(range.endContainer, range.endOffset);
|
||||||
|
pos = clonedRange.toString().length;
|
||||||
|
clonedRange.detach();
|
||||||
|
return pos;
|
||||||
|
} else if (oDocument.selection) {
|
||||||
|
return this.getOldIEPos();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
EditableCaret.prototype.getOldIEOffset = function() {
|
||||||
|
var range, rect;
|
||||||
|
range = oDocument.selection.createRange().duplicate();
|
||||||
|
range.moveStart("character", -1);
|
||||||
|
rect = range.getBoundingClientRect();
|
||||||
|
return {
|
||||||
|
height: rect.bottom - rect.top,
|
||||||
|
left: rect.left,
|
||||||
|
top: rect.top
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
EditableCaret.prototype.getOffset = function(pos) {
|
||||||
|
var clonedRange, offset, range, rect, shadowCaret;
|
||||||
|
if (oWindow.getSelection && (range = this.range())) {
|
||||||
|
if (range.endOffset - 1 > 0 && range.endContainer !== this.domInputor) {
|
||||||
|
clonedRange = range.cloneRange();
|
||||||
|
clonedRange.setStart(range.endContainer, range.endOffset - 1);
|
||||||
|
clonedRange.setEnd(range.endContainer, range.endOffset);
|
||||||
|
rect = clonedRange.getBoundingClientRect();
|
||||||
|
offset = {
|
||||||
|
height: rect.height,
|
||||||
|
left: rect.left + rect.width,
|
||||||
|
top: rect.top
|
||||||
|
};
|
||||||
|
clonedRange.detach();
|
||||||
|
}
|
||||||
|
if (!offset || (offset != null ? offset.height : void 0) === 0) {
|
||||||
|
clonedRange = range.cloneRange();
|
||||||
|
shadowCaret = $(oDocument.createTextNode("|"));
|
||||||
|
clonedRange.insertNode(shadowCaret[0]);
|
||||||
|
clonedRange.selectNode(shadowCaret[0]);
|
||||||
|
rect = clonedRange.getBoundingClientRect();
|
||||||
|
offset = {
|
||||||
|
height: rect.height,
|
||||||
|
left: rect.left,
|
||||||
|
top: rect.top
|
||||||
|
};
|
||||||
|
shadowCaret.remove();
|
||||||
|
clonedRange.detach();
|
||||||
|
}
|
||||||
|
} else if (oDocument.selection) {
|
||||||
|
offset = this.getOldIEOffset();
|
||||||
|
}
|
||||||
|
if (offset) {
|
||||||
|
offset.top += $(oWindow).scrollTop();
|
||||||
|
offset.left += $(oWindow).scrollLeft();
|
||||||
|
}
|
||||||
|
return offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
EditableCaret.prototype.range = function() {
|
||||||
|
var sel;
|
||||||
|
if (!oWindow.getSelection) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sel = oWindow.getSelection();
|
||||||
|
if (sel.rangeCount > 0) {
|
||||||
|
return sel.getRangeAt(0);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return EditableCaret;
|
||||||
|
|
||||||
|
})();
|
||||||
|
|
||||||
|
InputCaret = (function() {
|
||||||
|
function InputCaret($inputor) {
|
||||||
|
this.$inputor = $inputor;
|
||||||
|
this.domInputor = this.$inputor[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
InputCaret.prototype.getIEPos = function() {
|
||||||
|
var endRange, inputor, len, normalizedValue, pos, range, textInputRange;
|
||||||
|
inputor = this.domInputor;
|
||||||
|
range = oDocument.selection.createRange();
|
||||||
|
pos = 0;
|
||||||
|
if (range && range.parentElement() === inputor) {
|
||||||
|
normalizedValue = inputor.value.replace(/\r\n/g, "\n");
|
||||||
|
len = normalizedValue.length;
|
||||||
|
textInputRange = inputor.createTextRange();
|
||||||
|
textInputRange.moveToBookmark(range.getBookmark());
|
||||||
|
endRange = inputor.createTextRange();
|
||||||
|
endRange.collapse(false);
|
||||||
|
if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) {
|
||||||
|
pos = len;
|
||||||
|
} else {
|
||||||
|
pos = -textInputRange.moveStart("character", -len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pos;
|
||||||
|
};
|
||||||
|
|
||||||
|
InputCaret.prototype.getPos = function() {
|
||||||
|
if (oDocument.selection) {
|
||||||
|
return this.getIEPos();
|
||||||
|
} else {
|
||||||
|
return this.domInputor.selectionStart;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
InputCaret.prototype.setPos = function(pos) {
|
||||||
|
var inputor, range;
|
||||||
|
inputor = this.domInputor;
|
||||||
|
if (oDocument.selection) {
|
||||||
|
range = inputor.createTextRange();
|
||||||
|
range.move("character", pos);
|
||||||
|
range.select();
|
||||||
|
} else if (inputor.setSelectionRange) {
|
||||||
|
inputor.setSelectionRange(pos, pos);
|
||||||
|
}
|
||||||
|
return inputor;
|
||||||
|
};
|
||||||
|
|
||||||
|
InputCaret.prototype.getIEOffset = function(pos) {
|
||||||
|
var h, textRange, x, y;
|
||||||
|
textRange = this.domInputor.createTextRange();
|
||||||
|
pos || (pos = this.getPos());
|
||||||
|
textRange.move('character', pos);
|
||||||
|
x = textRange.boundingLeft;
|
||||||
|
y = textRange.boundingTop;
|
||||||
|
h = textRange.boundingHeight;
|
||||||
|
return {
|
||||||
|
left: x,
|
||||||
|
top: y,
|
||||||
|
height: h
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
InputCaret.prototype.getOffset = function(pos) {
|
||||||
|
var $inputor, offset, position;
|
||||||
|
$inputor = this.$inputor;
|
||||||
|
if (oDocument.selection) {
|
||||||
|
offset = this.getIEOffset(pos);
|
||||||
|
offset.top += $(oWindow).scrollTop() + $inputor.scrollTop();
|
||||||
|
offset.left += $(oWindow).scrollLeft() + $inputor.scrollLeft();
|
||||||
|
return offset;
|
||||||
|
} else {
|
||||||
|
offset = $inputor.offset();
|
||||||
|
position = this.getPosition(pos);
|
||||||
|
return offset = {
|
||||||
|
left: offset.left + position.left - $inputor.scrollLeft(),
|
||||||
|
top: offset.top + position.top - $inputor.scrollTop(),
|
||||||
|
height: position.height
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
InputCaret.prototype.getPosition = function(pos) {
|
||||||
|
var $inputor, at_rect, end_range, format, html, mirror, start_range;
|
||||||
|
$inputor = this.$inputor;
|
||||||
|
format = function(value) {
|
||||||
|
value = value.replace(/<|>|`|"|&/g, '?').replace(/\r\n|\r|\n/g, "<br/>");
|
||||||
|
if (/firefox/i.test(navigator.userAgent)) {
|
||||||
|
value = value.replace(/\s/g, ' ');
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
if (pos === void 0) {
|
||||||
|
pos = this.getPos();
|
||||||
|
}
|
||||||
|
start_range = $inputor.val().slice(0, pos);
|
||||||
|
end_range = $inputor.val().slice(pos);
|
||||||
|
html = "<span style='position: relative; display: inline;'>" + format(start_range) + "</span>";
|
||||||
|
html += "<span id='caret' style='position: relative; display: inline;'>|</span>";
|
||||||
|
html += "<span style='position: relative; display: inline;'>" + format(end_range) + "</span>";
|
||||||
|
mirror = new Mirror($inputor);
|
||||||
|
return at_rect = mirror.create(html).rect();
|
||||||
|
};
|
||||||
|
|
||||||
|
InputCaret.prototype.getIEPosition = function(pos) {
|
||||||
|
var h, inputorOffset, offset, x, y;
|
||||||
|
offset = this.getIEOffset(pos);
|
||||||
|
inputorOffset = this.$inputor.offset();
|
||||||
|
x = offset.left - inputorOffset.left;
|
||||||
|
y = offset.top - inputorOffset.top;
|
||||||
|
h = offset.height;
|
||||||
|
return {
|
||||||
|
left: x,
|
||||||
|
top: y,
|
||||||
|
height: h
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
return InputCaret;
|
||||||
|
|
||||||
|
})();
|
||||||
|
|
||||||
|
Mirror = (function() {
|
||||||
|
Mirror.prototype.css_attr = ["borderBottomWidth", "borderLeftWidth", "borderRightWidth", "borderTopStyle", "borderRightStyle", "borderBottomStyle", "borderLeftStyle", "borderTopWidth", "boxSizing", "fontFamily", "fontSize", "fontWeight", "height", "letterSpacing", "lineHeight", "marginBottom", "marginLeft", "marginRight", "marginTop", "outlineWidth", "overflow", "overflowX", "overflowY", "paddingBottom", "paddingLeft", "paddingRight", "paddingTop", "textAlign", "textOverflow", "textTransform", "whiteSpace", "wordBreak", "wordWrap"];
|
||||||
|
|
||||||
|
function Mirror($inputor) {
|
||||||
|
this.$inputor = $inputor;
|
||||||
|
}
|
||||||
|
|
||||||
|
Mirror.prototype.mirrorCss = function() {
|
||||||
|
var css,
|
||||||
|
_this = this;
|
||||||
|
css = {
|
||||||
|
position: 'absolute',
|
||||||
|
left: -9999,
|
||||||
|
top: 0,
|
||||||
|
zIndex: -20000
|
||||||
|
};
|
||||||
|
if (this.$inputor.prop('tagName') === 'TEXTAREA') {
|
||||||
|
this.css_attr.push('width');
|
||||||
|
}
|
||||||
|
$.each(this.css_attr, function(i, p) {
|
||||||
|
return css[p] = _this.$inputor.css(p);
|
||||||
|
});
|
||||||
|
return css;
|
||||||
|
};
|
||||||
|
|
||||||
|
Mirror.prototype.create = function(html) {
|
||||||
|
this.$mirror = $('<div></div>');
|
||||||
|
this.$mirror.css(this.mirrorCss());
|
||||||
|
this.$mirror.html(html);
|
||||||
|
this.$inputor.after(this.$mirror);
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
Mirror.prototype.rect = function() {
|
||||||
|
var $flag, pos, rect;
|
||||||
|
$flag = this.$mirror.find("#caret");
|
||||||
|
pos = $flag.position();
|
||||||
|
rect = {
|
||||||
|
left: pos.left,
|
||||||
|
top: pos.top,
|
||||||
|
height: $flag.height()
|
||||||
|
};
|
||||||
|
this.$mirror.remove();
|
||||||
|
return rect;
|
||||||
|
};
|
||||||
|
|
||||||
|
return Mirror;
|
||||||
|
|
||||||
|
})();
|
||||||
|
|
||||||
|
Utils = {
|
||||||
|
contentEditable: function($inputor) {
|
||||||
|
return !!($inputor[0].contentEditable && $inputor[0].contentEditable === 'true');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
methods = {
|
||||||
|
pos: function(pos) {
|
||||||
|
if (pos || pos === 0) {
|
||||||
|
return this.setPos(pos);
|
||||||
|
} else {
|
||||||
|
return this.getPos();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
position: function(pos) {
|
||||||
|
if (oDocument.selection) {
|
||||||
|
return this.getIEPosition(pos);
|
||||||
|
} else {
|
||||||
|
return this.getPosition(pos);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
offset: function(pos) {
|
||||||
|
var offset;
|
||||||
|
offset = this.getOffset(pos);
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
oDocument = null;
|
||||||
|
|
||||||
|
oWindow = null;
|
||||||
|
|
||||||
|
oFrame = null;
|
||||||
|
|
||||||
|
setContextBy = function(settings) {
|
||||||
|
var iframe;
|
||||||
|
if (iframe = settings != null ? settings.iframe : void 0) {
|
||||||
|
oFrame = iframe;
|
||||||
|
oWindow = iframe.contentWindow;
|
||||||
|
return oDocument = iframe.contentDocument || oWindow.document;
|
||||||
|
} else {
|
||||||
|
oFrame = void 0;
|
||||||
|
oWindow = window;
|
||||||
|
return oDocument = document;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
discoveryIframeOf = function($dom) {
|
||||||
|
var error;
|
||||||
|
oDocument = $dom[0].ownerDocument;
|
||||||
|
oWindow = oDocument.defaultView || oDocument.parentWindow;
|
||||||
|
try {
|
||||||
|
return oFrame = oWindow.frameElement;
|
||||||
|
} catch (_error) {
|
||||||
|
error = _error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$.fn.caret = function(method, value, settings) {
|
||||||
|
var caret;
|
||||||
|
if (methods[method]) {
|
||||||
|
if ($.isPlainObject(value)) {
|
||||||
|
setContextBy(value);
|
||||||
|
value = void 0;
|
||||||
|
} else {
|
||||||
|
setContextBy(settings);
|
||||||
|
}
|
||||||
|
caret = Utils.contentEditable(this) ? new EditableCaret(this) : new InputCaret(this);
|
||||||
|
return methods[method].apply(caret, [value]);
|
||||||
|
} else {
|
||||||
|
return $.error("Method " + method + " does not exist on jQuery.caret");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$.fn.caret.EditableCaret = EditableCaret;
|
||||||
|
|
||||||
|
$.fn.caret.InputCaret = InputCaret;
|
||||||
|
|
||||||
|
$.fn.caret.Utils = Utils;
|
||||||
|
|
||||||
|
$.fn.caret.apis = methods;
|
||||||
|
|
||||||
|
|
||||||
|
}));
|
9365
vendor/assets/javascripts/pdf.js
vendored
Executable file
9365
vendor/assets/javascripts/pdf.js
vendored
Executable file
File diff suppressed because it is too large
Load diff
6
vendor/assets/javascripts/pdf.min.js
vendored
Executable file
6
vendor/assets/javascripts/pdf.min.js
vendored
Executable file
File diff suppressed because one or more lines are too long
38338
vendor/assets/javascripts/pdf.worker.js
vendored
Executable file
38338
vendor/assets/javascripts/pdf.worker.js
vendored
Executable file
File diff suppressed because it is too large
Load diff
19
vendor/assets/javascripts/pdf.worker.min.js
vendored
Executable file
19
vendor/assets/javascripts/pdf.worker.min.js
vendored
Executable file
File diff suppressed because one or more lines are too long
2235
vendor/assets/javascripts/xterm/xterm.js
vendored
Normal file
2235
vendor/assets/javascripts/xterm/xterm.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
1
vendor/prometheus/values.yaml
vendored
1
vendor/prometheus/values.yaml
vendored
|
@ -14,6 +14,7 @@ rbac:
|
||||||
create: false
|
create: false
|
||||||
|
|
||||||
server:
|
server:
|
||||||
|
fullnameOverride: "prometheus-prometheus-server"
|
||||||
image:
|
image:
|
||||||
tag: v2.1.0
|
tag: v2.1.0
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue