Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
2373572b
Commit
2373572b
authored
May 17, 2019
by
GitLab Bot
Browse files
Options
Browse Files
Download
Plain Diff
Automatic merge of gitlab-org/gitlab-ce master
parents
dae9d589
5ba138b1
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
633 additions
and
1 deletion
+633
-1
changelogs/unreleased/mm12935.yml
changelogs/unreleased/mm12935.yml
+5
-0
lib/gitlab/path_regex.rb
lib/gitlab/path_regex.rb
+1
-0
lib/mattermost/session.rb
lib/mattermost/session.rb
+1
-1
public/visual-review-toolbar.js
public/visual-review-toolbar.js
+626
-0
No files found.
changelogs/unreleased/mm12935.yml
0 → 100644
View file @
2373572b
---
title
:
Remove Content-Type override for Mattermost OAuth login
merge_request
:
author
:
Harrison Healey
type
:
removed
lib/gitlab/path_regex.rb
View file @
2373572b
...
...
@@ -58,6 +58,7 @@ module Gitlab
uploads
users
v2
visual-review-toolbar.js
]
.
freeze
# This list should contain all words following `/*namespace_id/:project_id` in
...
...
lib/mattermost/session.rb
View file @
2373572b
...
...
@@ -122,7 +122,7 @@ module Mattermost
@oauth_uri
=
nil
response
=
get
(
'/oauth/gitlab/login'
,
follow_redirects:
false
,
format:
'text/html'
)
response
=
get
(
'/oauth/gitlab/login'
,
follow_redirects:
false
)
return
unless
(
300
...
400
)
===
response
.
code
redirect_uri
=
response
.
headers
[
'location'
]
...
...
public/visual-review-toolbar.js
0 → 100644
View file @
2373572b
///////////////////////////////////////////////
/////////////////// STYLES ////////////////////
///////////////////////////////////////////////
const
buttonClearStyles
=
`
-webkit-appearance: none;
`
;
const
buttonBaseStyles
=
`
cursor: pointer;
transition: background-color 100ms linear, border-color 100ms linear, color 100ms linear, box-shadow 100ms linear;
`
;
const
buttonSuccessActiveStyles
=
`
background-color: #168f48;
border-color: #12753a;
color: #fff;
`
;
const
buttonSuccessHoverStyles
=
`
color: #fff;
background-color: #137e3f;
border-color: #127339;
`
;
const
buttonSuccessStyles
=
`
${
buttonBaseStyles
}
background-color: #1aaa55;
border: 1px solid #168f48;
color: #fff;
`
;
const
buttonSecondaryStyles
=
`
${
buttonBaseStyles
}
background: none #fff;
margin: 0 .5rem;
border: 1px solid #e3e3e3;
`
;
const
buttonSecondaryActiveStyles
=
`
color: #2e2e2e;
background-color: #e1e1e1;
border-color: #dadada;
`
;
const
buttonSecondaryHoverStyles
=
`
background-color: #f0f0f0;
border-color: #e3e3e3;
color: #2e2e2e;
`
;
const
buttonWideStyles
=
`
width: 100%;
`
;
const
buttonWrapperStyles
=
`
margin-top: 1rem;
display: flex;
align-items: baseline;
justify-content: flex-end;
`
;
const
collapseStyles
=
`
${
buttonBaseStyles
}
width: 2.4rem;
height: 2.2rem;
margin-left: 1rem;
padding: .5rem;
`
;
const
collapseClosedStyles
=
`
${
collapseStyles
}
align-self: center;
`
;
const
collapseOpenStyles
=
`
${
collapseStyles
}
`
;
const
checkboxLabelStyles
=
`
padding: 0 .2rem;
`
;
const
checkboxWrapperStyles
=
`
display: flex;
align-items: baseline;
`
;
const
formStyles
=
`
display: flex;
flex-direction: column;
width: 100%
`
;
const
labelStyles
=
`
font-weight: 600;
display: inline-block;
width: 100%;
`
;
const
linkStyles
=
`
color: #1b69b6;
text-decoration: none;
background-color: transparent;
background-image: none;
`
;
const
messageStyles
=
`
padding: .25rem 0;
margin: 0;
line-height: 1.2rem;
`
;
const
metadataNoteStyles
=
`
font-size: .7rem;
line-height: 1rem;
color: #666;
margin-bottom: 0;
`
;
const
inputStyles
=
`
width: 100%;
border: 1px solid #dfdfdf;
border-radius: 4px;
padding: .1rem .2rem;
min-height: 2rem;
max-width: 17rem;
`
;
const
svgInnerStyles
=
`
pointer-events: none;
`
;
const
wrapperClosedStyles
=
`
max-width: 3.4rem;
max-height: 3.4rem;
`
;
const
wrapperOpenStyles
=
`
max-width: 22rem;
max-height: 22rem;
`
;
const
wrapperStyles
=
`
max-width: 22rem;
max-height: 22rem;
overflow: scroll;
position: fixed;
bottom: 1rem;
right: 1rem;
display: flex;
flex-direction: row-reverse;
padding: 1rem;
background-color: #fff;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell,
'Helvetica Neue', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol',
'Noto Color Emoji';
font-size: .8rem;
font-weight: 400;
color: #2e2e2e;
`
;
const
gitlabStyles
=
`
#gitlab-collapse > * {
${
svgInnerStyles
}
}
#gitlab-form-wrapper {
${
formStyles
}
}
#gitlab-review-container {
${
wrapperStyles
}
}
.gitlab-open-wrapper {
${
wrapperOpenStyles
}
}
.gitlab-closed-wrapper {
${
wrapperClosedStyles
}
}
.gitlab-button-secondary {
${
buttonSecondaryStyles
}
}
.gitlab-button-secondary:hover {
${
buttonSecondaryHoverStyles
}
}
.gitlab-button-secondary:active {
${
buttonSecondaryActiveStyles
}
}
.gitlab-button-success:hover {
${
buttonSuccessHoverStyles
}
}
.gitlab-button-success:active {
${
buttonSuccessActiveStyles
}
}
.gitlab-button-success {
${
buttonSuccessStyles
}
}
.gitlab-button-wide {
${
buttonWideStyles
}
}
.gitlab-button-wrapper {
${
buttonWrapperStyles
}
}
.gitlab-collapse-closed {
${
collapseClosedStyles
}
}
.gitlab-collapse-open {
${
collapseOpenStyles
}
}
.gitlab-checkbox-label {
${
checkboxLabelStyles
}
}
.gitlab-checkbox-wrapper {
${
checkboxWrapperStyles
}
}
.gitlab-label {
${
labelStyles
}
}
.gitlab-link {
${
linkStyles
}
}
.gitlab-message {
${
messageStyles
}
}
.gitlab-metadata-note {
${
metadataNoteStyles
}
}
.gitlab-input {
${
inputStyles
}
}
`
;
function
addStylesheet
()
{
const
styleEl
=
document
.
createElement
(
'
style
'
);
styleEl
.
insertAdjacentHTML
(
'
beforeend
'
,
gitlabStyles
);
document
.
head
.
appendChild
(
styleEl
);
}
///////////////////////////////////////////////
/////////////////// STATE ////////////////////
///////////////////////////////////////////////
const
data
=
{};
///////////////////////////////////////////////
///////////////// COMPONENTS //////////////////
///////////////////////////////////////////////
const
note
=
`
<p id='gitlab-validation-note' class='gitlab-message'></p>
`
;
const
comment
=
`
<div>
<textarea id='gitlab-comment' name='gitlab-comment' rows='3' placeholder='Enter your feedback or idea' class='gitlab-input'></textarea>
${
note
}
<p class='gitlab-metadata-note'>Additional metadata will be included: browser, OS, current page, user agent, and viewport dimensions.</p>
</div>
<div class='gitlab-button-wrapper''>
<button class='gitlab-button-secondary' style='
${
buttonClearStyles
}
' type='button' id='gitlab-logout-button'> Logout </button>
<button class='gitlab-button-success' style='
${
buttonClearStyles
}
' type='button' id='gitlab-comment-button'> Send feedback </button>
</div>
`
;
const
commentIcon
=
`
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><title>icn/comment</title><path d="M4 11.132l1.446-.964A1 1 0 0 1 6 10h5a1 1 0 0 0 1-1V5a1 1 0 0 0-1-1H5a1 1 0 0 0-1 1v6.132zM6.303 12l-2.748 1.832A1 1 0 0 1 2 13V5a3 3 0 0 1 3-3h6a3 3 0 0 1 3 3v4a3 3 0 0 1-3 3H6.303z" id="gitlab-comment-icon"/></svg>
`
const
compressIcon
=
`
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><title>icn/compress</title><path d="M5.27 12.182l-1.562 1.561a1 1 0 0 1-1.414 0h-.001a1 1 0 0 1 0-1.415l1.56-1.56L2.44 9.353a.5.5 0 0 1 .353-.854H7.09a.5.5 0 0 1 .5.5v4.294a.5.5 0 0 1-.853.353l-1.467-1.465zm6.911-6.914l1.464 1.464a.5.5 0 0 1-.353.854H8.999a.5.5 0 0 1-.5-.5V2.793a.5.5 0 0 1 .854-.354l1.414 1.415 1.56-1.561a1 1 0 1 1 1.415 1.414l-1.561 1.56z" id="gitlab-compress-icon"/></svg>
`
;
const
collapseButton
=
`
<button id='gitlab-collapse' style='
${
buttonClearStyles
}
' class='gitlab-collapse-open gitlab-button-secondary'>
${
compressIcon
}
</button>
`
;
const
form
=
(
content
)
=>
`
<div id='gitlab-form-wrapper'>
${
content
}
</div>
`
;
const
login
=
`
<div>
<label for='gitlab-token' class='gitlab-label'>Enter your <a class='gitlab-link' href="https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html">personal access token</a></label>
<input class='gitlab-input' type='password' id='gitlab-token' name='gitlab-token'>
${
note
}
</div>
<div class='gitlab-checkbox-wrapper'>
<input type="checkbox" id="remember_token" name="remember_token" value="remember">
<label for="remember_token" class='gitlab-checkbox-label'>Remember me</label>
</div>
<div class='gitlab-button-wrapper'>
<button class='gitlab-button-wide gitlab-button-success' style='
${
buttonClearStyles
}
' type='button' id='gitlab-login'> Submit </button>
</div>
`
;
///////////////////////////////////////////////
//////////////// INTERACTIONS /////////////////
///////////////////////////////////////////////
// from https://developer.mozilla.org/en-US/docs/Web/API/Window/navigator
function
getBrowserId
(
sUsrAg
)
{
var
aKeys
=
[
"
MSIE
"
,
"
Edge
"
,
"
Firefox
"
,
"
Safari
"
,
"
Chrome
"
,
"
Opera
"
],
nIdx
=
aKeys
.
length
-
1
;
for
(
nIdx
;
nIdx
>
-
1
&&
sUsrAg
.
indexOf
(
aKeys
[
nIdx
])
===
-
1
;
nIdx
--
);
return
aKeys
[
nIdx
];
}
function
addCommentForm
()
{
const
formWrapper
=
document
.
getElementById
(
'
gitlab-form-wrapper
'
);
formWrapper
.
innerHTML
=
comment
;
}
function
addLoginForm
()
{
const
formWrapper
=
document
.
getElementById
(
'
gitlab-form-wrapper
'
);
formWrapper
.
innerHTML
=
login
;
}
function
authorizeUser
()
{
// Clear any old errors
clearNote
(
'
gitlab-token
'
);
const
token
=
document
.
getElementById
(
'
gitlab-token
'
).
value
;
const
rememberMe
=
document
.
getElementById
(
'
remember_token
'
).
checked
;
if
(
!
token
)
{
postError
(
'
Please enter your token.
'
,
'
gitlab-token
'
);
return
;
}
if
(
rememberMe
)
{
storeToken
(
token
);
}
authSuccess
(
token
);
return
;
}
function
authSuccess
(
token
)
{
data
.
token
=
token
;
addCommentForm
();
}
function
clearNote
(
inputId
)
{
const
note
=
document
.
getElementById
(
'
gitlab-validation-note
'
);
note
.
innerText
=
''
;
note
.
style
.
color
=
''
;
if
(
inputId
)
{
const
field
=
document
.
getElementById
(
inputId
);
field
.
style
.
borderColor
=
''
;
}
}
function
confirmAndClear
(
discussionId
)
{
const
commentButton
=
document
.
getElementById
(
'
gitlab-comment-button
'
);
const
note
=
document
.
getElementById
(
'
gitlab-validation-note
'
);
commentButton
.
innerText
=
'
Feedback sent
'
;
note
.
innerText
=
`Your comment was successfully posted to issue #
${
discussionId
}
`
;
setTimeout
(
resetCommentButton
,
1000
);
}
function
getInitialState
()
{
const
{
localStorage
}
=
window
;
try
{
let
token
=
localStorage
.
getItem
(
'
token
'
);
if
(
token
)
{
data
.
token
=
token
;
return
comment
;
}
return
login
;
}
catch
(
err
)
{
return
login
;
}
}
function
getProjectDetails
()
{
const
{
innerWidth
,
innerHeight
,
location
:
{
href
},
navigator
:
{
platform
,
userAgent
}
}
=
window
;
const
browser
=
getBrowserId
(
userAgent
);
const
scriptEl
=
document
.
getElementById
(
'
review-app-toolbar-script
'
)
const
{
projectId
,
discussionId
,
mrUrl
}
=
scriptEl
.
dataset
;
return
{
href
,
platform
,
browser
,
userAgent
,
innerWidth
,
innerHeight
,
projectId
,
discussionId
,
mrUrl
,
};
}
function
logoutUser
()
{
const
{
localStorage
}
=
window
;
// All the browsers we support have localStorage, so let's silently fail
// and go on with the rest of the functionality.
try
{
localStorage
.
removeItem
(
'
token
'
);
}
catch
(
err
)
{
return
;
}
addLoginForm
();
}
function
postComment
({
href
,
platform
,
browser
,
userAgent
,
innerWidth
,
innerHeight
,
projectId
,
discussionId
,
mrUrl
,
})
{
// Clear any old errors
clearNote
(
'
gitlab-comment
'
);
setInProgressState
();
const
commentText
=
document
.
getElementById
(
'
gitlab-comment
'
).
value
.
trim
();
if
(
!
commentText
)
{
postError
(
'
Your comment appears to be empty.
'
,
'
gitlab-comment
'
);
resetCommentBox
();
return
;
}
const
detailText
=
`
<details>
<summary>Metadata</summary>
Posted from
${
href
}
|
${
platform
}
|
${
browser
}
|
${
innerWidth
}
x
${
innerHeight
}
.
<br /><br />
*User agent:
${
userAgent
}
*
</details>
`
;
const
url
=
`
${
mrUrl
}
/api/v4/projects/
${
projectId
}
/issues/
${
discussionId
}
/discussions`
;
const
body
=
`
${
commentText
}${
detailText
}
`
;
fetch
(
url
,
{
method
:
'
POST
'
,
headers
:
{
'
PRIVATE-TOKEN
'
:
data
.
token
,
'
Content-Type
'
:
'
application/json
'
,
},
body
:
JSON
.
stringify
({
body
}),
})
.
then
((
response
)
=>
{
if
(
response
.
ok
)
{
confirmAndClear
(
discussionId
);
return
;
}
throw
new
Error
(
`
${
response
.
status
}
:
${
response
.
statusText
}
`
)
})
.
catch
((
err
)
=>
{
postError
(
`The feedback was not sent successfully. Please try again. Error:
${
err
.
message
}
`
,
'
gitlab-comment
'
);
resetCommentBox
();
});
}
function
postError
(
message
,
inputId
)
{
const
note
=
document
.
getElementById
(
'
gitlab-validation-note
'
);
const
field
=
document
.
getElementById
(
inputId
);
field
.
style
.
borderColor
=
'
#db3b21
'
;
note
.
style
.
color
=
'
#db3b21
'
;
note
.
innerText
=
message
;
}
function
resetCommentBox
()
{
const
commentBox
=
document
.
getElementById
(
'
gitlab-comment
'
);
const
commentButton
=
document
.
getElementById
(
'
gitlab-comment-button
'
);
commentButton
.
innerText
=
'
Send feedback
'
;
commentButton
.
classList
.
replace
(
'
gitlab-button-secondary
'
,
'
gitlab-button-success
'
);
commentButton
.
style
.
opacity
=
1
;
commentBox
.
style
.
pointerEvents
=
'
auto
'
;
commentBox
.
style
.
color
=
'
rgba(0, 0, 0, 1)
'
;
}
function
resetCommentButton
()
{
const
commentBox
=
document
.
getElementById
(
'
gitlab-comment
'
);
const
note
=
document
.
getElementById
(
'
gitlab-validation-note
'
);
commentBox
.
value
=
''
;
note
.
innerText
=
''
;
resetCommentBox
();
}
function
setInProgressState
()
{
const
commentButton
=
document
.
getElementById
(
'
gitlab-comment-button
'
);
const
commentBox
=
document
.
getElementById
(
'
gitlab-comment
'
);
commentButton
.
innerText
=
'
Sending feedback
'
;
commentButton
.
classList
.
replace
(
'
gitlab-button-success
'
,
'
gitlab-button-secondary
'
);
commentButton
.
style
.
opacity
=
0.5
;
commentBox
.
style
.
color
=
'
rgba(223, 223, 223, 0.5)
'
;
commentBox
.
style
.
pointerEvents
=
'
none
'
;
}
function
storeToken
(
token
)
{
const
{
localStorage
}
=
window
;
// All the browsers we support have localStorage, so let's silently fail
// and go on with the rest of the functionality.
try
{
localStorage
.
setItem
(
'
token
'
,
token
);
}
catch
(
err
)
{
return
;
}
}
function
toggleForm
()
{
const
container
=
document
.
getElementById
(
'
gitlab-review-container
'
);
const
collapseButton
=
document
.
getElementById
(
'
gitlab-collapse
'
);
const
form
=
document
.
getElementById
(
'
gitlab-form-wrapper
'
);
const
OPEN
=
'
open
'
;
const
CLOSED
=
'
closed
'
;
const
stateVals
=
{
[
OPEN
]:
{
buttonClasses
:
[
'
gitlab-collapse-closed
'
,
'
gitlab-collapse-open
'
],
containerClasses
:
[
'
gitlab-closed-wrapper
'
,
'
gitlab-open-wrapper
'
],
icon
:
compressIcon
,
display
:
'
flex
'
,
backgroundColor
:
'
rgba(255, 255, 255, 1)
'
,
},
[
CLOSED
]:
{
buttonClasses
:
[
'
gitlab-collapse-open
'
,
'
gitlab-collapse-closed
'
],
containerClasses
:
[
'
gitlab-open-wrapper
'
,
'
gitlab-closed-wrapper
'
],
icon
:
commentIcon
,
display
:
'
none
'
,
backgroundColor
:
'
rgba(255, 255, 255, 0)
'
,
},
}
const
nextState
=
collapseButton
.
classList
.
contains
(
'
gitlab-collapse-open
'
)
?
CLOSED
:
OPEN
;
container
.
classList
.
replace
(...
stateVals
[
nextState
].
containerClasses
);
container
.
style
.
backgroundColor
=
stateVals
[
nextState
].
backgroundColor
;
form
.
style
.
display
=
stateVals
[
nextState
].
display
;
collapseButton
.
classList
.
replace
(...
stateVals
[
nextState
].
buttonClasses
);
collapseButton
.
innerHTML
=
stateVals
[
nextState
].
icon
;
}
///////////////////////////////////////////////
///////////////// INJECTION //////////////////
///////////////////////////////////////////////
function
noop
()
{};
const
eventLookup
=
({
target
:
{
id
}})
=>
{
switch
(
id
)
{
case
'
gitlab-collapse
'
:
return
toggleForm
;
case
'
gitlab-comment-button
'
:
const
projectDetails
=
getProjectDetails
();
return
postComment
.
bind
(
null
,
projectDetails
);
case
'
gitlab-login
'
:
return
authorizeUser
;
case
'
gitlab-logout-button
'
:
return
logoutUser
;
default
:
return
noop
;
}
};
window
.
addEventListener
(
'
load
'
,
()
=>
{
const
content
=
getInitialState
();
const
container
=
document
.
createElement
(
'
div
'
);
container
.
setAttribute
(
'
id
'
,
'
gitlab-review-container
'
);
container
.
insertAdjacentHTML
(
'
beforeend
'
,
collapseButton
);
container
.
insertAdjacentHTML
(
'
beforeend
'
,
form
(
content
));
document
.
body
.
insertBefore
(
container
,
document
.
body
.
firstChild
);
addStylesheet
();
document
.
getElementById
(
'
gitlab-review-container
'
).
addEventListener
(
'
click
'
,
(
event
)
=>
{
eventLookup
(
event
)();
});
});
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment