mirror of
https://github.com/nkanaev/yarr.git
synced 2025-05-24 00:33:14 +00:00
responsive video iframe
This commit is contained in:
parent
da267a56ef
commit
28f08ad42a
@ -360,6 +360,27 @@ select.form-control:not([multiple]):not([size]) {
|
|||||||
margin-bottom: 0.5rem;
|
margin-bottom: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.content .video-wrapper {
|
||||||
|
position: relative;
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content .video-wrapper::before {
|
||||||
|
display: block;
|
||||||
|
padding-top: 56.25%; /* 16x9 aspect ratio */
|
||||||
|
content: "";
|
||||||
|
}
|
||||||
|
|
||||||
|
.content .video-wrapper iframe {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.content pre {
|
.content pre {
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
|
@ -58,19 +58,31 @@ func Sanitize(baseURL, input string) string {
|
|||||||
attrNames, htmlAttributes := sanitizeAttributes(baseURL, tagName, token.Attr)
|
attrNames, htmlAttributes := sanitizeAttributes(baseURL, tagName, token.Attr)
|
||||||
|
|
||||||
if hasRequiredAttributes(tagName, attrNames) {
|
if hasRequiredAttributes(tagName, attrNames) {
|
||||||
|
wrap := isVideoIframe(token)
|
||||||
|
if wrap {
|
||||||
|
buffer.WriteString(`<div class="video-wrapper">`)
|
||||||
|
}
|
||||||
|
|
||||||
if len(attrNames) > 0 {
|
if len(attrNames) > 0 {
|
||||||
buffer.WriteString("<" + tagName + " " + htmlAttributes + ">")
|
buffer.WriteString("<" + tagName + " " + htmlAttributes + ">")
|
||||||
} else {
|
} else {
|
||||||
buffer.WriteString("<" + tagName + ">")
|
buffer.WriteString("<" + tagName + ">")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if wrap {
|
||||||
|
buffer.WriteString("</iframe></div>")
|
||||||
|
} else {
|
||||||
tagStack = append(tagStack, tagName)
|
tagStack = append(tagStack, tagName)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else if isBlockedTag(tagName) {
|
} else if isBlockedTag(tagName) {
|
||||||
blacklistedTagDepth++
|
blacklistedTagDepth++
|
||||||
}
|
}
|
||||||
case html.EndTagToken:
|
case html.EndTagToken:
|
||||||
tagName := token.Data
|
tagName := token.Data
|
||||||
|
if tagName == "iframe" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
if isValidTag(tagName) && inList(tagName, tagStack) {
|
if isValidTag(tagName) && inList(tagName, tagStack) {
|
||||||
buffer.WriteString(fmt.Sprintf("</%s>", tagName))
|
buffer.WriteString(fmt.Sprintf("</%s>", tagName))
|
||||||
} else if isBlockedTag(tagName) {
|
} else if isBlockedTag(tagName) {
|
||||||
@ -417,3 +429,22 @@ func isValidDataAttribute(value string) bool {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isVideoIframe(token html.Token) bool {
|
||||||
|
videoWhitelist := map[string]bool{
|
||||||
|
"player.bilibili.com": true,
|
||||||
|
"player.vimeo.com": true,
|
||||||
|
"www.dailymotion.com": true,
|
||||||
|
"www.youtube-nocookie.com": true,
|
||||||
|
"www.youtube.com": true,
|
||||||
|
}
|
||||||
|
if token.Data == "iframe" {
|
||||||
|
for _, attr := range token.Attr {
|
||||||
|
if attr.Key == "src" {
|
||||||
|
domain := htmlutil.URLDomain(attr.Val)
|
||||||
|
return videoWhitelist[domain]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
@ -175,7 +175,7 @@ func TestInvalidIFrame(t *testing.T) {
|
|||||||
|
|
||||||
func TestIFrameWithChildElements(t *testing.T) {
|
func TestIFrameWithChildElements(t *testing.T) {
|
||||||
input := `<iframe src="https://www.youtube.com/"><p>test</p></iframe>`
|
input := `<iframe src="https://www.youtube.com/"><p>test</p></iframe>`
|
||||||
expected := `<iframe src="https://www.youtube.com/" sandbox="allow-scripts allow-same-origin allow-popups" loading="lazy"></iframe>`
|
expected := `<div class="video-wrapper"><iframe src="https://www.youtube.com/" sandbox="allow-scripts allow-same-origin allow-popups" loading="lazy"></iframe></div>`
|
||||||
output := Sanitize("http://example.com/", input)
|
output := Sanitize("http://example.com/", input)
|
||||||
|
|
||||||
if expected != output {
|
if expected != output {
|
||||||
@ -255,7 +255,7 @@ func TestEspaceAttributes(t *testing.T) {
|
|||||||
|
|
||||||
func TestReplaceIframeURL(t *testing.T) {
|
func TestReplaceIframeURL(t *testing.T) {
|
||||||
input := `<iframe src="https://player.vimeo.com/video/123456?title=0&byline=0"></iframe>`
|
input := `<iframe src="https://player.vimeo.com/video/123456?title=0&byline=0"></iframe>`
|
||||||
expected := `<iframe src="https://player.vimeo.com/video/123456?title=0&byline=0" sandbox="allow-scripts allow-same-origin allow-popups" loading="lazy"></iframe>`
|
expected := `<div class="video-wrapper"><iframe src="https://player.vimeo.com/video/123456?title=0&byline=0" sandbox="allow-scripts allow-same-origin allow-popups" loading="lazy"></iframe></div>`
|
||||||
output := Sanitize("http://example.org/", input)
|
output := Sanitize("http://example.org/", input)
|
||||||
|
|
||||||
if expected != output {
|
if expected != output {
|
||||||
@ -292,3 +292,13 @@ func TestReplaceStyle(t *testing.T) {
|
|||||||
t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
|
t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestWrapYoutubeIFrames(t *testing.T) {
|
||||||
|
input := `<iframe src="https://www.youtube.com/embed/foobar"></iframe>`
|
||||||
|
expected := `<div class="video-wrapper"><iframe src="https://www.youtube.com/embed/foobar" sandbox="allow-scripts allow-same-origin allow-popups" loading="lazy"></iframe></div>`
|
||||||
|
output := Sanitize("http://example.org/", input)
|
||||||
|
|
||||||
|
if expected != output {
|
||||||
|
t.Errorf("Wrong output:\nwant: %v\nhave: %v", expected, output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -417,7 +417,7 @@ func (s *Server) handlePageCrawl(c *router.Context) {
|
|||||||
|
|
||||||
if content := silo.VideoIFrame(url); content != "" {
|
if content := silo.VideoIFrame(url); content != "" {
|
||||||
c.JSON(http.StatusOK, map[string]string{
|
c.JSON(http.StatusOK, map[string]string{
|
||||||
"content": content,
|
"content": sanitizer.Sanitize(url, content),
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user