Skip to content

Commit

Permalink
feat(gatsby-remark-copy-linked-files): add support for video elements…
Browse files Browse the repository at this point in the history
… with `src` attribute (gatsbyjs#10395)

This adds support for video elements that only have a `src` attribute.

```html
<video src="myvideo.mp4"></video>
```
  • Loading branch information
janmonschke authored and gpetrioli committed Jan 22, 2019
1 parent e7db5ec commit b2016f7
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 104 deletions.
12 changes: 12 additions & 0 deletions packages/gatsby-remark-copy-linked-files/src/__tests__/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,18 @@ describe(`gatsby-remark-copy-linked-files`, () => {
expect(fsExtra.copy).toHaveBeenCalled()
})

it(`can copy HTML videos from video elements with the src attribute`, async () => {
const path = `videos/sample-video.mp4`

const markdownAST = remark.parse(
`<video controls="controls" autoplay="true" src="${path}">\n<p>Your browser does not support the video element.</p>\n</video>`
)

await plugin({ files: getFiles(path), markdownAST, markdownNode, getNode })

expect(fsExtra.copy).toHaveBeenCalled()
})

it(`can copy HTML videos when some siblings are in ignore extensions`, async () => {
const path = `videos/sample-video.mp4`
const path1 = `images/sample-image.jpg`
Expand Down
150 changes: 46 additions & 104 deletions packages/gatsby-remark-copy-linked-files/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -206,127 +206,69 @@ module.exports = (
visit(markdownAST, `html`, node => {
const $ = cheerio.load(node.value)

// Handle Images
const imageRefs = []
$(`img`).each(function() {
try {
if (isRelativeUrl($(this).attr(`src`))) {
imageRefs.push($(this))
}
} catch (err) {
// Ignore
}
})

for (let thisImg of imageRefs) {
function processUrl({ url }) {
try {
const ext = thisImg
.attr(`src`)
.split(`.`)
.pop()
if (!options.ignoreFileExtensions.includes(ext)) {
generateImagesAndUpdateNode(thisImg, node)
}
} catch (err) {
// Ignore
}
}

// Handle video tags.
const videoRefs = []
$(`video source`).each(function() {
try {
if (isRelativeUrl($(this).attr(`src`))) {
videoRefs.push($(this))
}
} catch (err) {
// Ignore
}
})

for (let thisVideo of videoRefs) {
try {
const ext = thisVideo
.attr(`src`)
.split(`.`)
.pop()
const ext = url.split(`.`).pop()
if (!options.ignoreFileExtensions.includes(ext)) {
// The link object will be modified to the new location so we'll
// use that data to update our ref
const link = { url: thisVideo.attr(`src`) }
const link = { url }
visitor(link)
node.value = node.value.replace(
new RegExp(thisVideo.attr(`src`), `g`),
link.url
)
node.value = node.value.replace(new RegExp(url, `g`), link.url)
}
} catch (err) {
// Ignore
}
}

// Handle audio tags.
const audioRefs = []
$(`audio source`).each(function() {
try {
if (isRelativeUrl($(this).attr(`src`))) {
audioRefs.push($(this))
}
} catch (err) {
// Ignore
}
})

for (let thisAudio of audioRefs) {
try {
const ext = thisAudio
.attr(`src`)
.split(`.`)
.pop()
if (!options.ignoreFileExtensions.includes(ext)) {
const link = { url: thisAudio.attr(`src`) }
visitor(link)
node.value = node.value.replace(
new RegExp(thisAudio.attr(`src`), `g`),
link.url
)
}
} catch (err) {
// Ignore
}
// extracts all elements that have the provided url attribute
function extractUrlAttributeAndElement(selection, attribute) {
return (
selection
// extract the elements that have the attribute
.map(function() {
const element = $(this)
const url = $(this).attr(attribute)
if (url && isRelativeUrl(url)) {
return { url, element }
}
return undefined
})
// cheerio object -> array
.toArray()
// filter out empty or undefined values
.filter(Boolean)
)
}

// Handle a tags.
const aRefs = []
$(`a`).each(function() {
try {
if (isRelativeUrl($(this).attr(`href`))) {
aRefs.push($(this))
// Handle Images
extractUrlAttributeAndElement($(`img[src]`), `src`).forEach(
({ url, element }) => {
try {
const ext = url.split(`.`).pop()
if (!options.ignoreFileExtensions.includes(ext)) {
generateImagesAndUpdateNode(element, node)
}
} catch (err) {
// Ignore
}
} catch (err) {
// Ignore
}
})
)

for (let thisATag of aRefs) {
try {
const ext = thisATag
.attr(`href`)
.split(`.`)
.pop()
if (!options.ignoreFileExtensions.includes(ext)) {
const link = { url: thisATag.attr(`href`) }
visitor(link)
// Handle video tags.
extractUrlAttributeAndElement(
$(`video source[src], video[src]`),
`src`
).forEach(processUrl)

node.value = node.value.replace(
new RegExp(thisATag.attr(`href`), `g`),
link.url
)
}
} catch (err) {
// Ignore
}
}
// Handle audio tags.
extractUrlAttributeAndElement(
$(`audio source[src], audio[src]`),
`src`
).forEach(processUrl)

// Handle a tags.
extractUrlAttributeAndElement($(`a[href]`), `href`).forEach(processUrl)

return
})
Expand Down

0 comments on commit b2016f7

Please sign in to comment.