Skip to content

Commit

Permalink
CMS-33803: Use explicit alt text attribute
Browse files Browse the repository at this point in the history
  • Loading branch information
phensley committed Jun 2, 2021
1 parent 0f09a6b commit 44c9431
Show file tree
Hide file tree
Showing 17 changed files with 78 additions and 89 deletions.
4 changes: 4 additions & 0 deletions __tests__/helpers.ts
Expand Up @@ -123,6 +123,10 @@ export class Image extends Struct<Image> {
title(text: string): Image {
return this.set(text, 'title');
}

altText(text: string): Image {
return this.set(text, 'altText');
}
}

interface TestCase {
Expand Down
39 changes: 21 additions & 18 deletions __tests__/plugins/formatters.content.test.ts
Expand Up @@ -46,7 +46,8 @@ test('child image meta', () => {
.title('foo')
.originalSize('500x200')
.set({ foo: 1 }, 'licensedAssetPreview')
.assetUrl('http://glonk.com/');
.assetUrl('http://glonk.com/')
.altText('foo');

let vars = variables({ items: [image.get()] });
impl.apply([], vars, CTX);
Expand All @@ -57,23 +58,25 @@ test('child image meta', () => {
expect(vars[0].get()).toContain('data-image-focal-point="0.3,0.7"');
expect(vars[0].get()).toContain('alt="foo"');

vars = variables({
items: [image.title('').get()],
});
impl.apply([], vars, CTX);
expect(vars[0].get()).toContain('alt=""');

vars = variables({
items: [image.title('').set('bar', 'body').get()],
});
impl.apply([], vars, CTX);
expect(vars[0].get()).toContain('alt="bar"');

vars = variables({
items: [image.title('').set('baz', 'filename').get()],
});
impl.apply([], vars, CTX);
expect(vars[0].get()).toContain('alt="baz"');
// alt text is now set explicitly.
// TODO: remove these legacy test cases once feature is released
// vars = variables({
// items: [image.title('').get()],
// });
// impl.apply([], vars, CTX);
// expect(vars[0].get()).toContain('alt=""');

// vars = variables({
// items: [image.title('').set('bar', 'body').get()],
// });
// impl.apply([], vars, CTX);
// expect(vars[0].get()).toContain('alt="bar"');

// vars = variables({
// items: [image.title('').set('baz', 'filename').get()],
// });
// impl.apply([], vars, CTX);
// expect(vars[0].get()).toContain('alt="baz"');

vars = variables({
items: [image.set(undefined, 'mediaFocalPoint').get()],
Expand Down
5 changes: 3 additions & 2 deletions __tests__/plugins/resources/f-child-image-meta-1.html
Expand Up @@ -7,7 +7,8 @@
"originalSize": 1000,
"assetUrl": "/foo/bar.jpg",
"licensedAssetPreview": {},
"mediaFocalPoint": {"x": 0.3, "y": 0.7}
"mediaFocalPoint": {"x": 0.3, "y": 0.7},
"altText": "child alt text"
}
]
}
Expand All @@ -16,5 +17,5 @@
{@|child-image-meta 1}

:OUTPUT
data-licensed-asset-preview="true" data-src="/foo/bar.jpg" data-image="/foo/bar.jpg" data-image-dimensions="1000" data-image-focal-point="0.3,0.7" alt="child image"
data-licensed-asset-preview="true" data-src="/foo/bar.jpg" data-image="/foo/bar.jpg" data-image-dimensions="1000" data-image-focal-point="0.3,0.7" alt="child alt text"

5 changes: 3 additions & 2 deletions __tests__/plugins/resources/f-child-image-meta-2.html
Expand Up @@ -7,7 +7,8 @@
{
"body": "child image",
"originalSize": 1000,
"assetUrl": "/foo/bar.jpg"
"assetUrl": "/foo/bar.jpg",
"altText": "child alt text"
}
]
}
Expand All @@ -16,5 +17,5 @@
{@|child-image-meta 3}

:OUTPUT
data-src="/foo/bar.jpg" data-image="/foo/bar.jpg" data-image-dimensions="1000" data-image-focal-point="0.5,0.5" alt="child image"
data-src="/foo/bar.jpg" data-image="/foo/bar.jpg" data-image-dimensions="1000" data-image-focal-point="0.5,0.5" alt="child alt text"

5 changes: 3 additions & 2 deletions __tests__/plugins/resources/f-child-image-meta-3.html
Expand Up @@ -6,7 +6,8 @@
{
"filename": "child image",
"originalSize": 1000,
"assetUrl": "/foo/bar.jpg"
"assetUrl": "/foo/bar.jpg",
"altText": "child alt text"
}
]
}
Expand All @@ -15,5 +16,5 @@
{@|child-image-meta 2}

