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
379c6a3d
Commit
379c6a3d
authored
Aug 27, 2021
by
Dheeraj Joshi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update popovers to use v-safe-html
- Swaps v-html with v-safe-html - Adds specs for html support
parent
b169a4c1
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
23 additions
and
23 deletions
+23
-23
app/assets/javascripts/popovers/components/popovers.vue
app/assets/javascripts/popovers/components/popovers.vue
+9
-12
spec/frontend/popovers/components/popovers_spec.js
spec/frontend/popovers/components/popovers_spec.js
+14
-11
No files found.
app/assets/javascripts/popovers/components/popovers.vue
View file @
379c6a3d
<
script
>
<
script
>
// We can't use v-safe-html here as the popover's title or content might contains SVGs that would
import
{
GlPopover
,
GlSafeHtmlDirective
}
from
'
@gitlab/ui
'
;
// be stripped by the directive's sanitizer. Instead, we fallback on v-html and we use GitLab's
// dompurify config that lets SVGs be rendered properly.
// Context: https://gitlab.com/gitlab-org/gitlab/-/issues/247207
/* eslint-disable vue/no-v-html */
import
{
GlPopover
}
from
'
@gitlab/ui
'
;
import
{
sanitize
}
from
'
~/lib/dompurify
'
;
const
newPopover
=
(
element
)
=>
{
const
newPopover
=
(
element
)
=>
{
const
{
content
,
html
,
placement
,
title
,
triggers
=
'
focus
'
}
=
element
.
dataset
;
const
{
content
,
html
,
placement
,
title
,
triggers
=
'
focus
'
}
=
element
.
dataset
;
...
@@ -24,6 +18,9 @@ export default {
...
@@ -24,6 +18,9 @@ export default {
components
:
{
components
:
{
GlPopover
,
GlPopover
,
},
},
directives
:
{
SafeHtml
:
GlSafeHtmlDirective
,
},
data
()
{
data
()
{
return
{
return
{
popovers
:
[],
popovers
:
[],
...
@@ -71,9 +68,9 @@ export default {
...
@@ -71,9 +68,9 @@ export default {
popoverExists
(
element
)
{
popoverExists
(
element
)
{
return
this
.
popovers
.
some
((
popover
)
=>
popover
.
target
===
element
);
return
this
.
popovers
.
some
((
popover
)
=>
popover
.
target
===
element
);
},
},
getSafeHtml
(
html
)
{
},
return
sanitize
(
html
);
safeHtmlConfig
:
{
},
ADD_TAGS
:
[
'
use
'
],
// to support icon SVGs
},
},
};
};
</
script
>
</
script
>
...
@@ -82,10 +79,10 @@ export default {
...
@@ -82,10 +79,10 @@ export default {
<div>
<div>
<gl-popover
v-for=
"(popover, index) in popovers"
:key=
"index"
v-bind=
"popover"
>
<gl-popover
v-for=
"(popover, index) in popovers"
:key=
"index"
v-bind=
"popover"
>
<template
#title
>
<template
#title
>
<span
v-if=
"popover.html"
v-
html=
"getSafeHtml(popover.title)
"
></span>
<span
v-if=
"popover.html"
v-
safe-html:
[$
options.safeHtmlConfig]=
"popover.title
"
></span>
<span
v-else
>
{{
popover
.
title
}}
</span>
<span
v-else
>
{{
popover
.
title
}}
</span>
</
template
>
</
template
>
<span
v-if=
"popover.html"
v-
html=
"getSafeHtml(popover.content)
"
></span>
<span
v-if=
"popover.html"
v-
safe-html:
[$
options.safeHtmlConfig]=
"popover.content
"
></span>
<span
v-else
>
{{ popover.content }}
</span>
<span
v-else
>
{{ popover.content }}
</span>
</gl-popover>
</gl-popover>
</div>
</div>
...
...
spec/frontend/popovers/components/popovers_spec.js
View file @
379c6a3d
...
@@ -54,17 +54,20 @@ describe('popovers/components/popovers.vue', () => {
...
@@ -54,17 +54,20 @@ describe('popovers/components/popovers.vue', () => {
expect
(
wrapper
.
findAll
(
GlPopover
)).
toHaveLength
(
1
);
expect
(
wrapper
.
findAll
(
GlPopover
)).
toHaveLength
(
1
);
});
});
it
(
'
supports HTML content
'
,
async
()
=>
{
describe
(
'
supports HTML content
'
,
()
=>
{
const
content
=
'
content with <b>HTML</b>
'
;
const
svgIcon
=
'
<svg><use xlink:href="icons.svg#test"></use></svg>
'
;
await
buildWrapper
(
createPopoverTarget
({
it
.
each
`
content
,
description | content | render
html
:
true
,
${
'
renders html content correctly
'
}
|
${
'
<b>HTML</b>
'
}
|
${
'
<b>HTML</b>
'
}
}),
${
'
removes any unsafe content
'
}
|
${
'
<script>alert(XSS)</script>
'
}
|
${
''
}
);
${
'
renders svg icons correctly
'
}
|
${
svgIcon
}
|
${
svgIcon
}
const
html
=
wrapper
.
find
(
GlPopover
).
html
();
`
(
'
$description
'
,
async
({
content
,
render
})
=>
{
await
buildWrapper
(
createPopoverTarget
({
content
,
html
:
true
}));
expect
(
html
).
toContain
(
content
);
const
html
=
wrapper
.
find
(
GlPopover
).
html
();
expect
(
html
).
toContain
(
render
);
});
});
});
it
.
each
`
it
.
each
`
...
...
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