From 38f7b2e123acb02df85cf0b61fba9f74c8885be2 Mon Sep 17 00:00:00 2001 From: Erwin Mombay Date: Mon, 27 Feb 2017 11:30:41 -0800 Subject: [PATCH] trigger `amp-dom-update` event on insert and replace --- build-system/server.js | 12 ++-- examples/live-list-update.amp.html | 43 +++++++++---- extensions/amp-live-list/0.1/amp-live-list.js | 11 +++- .../0.1/test/test-amp-live-list.js | 61 +++++++++++++++++++ 4 files changed, 106 insertions(+), 21 deletions(-) diff --git a/build-system/server.js b/build-system/server.js index 3a427c307009a..28d9fdb6963e6 100644 --- a/build-system/server.js +++ b/build-system/server.js @@ -31,10 +31,6 @@ var url = require('url'); app.use(bodyParser.json()); -app.use('/ping', function(req, res, next) { - res.end('pong'); -}); - app.use('/pwa', function(req, res, next) { var file; var contentType; @@ -320,10 +316,10 @@ app.use('/examples/live-list-update.amp.(min|max).html', function(req, res) { }); function liveListReplace(item) { - //item.setAttribute('data-update-time', Date.now()); - //var itemContents = item.querySelectorAll('.content'); - //itemContents[0].textContent = Math.floor(Math.random() * 10); - //itemContents[1].textContent = Math.floor(Math.random() * 10); + item.setAttribute('data-update-time', Date.now()); + var itemContents = item.querySelectorAll('.content'); + itemContents[0].textContent = Math.floor(Math.random() * 10); + itemContents[1].textContent = Math.floor(Math.random() * 10); } function liveListInsert(liveList, node) { diff --git a/examples/live-list-update.amp.html b/examples/live-list-update.amp.html index 2401390fbdeb6..6ac78f965465c 100644 --- a/examples/live-list-update.amp.html +++ b/examples/live-list-update.amp.html @@ -91,7 +91,6 @@ - @@ -108,20 +107,42 @@
-
- -
+
+ +
2
+
+
+
2
+ +
-
- -
+
+ +
2
+
+
+
2
+ +
diff --git a/extensions/amp-live-list/0.1/amp-live-list.js b/extensions/amp-live-list/0.1/amp-live-list.js index 0590a5daa314c..f731161923d54 100644 --- a/extensions/amp-live-list/0.1/amp-live-list.js +++ b/extensions/amp-live-list/0.1/amp-live-list.js @@ -287,6 +287,9 @@ export class AmpLiveList extends AMP.BaseElement { const hasInsertItems = this.pendingItemsInsert_.length > 0; const hasTombstoneItems = this.pendingItemsTombstone_.length > 0; + const shouldSendAmpDomUpdateEvent = this.pendingItemsInsert_.length > 0 || + this.pendingItemsReplace_.length > 0; + let promise = this.mutateElement(() => { const itemsSlot = user().assertElement(this.itemsSlot_); @@ -333,10 +336,14 @@ export class AmpLiveList extends AMP.BaseElement { // number of items to delete down to `data-max-items-per-page`. return this.removeOverflowItems_(itemsSlot); // TODO(erwinm, #3332) compensate scroll position here. - }).then(() => { - this.sendAmpDomUpdateEvent_(); }); + if (shouldSendAmpDomUpdateEvent) { + promise = promise.then(() => { + this.sendAmpDomUpdateEvent_(); + }); + } + if (hasInsertItems) { promise = promise.then(() => { return this.viewport_.animateScrollIntoView(this.element); diff --git a/extensions/amp-live-list/0.1/test/test-amp-live-list.js b/extensions/amp-live-list/0.1/test/test-amp-live-list.js index fa2a8bfa5ec8c..d4843cf90dbba 100644 --- a/extensions/amp-live-list/0.1/test/test-amp-live-list.js +++ b/extensions/amp-live-list/0.1/test/test-amp-live-list.js @@ -262,6 +262,67 @@ describe('amp-live-list', () => { liveList.buildCallback(); }); + it('sends amp-dom-update event on new items', () => { + buildElement(elem, dftAttrs); + liveList.buildCallback(); + const spy = sandbox.spy(liveList, 'sendAmpDomUpdateEvent_' ); + const fromServer1 = createFromServer([{id: 'id0'}]); + liveList.update(fromServer1); + return liveList.updateAction_().then(() => { + expect(spy).to.have.been.calledOnce; + }); + }); + + it('sends amp-dom-update event on replace items', () => { + const child1 = document.createElement('div'); + const child2 = document.createElement('div'); + child1.setAttribute('id', 'id1'); + child2.setAttribute('id', 'id2'); + child1.setAttribute('data-sort-time', '123'); + child2.setAttribute('data-sort-time', '124'); + itemsSlot.appendChild(child1); + itemsSlot.appendChild(child2); + buildElement(elem, dftAttrs); + liveList.buildCallback(); + + const fromServer1 = createFromServer([ + {id: 'id1', updateTime: 125}, + ]); + const spy = sandbox.spy(liveList, 'sendAmpDomUpdateEvent_'); + // We stub and restore to not trigger `update` calling `updateAction_`. + const stub = sinon.stub(liveList, 'updateAction_'); + liveList.update(fromServer1); + stub.restore(); + return liveList.updateAction_().then(() => { + expect(spy).to.have.been.calledOnce; + }); + }); + + it('sends amp-dom-update event on tombstone items', () => { + const child1 = document.createElement('div'); + const child2 = document.createElement('div'); + child1.setAttribute('id', 'id1'); + child2.setAttribute('id', 'id2'); + child1.setAttribute('data-sort-time', '123'); + child2.setAttribute('data-sort-time', '124'); + itemsSlot.appendChild(child1); + itemsSlot.appendChild(child2); + buildElement(elem, dftAttrs); + liveList.buildCallback(); + + const fromServer1 = createFromServer([ + {id: 'id1', tombstone: null}, + ]); + const spy = sandbox.spy(liveList, 'sendAmpDomUpdateEvent_'); + // We stub and restore to not trigger `update` calling `updateAction_`. + const stub = sinon.stub(liveList, 'updateAction_'); + liveList.update(fromServer1); + stub.restore(); + return liveList.updateAction_().then(() => { + expect(spy).to.not.have.been.called; + }); + }); + it('validates children during update', () => { const update = document.createElement('div'); const updateLiveListItems = document.createElement('div');