Skip to content

Commit

Permalink
fix(gatsby-remark-responsive-iframe): iframe ratio is NaN if d… (#18328)
Browse files Browse the repository at this point in the history
* simplify width/height value check, ratio calculation doesnt return NaN

* update test snapshot

* modernize the code

* update test snapshot (remove extra colon, extra space)

* convert: add comments, trim off white space
  • Loading branch information
d4rekanguok authored and pieh committed Oct 8, 2019
1 parent 08dc747 commit 257f5d6
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 98 deletions.
1 change: 0 additions & 1 deletion packages/gatsby-remark-responsive-iframe/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
},
"dependencies": {
"@babel/runtime": "^7.6.2",
"bluebird": "^3.7.0",
"cheerio": "^1.0.0-rc.3",
"common-tags": "^1.8.0",
"lodash": "^4.17.15",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`gatsby-remark-responsive-iframe can copy JSX images 1`] = `"<div class=\\"gatsby-resp-iframe-wrapper\\" style=\\"padding-bottom: NaN%; position: relative; height: 0; overflow: hidden;\\" > <iframe url=\\"http://www.example.com/\\" style=\\"border:0; position: absolute; top: 0; left: 0; width: 100%; height: 100%; \\"></iframe> </div>"`;
exports[`gatsby-remark-responsive-iframe can copy JSX images 1`] = `"<div class=\\"gatsby-resp-iframe-wrapper\\" style=\\"padding-bottom: 66.66666666666666%; position: relative; height: 0; overflow: hidden; \\" > <iframe url=\\"http://www.example.com/\\" style=\\"border:0; position: absolute; top: 0; left: 0; width: 100%; height: 100%; \\"></iframe> </div>"`;
exports[`gatsby-remark-responsive-iframe doesn't transform an iframe with dimensions: '100%' '100' 1`] = `
" <iframe url=\\"http://www.example.com/\\" width=\\"100%\\" height=\\"100\\"></iframe>
Expand Down Expand Up @@ -42,18 +42,18 @@ exports[`gatsby-remark-responsive-iframe doesn't transform an object with dimens
"
`;
exports[`gatsby-remark-responsive-iframe transforms an iframe and maintains existing styles 1`] = `"<div class=\\"gatsby-resp-iframe-wrapper\\" style=\\"padding-bottom: NaN%; position: relative; height: 0; overflow: hidden;\\" > <iframe url=\\"http://www.example.com/\\" style=\\"border:0; position: absolute; top: 0; left: 0; width: 100%; height: 100%; \\"></iframe> </div>"`;
exports[`gatsby-remark-responsive-iframe transforms an iframe and maintains existing styles 1`] = `"<div class=\\"gatsby-resp-iframe-wrapper\\" style=\\"padding-bottom: 66.66666666666666%; position: relative; height: 0; overflow: hidden; \\" > <iframe url=\\"http://www.example.com/\\" style=\\"border:0; position: absolute; top: 0; left: 0; width: 100%; height: 100%; \\"></iframe> </div>"`;
exports[`gatsby-remark-responsive-iframe transforms an iframe and maintains existing styles when a semicolon exists 1`] = `"<div class=\\"gatsby-resp-iframe-wrapper\\" style=\\"padding-bottom: NaN%; position: relative; height: 0; overflow: hidden;\\" > <iframe url=\\"http://www.example.com/\\" style=\\"border:0; position: absolute; top: 0; left: 0; width: 100%; height: 100%; \\"></iframe> </div>"`;
exports[`gatsby-remark-responsive-iframe transforms an iframe and maintains existing styles when a semicolon exists 1`] = `"<div class=\\"gatsby-resp-iframe-wrapper\\" style=\\"padding-bottom: 66.66666666666666%; position: relative; height: 0; overflow: hidden; \\" > <iframe url=\\"http://www.example.com/\\" style=\\"border:0; position: absolute; top: 0; left: 0; width: 100%; height: 100%; \\"></iframe> </div>"`;
exports[`gatsby-remark-responsive-iframe transforms an iframe with pixel width and height 1`] = `"<div class=\\"gatsby-resp-iframe-wrapper\\" style=\\"padding-bottom: NaN%; position: relative; height: 0; overflow: hidden;\\" > <iframe url=\\"http://www.example.com/\\" style=\\" position: absolute; top: 0; left: 0; width: 100%; height: 100%; \\"></iframe> </div>"`;
exports[`gatsby-remark-responsive-iframe transforms an iframe with pixel width and height 1`] = `"<div class=\\"gatsby-resp-iframe-wrapper\\" style=\\"padding-bottom: 66.66666666666666%; position: relative; height: 0; overflow: hidden; \\" > <iframe url=\\"http://www.example.com/\\" style=\\" position: absolute; top: 0; left: 0; width: 100%; height: 100%; \\"></iframe> </div>"`;
exports[`gatsby-remark-responsive-iframe transforms an iframe with unitless width and height 1`] = `"<div class=\\"gatsby-resp-iframe-wrapper\\" style=\\"padding-bottom: 66.66666666666666%; position: relative; height: 0; overflow: hidden;\\" > <iframe url=\\"http://www.example.com/\\" style=\\" position: absolute; top: 0; left: 0; width: 100%; height: 100%; \\"></iframe> </div>"`;
exports[`gatsby-remark-responsive-iframe transforms an iframe with unitless width and height 1`] = `"<div class=\\"gatsby-resp-iframe-wrapper\\" style=\\"padding-bottom: 66.66666666666666%; position: relative; height: 0; overflow: hidden; \\" > <iframe url=\\"http://www.example.com/\\" style=\\" position: absolute; top: 0; left: 0; width: 100%; height: 100%; \\"></iframe> </div>"`;
exports[`gatsby-remark-responsive-iframe transforms an object and maintains existing styles 1`] = `"<div class=\\"gatsby-resp-iframe-wrapper\\" style=\\"padding-bottom: NaN%; position: relative; height: 0; overflow: hidden;\\" > <object url=\\"http://www.example.com/\\" style=\\" position: absolute; top: 0; left: 0; width: 100%; height: 100%; \\"></object> </div>"`;
exports[`gatsby-remark-responsive-iframe transforms an object and maintains existing styles 1`] = `"<div class=\\"gatsby-resp-iframe-wrapper\\" style=\\"padding-bottom: 66.66666666666666%; position: relative; height: 0; overflow: hidden; \\" > <object url=\\"http://www.example.com/\\" style=\\" position: absolute; top: 0; left: 0; width: 100%; height: 100%; \\"></object> </div>"`;
exports[`gatsby-remark-responsive-iframe transforms an object and maintains existing styles when a semicolon exists 1`] = `"<div class=\\"gatsby-resp-iframe-wrapper\\" style=\\"padding-bottom: NaN%; position: relative; height: 0; overflow: hidden;\\" > <object url=\\"http://www.example.com/\\" style=\\" position: absolute; top: 0; left: 0; width: 100%; height: 100%; \\"></object> </div>"`;
exports[`gatsby-remark-responsive-iframe transforms an object and maintains existing styles when a semicolon exists 1`] = `"<div class=\\"gatsby-resp-iframe-wrapper\\" style=\\"padding-bottom: 66.66666666666666%; position: relative; height: 0; overflow: hidden; \\" > <object url=\\"http://www.example.com/\\" style=\\" position: absolute; top: 0; left: 0; width: 100%; height: 100%; \\"></object> </div>"`;
exports[`gatsby-remark-responsive-iframe transforms an object with pixel width and height 1`] = `"<div class=\\"gatsby-resp-iframe-wrapper\\" style=\\"padding-bottom: NaN%; position: relative; height: 0; overflow: hidden;\\" > <object url=\\"http://www.example.com/\\" style=\\" position: absolute; top: 0; left: 0; width: 100%; height: 100%; \\"></object> </div>"`;
exports[`gatsby-remark-responsive-iframe transforms an object with pixel width and height 1`] = `"<div class=\\"gatsby-resp-iframe-wrapper\\" style=\\"padding-bottom: 66.66666666666666%; position: relative; height: 0; overflow: hidden; \\" > <object url=\\"http://www.example.com/\\" style=\\" position: absolute; top: 0; left: 0; width: 100%; height: 100%; \\"></object> </div>"`;
exports[`gatsby-remark-responsive-iframe transforms an object with unitless width and height 1`] = `"<div class=\\"gatsby-resp-iframe-wrapper\\" style=\\"padding-bottom: 66.66666666666666%; position: relative; height: 0; overflow: hidden;\\" > <object url=\\"http://www.example.com/\\" style=\\" position: absolute; top: 0; left: 0; width: 100%; height: 100%; \\"></object> </div>"`;
exports[`gatsby-remark-responsive-iframe transforms an object with unitless width and height 1`] = `"<div class=\\"gatsby-resp-iframe-wrapper\\" style=\\"padding-bottom: 66.66666666666666%; position: relative; height: 0; overflow: hidden; \\" > <object url=\\"http://www.example.com/\\" style=\\" position: absolute; top: 0; left: 0; width: 100%; height: 100%; \\"></object> </div>"`;
134 changes: 67 additions & 67 deletions packages/gatsby-remark-responsive-iframe/src/index.js
Original file line number Diff line number Diff line change
@@ -1,85 +1,85 @@
const visit = require(`unist-util-visit`)
const cheerio = require(`cheerio`)
const Promise = require(`bluebird`)
const { oneLine } = require(`common-tags`)
const _ = require(`lodash`)