:OUTPUT
data-src="/foo/bar.jpg" data-image="/foo/bar.jpg" data-image-dimensions="1000" data-image-focal-point="0.5,0.5" alt="child image"
data-src="/foo/bar.jpg" data-image="/foo/bar.jpg" data-image-dimensions="1000" data-image-focal-point="0.5,0.5" alt="child alt text"

5 changes: 3 additions & 2 deletions __tests__/plugins/resources/f-child-image-meta-4.html
Expand Up @@ -4,7 +4,8 @@
{
"body": "<b>bold</b><div><i>italics</i></div>",
"originalSize": 1000,
"assetUrl": "/foo/bar.jpg"
"assetUrl": "/foo/bar.jpg",
"altText": "<b>bold alt text</b>"
}
]
}
Expand All @@ -13,5 +14,5 @@
{@|child-image-meta}

:OUTPUT
data-src="/foo/bar.jpg" data-image="/foo/bar.jpg" data-image-dimensions="1000" data-image-focal-point="0.5,0.5" alt=" bold italics "
data-src="/foo/bar.jpg" data-image="/foo/bar.jpg" data-image-dimensions="1000" data-image-focal-point="0.5,0.5" alt=" bold alt text "

3 changes: 2 additions & 1 deletion __tests__/plugins/resources/f-child-image-meta-6.html
Expand Up @@ -8,7 +8,8 @@
"body": "",
"filename": "",
"originalSize": 1000,
"assetUrl": "/foo/bar.jpg"
"assetUrl": "/foo/bar.jpg",
"altText": ""
}
]
}
Expand Down
5 changes: 3 additions & 2 deletions __tests__/plugins/resources/f-image-1.html
Expand Up @@ -5,12 +5,13 @@
"originalSize": 1000,
"assetUrl": "/foo/bar.jpg",
"licensedAssetPreview": {},
"mediaFocalPoint": {"x": 0.3, "y": 0.7}
"mediaFocalPoint": {"x": 0.3, "y": 0.7},
"altText": "alt text"
}

:TEMPLATE
{@|image}

:OUTPUT
<noscript><img src="/foo/bar.jpg" alt="child image" /></noscript><img class="thumb-image" data-licensed-asset-preview="true" data-src="/foo/bar.jpg" data-image="/foo/bar.jpg" data-image-dimensions="1000" data-image-focal-point="0.3,0.7" alt="child image" data-load="false" data-image-id="560c37c1a7c8465c4a71d99a" data-type="image" />
<noscript><img src="/foo/bar.jpg" alt="alt text" /></noscript><img class="thumb-image" data-licensed-asset-preview="true" data-src="/foo/bar.jpg" data-image="/foo/bar.jpg" data-image-dimensions="1000" data-image-focal-point="0.3,0.7" alt="alt text" data-load="false" data-image-id="560c37c1a7c8465c4a71d99a" data-type="image" />

5 changes: 3 additions & 2 deletions __tests__/plugins/resources/f-image-2.html
Expand Up @@ -4,12 +4,13 @@
"title": "",
"originalSize": 1000,
"assetUrl": "/foo/bar.jpg",
"mediaFocalPoint": {"x": 0.3, "y": 0.7}
"mediaFocalPoint": {"x": 0.3, "y": 0.7},
"altText": "alt text"
}

:TEMPLATE
{@|image foo-bar-image}

:OUTPUT
<noscript><img src="/foo/bar.jpg" alt="" /></noscript><img class="foo-bar-image" data-src="/foo/bar.jpg" data-image="/foo/bar.jpg" data-image-dimensions="1000" data-image-focal-point="0.3,0.7" alt="" data-load="false" data-image-id="560c37c1a7c8465c4a71d99a" data-type="image" />
<noscript><img src="/foo/bar.jpg" alt="alt text" /></noscript><img class="foo-bar-image" data-src="/foo/bar.jpg" data-image="/foo/bar.jpg" data-image-dimensions="1000" data-image-focal-point="0.3,0.7" alt="alt text" data-load="false" data-image-id="560c37c1a7c8465c4a71d99a" data-type="image" />

8 changes: 3 additions & 5 deletions __tests__/plugins/resources/f-image-3.html
@@ -1,14 +1,12 @@
:COMMENTS
should print alt text from the info document

