diff --git a/extensions/amp-sidebar/0.1/amp-sidebar.css b/extensions/amp-sidebar/0.1/amp-sidebar.css index b499e295d2b2..f2843f17ddf6 100644 --- a/extensions/amp-sidebar/0.1/amp-sidebar.css +++ b/extensions/amp-sidebar/0.1/amp-sidebar.css @@ -28,6 +28,10 @@ amp-sidebar { -webkit-overflow-scrolling: touch; } +amp-sidebar[side] { + display: block !important; +} + amp-sidebar[side="left"] { left: 0 !important; transform: translateX(-80vw) !important; @@ -38,19 +42,15 @@ amp-sidebar[side="right"] { transform: translateX(80vw) !important; } -.amp-sidebar-open amp-sidebar { +amp-sidebar[side][open] { transform: translateX(0vw) !important; } -.amp-sidebar-closed amp-sidebar, -.amp-sidebar-open amp-sidebar { +amp-sidebar[open], +.-amp-sidebar-closed { transition: transform 0.5s ease; } -.amp-sidebar-open { - overflow: hidden !important; -} - .-amp-sidebar-mask { position: fixed !important; top: 0 !important; @@ -64,7 +64,3 @@ amp-sidebar[side="right"] { z-index: 9998 !important; display: none; } - -.amp-sidebar-open .-amp-sidebar-mask { - display: block; -} diff --git a/extensions/amp-sidebar/0.1/amp-sidebar.js b/extensions/amp-sidebar/0.1/amp-sidebar.js index cca3be320cd2..0a52797886d1 100644 --- a/extensions/amp-sidebar/0.1/amp-sidebar.js +++ b/extensions/amp-sidebar/0.1/amp-sidebar.js @@ -39,7 +39,7 @@ export class AmpSidebar extends AMP.BaseElement { /** @override */ isLayoutSupported(layout) { - return layout == Layout.CONTAINER; + return layout == Layout.NOLAYOUT; } /** @override */ @@ -67,8 +67,8 @@ export class AmpSidebar extends AMP.BaseElement { /** @private @const {!Viewport} */ this.viewport_ = this.getViewport(); - /** @private @const {boolean} */ - this.hasMask_ = false; + /** @private @const {!Element} */ + this.maskElement_ = false; /** @private @const {boolean} */ this.isPaddingAdjusted_ = false; @@ -97,9 +97,10 @@ export class AmpSidebar extends AMP.BaseElement { this.fixIosElasticScrollLeak_(); } - if (this.documentElement_.classList.contains('amp-sidebar-open')) { - // Create the mask if the sidebar is rendered in open mode. + if (this.isOpen_()) { this.open_(); + } else { + this.element.setAttribute('aria-hidden', 'true'); } this.documentElement_.addEventListener('keydown', event => { @@ -141,6 +142,7 @@ export class AmpSidebar extends AMP.BaseElement { setStyles(div, { 'height': IOS_SAFARI_BOTTOMBAR_HEIGHT, 'width': '100%', + 'background-color': 'transparent', }); this.element.appendChild(div); } @@ -152,13 +154,22 @@ export class AmpSidebar extends AMP.BaseElement { * @private */ toggle_() { - if (this.documentElement_.classList.contains('amp-sidebar-open')) { + if (this.isOpen_()) { this.close_(); } else { this.open_(); } } + /** + * Returns true if the sidebar is opened. + * @returns {boolean} + * @private + */ + isOpen_() { + return this.element.hasAttribute('open'); + } + /** * Reveals the sidebar. * @private @@ -170,9 +181,10 @@ export class AmpSidebar extends AMP.BaseElement { } this.mutateElement(() => { this.viewport_.addToFixedLayer(this.element); - this.createMask_(); - this.documentElement_.classList.add('amp-sidebar-open'); - this.documentElement_.classList.remove('amp-sidebar-closed'); + this.openMask_(); + this.element.setAttribute('open', ''); + this.element.classList.remove('-amp-sidebar-closed'); + this.element.setAttribute('aria-hidden', 'false'); this.element./*REVIEW*/scrollTop = 1; }); } @@ -184,8 +196,10 @@ export class AmpSidebar extends AMP.BaseElement { close_() { this.viewport_.restoreOriginalTouchZoom(); this.mutateElement(() => { - this.documentElement_.classList.remove('amp-sidebar-open'); - this.documentElement_.classList.add('amp-sidebar-closed'); + this.closeMask_() + this.element.removeAttribute('open'); + this.element.classList.add('-amp-sidebar-closed'); + this.element.setAttribute('aria-hidden', 'true'); this.viewport_.removeFromFixedLayer(this.element); }); } @@ -217,20 +231,33 @@ export class AmpSidebar extends AMP.BaseElement { /** * @private */ - createMask_() { - if (this.hasMask_) { - return; + openMask_() { + if (!this.maskElement_) { + const mask = this.document_.createElement('div'); + mask.classList.add('-amp-sidebar-mask'); + mask.addEventListener('click', () => { + this.close_(); + }); + this.element.parentNode.appendChild(mask); + mask.addEventListener('touchmove', e => { + e.preventDefault(); + }); + this.maskElement_ = mask; } - const mask = this.document_.createElement('div'); - mask.classList.add('-amp-sidebar-mask'); - mask.addEventListener('click', () => { - this.toggle_(); - }); - this.element.parentNode.appendChild(mask); - mask.addEventListener('touchmove', e => { - e.preventDefault(); + setStyles(this.maskElement_, { + 'display': 'block', }); - this.hasMask_ = true; + } + + /** + * @private + */ + closeMask_() { + if (this.maskElement_) { + setStyles(this.maskElement_, { + 'display': 'none', + }); + } } /** @@ -238,7 +265,7 @@ export class AmpSidebar extends AMP.BaseElement { */ fixIosElasticScrollLeak_() { this.element.addEventListener('scroll', e => { - if (this.documentElement_.classList.contains('amp-sidebar-open')) { + if (this.isOpen_()) { if (this.element./*REVIEW*/scrollTop < 1) { this.element./*REVIEW*/scrollTop = 1; e.preventDefault(); diff --git a/extensions/amp-sidebar/0.1/test/test-amp-sidebar.js b/extensions/amp-sidebar/0.1/test/test-amp-sidebar.js index c1bce917d54a..ea7dc88961bd 100644 --- a/extensions/amp-sidebar/0.1/test/test-amp-sidebar.js +++ b/extensions/amp-sidebar/0.1/test/test-amp-sidebar.js @@ -94,8 +94,10 @@ describe('amp-sidebar', () => { callback(); }; impl.open_(); - expect(iframe.doc.documentElement.classList.contains('amp-sidebar-open')) - .to.be.true; + expect(sidebarElement.hasAttribute('open')).to.be.true; + expect(sidebarElement.getAttribute('aria-hidden')).to.equal('false'); + expect(sidebarElement.classList.contains('-amp-sidebar-closed')) + .to.be.false; }); }); @@ -108,9 +110,10 @@ describe('amp-sidebar', () => { callback(); }; impl.close_(); - expect( - iframe.doc.documentElement.classList.contains('amp-sidebar-closed')) - .to.be.true; + expect(sidebarElement.hasAttribute('open')).to.be.false; + expect(sidebarElement.getAttribute('aria-hidden')).to.equal('true'); + expect(sidebarElement.classList.contains('-amp-sidebar-closed')) + .to.be.true; }); }); @@ -122,23 +125,20 @@ describe('amp-sidebar', () => { impl.mutateElement = function(callback) { callback(); }; - expect(iframe.doc.documentElement.classList.contains('amp-sidebar-open')) + expect(sidebarElement.hasAttribute('open')).to.be.false; + expect(sidebarElement.getAttribute('aria-hidden')).to.equal('true'); + expect(sidebarElement.classList.contains('-amp-sidebar-closed')) .to.be.false; - expect( - iframe.doc.documentElement.classList.contains('amp-sidebar-closed')) - .to.be.false; impl.toggle_(); - expect(iframe.doc.documentElement.classList.contains('amp-sidebar-open')) - .to.be.true; - expect( - iframe.doc.documentElement.classList.contains('amp-sidebar-closed')) - .to.be.false; - impl.toggle_(); - expect(iframe.doc.documentElement.classList.contains('amp-sidebar-open')) + expect(sidebarElement.hasAttribute('open')).to.be.true; + expect(sidebarElement.getAttribute('aria-hidden')).to.equal('false'); + expect(sidebarElement.classList.contains('-amp-sidebar-closed')) .to.be.false; - expect( - iframe.doc.documentElement.classList.contains('amp-sidebar-closed')) - .to.be.true; + impl.toggle_(); + expect(sidebarElement.hasAttribute('open')).to.be.false; + expect(sidebarElement.getAttribute('aria-hidden')).to.equal('true'); + expect(sidebarElement.classList.contains('-amp-sidebar-closed')) + .to.be.true; }); }); @@ -150,14 +150,12 @@ describe('amp-sidebar', () => { impl.mutateElement = function(callback) { callback(); }; - expect(iframe.doc.documentElement.classList.contains('amp-sidebar-open')) - .to.be.false; + expect(sidebarElement.hasAttribute('open')).to.be.false; impl.open_(); - expect(iframe.doc.documentElement.classList.contains('amp-sidebar-open')) - .to.be.true; - expect( - iframe.doc.documentElement.classList.contains('amp-sidebar-closed')) - .to.be.false; + expect(sidebarElement.hasAttribute('open')).to.be.true; + expect(sidebarElement.getAttribute('aria-hidden')).to.equal('false'); + expect(sidebarElement.classList.contains('-amp-sidebar-closed')) + .to.be.false; const eventObj = document.createEventObject ? document.createEventObject() : document.createEvent('Events'); if (eventObj.initEvent) { @@ -169,11 +167,10 @@ describe('amp-sidebar', () => { const el = iframe.doc.documentElement; el.dispatchEvent ? el.dispatchEvent(eventObj) : el.fireEvent('onkeydown', eventObj); - expect(iframe.doc.documentElement.classList.contains('amp-sidebar-open')) - .to.be.false; - expect( - iframe.doc.documentElement.classList.contains('amp-sidebar-closed')) - .to.be.true; + expect(sidebarElement.hasAttribute('open')).to.be.false; + expect(sidebarElement.getAttribute('aria-hidden')).to.equal('true'); + expect(sidebarElement.classList.contains('-amp-sidebar-closed')) + .to.be.true; }); }); diff --git a/extensions/amp-sidebar/amp-sidebar.md b/extensions/amp-sidebar/amp-sidebar.md index 62dbec087d2b..5b8d6ed3337b 100644 --- a/extensions/amp-sidebar/amp-sidebar.md +++ b/extensions/amp-sidebar/amp-sidebar.md @@ -71,6 +71,7 @@ Alternatively pressing the escape key on the keyboard will also close the lightb Example ```html