diff --git a/src/component.js b/src/component.js index a02f9949..99c0efb6 100644 --- a/src/component.js +++ b/src/component.js @@ -152,6 +152,14 @@ export default class Component { }; } + /** + * get iframe title for component. + * @return {String} iframe title. + */ + get iframeTitle() { + return this.options.text && this.options.text.iframeTitle; + } + /** * initializes component by creating model and rendering view. * @param {Object} [data] - data to initialize model with. diff --git a/src/components/cart.js b/src/components/cart.js index ce8c3e9a..8eaeca3f 100644 --- a/src/components/cart.js +++ b/src/components/cart.js @@ -201,6 +201,10 @@ export default class Cart extends Component { return `${this.props.client.config.storefrontAccessToken}.${this.props.client.config.domain}.checkoutId`; } + get iframeTitle() { + return this.options.text.title; + } + imageForLineItem(lineItem) { const imageSize = 180; const imageOptions = { diff --git a/src/defaults/components.js b/src/defaults/components.js index 72f12c72..1bc66056 100644 --- a/src/defaults/components.js +++ b/src/defaults/components.js @@ -84,6 +84,7 @@ const defaults = { unitPriceAccessibilitySeparator: 'per', regularPriceAccessibilityLabel: 'Regular price', salePriceAccessibilityLabel: 'Sale price', + iframeTitle: 'Product buy button', }, }, modalProduct: { @@ -122,6 +123,7 @@ const defaults = { buttonDestination: 'cart', text: { button: 'ADD TO CART', + iframeTitle: 'Product details modal buy button', }, }, modal: { @@ -147,6 +149,9 @@ const defaults = { }, order: ['contents'], templates: modalTemplates, + text: { + iframeTitle: 'Product details modal', + }, }, productSet: { iframe: true, @@ -173,6 +178,7 @@ const defaults = { }, text: { nextPageButton: 'Next page', + iframeTitle: 'Product collection buy buttons', }, }, option: { @@ -305,6 +311,7 @@ const defaults = { }, text: { title: 'cart', + iframeTitle: 'Cart toggle', }, }, window: { diff --git a/src/iframe.js b/src/iframe.js index 43e36f0d..b95ed414 100644 --- a/src/iframe.js +++ b/src/iframe.js @@ -93,6 +93,9 @@ export default class iframe { }); Object.keys(iframeAttrs).forEach((key) => this.el.setAttribute(key, iframeAttrs[key])); this.el.setAttribute('name', config.name); + if (config.title) { + this.el.setAttribute('title', config.title); + } this.styleTag = null; } diff --git a/src/view.js b/src/view.js index 9701f213..ff2825b0 100644 --- a/src/view.js +++ b/src/view.js @@ -30,6 +30,7 @@ export default class View { googleFonts: this.component.googleFonts, name: this.component.name, width: this.component.options.layout === 'vertical' ? this.component.options.width : null, + title: this.component.iframeTitle, }); this.iframe.addClass(this.className); return this.iframe.load(); diff --git a/test/unit/cart/cart.js b/test/unit/cart/cart.js index 8958ff92..8e4fd899 100644 --- a/test/unit/cart/cart.js +++ b/test/unit/cart/cart.js @@ -1590,4 +1590,10 @@ describe('Cart class', () => { viewSetFocusStub.restore(); }); }); + + describe('get iframeTitle', () => { + it('returns the title from the options text', () => { + assert.equal(cart.iframeTitle, cart.options.text.title); + }); + }); }); diff --git a/test/unit/component.js b/test/unit/component.js index 55ee04df..fa0f7ec8 100644 --- a/test/unit/component.js +++ b/test/unit/component.js @@ -417,6 +417,12 @@ describe('Component class', () => { }); }); }); + + describe('iframeTitle', () => { + it('returns the iframeTitle from the options text', () => { + assert.equal(component.iframeTitle, component.options.text.iframeTitle); + }); + }); }); describe('"private" methods', () => { diff --git a/test/unit/iframe.js b/test/unit/iframe.js index 6d3dad5e..75659320 100644 --- a/test/unit/iframe.js +++ b/test/unit/iframe.js @@ -62,6 +62,7 @@ describe('Iframe class', () => { constructorConfig = Object.assign({}, configObject, { googleFonts: ['Arial', 'Calibri'], width: '200px', + title: 'Iframe title', }); createElementSpy = sinon.spy(document, 'createElement'); setWidthStub = sinon.stub(Iframe.prototype, 'setWidth'); @@ -137,6 +138,19 @@ describe('Iframe class', () => { assert.equal(iframe.el.getAttribute('name'), constructorConfig.name); }); + it('sets element title to title in config if it exists', () => { + assert.equal(iframe.el.getAttribute('title'), constructorConfig.title); + }); + + it('does not set element title if it does not exist in the config', () => { + constructorConfig.title = null; + const setAttributeStub = sinon.stub(iframe.el, 'setAttribute'); + iframe = new Iframe(parent, constructorConfig); + assert.neverCalledWith(setAttributeStub, 'title'); + assert.equal(iframe.el.getAttribute('title'), null); + setAttributeStub.restore(); + }); + it('sets styleTag to null', () => { iframe = new Iframe(parent, constructorConfig); assert.equal(iframe.styleTag = null); diff --git a/test/unit/view.js b/test/unit/view.js index bf83ced3..789133b9 100644 --- a/test/unit/view.js +++ b/test/unit/view.js @@ -65,6 +65,9 @@ describe('View class', () => { value: { iframe: true, manifest: ['product', 'option'], + text: { + iframeTitle: 'Iframe title', + }, }, }); });