const isPixelNumber = n => /\d+px$/.test(n)

const isUnitlessNumber = n => {
const nToNum = _.toNumber(n)
return _.isFinite(nToNum)
}
const needsSemicolon = str => !str.endsWith(`;`)

const isUnitlessOrPixelNumber = n =>
n && (isUnitlessNumber(n) || isPixelNumber(n))
/**
* Convert anything to number, except for % value.
* We don't have to check for other values (em, vw, etc.)
* because the browsers will treat them as px anyway.
* @param {*} n something to be converted to number
* @returns {number}
*/
const convert = n =>
typeof n === `string` && n.trim().endsWith(`%`) ? NaN : parseInt(n, 10)

const needsSemicolon = str => !str.endsWith(`;`)
/**
* Check whether all passed in arguments are valid number or not
* @param {...number} args dimension to check
* @returns {boolean}
*/
const isValidDimensions = (...args) => args.every(n => _.isFinite(n))

// Aspect ratio can only be determined if both width and height are unitless or
// pixel values. Any other values mean the responsive wrapper is not applied.
const acceptedDimensions = (width, height) =>
isUnitlessOrPixelNumber(width) && isUnitlessOrPixelNumber(height)
module.exports = async ({ markdownAST }, pluginOptions = {}) => {
const defaults = {
wrapperStyle: ``,
}
const options = _.defaults(pluginOptions, defaults)
visit(markdownAST, [`html`, `jsx`], node => {
const $ = cheerio.load(node.value)
const iframe = $(`iframe, object`)
if (iframe.length === 0) {
return
}

module.exports = ({ markdownAST }, pluginOptions = {}) =>
new Promise(resolve => {
const defaults = {
wrapperStyle: ``,
const width = convert(iframe.attr(`width`))
const height = convert(iframe.attr(`height`))
if (!isValidDimensions(width, height)) {
return
}
const options = _.defaults(pluginOptions, defaults)
visit(markdownAST, [`html`, `jsx`], node => {
const $ = cheerio.load(node.value)
const iframe = $(`iframe, object`)
if (iframe.length) {
const width = iframe.attr(`width`)
const height = iframe.attr(`height`)

if (acceptedDimensions(width, height)) {
const existingStyle = $(`iframe`).attr(`style`) // Other plugins might set border: 0
// so we make sure that we maintain those existing styles. If other styles like height or
// width are already defined they will be overridden anyway.
let fullStyle = $(`iframe`).attr(`style`) || `` // Other plugins might set border: 0
// so we make sure that we maintain those existing styles. If other styles like height or
// width are already defined they will be overridden anyway.

let fullStyle = ``
if (existingStyle && needsSemicolon(existingStyle)) {
fullStyle = `${existingStyle};`
} else if (existingStyle) {
fullStyle = existingStyle
}
if (fullStyle.length > 0 && needsSemicolon(fullStyle)) {
fullStyle = `${fullStyle};`
}

$(`iframe, object`).attr(
`style`,
`${fullStyle}
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
`
)
$(`iframe, object`)
.attr(`width`, null)
.attr(`height`, null)
const newIframe = $(`body`).html() // fix for cheerio v1
$(`iframe, object`)
.attr(
`style`,
`${fullStyle}
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
`
)
.attr(`width`, null)
.attr(`height`, null)

// TODO add youtube preview image as background-image.
const newIframe = $(`body`).html() // fix for cheerio v1

const rawHTML = oneLine`
<div
class="gatsby-resp-iframe-wrapper"
style="padding-bottom: ${(height / width) *
100}%; position: relative; height: 0; overflow: hidden;${
options.wrapperStyle
}"
>
${newIframe}
</div>
`
// TODO add youtube preview image as background-image.

node.type = `html`
node.value = rawHTML
}
}
})
const rawHTML = oneLine`
<div
class="gatsby-resp-iframe-wrapper"
style="padding-bottom: ${(height / width) *
100}%; position: relative; height: 0; overflow: hidden;
${options.wrapperStyle}"
>
${newIframe}
</div>
`

return resolve(markdownAST)
node.type = `html`
node.value = rawHTML
})

return markdownAST
}
23 changes: 2 additions & 21 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -19784,7 +19784,7 @@ type-of@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/type-of/-/type-of-2.0.1.tgz#e72a1741896568e9f628378d816d6912f7f23972"

typedarray-to-buffer@^3.1.5, typedarray-to-buffer@~3.1.5:
typedarray-to-buffer@~3.1.5:
version "3.1.5"
resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080"
integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==
Expand Down Expand Up @@ -21119,7 +21119,7 @@ wrappy@1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"

write-file-atomic@2.4.1, write-file-atomic@^2.0.0, write-file-atomic@^2.3.0:
write-file-atomic@2.4.1, write-file-atomic@^2.0.0, write-file-atomic@^2.3.0, write-file-atomic@^2.4.2, write-file-atomic@^3.0.0:
version "2.4.1"
resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.1.tgz#d0b05463c188ae804396fd5ab2a370062af87529"
integrity sha512-TGHFeZEZMnv+gBFRfjAcxL5bPHrsGKtnb4qsFAws7/vlh+QfwAaySIw4AXP9ZskTTh5GWu3FLuJhsWVdiJPGvg==
Expand All @@ -21128,25 +21128,6 @@ write-file-atomic@2.4.1, write-file-atomic@^2.0.0, write-file-atomic@^2.3.0:
imurmurhash "^0.1.4"
signal-exit "^3.0.2"

write-file-atomic@^2.4.2:
version "2.4.3"
resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.3.tgz#1fd2e9ae1df3e75b8d8c367443c692d4ca81f481"
integrity sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==
dependencies:
graceful-fs "^4.1.11"
imurmurhash "^0.1.4"
signal-exit "^3.0.2"

write-file-atomic@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.0.tgz#1b64dbbf77cb58fd09056963d63e62667ab4fb21"
integrity sha512-EIgkf60l2oWsffja2Sf2AL384dx328c0B+cIYPTQq5q2rOYuDV00/iPFBOUiDKKwKMOhkymH8AidPaRvzfxY+Q==
dependencies:
imurmurhash "^0.1.4"
is-typedarray "^1.0.0"
signal-exit "^3.0.2"
typedarray-to-buffer "^3.1.5"

write-file-stdout@0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/write-file-stdout/-/write-file-stdout-0.0.2.tgz#c252d7c7c5b1b402897630e3453c7bfe690d9ca1"
Expand Down

0 comments on commit 257f5d6

Please # to comment.