Esempio n. 1
0
  visit(markdownAST, `html`, node => {
    if (node.value.startsWith(`<img`)) {
      let image = Object.assign(node, $.parseHTML(node.value)[0].attribs)
      image.url = image.src
      image.type = `image`
      image.position = node.position

      const imagePath = path.join(getNode(markdownNode.parent).dir, image.url)
      const imageNode = _.find(files, file => {
        if (file && file.absolutePath) {
          return file.absolutePath === imagePath
        }
        return false
      })
      if (
        imageNode &&
        (imageNode.extension === `gif` || imageNode.extension === `svg`)
      ) {
        visitor(image)
      }
    }
  })
Esempio n. 2
0
module.exports = (
  { files, markdownNode, markdownAST, pathPrefix, getNode },
  pluginOptions
) => {
  const defaults = {
    maxWidth: 650,
    wrapperStyle: ``,
    backgroundColor: `white`,
  }

  const options = _.defaults(pluginOptions, defaults)

  // This will only work for markdown syntax image tags
  const imageNodes = select(markdownAST, `image`)

  // This will also allow the use of html image tags
  const rawHtmlImageNodes = select(markdownAST, `html`).filter(node =>
    node.value.startsWith(`<img`)
  )

  for (let node of rawHtmlImageNodes) {
    let formattedImgTag = Object.assign(
      node,
      $.parseHTML(node.value)[0].attribs
    )
    formattedImgTag.url = formattedImgTag.src
    formattedImgTag.type = `image`
    formattedImgTag.position = node.position

    imageNodes.push(formattedImgTag)
  }

  return Promise.all(
    imageNodes.map(
      node =>
        new Promise((resolve, reject) => {
          const fileType = node.url.slice(-3)

          // Ignore gifs as we can't process them,
          // svgs as they are already responsive by definition
          if (
            isRelativeUrl(node.url) &&
            fileType !== `gif` &&
            fileType !== `svg`
          ) {
            const imagePath = path.posix.join(
              getNode(markdownNode.parent).dir,
              node.url
            )
            const imageNode = _.find(files, file => {
              if (file && file.absolutePath) {
                return file.absolutePath === imagePath
              }
              return null
            })
            if (!imageNode || !imageNode.absolutePath) {
              return resolve()
            }

            responsiveSizes({
              file: imageNode,
              args: options,
            }).then(responsiveSizesResult => {
              // console.log("responsiveSizesResult", responsiveSizesResult)
              // Calculate the paddingBottom %
              const ratio = `${1 / responsiveSizesResult.aspectRatio * 100}%`

              const originalImg = responsiveSizesResult.originalImage
              const fallbackSrc = responsiveSizesResult.src
              const srcSet = responsiveSizesResult.srcSet

              // TODO
              // add support for sub-plugins having a gatsby-node.js so can add a
              // bit of js/css to add blurry fade-in.
              // https://www.perpetual-beta.org/weblog/silky-smooth-image-loading.html
              //
              // TODO make linking to original image optional.

              // Construct new image node w/ aspect ratio placeholder
              const rawHTML = `
          <a
            class="gatsby-resp-image-link"
            href="${originalImg}"
            style="display: block"
            target="_blank"
            rel="noopener"
          >
            <span
              class="gatsby-resp-image-wrapper"
              style="position: relative; z-index: -1; display: block; ${options.wrapperStyle}"
            >
              <span
                class="gatsby-resp-image-background-image"
                style="padding-bottom: ${ratio};position: relative; width: 100%; bottom: 0; left: 0; background-image: url('${responsiveSizesResult.base64}'); background-size: cover; display: block;"
              >
                <img
                  class="gatsby-resp-image-image"
                  style="width: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px ${options.backgroundColor};"
                  alt="${node.alt ? node.alt : ``}"
                  title="${node.title ? node.title : ``}"
                  src="${fallbackSrc}"
                  srcset="${srcSet}"
                  sizes="${responsiveSizesResult.sizes}"
                />
              </span>
            </span>
          </a>
          `

              // Replace the image node with an inline HTML node.
              node.type = `html`
              node.value = rawHTML
              return resolve()
            })
          } else {
            // Image isn't relative so there's nothing for us to do.
            return resolve()
          }
        })
    )
  )
}