Skip to content

Commit

Permalink
[1.0] [source-contentful] Allow for querying gifs & when user queries…
Browse files Browse the repository at this point in the history
… for image height, actually crop (#1339)

* Rename files

* Handle gif images

* Set default focus/fit behaviors when height is set to actually trigger cropping

* Update snapshots
  • Loading branch information
KyleAMathews authored Jul 2, 2017
1 parent cbb69c3 commit 14bfcb1
Show file tree
Hide file tree
Showing 11 changed files with 103 additions and 51 deletions.
4 changes: 2 additions & 2 deletions packages/gatsby-source-contentful/.gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/gatsby-node.js
/extend-node-type.js
/process-api-data.js
/fetch-data.js
/normalize.js
/fetch.js
/__tests__
/yarn.lock
2 changes: 1 addition & 1 deletion packages/gatsby-source-contentful/scripts/download-data.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const fs = require(`fs`)
const stringify = require(`json-stringify-safe`)
const fetchData = require(`../src/fetch-data`)
const fetchData = require(`../src/fetch`)

// Fetch data from our sample site and save it to disk.
const spaceId = `rocybtov1ozk`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Object {
"aspectRatio": 1.1278195488721805,
"base64": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAlgCWAAD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wAARCAAbABQDAREAAhEBAxEB/8QAGQABAAIDAAAAAAAAAAAAAAAABgIHAwQJ/8QALhAAAQMDAgIHCQAAAAAAAAAAAQIDBAAFEQYSEzEHFCEiQVFhFRYkMkJDcXKj/8QAGQEAAgMBAAAAAAAAAAAAAAAAAQIAAwQF/8QAJREAAQQCAQEJAAAAAAAAAAAAAQACAxEEQSEiEhMxQlFhcYGh/9oADAMBAAIRAxEAPwDp4Zz3vV1Tf8OIXF2YHzb8Zzz5UNpL6qWixdparPY3lO5clSUIdVtHeSQo49OQoXwl7RoFJaZWo8tWNcqHh7Mz/U0u0nnRF2+O3DRmiJtilRJLDtyY4jzm4oLQDgXtx9WRjyrSGNhcWZAINfuvpcl078mCOXBc0guFk3VAkOqtqz6oXZQK7amhQ+lJy0rcUJy9PrlIRtOCgOqBOeXMVZ3TywzaHCwuyo2ZTccnqLSR8A+qPR2o9v0nYLbGQhhqM68oIbSAEYX4Afuazue6TlxspYo2RRNjjAAF+CtiI+JUVl4fcQFdnqKsW8cqKrfGXN62plJk8Is8Qjt2E52/jNH2QoXamIrIxhlsY5d0dlBMsgAAwBgeQqKL/9k=",
"height": 399,
"src": "//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=450&h=399&q=50",
"src": "//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=450&h=399&q=50&fit=fill&f=faces",
"width": 450,
}
`;
Expand All @@ -43,11 +43,11 @@ Object {
"aspectRatio": 1.1278195488721805,
"base64": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAlgCWAAD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wAARCAAbABQDAREAAhEBAxEB/8QAGQABAAIDAAAAAAAAAAAAAAAABgIHAwQJ/8QALhAAAQMDAgIHCQAAAAAAAAAAAQIDBAAFEQYSEzEHFCEiQVFhFRYkMkJDcXKj/8QAGQEAAgMBAAAAAAAAAAAAAAAAAQIAAwQF/8QAJREAAQQCAQEJAAAAAAAAAAAAAQACAxEEQSEiEhMxQlFhcYGh/9oADAMBAAIRAxEAPwDp4Zz3vV1Tf8OIXF2YHzb8Zzz5UNpL6qWixdparPY3lO5clSUIdVtHeSQo49OQoXwl7RoFJaZWo8tWNcqHh7Mz/U0u0nnRF2+O3DRmiJtilRJLDtyY4jzm4oLQDgXtx9WRjyrSGNhcWZAINfuvpcl078mCOXBc0guFk3VAkOqtqz6oXZQK7amhQ+lJy0rcUJy9PrlIRtOCgOqBOeXMVZ3TywzaHCwuyo2ZTccnqLSR8A+qPR2o9v0nYLbGQhhqM68oIbSAEYX4Afuazue6TlxspYo2RRNjjAAF+CtiI+JUVl4fcQFdnqKsW8cqKrfGXN62plJk8Is8Qjt2E52/jNH2QoXamIrIxhlsY5d0dlBMsgAAwBgeQqKL/9k=",
"height": 399,
"src": "//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=450&h=399&q=50",
"srcSet": "//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=450&h=399&q=50 1x,
//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=675&h=599&q=50 1.5x,
//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=900&h=798&q=50 2x,
//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=1350&h=1197&q=50 3x",
"src": "//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=450&h=399&q=50&fit=fill&f=faces",
"srcSet": "//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=450&h=399&q=50&fit=fill&f=faces 1x,
//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=675&h=599&q=50&fit=fill&f=faces 1.5x,
//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=900&h=798&q=50&fit=fill&f=faces 2x,
//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=1350&h=1197&q=50&fit=fill&f=faces 3x",
"width": 450,
}
`;
Expand Down
2 changes: 1 addition & 1 deletion packages/gatsby-source-contentful/src/__tests__/data.json
Original file line number Diff line number Diff line change
Expand Up @@ -2177,4 +2177,4 @@
"fallbackCode": "en-US"
}
]
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const processAPIData = require(`../process-api-data`)
const normalize = require(`../normalize`)
const {
currentSyncData,
contentTypeItems,
Expand All @@ -15,15 +15,15 @@ const restrictedNodeFields = [`id`, `children`, `parent`, `fields`, `internal`]

describe(`Process contentful data`, () => {
it(`builds entry list`, () => {
entryList = processAPIData.buildEntryList({
entryList = normalize.buildEntryList({
currentSyncData,
contentTypeItems,
})
expect(entryList).toMatchSnapshot()
})

it(`builds list of resolvable data`, () => {
resolvable = processAPIData.buildResolvableSet({
resolvable = normalize.buildResolvableSet({
assets: currentSyncData.assets,
entryList,
defaultLocale,
Expand All @@ -33,7 +33,7 @@ describe(`Process contentful data`, () => {
})

it(`builds foreignReferenceMap`, () => {
foreignReferenceMap = processAPIData.buildForeignReferenceMap({
foreignReferenceMap = normalize.buildForeignReferenceMap({
contentTypeItems,
entryList,
resolvable,
Expand All @@ -46,7 +46,7 @@ describe(`Process contentful data`, () => {
it(`creates nodes for each entry`, () => {
const createNode = jest.fn()
contentTypeItems.forEach((contentTypeItem, i) => {
processAPIData.createContentTypeNodes({
normalize.createContentTypeNodes({
contentTypeItem,
restrictedNodeFields,
conflictFieldPrefix,
Expand All @@ -65,7 +65,7 @@ describe(`Process contentful data`, () => {
const createNode = jest.fn()
const assets = currentSyncData.assets
assets.forEach(assetItem => {
processAPIData.createAssetNodes({
normalize.createAssetNodes({
assetItem,
createNode,
defaultLocale,
Expand All @@ -78,10 +78,10 @@ describe(`Process contentful data`, () => {

describe(`Fix contentful IDs`, () => {
it(`leaves ids that start with a string the same`, () => {
expect(processAPIData.fixId(`a123`)).toEqual(`a123`)
expect(normalize.fixId(`a123`)).toEqual(`a123`)
})
it(`left pads ids that start with a number of a "c"`, () => {
expect(processAPIData.fixId(`123`)).toEqual(`c123`)
expect(normalize.fixId(`123`)).toEqual(`c123`)
})
})

Expand All @@ -92,7 +92,7 @@ describe(`Gets field value based on current locale`, () => {
}
it(`Gets the specified locale`, () => {
expect(
processAPIData.getLocalizedField({
normalize.getLocalizedField({
field,
defaultLocale: `en-US`,
locale: {
Expand All @@ -101,7 +101,7 @@ describe(`Gets field value based on current locale`, () => {
})
).toBe(field[`en-US`])
expect(
processAPIData.getLocalizedField({
normalize.getLocalizedField({
field,
defaultLocale: `en-US`,
locale: {
Expand All @@ -112,7 +112,7 @@ describe(`Gets field value based on current locale`, () => {
})
it(`falls back to the locale's fallback locale if passed a locale that doesn't have a localized field`, () => {
expect(
processAPIData.getLocalizedField({
normalize.getLocalizedField({
field,
defaultLocale: `en-US`,
locale: {
Expand All @@ -124,7 +124,7 @@ describe(`Gets field value based on current locale`, () => {
})
it(`falls back to the default locale if passed a locale that doesn't have a field nor a fallbackCode`, () => {
expect(
processAPIData.getLocalizedField({
normalize.getLocalizedField({
field,
defaultLocale: `en-US`,
locale: {
Expand All @@ -139,7 +139,7 @@ describe(`Gets field value based on current locale`, () => {
describe(`Make IDs`, () => {
it(`It doesn't postfix the id if its the default locale`, () => {
expect(
processAPIData.makeId({
normalize.makeId({
id: `id`,
defaultLocale: `en-US`,
currentLocale: `en-US`,
Expand All @@ -148,7 +148,7 @@ describe(`Make IDs`, () => {
})
it(`It does postfix the id if its not the default locale`, () => {
expect(
processAPIData.makeId({
normalize.makeId({
id: `id`,
defaultLocale: `en-US`,
currentLocale: `en-GB`,
Expand Down
70 changes: 66 additions & 4 deletions packages/gatsby-source-contentful/src/extend-node-type.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ const ImageCropFocusType = new GraphQLEnumType({

const isImage = image =>
_.includes(
[`image/jpeg`, `image/jpg`, `image/png`, `image/webp`],
[`image/jpeg`, `image/jpg`, `image/png`, `image/webp`, `image/gif`],
image.file.contentType
)

Expand All @@ -95,6 +95,7 @@ const getBase64ImageAndBasicMeasurements = (image, args) =>
}

resolve({
contentType: image.file.contentType,
base64Str,
aspectRatio,
width: image.file.details.image.width,
Expand Down Expand Up @@ -126,14 +127,38 @@ const resolveResponsiveResolution = (image, options) => {
getBase64ImageAndBasicMeasurements(
image,
options
).then(({ base64Str, width, height, aspectRatio }) => {
).then(({ contentType, base64Str, width, height, aspectRatio }) => {
// Special case handling gifs. Contentful's image api can't handle
// them so we just return them as is.
if (contentType === `image/gif`) {
return resolve({
base64: ``,
aspectRatio: aspectRatio,
width: Math.round(options.width),
height: Math.round(pickedHeight),
src: image.file.url,
srcSet: ``,
})
}

let desiredAspectRatio = aspectRatio

// If we're cropping, calculate the specified aspect ratio.
if (options.height) {
desiredAspectRatio = options.width / options.height
}

// If the user selected a height (so cropping) and options for focus
// and fit aren't set, we'll set our defaults
if (options.height) {
if (!options.resizingBehavior) {
options.resizingBehavior = `fill`
}
if (!options.cropFocus) {
options.cropFocus = `faces`
}
}

// Create sizes (in width) for the image. If the width of the
// image is 800px, the sizes would then be: 800, 1200, 1600,
// 2400.
Expand Down Expand Up @@ -212,7 +237,21 @@ const resolveResponsiveSizes = (image, options) => {
getBase64ImageAndBasicMeasurements(
image,
options
).then(({ base64Str, width, height, aspectRatio }) => {
).then(({ contentType, base64Str, width, height, aspectRatio }) => {
// Special case handling gifs. Contentful's image api can't handle
// them so we just return them as is.
if (contentType === `image/gif`) {
return resolve({
base64: ``,
srcSet: ``,
sizes: ``,
aspectRatio: aspectRatio,
width: Math.round(options.width),
height: Math.round(pickedHeight),
src: image.file.url,
})
}

let desiredAspectRatio = aspectRatio

// If we're cropping, calculate the specified aspect ratio.
Expand Down Expand Up @@ -286,7 +325,30 @@ const resolveResize = (image, options) =>
getBase64ImageAndBasicMeasurements(
image,
options
).then(({ base64Str, width, height, aspectRatio }) => {
).then(({ contentType, base64Str, width, height, aspectRatio }) => {
// Special case handling gifs. Contentful's image api can't handle
// them so we just return them as is.
if (contentType === `image/gif`) {
return resolve({
base64: ``,
aspectRatio: aspectRatio,
width: Math.round(options.width),
height: Math.round(pickedHeight),
src: image.file.url,
})
}

// If the user selected a height (so cropping) and options for focus
// and fit aren't set, we'll set our defaults
if (options.height) {
if (!options.resizingBehavior) {
options.resizingBehavior = `fill`
}
if (!options.cropFocus) {
options.cropFocus = `faces`
}
}

if (options.base64) {
return resolve(base64Str)
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const contentful = require(`contentful`)
const _ = require(`lodash`)

const processAPIData = require(`./process-api-data`)
const normalize = require(`./normalize`)

module.exports = async ({ spaceId, accessToken, syncToken }) => {
// Fetch articles.
Expand Down Expand Up @@ -56,26 +56,26 @@ module.exports = async ({ spaceId, accessToken, syncToken }) => {
let contentTypeItems = contentTypes.items

// Fix IDs on entries and assets, created/updated and deleted.
contentTypeItems = contentTypeItems.map(c => processAPIData.fixIds(c))
contentTypeItems = contentTypeItems.map(c => normalize.fixIds(c))

currentSyncData.entries = currentSyncData.entries.map(e => {
if (e) {
return processAPIData.fixIds(e)
return normalize.fixIds(e)
}
})
currentSyncData.assets = currentSyncData.assets.map(a => {
if (a) {
return processAPIData.fixIds(a)
return normalize.fixIds(a)
}
})
currentSyncData.deletedEntries = currentSyncData.deletedEntries.map(e => {
if (e) {
return processAPIData.fixIds(e)
return normalize.fixIds(e)
}
})
currentSyncData.deletedAssets = currentSyncData.deletedAssets.map(a => {
if (a) {
return processAPIData.fixIds(a)
return normalize.fixIds(a)
}
})

Expand Down
14 changes: 7 additions & 7 deletions packages/gatsby-source-contentful/src/gatsby-node.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const _ = require(`lodash`)

const processAPIData = require(`./process-api-data`)
const fetchData = require(`./fetch-data`)
const normalize = require(`./normalize`)
const fetchData = require(`./fetch`)

const conflictFieldPrefix = `contentful`

Expand Down Expand Up @@ -53,7 +53,7 @@ exports.sourceNodes = async (
accessToken,
})

const entryList = processAPIData.buildEntryList({
const entryList = normalize.buildEntryList({
currentSyncData,
contentTypeItems,
})
Expand Down Expand Up @@ -89,7 +89,7 @@ exports.sourceNodes = async (

// Create map of resolvable ids so we can check links against them while creating
// links.
const resolvable = processAPIData.buildResolvableSet({
const resolvable = normalize.buildResolvableSet({
existingNodes,
entryList,
assets,
Expand All @@ -98,7 +98,7 @@ exports.sourceNodes = async (
})

// Build foreign reference map before starting to insert any nodes
const foreignReferenceMap = processAPIData.buildForeignReferenceMap({
const foreignReferenceMap = normalize.buildForeignReferenceMap({
contentTypeItems,
entryList,
resolvable,
Expand Down Expand Up @@ -136,7 +136,7 @@ exports.sourceNodes = async (
})

contentTypeItems.forEach((contentTypeItem, i) => {
processAPIData.createContentTypeNodes({
normalize.createContentTypeNodes({
contentTypeItem,
restrictedNodeFields,
conflictFieldPrefix,
Expand All @@ -150,7 +150,7 @@ exports.sourceNodes = async (
})

assets.forEach(assetItem => {
processAPIData.createAssetNodes({
normalize.createAssetNodes({
assetItem,
createNode,
defaultLocale,
Expand Down
10 changes: 0 additions & 10 deletions packages/gatsby-source-contentful/src/proxy-handlers.js

This file was deleted.

0 comments on commit 14bfcb1

Please sign in to comment.