diff options
Diffstat (limited to 'app')
28 files changed, 388 insertions, 185 deletions
diff --git a/app/assets/javascripts/ide/components/commit_sidebar/actions.vue b/app/assets/javascripts/ide/components/commit_sidebar/actions.vue index 2cbd982af19..45321df191c 100644 --- a/app/assets/javascripts/ide/components/commit_sidebar/actions.vue +++ b/app/assets/javascripts/ide/components/commit_sidebar/actions.vue @@ -1,41 +1,27 @@ <script> - import { mapState } from 'vuex'; - import { sprintf, __ } from '~/locale'; - import * as consts from '../../stores/modules/commit/constants'; - import RadioGroup from './radio_group.vue'; +import { mapState } from 'vuex'; +import { sprintf, __ } from '~/locale'; +import * as consts from '../../stores/modules/commit/constants'; +import RadioGroup from './radio_group.vue'; - export default { - components: { - RadioGroup, +export default { + components: { + RadioGroup, + }, + computed: { + ...mapState(['currentBranchId']), + commitToCurrentBranchText() { + return sprintf( + __('Commit to %{branchName} branch'), + { branchName: `<strong class="monospace">${this.currentBranchId}</strong>` }, + false, + ); }, - computed: { - ...mapState([ - 'currentBranchId', - ]), - newMergeRequestHelpText() { - return sprintf( - __('Creates a new branch from %{branchName} and re-directs to create a new merge request'), - { branchName: this.currentBranchId }, - ); - }, - commitToCurrentBranchText() { - return sprintf( - __('Commit to %{branchName} branch'), - { branchName: `<strong>${this.currentBranchId}</strong>` }, - false, - ); - }, - commitToNewBranchText() { - return sprintf( - __('Creates a new branch from %{branchName}'), - { branchName: this.currentBranchId }, - ); - }, - }, - commitToCurrentBranch: consts.COMMIT_TO_CURRENT_BRANCH, - commitToNewBranch: consts.COMMIT_TO_NEW_BRANCH, - commitToNewBranchMR: consts.COMMIT_TO_NEW_BRANCH_MR, - }; + }, + commitToCurrentBranch: consts.COMMIT_TO_CURRENT_BRANCH, + commitToNewBranch: consts.COMMIT_TO_NEW_BRANCH, + commitToNewBranchMR: consts.COMMIT_TO_NEW_BRANCH_MR, +}; </script> <template> @@ -53,13 +39,11 @@ :value="$options.commitToNewBranch" :label="__('Create a new branch')" :show-input="true" - :help-text="commitToNewBranchText" /> <radio-group :value="$options.commitToNewBranchMR" :label="__('Create a new branch and merge request')" :show-input="true" - :help-text="newMergeRequestHelpText" /> </div> </template> diff --git a/app/assets/javascripts/ide/components/commit_sidebar/message_field.vue b/app/assets/javascripts/ide/components/commit_sidebar/message_field.vue new file mode 100644 index 00000000000..dcd934f76b7 --- /dev/null +++ b/app/assets/javascripts/ide/components/commit_sidebar/message_field.vue @@ -0,0 +1,130 @@ +<script> +import { __, sprintf } from '../../../locale'; +import Icon from '../../../vue_shared/components/icon.vue'; +import popover from '../../../vue_shared/directives/popover'; +import { MAX_TITLE_LENGTH, MAX_BODY_LENGTH } from '../../constants'; + +export default { + directives: { + popover, + }, + components: { + Icon, + }, + props: { + text: { + type: String, + required: true, + }, + }, + data() { + return { + scrollTop: 0, + isFocused: false, + }; + }, + computed: { + allLines() { + return this.text.split('\n').map((line, i) => ({ + text: line.substr(0, this.getLineLength(i)) || ' ', + highlightedText: line.substr(this.getLineLength(i)), + })); + }, + }, + methods: { + handleScroll() { + if (this.$refs.textarea) { + this.$nextTick(() => { + this.scrollTop = this.$refs.textarea.scrollTop; + }); + } + }, + getLineLength(i) { + return i === 0 ? MAX_TITLE_LENGTH : MAX_BODY_LENGTH; + }, + onInput(e) { + this.$emit('input', e.target.value); + }, + updateIsFocused(isFocused) { + this.isFocused = isFocused; + }, + }, + popoverOptions: { + trigger: 'hover', + placement: 'top', + content: sprintf( + __(` + The character highligher helps you keep the subject line to %{titleLength} characters + and wrap the body at %{bodyLength} so they are readable in git. + `), + { titleLength: MAX_TITLE_LENGTH, bodyLength: MAX_BODY_LENGTH }, + ), + }, +}; +</script> + +<template> + <fieldset class="common-note-form ide-commit-message-field"> + <div + class="md-area" + :class="{ + 'is-focused': isFocused + }" + > + <div + v-once + class="md-header" + > + <ul class="nav-links"> + <li> + {{ __('Commit Message') }} + <span + v-popover="$options.popoverOptions" + class="help-block prepend-left-10" + > + <icon + name="question" + /> + </span> + </li> + </ul> + </div> + <div class="ide-commit-message-textarea-container"> + <div class="ide-commit-message-highlights-container"> + <div + class="note-textarea highlights monospace" + :style="{ + transform: `translate3d(0, ${-scrollTop}px, 0)` + }" + > + <div + v-for="(line, index) in allLines" + :key="index" + > + <span + v-text="line.text" + > + </span><mark + v-show="line.highlightedText" + v-text="line.highlightedText" + > + </mark> + </div> + </div> + </div> + <textarea + class="note-textarea ide-commit-message-textarea" + name="commit-message" + :placeholder="__('Write a commit message...')" + :value="text" + @scroll="handleScroll" + @input="onInput" + @focus="updateIsFocused(true)" + @blur="updateIsFocused(false)" + ref="textarea" + > + </textarea> + </div> + </div> + </fieldset> +</template> diff --git a/app/assets/javascripts/ide/components/commit_sidebar/radio_group.vue b/app/assets/javascripts/ide/components/commit_sidebar/radio_group.vue index 4310d762c78..b660a2961cb 100644 --- a/app/assets/javascripts/ide/components/commit_sidebar/radio_group.vue +++ b/app/assets/javascripts/ide/components/commit_sidebar/radio_group.vue @@ -1,52 +1,40 @@ <script> - import { mapActions, mapState, mapGetters } from 'vuex'; - import tooltip from '~/vue_shared/directives/tooltip'; +import { mapActions, mapState, mapGetters } from 'vuex'; +import tooltip from '~/vue_shared/directives/tooltip'; - export default { - directives: { - tooltip, +export default { + directives: { + tooltip, + }, + props: { + value: { + type: String, + required: true, }, - props: { - value: { - type: String, - required: true, - }, - label: { - type: String, - required: false, - default: null, - }, - checked: { - type: Boolean, - required: false, - default: false, - }, - showInput: { - type: Boolean, - required: false, - default: false, - }, - helpText: { - type: String, - required: false, - default: null, - }, + label: { + type: String, + required: false, + default: null, }, - computed: { - ...mapState('commit', [ - 'commitAction', - ]), - ...mapGetters('commit', [ - 'newBranchName', - ]), + checked: { + type: Boolean, + required: false, + default: false, }, - methods: { - ...mapActions('commit', [ - 'updateCommitAction', - 'updateBranchName', - ]), + showInput: { + type: Boolean, + required: false, + default: false, }, - }; + }, + computed: { + ...mapState('commit', ['commitAction']), + ...mapGetters('commit', ['newBranchName']), + }, + methods: { + ...mapActions('commit', ['updateCommitAction', 'updateBranchName']), + }, +}; </script> <template> @@ -65,18 +53,6 @@ {{ label }} </template> <slot v-else></slot> - <span - v-if="helpText" - v-tooltip - class="help-block inline" - :title="helpText" - > - <i - class="fa fa-question-circle" - aria-hidden="true" - > - </i> - </span> </span> </label> <div @@ -85,7 +61,7 @@ > <input type="text" - class="form-control" + class="form-control monospace" :placeholder="newBranchName" @input="updateBranchName($event.target.value)" /> diff --git a/app/assets/javascripts/ide/components/repo_commit_section.vue b/app/assets/javascripts/ide/components/repo_commit_section.vue index d885ed5e301..14673754503 100644 --- a/app/assets/javascripts/ide/components/repo_commit_section.vue +++ b/app/assets/javascripts/ide/components/repo_commit_section.vue @@ -5,6 +5,7 @@ import icon from '~/vue_shared/components/icon.vue'; import DeprecatedModal from '~/vue_shared/components/deprecated_modal.vue'; import LoadingButton from '~/vue_shared/components/loading_button.vue'; import commitFilesList from './commit_sidebar/list.vue'; +import CommitMessageField from './commit_sidebar/message_field.vue'; import * as consts from '../stores/modules/commit/constants'; import Actions from './commit_sidebar/actions.vue'; @@ -15,6 +16,7 @@ export default { commitFilesList, Actions, LoadingButton, + CommitMessageField, }, directives: { tooltip, @@ -38,15 +40,9 @@ export default { 'changedFiles', ]), ...mapState('commit', ['commitMessage', 'submitCommitLoading']), - ...mapGetters('commit', [ - 'commitButtonDisabled', - 'discardDraftButtonDisabled', - 'branchName', - ]), + ...mapGetters('commit', ['commitButtonDisabled', 'discardDraftButtonDisabled', 'branchName']), statusSvg() { - return this.lastCommitMsg - ? this.committedStateSvgPath - : this.noChangesStateSvgPath; + return this.lastCommitMsg ? this.committedStateSvgPath : this.noChangesStateSvgPath; }, }, methods: { @@ -64,9 +60,7 @@ export default { }); }, forceCreateNewBranch() { - return this.updateCommitAction(consts.COMMIT_TO_NEW_BRANCH).then(() => - this.commitChanges(), - ); + return this.updateCommitAction(consts.COMMIT_TO_NEW_BRANCH).then(() => this.commitChanges()); }, }, }; @@ -105,16 +99,10 @@ export default { @submit.prevent.stop="commitChanges" v-if="!rightPanelCollapsed" > - <div class="multi-file-commit-fieldset"> - <textarea - class="form-control multi-file-commit-message" - name="commit-message" - :value="commitMessage" - :placeholder="__('Write a commit message...')" - @input="updateCommitMessage($event.target.value)" - > - </textarea> - </div> + <commit-message-field + :text="commitMessage" + @input="updateCommitMessage" + /> <div class="clearfix prepend-top-15"> <actions /> <loading-button diff --git a/app/assets/javascripts/ide/constants.js b/app/assets/javascripts/ide/constants.js new file mode 100644 index 00000000000..b60d042e0be --- /dev/null +++ b/app/assets/javascripts/ide/constants.js @@ -0,0 +1,3 @@ +// Fuzzy file finder +export const MAX_TITLE_LENGTH = 50; +export const MAX_BODY_LENGTH = 72; diff --git a/app/assets/javascripts/ide/stores/actions/project.js b/app/assets/javascripts/ide/stores/actions/project.js index b3882cb8d21..4eb23b2ee0f 100644 --- a/app/assets/javascripts/ide/stores/actions/project.js +++ b/app/assets/javascripts/ide/stores/actions/project.js @@ -5,45 +5,71 @@ import * as types from '../mutation_types'; export const getProjectData = ( { commit, state, dispatch }, { namespace, projectId, force = false } = {}, -) => new Promise((resolve, reject) => { - if (!state.projects[`${namespace}/${projectId}`] || force) { - commit(types.TOGGLE_LOADING, { entry: state }); - service.getProjectData(namespace, projectId) - .then(res => res.data) - .then((data) => { +) => + new Promise((resolve, reject) => { + if (!state.projects[`${namespace}/${projectId}`] || force) { commit(types.TOGGLE_LOADING, { entry: state }); - commit(types.SET_PROJECT, { projectPath: `${namespace}/${projectId}`, project: data }); - if (!state.currentProjectId) commit(types.SET_CURRENT_PROJECT, `${namespace}/${projectId}`); - resolve(data); - }) - .catch(() => { - flash('Error loading project data. Please try again.', 'alert', document, null, false, true); - reject(new Error(`Project not loaded ${namespace}/${projectId}`)); - }); - } else { - resolve(state.projects[`${namespace}/${projectId}`]); - } -}); + service + .getProjectData(namespace, projectId) + .then(res => res.data) + .then(data => { + commit(types.TOGGLE_LOADING, { entry: state }); + commit(types.SET_PROJECT, { projectPath: `${namespace}/${projectId}`, project: data }); + if (!state.currentProjectId) + commit(types.SET_CURRENT_PROJECT, `${namespace}/${projectId}`); + resolve(data); + }) + .catch(() => { + flash( + 'Error loading project data. Please try again.', + 'alert', + document, + null, + false, + true, + ); + reject(new Error(`Project not loaded ${namespace}/${projectId}`)); + }); + } else { + resolve(state.projects[`${namespace}/${projectId}`]); + } + }); export const getBranchData = ( { commit, state, dispatch }, { projectId, branchId, force = false } = {}, -) => new Promise((resolve, reject) => { - if ((typeof state.projects[`${projectId}`] === 'undefined' || - !state.projects[`${projectId}`].branches[branchId]) - || force) { - service.getBranchData(`${projectId}`, branchId) - .then(({ data }) => { - const { id } = data.commit; - commit(types.SET_BRANCH, { projectPath: `${projectId}`, branchName: branchId, branch: data }); - commit(types.SET_BRANCH_WORKING_REFERENCE, { projectId, branchId, reference: id }); - resolve(data); - }) - .catch(() => { - flash('Error loading branch data. Please try again.', 'alert', document, null, false, true); - reject(new Error(`Branch not loaded - ${projectId}/${branchId}`)); - }); - } else { - resolve(state.projects[`${projectId}`].branches[branchId]); - } -}); +) => + new Promise((resolve, reject) => { + if ( + typeof state.projects[`${projectId}`] === 'undefined' || + !state.projects[`${projectId}`].branches[branchId] || + force + ) { + service + .getBranchData(`${projectId}`, branchId) + .then(({ data }) => { + const { id } = data.commit; + commit(types.SET_BRANCH, { + projectPath: `${projectId}`, + branchName: branchId, + branch: data, + }); + commit(types.SET_BRANCH_WORKING_REFERENCE, { projectId, branchId, reference: id }); + commit(types.SET_CURRENT_BRANCH, branchId); + resolve(data); + }) + .catch(() => { + flash( + 'Error loading branch data. Please try again.', + 'alert', + document, + null, + false, + true, + ); + reject(new Error(`Branch not loaded - ${projectId}/${branchId}`)); + }); + } else { + resolve(state.projects[`${projectId}`].branches[branchId]); + } + }); diff --git a/app/assets/stylesheets/pages/commits.scss b/app/assets/stylesheets/pages/commits.scss index 86cdda0359e..e9384d41e00 100644 --- a/app/assets/stylesheets/pages/commits.scss +++ b/app/assets/stylesheets/pages/commits.scss @@ -180,10 +180,6 @@ justify-content: space-between; align-items: center; flex-grow: 1; - - .merge-request-branches & { - flex-direction: column; - } } .commit-content { diff --git a/app/assets/stylesheets/pages/repo.scss b/app/assets/stylesheets/pages/repo.scss index 5f46e69a56d..f58f2579050 100644 --- a/app/assets/stylesheets/pages/repo.scss +++ b/app/assets/stylesheets/pages/repo.scss @@ -662,11 +662,6 @@ } } -.multi-file-commit-message.form-control { - height: 160px; - resize: none; -} - .dirty-diff { // !important need to override monaco inline style width: 4px !important; @@ -839,3 +834,74 @@ align-items: center; font-weight: $gl-font-weight-bold; } + +.ide-commit-message-field { + height: 200px; + background-color: $white-light; + + .md-area { + display: flex; + flex-direction: column; + height: 100%; + } + + .nav-links { + height: 30px; + } + + .help-block { + margin-top: 2px; + color: $blue-500; + cursor: pointer; + } +} + +.ide-commit-message-textarea-container { + position: relative; + width: 100%; + height: 100%; + overflow: hidden; + + .note-textarea { + font-family: $monospace_font; + } +} + +.ide-commit-message-highlights-container { + position: absolute; + left: 0; + top: 0; + right: -100px; + bottom: 0; + padding-right: 100px; + pointer-events: none; + z-index: 1; + + .highlights { + white-space: pre-wrap; + word-wrap: break-word; + color: transparent; + } + + mark { + margin-left: -1px; + padding: 0 2px; + border-radius: $border-radius-small; + background-color: $orange-200; + color: transparent; + opacity: 0.6; + } +} + +.ide-commit-message-textarea { + position: absolute; + left: 0; + top: 0; + right: 0; + bottom: 0; + width: 100%; + height: 100%; + z-index: 2; + background: transparent; + resize: none; +} diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 24651dd392c..0fdd4d2cb47 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -5,6 +5,7 @@ class ApplicationController < ActionController::Base include Gitlab::GonHelper include GitlabRoutingHelper include PageLayoutHelper + include SafeParamsHelper include SentryHelper include WorkhorseHelper include EnforcesTwoFactorAuthentication diff --git a/app/controllers/dashboard/todos_controller.rb b/app/controllers/dashboard/todos_controller.rb index e89eaf7edda..f9e8fe624e8 100644 --- a/app/controllers/dashboard/todos_controller.rb +++ b/app/controllers/dashboard/todos_controller.rb @@ -86,7 +86,7 @@ class Dashboard::TodosController < Dashboard::ApplicationController out_of_range = todos.current_page > total_pages if out_of_range - redirect_to url_for(params.merge(page: total_pages, only_path: true)) + redirect_to url_for(safe_params.merge(page: total_pages, only_path: true)) end out_of_range diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb index 5ac4b8710e2..79fa5818359 100644 --- a/app/controllers/groups_controller.rb +++ b/app/controllers/groups_controller.rb @@ -189,6 +189,6 @@ class GroupsController < Groups::ApplicationController params[:id] = group.to_param - url_for(params) + url_for(safe_params) end end diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 37f14230196..a93b116c6fe 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -404,7 +404,7 @@ class ProjectsController < Projects::ApplicationController params[:namespace_id] = project.namespace.to_param params[:id] = project.to_param - url_for(params) + url_for(safe_params) end def project_export_enabled diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 956df4a0a16..31f47a7aa7c 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -146,6 +146,6 @@ class UsersController < ApplicationController end def build_canonical_path(user) - url_for(params.merge(username: user.to_param)) + url_for(safe_params.merge(username: user.to_param)) end end diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb index 866b8773db6..fef29789832 100644 --- a/app/helpers/blob_helper.rb +++ b/app/helpers/blob_helper.rb @@ -259,7 +259,7 @@ module BlobHelper options = [] if error == :collapsed - options << link_to('load it anyway', url_for(params.merge(viewer: viewer.type, expanded: true, format: nil))) + options << link_to('load it anyway', url_for(safe_params.merge(viewer: viewer.type, expanded: true, format: nil))) end # If the error is `:server_side_but_stored_externally`, the simple viewer will show the same error, diff --git a/app/helpers/diff_helper.rb b/app/helpers/diff_helper.rb index b5ca39711bc..1bb82fd8150 100644 --- a/app/helpers/diff_helper.rb +++ b/app/helpers/diff_helper.rb @@ -180,7 +180,7 @@ module DiffHelper private def diff_btn(title, name, selected) - params_copy = params.dup + params_copy = safe_params.dup params_copy[:view] = name # Always use HTML to handle case where JSON diff rendered this button diff --git a/app/helpers/safe_params_helper.rb b/app/helpers/safe_params_helper.rb new file mode 100644 index 00000000000..b568e8810cc --- /dev/null +++ b/app/helpers/safe_params_helper.rb @@ -0,0 +1,11 @@ +module SafeParamsHelper + # Rails 5.0 requires to permit `params` if they're used in url helpers. + # Use this helper when generating links with `params.merge(...)` + def safe_params + if params.respond_to?(:permit!) + params.except(:host, :port, :protocol).permit! + else + params + end + end +end diff --git a/app/models/concerns/cache_markdown_field.rb b/app/models/concerns/cache_markdown_field.rb index 4ae5dd8c677..db8cf322ef7 100644 --- a/app/models/concerns/cache_markdown_field.rb +++ b/app/models/concerns/cache_markdown_field.rb @@ -11,7 +11,9 @@ module CacheMarkdownField extend ActiveSupport::Concern # Increment this number every time the renderer changes its output - CACHE_VERSION = 3 + CACHE_REDCARPET_VERSION = 3 + CACHE_COMMONMARK_VERSION_START = 10 + CACHE_COMMONMARK_VERSION = 11 # changes to these attributes cause the cache to be invalidates INVALIDATED_BY = %w[author project].freeze @@ -49,12 +51,14 @@ module CacheMarkdownField # Always include a project key, or Banzai complains project = self.project if self.respond_to?(:project) - group = self.group if self.respond_to?(:group) + group = self.group if self.respond_to?(:group) context = cached_markdown_fields[field].merge(project: project, group: group) # Banzai is less strict about authors, so don't always have an author key context[:author] = self.author if self.respond_to?(:author) + context[:markdown_engine] = markdown_engine + context end @@ -69,7 +73,7 @@ module CacheMarkdownField Banzai::Renderer.cacheless_render_field(self, markdown_field, options) ] end.to_h - updates['cached_markdown_version'] = CacheMarkdownField::CACHE_VERSION + updates['cached_markdown_version'] = latest_cached_markdown_version updates.each {|html_field, data| write_attribute(html_field, data) } end @@ -90,7 +94,7 @@ module CacheMarkdownField markdown_changed = attribute_changed?(markdown_field) || false html_changed = attribute_changed?(html_field) || false - CacheMarkdownField::CACHE_VERSION == cached_markdown_version && + latest_cached_markdown_version == cached_markdown_version && (html_changed || markdown_changed == html_changed) end @@ -109,6 +113,24 @@ module CacheMarkdownField __send__(cached_markdown_fields.html_field(markdown_field)) # rubocop:disable GitlabSecurity/PublicSend end + def latest_cached_markdown_version + return CacheMarkdownField::CACHE_REDCARPET_VERSION unless cached_markdown_version + + if cached_markdown_version < CacheMarkdownField::CACHE_COMMONMARK_VERSION_START + CacheMarkdownField::CACHE_REDCARPET_VERSION + else + CacheMarkdownField::CACHE_COMMONMARK_VERSION + end + end + + def markdown_engine + if latest_cached_markdown_version < CacheMarkdownField::CACHE_COMMONMARK_VERSION_START + :redcarpet + else + :common_mark + end + end + included do cattr_reader :cached_markdown_fields do FieldData.new diff --git a/app/views/dashboard/issues.atom.builder b/app/views/dashboard/issues.atom.builder index 70ec6bc6257..d7b6fb9a4a1 100644 --- a/app/views/dashboard/issues.atom.builder +++ b/app/views/dashboard/issues.atom.builder @@ -1,5 +1,5 @@ xml.title "#{current_user.name} issues" -xml.link href: url_for(params), rel: "self", type: "application/atom+xml" +xml.link href: url_for(safe_params), rel: "self", type: "application/atom+xml" xml.link href: issues_dashboard_url, rel: "alternate", type: "text/html" xml.id issues_dashboard_url xml.updated @issues.first.updated_at.xmlschema if @issues.reorder(nil).any? diff --git a/app/views/dashboard/issues.html.haml b/app/views/dashboard/issues.html.haml index bb472b4c900..4bf04dadf01 100644 --- a/app/views/dashboard/issues.html.haml +++ b/app/views/dashboard/issues.html.haml @@ -2,12 +2,12 @@ - page_title _("Issues") - @breadcrumb_link = issues_dashboard_path(assignee_id: current_user.id) = content_for :meta_tags do - = auto_discovery_link_tag(:atom, params.merge(rss_url_options), title: "#{current_user.name} issues") + = auto_discovery_link_tag(:atom, safe_params.merge(rss_url_options).to_h, title: "#{current_user.name} issues") .top-area = render 'shared/issuable/nav', type: :issues, display_count: !@no_filters_set .nav-controls - = link_to params.merge(rss_url_options), class: 'btn has-tooltip', data: { container: 'body' }, title: 'Subscribe' do + = link_to safe_params.merge(rss_url_options), class: 'btn has-tooltip', data: { container: 'body' }, title: 'Subscribe' do = icon('rss') = render 'shared/new_project_item_select', path: 'issues/new', label: "New issue", with_feature_enabled: 'issues', type: :issues diff --git a/app/views/groups/issues.atom.builder b/app/views/groups/issues.atom.builder index a239ea8caf0..2a385b661e5 100644 --- a/app/views/groups/issues.atom.builder +++ b/app/views/groups/issues.atom.builder @@ -1,5 +1,5 @@ xml.title "#{@group.name} issues" -xml.link href: url_for(params), rel: "self", type: "application/atom+xml" +xml.link href: url_for(safe_params), rel: "self", type: "application/atom+xml" xml.link href: issues_group_url, rel: "alternate", type: "text/html" xml.id issues_group_url xml.updated @issues.first.updated_at.xmlschema if @issues.reorder(nil).any? diff --git a/app/views/groups/issues.html.haml b/app/views/groups/issues.html.haml index 36df03302e8..bbfbea4ac7a 100644 --- a/app/views/groups/issues.html.haml +++ b/app/views/groups/issues.html.haml @@ -1,6 +1,6 @@ - page_title "Issues" = content_for :meta_tags do - = auto_discovery_link_tag(:atom, params.merge(rss_url_options), title: "#{@group.name} issues") + = auto_discovery_link_tag(:atom, safe_params.merge(rss_url_options).to_h, title: "#{@group.name} issues") - if group_issues_count(state: 'all').zero? = render 'shared/empty_states/issues', project_select_button: true diff --git a/app/views/projects/blob/_viewer.html.haml b/app/views/projects/blob/_viewer.html.haml index 9c760c81527..b9663bbba15 100644 --- a/app/views/projects/blob/_viewer.html.haml +++ b/app/views/projects/blob/_viewer.html.haml @@ -4,7 +4,7 @@ - load_async = local_assigns.fetch(:load_async, viewer.load_async? && render_error.nil?) - external_embed = local_assigns.fetch(:external_embed, false) -- viewer_url = local_assigns.fetch(:viewer_url) { url_for(params.merge(viewer: viewer.type, format: :json)) } if load_async +- viewer_url = local_assigns.fetch(:viewer_url) { url_for(safe_params.merge(viewer: viewer.type, format: :json)) } if load_async .blob-viewer{ data: { type: viewer.type, rich_type: rich_type, url: viewer_url }, class: ('hidden' if hidden) } - if render_error = render 'projects/blob/render_error', viewer: viewer diff --git a/app/views/projects/diffs/_collapsed.html.haml b/app/views/projects/diffs/_collapsed.html.haml index 8772bd4705f..5762f4d86d7 100644 --- a/app/views/projects/diffs/_collapsed.html.haml +++ b/app/views/projects/diffs/_collapsed.html.haml @@ -1,5 +1,5 @@ - diff_file = viewer.diff_file -- url = url_for(params.merge(action: :diff_for_path, old_path: diff_file.old_path, new_path: diff_file.new_path, file_identifier: diff_file.file_identifier)) +- url = url_for(safe_params.merge(action: :diff_for_path, old_path: diff_file.old_path, new_path: diff_file.new_path, file_identifier: diff_file.file_identifier)) .nothing-here-block.diff-collapsed{ data: { diff_for_path: url } } This diff is collapsed. %a.click-to-expand Click to expand it. diff --git a/app/views/projects/issues/_nav_btns.html.haml b/app/views/projects/issues/_nav_btns.html.haml index dd1a836fa20..297b928f020 100644 --- a/app/views/projects/issues/_nav_btns.html.haml +++ b/app/views/projects/issues/_nav_btns.html.haml @@ -1,4 +1,4 @@ -= link_to params.merge(rss_url_options), class: 'btn btn-default append-right-10 has-tooltip', title: 'Subscribe' do += link_to safe_params.merge(rss_url_options), class: 'btn btn-default append-right-10 has-tooltip', title: 'Subscribe' do = icon('rss') - if @can_bulk_update = button_tag "Edit issues", class: "btn btn-default append-right-10 js-bulk-update-toggle" diff --git a/app/views/projects/issues/index.atom.builder b/app/views/projects/issues/index.atom.builder index 4029926f373..6330245954e 100644 --- a/app/views/projects/issues/index.atom.builder +++ b/app/views/projects/issues/index.atom.builder @@ -1,5 +1,5 @@ xml.title "#{@project.name} issues" -xml.link href: url_for(params), rel: "self", type: "application/atom+xml" +xml.link href: url_for(safe_params), rel: "self", type: "application/atom+xml" xml.link href: project_issues_url(@project), rel: "alternate", type: "text/html" xml.id project_issues_url(@project) xml.updated @issues.first.updated_at.xmlschema if @issues.reorder(nil).any? diff --git a/app/views/projects/issues/index.html.haml b/app/views/projects/issues/index.html.haml index c427a9eedc2..1e7737aeb97 100644 --- a/app/views/projects/issues/index.html.haml +++ b/app/views/projects/issues/index.html.haml @@ -5,7 +5,7 @@ - new_issue_email = @project.new_issuable_address(current_user, 'issue') = content_for :meta_tags do - = auto_discovery_link_tag(:atom, params.merge(rss_url_options), title: "#{@project.name} issues") + = auto_discovery_link_tag(:atom, safe_params.merge(rss_url_options).to_h, title: "#{@project.name} issues") - if project_issues(@project).exists? %div{ class: (container_class) } diff --git a/app/views/projects/merge_requests/creations/_new_compare.html.haml b/app/views/projects/merge_requests/creations/_new_compare.html.haml index 9d5cebdda53..f81db9b4e28 100644 --- a/app/views/projects/merge_requests/creations/_new_compare.html.haml +++ b/app/views/projects/merge_requests/creations/_new_compare.html.haml @@ -3,7 +3,7 @@ = form_for [@project.namespace.becomes(Namespace), @project, @merge_request], url: project_new_merge_request_path(@project), method: :get, html: { class: "merge-request-form form-inline js-requires-input" } do |f| .hide.alert.alert-danger.mr-compare-errors - .merge-request-branches.js-merge-request-new-compare.row{ 'data-target-project-url': project_new_merge_request_update_branches_path(@source_project), 'data-source-branch-url': project_new_merge_request_branch_from_path(@source_project), 'data-target-branch-url': project_new_merge_request_branch_to_path(@source_project) } + .js-merge-request-new-compare.row{ 'data-target-project-url': project_new_merge_request_update_branches_path(@source_project), 'data-source-branch-url': project_new_merge_request_branch_from_path(@source_project), 'data-target-branch-url': project_new_merge_request_branch_to_path(@source_project) } .col-md-6 .panel.panel-default.panel-new-merge-request .panel-heading diff --git a/app/views/projects/merge_requests/creations/_new_submit.html.haml b/app/views/projects/merge_requests/creations/_new_submit.html.haml index 376ac377562..68780cedeb1 100644 --- a/app/views/projects/merge_requests/creations/_new_submit.html.haml +++ b/app/views/projects/merge_requests/creations/_new_submit.html.haml @@ -26,16 +26,16 @@ - else %ul.merge-request-tabs.nav-links.no-top.no-bottom %li.commits-tab.active - = link_to url_for(params), data: {target: 'div#commits', action: 'new', toggle: 'tab'} do + = link_to url_for(safe_params), data: {target: 'div#commits', action: 'new', toggle: 'tab'} do Commits %span.badge= @commits.size - if @pipelines.any? %li.builds-tab - = link_to url_for(params.merge(action: 'pipelines')), data: {target: 'div#pipelines', action: 'pipelines', toggle: 'tab'} do + = link_to url_for(safe_params.merge(action: 'pipelines')), data: {target: 'div#pipelines', action: 'pipelines', toggle: 'tab'} do Pipelines %span.badge= @pipelines.size %li.diffs-tab - = link_to url_for(params.merge(action: 'diffs')), data: {target: 'div#diffs', action: 'diffs', toggle: 'tab'} do + = link_to url_for(safe_params.merge(action: 'diffs')), data: {target: 'div#diffs', action: 'diffs', toggle: 'tab'} do Changes %span.badge= @merge_request.diff_size @@ -46,7 +46,7 @@ -# This tab is always loaded via AJAX - if @pipelines.any? #pipelines.pipelines.tab-pane - = render 'projects/merge_requests/pipelines', endpoint: url_for(params.merge(action: 'pipelines', format: :json)), disable_initialization: true + = render 'projects/merge_requests/pipelines', endpoint: url_for(safe_params.merge(action: 'pipelines', format: :json)), disable_initialization: true .mr-loading-status = spinner |