:JSON
{
"img":{
"id": "560c37c1a7c8465c4a71d99a",
"title": "This should not be used, as the info.altText field should override",
"originalSize": 1000,
"assetUrl": "/foo/bar.jpg",
"mediaFocalPoint": {"x": 0.3, "y": 0.7}
"mediaFocalPoint": {"x": 0.3, "y": 0.7},
"altText": "alt text"
},
"info": {
"altText": "baz"
Expand All @@ -19,4 +17,4 @@
{img|image foo-bar-image}

:OUTPUT
<noscript><img src="/foo/bar.jpg" alt="baz" /></noscript><img class="foo-bar-image" data-src="/foo/bar.jpg" data-image="/foo/bar.jpg" data-image-dimensions="1000" data-image-focal-point="0.3,0.7" alt="baz" data-load="false" data-image-id="560c37c1a7c8465c4a71d99a" data-type="image" />
<noscript><img src="/foo/bar.jpg" alt="alt text" /></noscript><img class="foo-bar-image" data-src="/foo/bar.jpg" data-image="/foo/bar.jpg" data-image-dimensions="1000" data-image-focal-point="0.3,0.7" alt="alt text" data-load="false" data-image-id="560c37c1a7c8465c4a71d99a" data-type="image" />
7 changes: 4 additions & 3 deletions __tests__/plugins/resources/f-image-4.html
@@ -1,5 +1,5 @@
:COMMENTS
should print data-component-key, and alt text from image.title
should print data-component-key

:JSON
{
Expand All @@ -9,7 +9,8 @@
"originalSize": 1000,
"assetUrl": "/foo/bar.jpg",
"mediaFocalPoint": {"x": 0.3, "y": 0.7},
"componentKey": "baz"
"componentKey": "baz",
"altText": "alt text"
},
"info": {
"something": "else"
Expand All @@ -20,4 +21,4 @@
{img|image foo-bar-image}

:OUTPUT
<noscript><img src="/foo/bar.jpg" alt="no-info-alt" /></noscript><img class="foo-bar-image" data-component-key="baz" data-src="/foo/bar.jpg" data-image="/foo/bar.jpg" data-image-dimensions="1000" data-image-focal-point="0.3,0.7" alt="no-info-alt" data-load="false" data-image-id="560c37c1a7c8465c4a71d99a" data-type="image" />
<noscript><img src="/foo/bar.jpg" alt="alt text" /></noscript><img class="foo-bar-image" data-component-key="baz" data-src="/foo/bar.jpg" data-image="/foo/bar.jpg" data-image-dimensions="1000" data-image-focal-point="0.3,0.7" alt="alt text" data-load="false" data-image-id="560c37c1a7c8465c4a71d99a" data-type="image" />
8 changes: 3 additions & 5 deletions __tests__/plugins/resources/f-image-5.html
@@ -1,6 +1,3 @@
:COMMENTS
should print alt text from image.body if title is missing. Multiple whitespace characters should be reduced to 1

:JSON
{
"img": {
Expand All @@ -9,7 +6,8 @@
"originalSize": 1000,
"assetUrl": "/foo/bar.jpg",
"mediaFocalPoint": {"x": 0.3, "y": 0.7},
"body": "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa."
"body": "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.",
"altText": "alt text"
},
"info": {
"something": "else"
Expand All @@ -20,4 +18,4 @@
{img|image foo-bar-image}

:OUTPUT
<noscript><img src="/foo/bar.jpg" alt="Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa." /></noscript><img class="foo-bar-image" data-src="/foo/bar.jpg" data-image="/foo/bar.jpg" data-image-dimensions="1000" data-image-focal-point="0.3,0.7" alt="Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa." data-load="false" data-image-id="560c37c1a7c8465c4a71d99a" data-type="image" />
<noscript><img src="/foo/bar.jpg" alt="alt text" /></noscript><img class="foo-bar-image" data-src="/foo/bar.jpg" data-image="/foo/bar.jpg" data-image-dimensions="1000" data-image-focal-point="0.3,0.7" alt="alt text" data-load="false" data-image-id="560c37c1a7c8465c4a71d99a" data-type="image" />
8 changes: 3 additions & 5 deletions __tests__/plugins/resources/f-image-6.html
@@ -1,6 +1,3 @@
:COMMENTS
should print truncated alt text from image.body if title is missing and body length is more than 1000 characters

:JSON
{
"img": {
Expand All @@ -9,7 +6,8 @@
"originalSize": 1000,
"assetUrl": "/foo/bar.jpg",
"mediaFocalPoint": {"x": 0.3, "y": 0.7},
"body": "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean condimentum duis egestas felis placerat quisque nulla vestibulum aenean posuere vivamus diam semper aenean Consectetuer. Pede senectus sagittis turpis nulla, ultrices ultrices laoreet integer parturient tristique aliquet. Suscipit Id libero magna tempor in porttitor sagittis at, metus tempor dapibus vestibulum, mollis sed lacus Risus rutrum pede hendrerit semper felis primis fames nam et. Phasellus nulla dapibus dictum. Leo cum suscipit. Sed maecenas vitae senectus auctor ipsum. Cursus erat, habitant lacus diam blandit odio fermentum faucibus euismod porttitor a hymenaeos lobortis vulputate nullam vestibulum euismod neque nullam Donec fermentum varius egestas justo. Natoque ipsum penatibus magnis nunc odio. Aenean, gravida et. Habitant. Curae; augue. Nullam pulvinar ligula magna auctor etiam bibendum dictum. Blandit parturient mollis at. Neque auctor penatibus metus. Erat viverra puribus. THIS DOES NOT SHOW UP"
"body": "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean condimentum duis egestas felis placerat quisque nulla vestibulum aenean posuere vivamus diam semper aenean Consectetuer. Pede senectus sagittis turpis nulla, ultrices ultrices laoreet integer parturient tristique aliquet. Suscipit Id libero magna tempor in porttitor sagittis at, metus tempor dapibus vestibulum, mollis sed lacus Risus rutrum pede hendrerit semper felis primis fames nam et. Phasellus nulla dapibus dictum. Leo cum suscipit. Sed maecenas vitae senectus auctor ipsum. Cursus erat, habitant lacus diam blandit odio fermentum faucibus euismod porttitor a hymenaeos lobortis vulputate nullam vestibulum euismod neque nullam Donec fermentum varius egestas justo. Natoque ipsum penatibus magnis nunc odio. Aenean, gravida et. Habitant. Curae; augue. Nullam pulvinar ligula magna auctor etiam bibendum dictum. Blandit parturient mollis at. Neque auctor penatibus metus. Erat viverra puribus. THIS DOES NOT SHOW UP",
"altText": "alt text"
},
"info": {
"something": "else"
Expand All @@ -20,4 +18,4 @@
{img|image foo-bar-image}

:OUTPUT
<noscript><img src="/foo/bar.jpg" alt="Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean condimentum duis egestas felis placerat quisque nulla vestibulum aenean posuere vivamus diam semper aenean Consectetuer. Pede senectus sagittis turpis nulla, ultrices ultrices laoreet integer parturient tristique aliquet. Suscipit Id libero magna tempor in porttitor sagittis at, metus tempor dapibus vestibulum, mollis sed lacus Risus rutrum pede hendrerit semper felis primis fames nam et. Phasellus nulla dapibus dictum. Leo cum suscipit. Sed maecenas vitae senectus auctor ipsum. Cursus erat, habitant lacus diam blandit odio fermentum faucibus euismod porttitor a hymenaeos lobortis vulputate nullam vestibulum euismod neque nullam Donec fermentum varius egestas justo. Natoque ipsum penatibus magnis nunc odio. Aenean, gravida et. Habitant. Curae; augue. Nullam pulvinar ligula magna auctor etiam bibendum dictum. Blandit parturient mollis at. Neque auctor penatibus metus. Erat viverra puribus." /></noscript><img class="foo-bar-image" data-src="/foo/bar.jpg" data-image="/foo/bar.jpg" data-image-dimensions="1000" data-image-focal-point="0.3,0.7" alt="Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean condimentum duis egestas felis placerat quisque nulla vestibulum aenean posuere vivamus diam semper aenean Consectetuer. Pede senectus sagittis turpis nulla, ultrices ultrices laoreet integer parturient tristique aliquet. Suscipit Id libero magna tempor in porttitor sagittis at, metus tempor dapibus vestibulum, mollis sed lacus Risus rutrum pede hendrerit semper felis primis fames nam et. Phasellus nulla dapibus dictum. Leo cum suscipit. Sed maecenas vitae senectus auctor ipsum. Cursus erat, habitant lacus diam blandit odio fermentum faucibus euismod porttitor a hymenaeos lobortis vulputate nullam vestibulum euismod neque nullam Donec fermentum varius egestas justo. Natoque ipsum penatibus magnis nunc odio. Aenean, gravida et. Habitant. Curae; augue. Nullam pulvinar ligula magna auctor etiam bibendum dictum. Blandit parturient mollis at. Neque auctor penatibus metus. Erat viverra puribus." data-load="false" data-image-id="560c37c1a7c8465c4a71d99a" data-type="image" />
<noscript><img src="/foo/bar.jpg" alt="alt text" /></noscript><img class="foo-bar-image" data-src="/foo/bar.jpg" data-image="/foo/bar.jpg" data-image-dimensions="1000" data-image-focal-point="0.3,0.7" alt="alt text" data-load="false" data-image-id="560c37c1a7c8465c4a71d99a" data-type="image" />
6 changes: 3 additions & 3 deletions __tests__/plugins/resources/f-image-meta-1.html
Expand Up @@ -4,13 +4,13 @@
"originalSize": 1000,
"assetUrl": "/foo/bar.jpg",
"licensedAssetPreview": {},
"mediaFocalPoint": {"x": 0.3, "y": 0.7}
"mediaFocalPoint": {"x": 0.3, "y": 0.7},
"altText": "alt text"
}


:TEMPLATE
{@|image-meta 1}

:OUTPUT
data-licensed-asset-preview="true" data-src="/foo/bar.jpg" data-image="/foo/bar.jpg" data-image-dimensions="1000" data-image-focal-point="0.3,0.7" alt="image"

data-licensed-asset-preview="true" data-src="/foo/bar.jpg" data-image="/foo/bar.jpg" data-image-dimensions="1000" data-image-focal-point="0.3,0.7" alt="alt text"
15 changes: 13 additions & 2 deletions __tests__/plugins/resources/f-image-meta-2.html
@@ -1,8 +1,19 @@
:COMMENTS
should print data-component-key, and default to empty alt text

:JSON
{}
{
"originalSize": 1000,
"assetUrl": "/foo/bar.jpg",
"licensedAssetPreview": {},
"mediaFocalPoint": {"x": 0.3, "y": 0.7},
"componentKey": "baz",
"altText": "alt text"
}


:TEMPLATE
{foo|image-meta 1}
{@|image-meta 1}

:OUTPUT
data-licensed-asset-preview="true" data-component-key="baz" data-src="/foo/bar.jpg" data-image="/foo/bar.jpg" data-image-dimensions="1000" data-image-focal-point="0.3,0.7" alt="alt text"
17 changes: 1 addition & 16 deletions src/plugins/formatters.content.ts
Expand Up @@ -109,7 +109,7 @@ export class ImageFormatter extends Formatter {
const cls = args.length === 1 ? args[0] : 'thumb-image';

const id = node.get('id').asString();
const altText = escapeHtmlAttributes(this.getAltText(ctx));
const altText = escapeHtmlAttributes(getAltTextFromContentItem(node));
const assetUrl = node.get('assetUrl').asString();

let res = '<noscript>';
Expand All @@ -125,21 +125,6 @@ export class ImageFormatter extends Formatter {
res += 'data-type="image" />';
first.set(res);
}

getAltText(ctx: Context): string {
// For image blocks, caption is stored on the block and not the item.
// need to reach out via the context to see if it exist first,
// before falling back on the data on the item
const alt = ctx.resolve(['info', 'altText']);
if (!alt.isMissing()) {
const text = alt.asString().trim();
if (text.length > 0) {
return text;
}
}

return getAltTextFromContentItem(ctx.node());
}
}

const IMAGE_COLOR_POSITIONS = [
Expand Down
22 changes: 3 additions & 19 deletions src/plugins/util.content.ts
Expand Up @@ -2,8 +2,6 @@ import { isTruthy, Node } from '../node';
import { escapeHtmlAttributes, removeTags } from './util.string';
import { Type } from '../types';

const MAX_ALT_TEXT_LENGTH = 1000;

export const getFocalPoint = (media: Node) => {
const node = media.get('mediaFocalPoint');
if (!node.isMissing()) {
Expand All @@ -15,23 +13,9 @@ export const getFocalPoint = (media: Node) => {
};

export const getAltTextFromContentItem = (item: Node) => {
const title = item.get('title');
if (isTruthy(title)) {
return title.asString();
}

const body = item.get('body');
if (isTruthy(body)) {
const text = removeTags(body.asString());
const len = text.length;
if (len > 0) {
return text.substring(0, Math.min(len, MAX_ALT_TEXT_LENGTH));
}
}

const filename = item.get('filename');
if (isTruthy(filename)) {
return filename.asString();
const alt = item.get('altText');
if (isTruthy(alt)) {
return removeTags(alt.asString());
}

return '';
Expand Down

0 comments on commit 44c9431

Please sign in to comment.