diff --git a/packages/ember-svg-jar/addon/utils/make-svg.js b/packages/ember-svg-jar/addon/utils/make-svg.js index c53bfc6..f9aa27f 100644 --- a/packages/ember-svg-jar/addon/utils/make-svg.js +++ b/packages/ember-svg-jar/addon/utils/make-svg.js @@ -1,6 +1,17 @@ import { isNone } from '@ember/utils'; import { htmlSafe } from '@ember/template'; -import { guidFor } from '@ember/object/internals'; + +/** + * This taken from https://github.com/emberjs/ember.js/blob/089a021b1b5c5f8ea1cb574fcd841a73af7b2031/packages/%40ember/-internals/glimmer/lib/helpers/unique-id.ts#L44 + * In the future it should be possible to import this function like + * `import { uniqueId } from '@ember/helper` + * see https://github.com/emberjs/ember.js/pull/20165 + */ +function uniqueId() { + return ([3e7] + -1e3 + -4e3 + -2e3 + -1e11).replace(/[0-3]/g, a => + ((a * 4) ^ ((Math.random() * 16) >> (a & 2))).toString(16) + ); +} const accessibilityElements = ['title', 'desc']; @@ -44,13 +55,17 @@ export function sanitizeAttrs(attrs) { export function generateAccessibilityIds(attrs) { if (attrs.title) { - attrs.title = { text: attrs.title }; - attrs.title.id = guidFor(attrs.title); + attrs.title = { + id: uniqueId(), + text: attrs.title, + }; } if (attrs.desc) { - attrs.desc = { text: attrs.desc }; - attrs.desc.id = guidFor(attrs.desc); + attrs.desc = { + id: uniqueId(), + text: attrs.desc, + }; } return attrs; diff --git a/packages/ember-svg-jar/tests/integration/helpers/svg-jar-test.js b/packages/ember-svg-jar/tests/integration/helpers/svg-jar-test.js index 912e6d5..37db1f9 100644 --- a/packages/ember-svg-jar/tests/integration/helpers/svg-jar-test.js +++ b/packages/ember-svg-jar/tests/integration/helpers/svg-jar-test.js @@ -1,6 +1,6 @@ import { module, test } from 'qunit'; import { setupRenderingTest } from 'ember-qunit'; -import { render } from '@ember/test-helpers'; +import { find, render } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; module('Integration | Helper | svg-jar', function (hooks) { @@ -68,6 +68,44 @@ module('Integration | Helper | svg-jar', function (hooks) { .doesNotHaveAttribute('desc'); }); + test('it adds unqiue ids to SVG accessibility elements when multiple svg-jar instances use the same text for title or desc', async function (assert) { + await render( + hbs` + {{svg-jar "icon" class="myicon" title="Green rectangle" desc="A light green rectangle" data-test-icon="true" data-test-id="one"}} + {{svg-jar "icon" class="myicon" title="Green rectangle" desc="A light green rectangle" data-test-icon="true" data-test-id="two"}}` + ); + + assert + .dom('[data-test-id="one"] title') + .hasText('Green rectangle') + .hasAttribute('id'); + + assert + .dom('[data-test-id="one"] desc') + .hasText('A light green rectangle') + .hasAttribute('id'); + + assert + .dom('[data-test-id="two"] title') + .hasText('Green rectangle') + .hasAttribute('id'); + + assert + .dom('[data-test-id="two"] desc') + .hasText('A light green rectangle') + .hasAttribute('id'); + + assert.notEqual( + find('[data-test-id="one"] title').id, + find('[data-test-id="two"] title').id + ); + + assert.notEqual( + find('[data-test-id="one"] desc').id, + find('[data-test-id="two"] desc').id + ); + }); + test('it allows to set a11y SVG attributes for decorative images', async function (assert) { await render( hbs`{{svg-jar "icon" role="presentation" data-test-id="one"}}`